[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
This commit is contained in:
Joshua Smith
2022-10-26 22:56:52 +01:00
committed by GitHub
parent 5a48b0d7d6
commit 043a24f2e4
30 changed files with 766 additions and 65 deletions

View File

@@ -147,7 +147,7 @@ TS_OPTS = ["--ts", "--gen-name-strings"]
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 @@ flatc(
# 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 @@ flatc(
)
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)

View File

@@ -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);

View File

@@ -38,11 +38,15 @@ class AbilityT(object):
@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()

View File

@@ -123,11 +123,15 @@ class ArrayStructT(object):
@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()

View File

@@ -62,11 +62,15 @@ class ArrayTableT(object):
@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()

View File

@@ -1131,11 +1131,15 @@ class MonsterT(object):
@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()

View File

@@ -111,11 +111,15 @@ class NestedStructT(object):
@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()

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -53,11 +53,15 @@ class ReferrableT(object):
@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()

View File

@@ -75,11 +75,15 @@ class StatT(object):
@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()

View File

@@ -64,11 +64,15 @@ class StructOfStructsT(object):
@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()

View File

@@ -52,11 +52,15 @@ class StructOfStructsOfStructsT(object):
@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()

View File

@@ -39,11 +39,15 @@ class TestT(object):
@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()

View File

@@ -53,11 +53,15 @@ class TestSimpleTableWithEnumT(object):
@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()

View File

@@ -224,11 +224,15 @@ class TypeAliasesT(object):
@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()

View File

@@ -68,11 +68,15 @@ class Vec3T(object):
@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()

View File

@@ -43,11 +43,15 @@ class MonsterT(object):
@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()

View File

@@ -43,11 +43,15 @@ class InParentNamespaceT(object):
@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()

View File

@@ -202,11 +202,15 @@ class MonsterExtraT(object):
@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()

View File

@@ -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 <interpreter> <benchmark vtable dedupes>
# <benchmark read count> <benchmark build count>

View File

@@ -120,11 +120,15 @@ class InParentNamespaceT(object):
@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 @@ class MonsterT(object):
@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 @@ class TestT(object):
@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 @@ class TestSimpleTableWithEnumT(object):
@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 @@ class Vec3T(object):
@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 @@ class AbilityT(object):
@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 @@ class StructOfStructsT(object):
@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 @@ class StructOfStructsOfStructsT(object):
@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 @@ class StatT(object):
@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 @@ class ReferrableT(object):
@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 @@ class MonsterT(object):
@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 @@ class TypeAliasesT(object):
@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()

View File

@@ -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;

View File

@@ -438,11 +438,15 @@ class ScalarStuffT(object):
@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()

View File

@@ -47,6 +47,11 @@ import MyGame.Example.ArrayTable # refers to generated code
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 @@ class TestFixedLengthArrays(unittest.TestCase):
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()