kaitai_struct
kaitai_struct copied to clipboard
Python: referencing imported nested types
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
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.
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.
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.