From 043a24f2e498358ee0aebd70f45f1a9b6654e1f0 Mon Sep 17 00:00:00 2001 From: Joshua Smith <102520999+joshua-smith8@users.noreply.github.com> Date: Wed, 26 Oct 2022 22:56:52 +0100 Subject: [PATCH] [Python] Fixed the issue with nested unions relying on InitFromBuf. (#7576) * feat: Fixed the issue with nested unions relying on InitFromBuf. Problem: Issue #7569 Nested Unions were broken with the introduction of parsing buffers with an initial encoding offset. Fix: Revert the InitFromBuf method to the previous version and introduction of InitFromPackedBuf that allows users to read types from packed buffers applying the offset automatically. Test: Added in TestNestedUnionTables to test the encoding and decoding ability using a nested table with a union field. * fix: Uncommented generate code command --- scripts/generate_code.py | 16 +- src/idl_gen_python.cpp | 18 +- tests/MyGame/Example/Ability.py | 8 +- tests/MyGame/Example/ArrayStruct.py | 8 +- tests/MyGame/Example/ArrayTable.py | 8 +- tests/MyGame/Example/Monster.py | 8 +- tests/MyGame/Example/NestedStruct.py | 8 +- tests/MyGame/Example/NestedUnion/Any.py | 20 +++ tests/MyGame/Example/NestedUnion/Color.py | 12 ++ .../Example/NestedUnion/NestedUnionTest.py | 133 +++++++++++++++ tests/MyGame/Example/NestedUnion/Test.py | 66 ++++++++ .../NestedUnion/TestSimpleTableWithEnum.py | 78 +++++++++ tests/MyGame/Example/NestedUnion/Vec3.py | 155 ++++++++++++++++++ tests/MyGame/Example/NestedUnion/__init__.py | 0 tests/MyGame/Example/Referrable.py | 8 +- tests/MyGame/Example/Stat.py | 8 +- tests/MyGame/Example/StructOfStructs.py | 8 +- .../Example/StructOfStructsOfStructs.py | 8 +- tests/MyGame/Example/Test.py | 8 +- .../MyGame/Example/TestSimpleTableWithEnum.py | 8 +- tests/MyGame/Example/TypeAliases.py | 8 +- tests/MyGame/Example/Vec3.py | 8 +- tests/MyGame/Example2/Monster.py | 8 +- tests/MyGame/InParentNamespace.py | 8 +- tests/MyGame/MonsterExtra.py | 8 +- tests/PythonTest.sh | 1 + tests/monster_test_generated.py | 96 ++++++++--- tests/nested_union_test.fbs | 36 ++++ tests/optional_scalars/ScalarStuff.py | 8 +- tests/py_test.py | 64 ++++++++ 30 files changed, 766 insertions(+), 65 deletions(-) create mode 100644 tests/MyGame/Example/NestedUnion/Any.py create mode 100644 tests/MyGame/Example/NestedUnion/Color.py create mode 100644 tests/MyGame/Example/NestedUnion/NestedUnionTest.py create mode 100644 tests/MyGame/Example/NestedUnion/Test.py create mode 100644 tests/MyGame/Example/NestedUnion/TestSimpleTableWithEnum.py create mode 100644 tests/MyGame/Example/NestedUnion/Vec3.py create mode 100644 tests/MyGame/Example/NestedUnion/__init__.py create mode 100644 tests/nested_union_test.fbs diff --git a/scripts/generate_code.py b/scripts/generate_code.py index 96a7b8eaa99..dd84cfdfb0f 100755 --- a/scripts/generate_code.py +++ b/scripts/generate_code.py @@ -147,7 +147,7 @@ def glob(path, pattern): LOBSTER_OPTS = ["--lobster"] SWIFT_OPTS = ["--swift", "--gen-json-emit", "--bfbs-filenames", str(tests_path)] SWIFT_OPTS_CODE_GEN = [ - "--swift", + "--swift", "--gen-json-emit", "--bfbs-filenames", swift_code_gen @@ -305,14 +305,14 @@ def glob(path, pattern): # Generate the annotated binary of the monster_test binary schema. flatc_annotate( - schema="../reflection/reflection.fbs", - file="monster_test.bfbs", + schema="../reflection/reflection.fbs", + file="monster_test.bfbs", include="include_test" ) flatc_annotate( - schema="monster_test.fbs", - file="monsterdata_test.mon", + schema="monster_test.fbs", + file="monsterdata_test.mon", include="include_test" ) @@ -371,6 +371,12 @@ def glob(path, pattern): ) +flatc( + BASE_OPTS + PYTHON_OPTS, + schema="nested_union_test.fbs", +) + + # Optional Scalars optional_scalars_schema = "optional_scalars.fbs" flatc(["--java", "--kotlin", "--lobster"], schema=optional_scalars_schema) diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp index 289b18691f1..52fc6e5a927 100644 --- a/src/idl_gen_python.cpp +++ b/src/idl_gen_python.cpp @@ -1108,13 +1108,25 @@ class PythonGenerator : public BaseGenerator { code += GenIndents(1) + "@classmethod"; code += GenIndents(1) + "def InitFromBuf(cls, buf, pos):"; - code += GenIndents(2) + "n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0)"; code += GenIndents(2) + struct_var + " = " + struct_type + "()"; - code += GenIndents(2) + struct_var + ".Init(buf, pos+n)"; + code += GenIndents(2) + struct_var + ".Init(buf, pos)"; code += GenIndents(2) + "return cls.InitFromObj(" + struct_var + ")"; code += "\n"; } + void InitializeFromPackedBuf(const StructDef &struct_def, + std::string *code_ptr) const { + auto &code = *code_ptr; + const auto struct_var = namer_.Variable(struct_def); + const auto struct_type = namer_.Type(struct_def); + + code += GenIndents(1) + "@classmethod"; + code += GenIndents(1) + "def InitFromPackedBuf(cls, buf, pos=0):"; + code += GenIndents(2) + "n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)"; + code += GenIndents(2) + "return cls.InitFromBuf(buf, pos+n)"; + code += "\n"; + } + void InitializeFromObjForObject(const StructDef &struct_def, std::string *code_ptr) const { auto &code = *code_ptr; @@ -1607,6 +1619,8 @@ class PythonGenerator : public BaseGenerator { InitializeFromBuf(struct_def, &code); + InitializeFromPackedBuf(struct_def, &code); + InitializeFromObjForObject(struct_def, &code); GenUnPack(struct_def, &code); diff --git a/tests/MyGame/Example/Ability.py b/tests/MyGame/Example/Ability.py index 7d3b9552bfd..e0344e5fd0e 100644 --- a/tests/MyGame/Example/Ability.py +++ b/tests/MyGame/Example/Ability.py @@ -38,11 +38,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) ability = Ability() - ability.Init(buf, pos+n) + ability.Init(buf, pos) return cls.InitFromObj(ability) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, ability): x = AbilityT() diff --git a/tests/MyGame/Example/ArrayStruct.py b/tests/MyGame/Example/ArrayStruct.py index 3b54cb23794..d80f84253f5 100644 --- a/tests/MyGame/Example/ArrayStruct.py +++ b/tests/MyGame/Example/ArrayStruct.py @@ -123,11 +123,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) arrayStruct = ArrayStruct() - arrayStruct.Init(buf, pos+n) + arrayStruct.Init(buf, pos) return cls.InitFromObj(arrayStruct) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, arrayStruct): x = ArrayStructT() diff --git a/tests/MyGame/Example/ArrayTable.py b/tests/MyGame/Example/ArrayTable.py index 0eacdb99d19..b7a3ac5b676 100644 --- a/tests/MyGame/Example/ArrayTable.py +++ b/tests/MyGame/Example/ArrayTable.py @@ -62,11 +62,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) arrayTable = ArrayTable() - arrayTable.Init(buf, pos+n) + arrayTable.Init(buf, pos) return cls.InitFromObj(arrayTable) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, arrayTable): x = ArrayTableT() diff --git a/tests/MyGame/Example/Monster.py b/tests/MyGame/Example/Monster.py index 654fdcbe3b5..2490c2849ee 100644 --- a/tests/MyGame/Example/Monster.py +++ b/tests/MyGame/Example/Monster.py @@ -1131,11 +1131,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) monster = Monster() - monster.Init(buf, pos+n) + monster.Init(buf, pos) return cls.InitFromObj(monster) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, monster): x = MonsterT() diff --git a/tests/MyGame/Example/NestedStruct.py b/tests/MyGame/Example/NestedStruct.py index 21065efae2c..7f8d18ef196 100644 --- a/tests/MyGame/Example/NestedStruct.py +++ b/tests/MyGame/Example/NestedStruct.py @@ -111,11 +111,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) nestedStruct = NestedStruct() - nestedStruct.Init(buf, pos+n) + nestedStruct.Init(buf, pos) return cls.InitFromObj(nestedStruct) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, nestedStruct): x = NestedStructT() diff --git a/tests/MyGame/Example/NestedUnion/Any.py b/tests/MyGame/Example/NestedUnion/Any.py new file mode 100644 index 00000000000..e0b85942414 --- /dev/null +++ b/tests/MyGame/Example/NestedUnion/Any.py @@ -0,0 +1,20 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: NestedUnion + +class Any(object): + NONE = 0 + Vec3 = 1 + TestSimpleTableWithEnum = 2 + +def AnyCreator(unionType, table): + from flatbuffers.table import Table + if not isinstance(table, Table): + return None + if unionType == Any().Vec3: + import MyGame.Example.NestedUnion.Vec3 + return MyGame.Example.NestedUnion.Vec3.Vec3T.InitFromBuf(table.Bytes, table.Pos) + if unionType == Any().TestSimpleTableWithEnum: + import MyGame.Example.NestedUnion.TestSimpleTableWithEnum + return MyGame.Example.NestedUnion.TestSimpleTableWithEnum.TestSimpleTableWithEnumT.InitFromBuf(table.Bytes, table.Pos) + return None diff --git a/tests/MyGame/Example/NestedUnion/Color.py b/tests/MyGame/Example/NestedUnion/Color.py new file mode 100644 index 00000000000..6ba9ca1c633 --- /dev/null +++ b/tests/MyGame/Example/NestedUnion/Color.py @@ -0,0 +1,12 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: NestedUnion + +# Composite components of Monster color. +class Color(object): + Red = 1 + # \brief color Green + # Green is bit_flag with value (1u << 1) + Green = 2 + # \brief color Blue (1u << 3) + Blue = 8 diff --git a/tests/MyGame/Example/NestedUnion/NestedUnionTest.py b/tests/MyGame/Example/NestedUnion/NestedUnionTest.py new file mode 100644 index 00000000000..9a3cbee2250 --- /dev/null +++ b/tests/MyGame/Example/NestedUnion/NestedUnionTest.py @@ -0,0 +1,133 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: NestedUnion + +import flatbuffers +from flatbuffers.compat import import_numpy +np = import_numpy() + +class NestedUnionTest(object): + __slots__ = ['_tab'] + + @classmethod + def GetRootAs(cls, buf, offset=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset) + x = NestedUnionTest() + x.Init(buf, n + offset) + return x + + @classmethod + def GetRootAsNestedUnionTest(cls, buf, offset=0): + """This method is deprecated. Please switch to GetRootAs.""" + return cls.GetRootAs(buf, offset) + # NestedUnionTest + def Init(self, buf, pos): + self._tab = flatbuffers.table.Table(buf, pos) + + # NestedUnionTest + def Name(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) + if o != 0: + return self._tab.String(o + self._tab.Pos) + return None + + # NestedUnionTest + def DataType(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos) + return 0 + + # NestedUnionTest + def Data(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8)) + if o != 0: + from flatbuffers.table import Table + obj = Table(bytearray(), 0) + self._tab.Union(obj, o) + return obj + return None + + # NestedUnionTest + def Id(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos) + return 0 + +def NestedUnionTestStart(builder): builder.StartObject(4) +def Start(builder): + return NestedUnionTestStart(builder) +def NestedUnionTestAddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0) +def AddName(builder, name): + return NestedUnionTestAddName(builder, name) +def NestedUnionTestAddDataType(builder, dataType): builder.PrependUint8Slot(1, dataType, 0) +def AddDataType(builder, dataType): + return NestedUnionTestAddDataType(builder, dataType) +def NestedUnionTestAddData(builder, data): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(data), 0) +def AddData(builder, data): + return NestedUnionTestAddData(builder, data) +def NestedUnionTestAddId(builder, id): builder.PrependInt16Slot(3, id, 0) +def AddId(builder, id): + return NestedUnionTestAddId(builder, id) +def NestedUnionTestEnd(builder): return builder.EndObject() +def End(builder): + return NestedUnionTestEnd(builder) +import MyGame.Example.NestedUnion.Any +import MyGame.Example.NestedUnion.TestSimpleTableWithEnum +import MyGame.Example.NestedUnion.Vec3 +try: + from typing import Union +except: + pass + +class NestedUnionTestT(object): + + # NestedUnionTestT + def __init__(self): + self.name = None # type: str + self.dataType = 0 # type: int + self.data = None # type: Union[None, MyGame.Example.NestedUnion.Vec3.Vec3T, MyGame.Example.NestedUnion.TestSimpleTableWithEnum.TestSimpleTableWithEnumT] + self.id = 0 # type: int + + @classmethod + def InitFromBuf(cls, buf, pos): + nestedUnionTest = NestedUnionTest() + nestedUnionTest.Init(buf, pos) + return cls.InitFromObj(nestedUnionTest) + + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + + @classmethod + def InitFromObj(cls, nestedUnionTest): + x = NestedUnionTestT() + x._UnPack(nestedUnionTest) + return x + + # NestedUnionTestT + def _UnPack(self, nestedUnionTest): + if nestedUnionTest is None: + return + self.name = nestedUnionTest.Name() + self.dataType = nestedUnionTest.DataType() + self.data = MyGame.Example.NestedUnion.Any.AnyCreator(self.dataType, nestedUnionTest.Data()) + self.id = nestedUnionTest.Id() + + # NestedUnionTestT + def Pack(self, builder): + if self.name is not None: + name = builder.CreateString(self.name) + if self.data is not None: + data = self.data.Pack(builder) + NestedUnionTestStart(builder) + if self.name is not None: + NestedUnionTestAddName(builder, name) + NestedUnionTestAddDataType(builder, self.dataType) + if self.data is not None: + NestedUnionTestAddData(builder, data) + NestedUnionTestAddId(builder, self.id) + nestedUnionTest = NestedUnionTestEnd(builder) + return nestedUnionTest diff --git a/tests/MyGame/Example/NestedUnion/Test.py b/tests/MyGame/Example/NestedUnion/Test.py new file mode 100644 index 00000000000..143d1dfde99 --- /dev/null +++ b/tests/MyGame/Example/NestedUnion/Test.py @@ -0,0 +1,66 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: NestedUnion + +import flatbuffers +from flatbuffers.compat import import_numpy +np = import_numpy() + +class Test(object): + __slots__ = ['_tab'] + + @classmethod + def SizeOf(cls): + return 4 + + # Test + def Init(self, buf, pos): + self._tab = flatbuffers.table.Table(buf, pos) + + # Test + def A(self): return self._tab.Get(flatbuffers.number_types.Int16Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0)) + # Test + def B(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(2)) + +def CreateTest(builder, a, b): + builder.Prep(2, 4) + builder.Pad(1) + builder.PrependInt8(b) + builder.PrependInt16(a) + return builder.Offset() + + +class TestT(object): + + # TestT + def __init__(self): + self.a = 0 # type: int + self.b = 0 # type: int + + @classmethod + def InitFromBuf(cls, buf, pos): + test = Test() + test.Init(buf, pos) + return cls.InitFromObj(test) + + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + + @classmethod + def InitFromObj(cls, test): + x = TestT() + x._UnPack(test) + return x + + # TestT + def _UnPack(self, test): + if test is None: + return + self.a = test.A() + self.b = test.B() + + # TestT + def Pack(self, builder): + return CreateTest(builder, self.a, self.b) diff --git a/tests/MyGame/Example/NestedUnion/TestSimpleTableWithEnum.py b/tests/MyGame/Example/NestedUnion/TestSimpleTableWithEnum.py new file mode 100644 index 00000000000..46ebc263c92 --- /dev/null +++ b/tests/MyGame/Example/NestedUnion/TestSimpleTableWithEnum.py @@ -0,0 +1,78 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: NestedUnion + +import flatbuffers +from flatbuffers.compat import import_numpy +np = import_numpy() + +class TestSimpleTableWithEnum(object): + __slots__ = ['_tab'] + + @classmethod + def GetRootAs(cls, buf, offset=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset) + x = TestSimpleTableWithEnum() + x.Init(buf, n + offset) + return x + + @classmethod + def GetRootAsTestSimpleTableWithEnum(cls, buf, offset=0): + """This method is deprecated. Please switch to GetRootAs.""" + return cls.GetRootAs(buf, offset) + # TestSimpleTableWithEnum + def Init(self, buf, pos): + self._tab = flatbuffers.table.Table(buf, pos) + + # TestSimpleTableWithEnum + def Color(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos) + return 2 + +def TestSimpleTableWithEnumStart(builder): builder.StartObject(1) +def Start(builder): + return TestSimpleTableWithEnumStart(builder) +def TestSimpleTableWithEnumAddColor(builder, color): builder.PrependUint8Slot(0, color, 2) +def AddColor(builder, color): + return TestSimpleTableWithEnumAddColor(builder, color) +def TestSimpleTableWithEnumEnd(builder): return builder.EndObject() +def End(builder): + return TestSimpleTableWithEnumEnd(builder) + +class TestSimpleTableWithEnumT(object): + + # TestSimpleTableWithEnumT + def __init__(self): + self.color = 2 # type: int + + @classmethod + def InitFromBuf(cls, buf, pos): + testSimpleTableWithEnum = TestSimpleTableWithEnum() + testSimpleTableWithEnum.Init(buf, pos) + return cls.InitFromObj(testSimpleTableWithEnum) + + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + + @classmethod + def InitFromObj(cls, testSimpleTableWithEnum): + x = TestSimpleTableWithEnumT() + x._UnPack(testSimpleTableWithEnum) + return x + + # TestSimpleTableWithEnumT + def _UnPack(self, testSimpleTableWithEnum): + if testSimpleTableWithEnum is None: + return + self.color = testSimpleTableWithEnum.Color() + + # TestSimpleTableWithEnumT + def Pack(self, builder): + TestSimpleTableWithEnumStart(builder) + TestSimpleTableWithEnumAddColor(builder, self.color) + testSimpleTableWithEnum = TestSimpleTableWithEnumEnd(builder) + return testSimpleTableWithEnum diff --git a/tests/MyGame/Example/NestedUnion/Vec3.py b/tests/MyGame/Example/NestedUnion/Vec3.py new file mode 100644 index 00000000000..f3bb75f26ca --- /dev/null +++ b/tests/MyGame/Example/NestedUnion/Vec3.py @@ -0,0 +1,155 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: NestedUnion + +import flatbuffers +from flatbuffers.compat import import_numpy +np = import_numpy() + +class Vec3(object): + __slots__ = ['_tab'] + + @classmethod + def GetRootAs(cls, buf, offset=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset) + x = Vec3() + x.Init(buf, n + offset) + return x + + @classmethod + def GetRootAsVec3(cls, buf, offset=0): + """This method is deprecated. Please switch to GetRootAs.""" + return cls.GetRootAs(buf, offset) + # Vec3 + def Init(self, buf, pos): + self._tab = flatbuffers.table.Table(buf, pos) + + # Vec3 + def X(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos) + return 0.0 + + # Vec3 + def Y(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos) + return 0.0 + + # Vec3 + def Z(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos) + return 0.0 + + # Vec3 + def Test1(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos) + return 0.0 + + # Vec3 + def Test2(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos) + return 0 + + # Vec3 + def Test3(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14)) + if o != 0: + x = o + self._tab.Pos + from MyGame.Example.NestedUnion.Test import Test + obj = Test() + obj.Init(self._tab.Bytes, x) + return obj + return None + +def Vec3Start(builder): builder.StartObject(6) +def Start(builder): + return Vec3Start(builder) +def Vec3AddX(builder, x): builder.PrependFloat64Slot(0, x, 0.0) +def AddX(builder, x): + return Vec3AddX(builder, x) +def Vec3AddY(builder, y): builder.PrependFloat64Slot(1, y, 0.0) +def AddY(builder, y): + return Vec3AddY(builder, y) +def Vec3AddZ(builder, z): builder.PrependFloat64Slot(2, z, 0.0) +def AddZ(builder, z): + return Vec3AddZ(builder, z) +def Vec3AddTest1(builder, test1): builder.PrependFloat64Slot(3, test1, 0.0) +def AddTest1(builder, test1): + return Vec3AddTest1(builder, test1) +def Vec3AddTest2(builder, test2): builder.PrependUint8Slot(4, test2, 0) +def AddTest2(builder, test2): + return Vec3AddTest2(builder, test2) +def Vec3AddTest3(builder, test3): builder.PrependStructSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(test3), 0) +def AddTest3(builder, test3): + return Vec3AddTest3(builder, test3) +def Vec3End(builder): return builder.EndObject() +def End(builder): + return Vec3End(builder) +import MyGame.Example.NestedUnion.Test +try: + from typing import Optional +except: + pass + +class Vec3T(object): + + # Vec3T + def __init__(self): + self.x = 0.0 # type: float + self.y = 0.0 # type: float + self.z = 0.0 # type: float + self.test1 = 0.0 # type: float + self.test2 = 0 # type: int + self.test3 = None # type: Optional[MyGame.Example.NestedUnion.Test.TestT] + + @classmethod + def InitFromBuf(cls, buf, pos): + vec3 = Vec3() + vec3.Init(buf, pos) + return cls.InitFromObj(vec3) + + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + + @classmethod + def InitFromObj(cls, vec3): + x = Vec3T() + x._UnPack(vec3) + return x + + # Vec3T + def _UnPack(self, vec3): + if vec3 is None: + return + self.x = vec3.X() + self.y = vec3.Y() + self.z = vec3.Z() + self.test1 = vec3.Test1() + self.test2 = vec3.Test2() + if vec3.Test3() is not None: + self.test3 = MyGame.Example.NestedUnion.Test.TestT.InitFromObj(vec3.Test3()) + + # Vec3T + def Pack(self, builder): + Vec3Start(builder) + Vec3AddX(builder, self.x) + Vec3AddY(builder, self.y) + Vec3AddZ(builder, self.z) + Vec3AddTest1(builder, self.test1) + Vec3AddTest2(builder, self.test2) + if self.test3 is not None: + test3 = self.test3.Pack(builder) + Vec3AddTest3(builder, test3) + vec3 = Vec3End(builder) + return vec3 diff --git a/tests/MyGame/Example/NestedUnion/__init__.py b/tests/MyGame/Example/NestedUnion/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/MyGame/Example/Referrable.py b/tests/MyGame/Example/Referrable.py index 8bf6ceba36f..5fd1e24a27f 100644 --- a/tests/MyGame/Example/Referrable.py +++ b/tests/MyGame/Example/Referrable.py @@ -53,11 +53,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) referrable = Referrable() - referrable.Init(buf, pos+n) + referrable.Init(buf, pos) return cls.InitFromObj(referrable) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, referrable): x = ReferrableT() diff --git a/tests/MyGame/Example/Stat.py b/tests/MyGame/Example/Stat.py index 7845eb3df73..471bc36ff06 100644 --- a/tests/MyGame/Example/Stat.py +++ b/tests/MyGame/Example/Stat.py @@ -75,11 +75,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) stat = Stat() - stat.Init(buf, pos+n) + stat.Init(buf, pos) return cls.InitFromObj(stat) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, stat): x = StatT() diff --git a/tests/MyGame/Example/StructOfStructs.py b/tests/MyGame/Example/StructOfStructs.py index f12ca5e611b..88c469ed7c4 100644 --- a/tests/MyGame/Example/StructOfStructs.py +++ b/tests/MyGame/Example/StructOfStructs.py @@ -64,11 +64,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) structOfStructs = StructOfStructs() - structOfStructs.Init(buf, pos+n) + structOfStructs.Init(buf, pos) return cls.InitFromObj(structOfStructs) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, structOfStructs): x = StructOfStructsT() diff --git a/tests/MyGame/Example/StructOfStructsOfStructs.py b/tests/MyGame/Example/StructOfStructsOfStructs.py index afef10ea7fc..0243f71c4d4 100644 --- a/tests/MyGame/Example/StructOfStructsOfStructs.py +++ b/tests/MyGame/Example/StructOfStructsOfStructs.py @@ -52,11 +52,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) structOfStructsOfStructs = StructOfStructsOfStructs() - structOfStructsOfStructs.Init(buf, pos+n) + structOfStructsOfStructs.Init(buf, pos) return cls.InitFromObj(structOfStructsOfStructs) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, structOfStructsOfStructs): x = StructOfStructsOfStructsT() diff --git a/tests/MyGame/Example/Test.py b/tests/MyGame/Example/Test.py index 17a71b82a8d..f095d33451a 100644 --- a/tests/MyGame/Example/Test.py +++ b/tests/MyGame/Example/Test.py @@ -39,11 +39,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) test = Test() - test.Init(buf, pos+n) + test.Init(buf, pos) return cls.InitFromObj(test) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, test): x = TestT() diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.py b/tests/MyGame/Example/TestSimpleTableWithEnum.py index 7caf78f3c18..9e58cc4b551 100644 --- a/tests/MyGame/Example/TestSimpleTableWithEnum.py +++ b/tests/MyGame/Example/TestSimpleTableWithEnum.py @@ -53,11 +53,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) testSimpleTableWithEnum = TestSimpleTableWithEnum() - testSimpleTableWithEnum.Init(buf, pos+n) + testSimpleTableWithEnum.Init(buf, pos) return cls.InitFromObj(testSimpleTableWithEnum) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, testSimpleTableWithEnum): x = TestSimpleTableWithEnumT() diff --git a/tests/MyGame/Example/TypeAliases.py b/tests/MyGame/Example/TypeAliases.py index 6f08bd8cb50..b3020490a0b 100644 --- a/tests/MyGame/Example/TypeAliases.py +++ b/tests/MyGame/Example/TypeAliases.py @@ -224,11 +224,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) typeAliases = TypeAliases() - typeAliases.Init(buf, pos+n) + typeAliases.Init(buf, pos) return cls.InitFromObj(typeAliases) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, typeAliases): x = TypeAliasesT() diff --git a/tests/MyGame/Example/Vec3.py b/tests/MyGame/Example/Vec3.py index c0a44a81d53..3a394a269ce 100644 --- a/tests/MyGame/Example/Vec3.py +++ b/tests/MyGame/Example/Vec3.py @@ -68,11 +68,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) vec3 = Vec3() - vec3.Init(buf, pos+n) + vec3.Init(buf, pos) return cls.InitFromObj(vec3) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, vec3): x = Vec3T() diff --git a/tests/MyGame/Example2/Monster.py b/tests/MyGame/Example2/Monster.py index fda0a0417ae..020efef731c 100644 --- a/tests/MyGame/Example2/Monster.py +++ b/tests/MyGame/Example2/Monster.py @@ -43,11 +43,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) monster = Monster() - monster.Init(buf, pos+n) + monster.Init(buf, pos) return cls.InitFromObj(monster) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, monster): x = MonsterT() diff --git a/tests/MyGame/InParentNamespace.py b/tests/MyGame/InParentNamespace.py index 807133d6a90..0914aa46248 100644 --- a/tests/MyGame/InParentNamespace.py +++ b/tests/MyGame/InParentNamespace.py @@ -43,11 +43,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) inParentNamespace = InParentNamespace() - inParentNamespace.Init(buf, pos+n) + inParentNamespace.Init(buf, pos) return cls.InitFromObj(inParentNamespace) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, inParentNamespace): x = InParentNamespaceT() diff --git a/tests/MyGame/MonsterExtra.py b/tests/MyGame/MonsterExtra.py index 4569b513f97..b30ee6e788d 100644 --- a/tests/MyGame/MonsterExtra.py +++ b/tests/MyGame/MonsterExtra.py @@ -202,11 +202,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) monsterExtra = MonsterExtra() - monsterExtra.Init(buf, pos+n) + monsterExtra.Init(buf, pos) return cls.InitFromObj(monsterExtra) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, monsterExtra): x = MonsterExtraT() diff --git a/tests/PythonTest.sh b/tests/PythonTest.sh index 0d0ee695b57..925bd95ebbe 100755 --- a/tests/PythonTest.sh +++ b/tests/PythonTest.sh @@ -24,6 +24,7 @@ ${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_test.fbs --g ${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_test.fbs --gen-object-api --gen-onefile ${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_extra.fbs --gen-object-api ${test_dir}/../flatc -p -o ${gen_code_path} -I include_test arrays_test.fbs --gen-object-api +${test_dir}/../flatc -p -o ${gen_code_path} -I include_test nested_union_test.fbs --gen-object-api # Syntax: run_tests # diff --git a/tests/monster_test_generated.py b/tests/monster_test_generated.py index 27aff92dace..55209a00230 100644 --- a/tests/monster_test_generated.py +++ b/tests/monster_test_generated.py @@ -120,11 +120,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) inParentNamespace = InParentNamespace() - inParentNamespace.Init(buf, pos+n) + inParentNamespace.Init(buf, pos) return cls.InitFromObj(inParentNamespace) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, inParentNamespace): x = InParentNamespaceT() @@ -177,11 +181,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) monster = Monster() - monster.Init(buf, pos+n) + monster.Init(buf, pos) return cls.InitFromObj(monster) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, monster): x = MonsterT() @@ -233,11 +241,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) test = Test() - test.Init(buf, pos+n) + test.Init(buf, pos) return cls.InitFromObj(test) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, test): x = TestT() @@ -298,11 +310,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) testSimpleTableWithEnum = TestSimpleTableWithEnum() - testSimpleTableWithEnum.Init(buf, pos+n) + testSimpleTableWithEnum.Init(buf, pos) return cls.InitFromObj(testSimpleTableWithEnum) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, testSimpleTableWithEnum): x = TestSimpleTableWithEnumT() @@ -384,11 +400,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) vec3 = Vec3() - vec3.Init(buf, pos+n) + vec3.Init(buf, pos) return cls.InitFromObj(vec3) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, vec3): x = Vec3T() @@ -444,11 +464,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) ability = Ability() - ability.Init(buf, pos+n) + ability.Init(buf, pos) return cls.InitFromObj(ability) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, ability): x = AbilityT() @@ -523,11 +547,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) structOfStructs = StructOfStructs() - structOfStructs.Init(buf, pos+n) + structOfStructs.Init(buf, pos) return cls.InitFromObj(structOfStructs) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, structOfStructs): x = StructOfStructsT() @@ -595,11 +623,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) structOfStructsOfStructs = StructOfStructsOfStructs() - structOfStructsOfStructs.Init(buf, pos+n) + structOfStructsOfStructs.Init(buf, pos) return cls.InitFromObj(structOfStructsOfStructs) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, structOfStructsOfStructs): x = StructOfStructsOfStructsT() @@ -678,11 +710,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) stat = Stat() - stat.Init(buf, pos+n) + stat.Init(buf, pos) return cls.InitFromObj(stat) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, stat): x = StatT() @@ -752,11 +788,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) referrable = Referrable() - referrable.Init(buf, pos+n) + referrable.Init(buf, pos) return cls.InitFromObj(referrable) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, referrable): x = ReferrableT() @@ -1726,11 +1766,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) monster = Monster() - monster.Init(buf, pos+n) + monster.Init(buf, pos) return cls.InitFromObj(monster) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, monster): x = MonsterT() @@ -2364,11 +2408,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) typeAliases = TypeAliases() - typeAliases.Init(buf, pos+n) + typeAliases.Init(buf, pos) return cls.InitFromObj(typeAliases) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, typeAliases): x = TypeAliasesT() diff --git a/tests/nested_union_test.fbs b/tests/nested_union_test.fbs new file mode 100644 index 00000000000..daa6048b566 --- /dev/null +++ b/tests/nested_union_test.fbs @@ -0,0 +1,36 @@ +namespace MyGame.Example.NestedUnion; + +/// Composite components of Monster color. +enum Color:ubyte (bit_flags) { + Red = 0, // color Red = (1u << 0) + /// \brief color Green + /// Green is bit_flag with value (1u << 1) + Green, + /// \brief color Blue (1u << 3) + Blue = 3, +} + +table TestSimpleTableWithEnum (csharp_partial, private) { + color: Color = Green; +} + +struct Test { a:short; b:byte; } + +table Vec3 { + x:double; + y:double; + z:double; + test1:double; + test2:Color; + test3:Test; +} + +union Any { Vec3, TestSimpleTableWithEnum } + +table NestedUnionTest { + name:string; + data:Any; + id:short; +} + +root_type NestedUnionTest; \ No newline at end of file diff --git a/tests/optional_scalars/ScalarStuff.py b/tests/optional_scalars/ScalarStuff.py index 3e7d2a221b6..ca7c253a647 100644 --- a/tests/optional_scalars/ScalarStuff.py +++ b/tests/optional_scalars/ScalarStuff.py @@ -438,11 +438,15 @@ def __init__(self): @classmethod def InitFromBuf(cls, buf, pos): - n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0) scalarStuff = ScalarStuff() - scalarStuff.Init(buf, pos+n) + scalarStuff.Init(buf, pos) return cls.InitFromObj(scalarStuff) + @classmethod + def InitFromPackedBuf(cls, buf, pos=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos) + return cls.InitFromBuf(buf, pos+n) + @classmethod def InitFromObj(cls, scalarStuff): x = ScalarStuffT() diff --git a/tests/py_test.py b/tests/py_test.py index 1332257fdc7..b7e88b25102 100644 --- a/tests/py_test.py +++ b/tests/py_test.py @@ -47,6 +47,11 @@ import MyGame.Example.ArrayStruct # refers to generated code import MyGame.Example.NestedStruct # refers to generated code import MyGame.Example.TestEnum # refers to generated code +import MyGame.Example.NestedUnion.NestedUnionTest # refers to generated code +import MyGame.Example.NestedUnion.Vec3 # refers to generated code +import MyGame.Example.NestedUnion.Any # refers to generated code +import MyGame.Example.NestedUnion.Test # refers to generated code +import MyGame.Example.NestedUnion.Color # refers to generated code import monster_test_generated # the one-file version import optional_scalars import optional_scalars.ScalarStuff @@ -2663,6 +2668,65 @@ def test_fixed_length_array(self): self.assertEqual(table.A().D(1).D(0), -2) self.assertEqual(table.A().D(1).D(1), 2) +class TestNestedUnionTables(unittest.TestCase): + + def test_nested_union_tables(self): + nestUnion = MyGame.Example.NestedUnion.NestedUnionTest.NestedUnionTestT() + nestUnion.name = b"testUnion1" + nestUnion.id = 1 + nestUnion.data = MyGame.Example.NestedUnion.Vec3.Vec3T() + nestUnion.dataType = MyGame.Example.NestedUnion.Any.Any.Vec3 + nestUnion.data.x = 4.278975356 + nestUnion.data.y = 5.32 + nestUnion.data.z = -6.464 + nestUnion.data.test1 = 0.9 + nestUnion.data.test2 = MyGame.Example.NestedUnion.Color.Color.Red + nestUnion.data.test3 = MyGame.Example.NestedUnion.Test.TestT() + nestUnion.data.test3.a = 5 + nestUnion.data.test3.b = 2 + + b = flatbuffers.Builder(0) + b.Finish(nestUnion.Pack(b)) + + nestUnionDecode = MyGame.Example.NestedUnion.NestedUnionTest.NestedUnionTest.GetRootAs(b.Bytes, b.Head()) + nestUnionDecodeT = MyGame.Example.NestedUnion.NestedUnionTest.NestedUnionTestT.InitFromObj(nestUnionDecode) + self.assertEqual(nestUnionDecodeT.name, nestUnion.name) + self.assertEqual(nestUnionDecodeT.id, nestUnion.id) + self.assertEqual(nestUnionDecodeT.dataType, nestUnion.dataType) + self.assertEqual(nestUnionDecodeT.data.x, nestUnion.data.x) + self.assertEqual(nestUnionDecodeT.data.y, nestUnion.data.y) + self.assertEqual(nestUnionDecodeT.data.z, nestUnion.data.z) + self.assertEqual(nestUnionDecodeT.data.test1, nestUnion.data.test1) + self.assertEqual(nestUnionDecodeT.data.test2, nestUnion.data.test2) + self.assertEqual(nestUnionDecodeT.data.test3.a, nestUnion.data.test3.a) + self.assertEqual(nestUnionDecodeT.data.test3.b, nestUnion.data.test3.b) + + nestUnionDecodeTFromBuf = MyGame.Example.NestedUnion.NestedUnionTest.NestedUnionTestT.InitFromPackedBuf(b.Bytes, b.Head()) + self.assertEqual(nestUnionDecodeTFromBuf.name, nestUnion.name) + self.assertEqual(nestUnionDecodeTFromBuf.id, nestUnion.id) + self.assertEqual(nestUnionDecodeTFromBuf.dataType, nestUnion.dataType) + self.assertEqual(nestUnionDecodeTFromBuf.data.x, nestUnion.data.x) + self.assertEqual(nestUnionDecodeTFromBuf.data.y, nestUnion.data.y) + self.assertEqual(nestUnionDecodeTFromBuf.data.z, nestUnion.data.z) + self.assertEqual(nestUnionDecodeTFromBuf.data.test1, nestUnion.data.test1) + self.assertEqual(nestUnionDecodeTFromBuf.data.test2, nestUnion.data.test2) + self.assertEqual(nestUnionDecodeTFromBuf.data.test3.a, nestUnion.data.test3.a) + self.assertEqual(nestUnionDecodeTFromBuf.data.test3.b, nestUnion.data.test3.b) + + + nestUnionDecodeTFromBuf2 = MyGame.Example.NestedUnion.NestedUnionTest.NestedUnionTestT.InitFromPackedBuf(b.Output()) + self.assertEqual(nestUnionDecodeTFromBuf2.name, nestUnion.name) + self.assertEqual(nestUnionDecodeTFromBuf2.id, nestUnion.id) + self.assertEqual(nestUnionDecodeTFromBuf2.dataType, nestUnion.dataType) + self.assertEqual(nestUnionDecodeTFromBuf2.data.x, nestUnion.data.x) + self.assertEqual(nestUnionDecodeTFromBuf2.data.y, nestUnion.data.y) + self.assertEqual(nestUnionDecodeTFromBuf2.data.z, nestUnion.data.z) + self.assertEqual(nestUnionDecodeTFromBuf2.data.test1, nestUnion.data.test1) + self.assertEqual(nestUnionDecodeTFromBuf2.data.test2, nestUnion.data.test2) + self.assertEqual(nestUnionDecodeTFromBuf2.data.test3.a, nestUnion.data.test3.a) + self.assertEqual(nestUnionDecodeTFromBuf2.data.test3.b, nestUnion.data.test3.b) + + def CheckAgainstGoldDataGo(): try: gen_buf, gen_off = make_monster_from_generated_code()