Files
flatbuffers-bigfoot/tests/MyGame/Example/ArrayStruct.py
Joshua Smith 413115858c [Python] Python fixed size array (#7529)
* feat: Added support for fixed sized arrays to python

Problem:
We encountered that using fixed arrays from C++ to python that python would
not read those arrays correctly due to no size information being encoded in the byte
array itself.

Fix:
Encode the sizes within the generated python file during code generation.
Specfically we add GetArrayAsNumpy to the python version of table, which takes as input
the length of the vector. When generating the python message files we include this length
from the VectorType().fixed_length.

* fix: added digit support for camel case to snake case conversion

Problem:
When including a number in the message name we would encounter cases where SnakeCase would
not add the appropirate breaks. e.g. Int32Stamped -> int_32stamped rather than int_32_stamped.

Fix:
To fix this we can add the condition that we check if the current character is not lower and
not a digit, that we check if the previous character was a lower or digit. If it was a lower
or digit then we add the break.

* fix: Array support for structures

Problem:
The python generated code for handling non-struct and struct vectors
and arrays was inconsistent. The calls to populate the obj api was
creating incorrect code.

Solution:
To fix this the VectorOfStruct and VectorOfNonStruct was rewritten
to handle array cases and bring the two methods in line which each
other.

Testing:
PythonTesting.sh now correctly runs and generates the code for
array_test.fbs.
Minor modifications were done on the test to use the new index
accessor for struct arrays and the script correctly sources the
location of the python code.

* chore: clang format changes

* Added code generated by scripts/generate_code. Modified GetArrayOfNonStruct slightly
to allow for function overloading allowing the user to get a single element of an array
or the whole array.

* Added new_line parameter to OffsetPrefix to allow optional new lines to be added.
This allows us to use the GenIndents method that automatically adds new lines instead.

* Reupload of generated code from the scripts/generate_code.py

* Removed new line in GetVectorAsNumpy.

* Updated Array lengths to use Length methods where possible. Added fallthrough for GenTypePointer. Added digit check to CamelToSnake method. Added and modified tests for ToSnakeCase and CamelToSnake.

* Added range check on the getter methods for vector and array types. Renamed == as is for python
2022-09-22 11:08:09 -07:00

170 lines
5.5 KiB
Python

# automatically generated by the FlatBuffers compiler, do not modify
# namespace: Example
import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()
class ArrayStruct(object):
__slots__ = ['_tab']
@classmethod
def SizeOf(cls):
return 160
# ArrayStruct
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# ArrayStruct
def A(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
# ArrayStruct
def B(self, j = None):
if j is None:
return [self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4 + i * 4)) for i in range(self.BLength())]
elif j >= 0 and j < self.BLength():
return self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4 + j * 4))
else:
return None
# ArrayStruct
def BAsNumpy(self):
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Int32Flags, self._tab.Pos + 4, self.BLength())
# ArrayStruct
def BLength(self):
return 15
# ArrayStruct
def BIsNone(self):
return False
# ArrayStruct
def C(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(64))
# ArrayStruct
def D(self, i: int):
from MyGame.Example.NestedStruct import NestedStruct
obj = NestedStruct()
obj.Init(self._tab.Bytes, self._tab.Pos + 72 + i * 32)
return obj
# ArrayStruct
def DLength(self):
return 2
# ArrayStruct
def DIsNone(self):
return False
# ArrayStruct
def E(self): return self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(136))
# ArrayStruct
def F(self, j = None):
if j is None:
return [self._tab.Get(flatbuffers.number_types.Int64Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(144 + i * 8)) for i in range(self.FLength())]
elif j >= 0 and j < self.FLength():
return self._tab.Get(flatbuffers.number_types.Int64Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(144 + j * 8))
else:
return None
# ArrayStruct
def FAsNumpy(self):
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Int64Flags, self._tab.Pos + 144, self.FLength())
# ArrayStruct
def FLength(self):
return 2
# ArrayStruct
def FIsNone(self):
return False
def CreateArrayStruct(builder, a, b, c, d_a, d_b, d_c, d_d, e, f):
builder.Prep(8, 160)
for _idx0 in range(2 , 0, -1):
builder.PrependInt64(f[_idx0-1])
builder.Pad(4)
builder.PrependInt32(e)
for _idx0 in range(2 , 0, -1):
builder.Prep(8, 32)
for _idx1 in range(2 , 0, -1):
builder.PrependInt64(d_d[_idx0-1][_idx1-1])
builder.Pad(5)
for _idx1 in range(2 , 0, -1):
builder.PrependInt8(d_c[_idx0-1][_idx1-1])
builder.PrependInt8(d_b[_idx0-1])
for _idx1 in range(2 , 0, -1):
builder.PrependInt32(d_a[_idx0-1][_idx1-1])
builder.Pad(7)
builder.PrependInt8(c)
for _idx0 in range(15 , 0, -1):
builder.PrependInt32(b[_idx0-1])
builder.PrependFloat32(a)
return builder.Offset()
import MyGame.Example.NestedStruct
try:
from typing import List
except:
pass
class ArrayStructT(object):
# ArrayStructT
def __init__(self):
self.a = 0.0 # type: float
self.b = None # type: List[int]
self.c = 0 # type: int
self.d = None # type: List[MyGame.Example.NestedStruct.NestedStructT]
self.e = 0 # type: int
self.f = None # type: List[int]
@classmethod
def InitFromBuf(cls, buf, pos):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0)
arrayStruct = ArrayStruct()
arrayStruct.Init(buf, pos+n)
return cls.InitFromObj(arrayStruct)
@classmethod
def InitFromObj(cls, arrayStruct):
x = ArrayStructT()
x._UnPack(arrayStruct)
return x
# ArrayStructT
def _UnPack(self, arrayStruct):
if arrayStruct is None:
return
self.a = arrayStruct.A()
if not arrayStruct.BIsNone():
if np is None:
self.b = []
for i in range(arrayStruct.BLength()):
self.b.append(arrayStruct.B(i))
else:
self.b = arrayStruct.BAsNumpy()
self.c = arrayStruct.C()
if not arrayStruct.DIsNone():
self.d = []
for i in range(arrayStruct.DLength()):
if arrayStruct.D(i) is None:
self.d.append(None)
else:
nestedStruct_ = MyGame.Example.NestedStruct.NestedStructT.InitFromObj(arrayStruct.D(i))
self.d.append(nestedStruct_)
self.e = arrayStruct.E()
if not arrayStruct.FIsNone():
if np is None:
self.f = []
for i in range(arrayStruct.FLength()):
self.f.append(arrayStruct.F(i))
else:
self.f = arrayStruct.FAsNumpy()
# ArrayStructT
def Pack(self, builder):
return CreateArrayStruct(builder, self.a, self.b, self.c, self.d.a, self.d.b, self.d.c, self.d.d, self.e, self.f)