kaitai_struct icon indicating copy to clipboard operation
kaitai_struct copied to clipboard

Python: referencing imported nested types

Open GreyCat opened this issue 5 years ago • 3 comments

Hi, I wonder if this is already implemented, or I'm using it the wrong way. I'm trying to consolidate various individual ksy files into one file, and then calling those as subtypes, but I'm not getting the expected results at least under python. However using opaques, It works. How should I use it, if it is implemented?

Follow is the example

File test1.ksy

meta:
  id: test1
  imports:
    - test2

seq:
  - id: test3
    type: test2::test3

I got the following python, no import test2, and no test2.Test3 neither

class Test1(KaitaiStruct):
    def __init__(self, _io, _parent=None, _root=None):
        self._io = _io
        self._parent = _parent
        self._root = _root if _root else self
        self._read()

    def _read(self):
        self.test3 = self._root.Test3(self._io, self, self._root)

However, if I use opaque-types as follows:

File test1.ksy

meta:
  id: test1
  ks-opaque-types: true

seq:
  - id: test3
    type: test2::test3

Then python code is:

import test2
class Test1(KaitaiStruct):
    def __init__(self, _io, _parent=None, _root=None):
        self._io = _io
        self._parent = _parent
        self._root = _root if _root else self
        self._read()

    def _read(self):
        self.test3 = test2.self._root.Test3(self._io)

Originally posted by @LmpOSX in https://github.com/kaitai-io/kaitai_struct/issues/35#issuecomment-586656870

GreyCat avatar Feb 17 '20 10:02 GreyCat

I confirm that (1) the syntax is correct, (2) this seems to be broken now and needs fixing.

It looks like we do have a::b::c syntax test in nested_types3, but we don't have the relevant test for that + imported types.

GreyCat avatar Feb 17 '20 10:02 GreyCat

Facing the same issue here. Trying to put a bunch of enums in a separate file and import and reference them. Doesn't work in Python.

kjczarne avatar Jul 16 '20 10:07 kjczarne

I did some fiddling with this. Top-level imports work, but anything under types or enums from an imported file doesn't get code-generated properly. Kaitai will accept that as valid ksy, but the output code will be missing the imports.

If you use a top-level import dummy (as some comments have suggested), code-gen will put an import your_module_here statement, however, using individual types and enums still does not work. I also found that ks-opaque-types: true has no impact on this generation.

Given this ksy

meta:
  id: example
  endian: le
  imports:
    - shared
seq:
  - id: field1
    type: shared::thing
types:
  dummy:
    seq:
      - id: dummy
        type: shared

We get this output

from pkg_resources import parse_version
import kaitaistruct
from kaitaistruct import KaitaiStruct, KaitaiStream, BytesIO


if parse_version(kaitaistruct.__version__) < parse_version('0.9'):
    raise Exception("Incompatible Kaitai Struct Python API: 0.9 or later is required, but you have %s" % (kaitaistruct.__version__))

# The import we want to see!
import shared 
class Example(KaitaiStruct):
    def __init__(self, _io, _parent=None, _root=None):
        self._io = _io
        self._parent = _parent
        self._root = _root if _root else self
        self._read()

    def _read(self):
        # This still doesn't work because we need shared.Shared	
        self.field1 = Shared.Thing(self._io, self, self._root)

    class Dummy(KaitaiStruct):
        def __init__(self, _io, _parent=None, _root=None):
            self._io = _io
            self._parent = _parent
            self._root = _root if _root else self
            self._read()

        def _read(self):
            self.dummy = shared.Shared(self._io)

So I suppose this means we can import a single type (provided there is only one per-file as the top-level seq), however we cannot use imported enums currently.

Also worth pointing out no import statements are generated for the Construct target.

Mimickal avatar Jan 28 '22 05:01 Mimickal