Skip to content

Commit 4b66e25

Browse files
committed
fix(python): make fixed array metadata methods static
1 parent 81edeb1 commit 4b66e25

8 files changed

Lines changed: 124 additions & 53 deletions

File tree

src/idl_gen_python.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -478,8 +478,17 @@ class PythonStubGenerator {
478478
}
479479
break;
480480
}
481-
stub << " def " << name << "Length(self) -> int: ...\n";
482-
stub << " def " << name << "IsNone(self) -> bool: ...\n";
481+
const bool is_array = field_type.base_type == BASE_TYPE_ARRAY;
482+
if (is_array) {
483+
stub << " @staticmethod\n";
484+
}
485+
stub << " def " << name << "Length(" << (is_array ? "" : "self")
486+
<< ") -> int: ...\n";
487+
if (is_array) {
488+
stub << " @staticmethod\n";
489+
}
490+
stub << " def " << name << "IsNone(" << (is_array ? "" : "self")
491+
<< ") -> bool: ...\n";
483492
break;
484493
}
485494
case BASE_TYPE_UNION: {
@@ -805,13 +814,15 @@ class PythonGenerator : public BaseGenerator {
805814
std::string* code_ptr) const {
806815
auto& code = *code_ptr;
807816

808-
GenReceiver(struct_def, code_ptr);
809-
code += namer_.Method(field) + "Length(self)";
817+
const bool is_array = IsArray(field.value.type);
818+
GenReceiver(struct_def, code_ptr, is_array);
819+
code += namer_.Method(field) + "Length(" +
820+
(is_array ? std::string() : "self") + ")";
810821
if (parser_.opts.python_typing) {
811822
code += " -> int";
812823
}
813824
code += ":";
814-
if (!IsArray(field.value.type)) {
825+
if (!is_array) {
815826
code += OffsetPrefix(field, false);
816827
code += GenIndents(3) + "return self._tab.VectorLen(o)";
817828
code += GenIndents(2) + "return 0\n\n";
@@ -826,13 +837,15 @@ class PythonGenerator : public BaseGenerator {
826837
std::string* code_ptr) const {
827838
auto& code = *code_ptr;
828839

829-
GenReceiver(struct_def, code_ptr);
830-
code += namer_.Method(field) + "IsNone(self)";
840+
const bool is_array = IsArray(field.value.type);
841+
GenReceiver(struct_def, code_ptr, is_array);
842+
code += namer_.Method(field) + "IsNone(" +
843+
(is_array ? std::string() : "self") + ")";
831844
if (parser_.opts.python_typing) {
832845
code += " -> bool";
833846
}
834847
code += ":";
835-
if (!IsArray(field.value.type)) {
848+
if (!is_array) {
836849
code += GenIndents(2) +
837850
"o = flatbuffers.number_types.UOffsetTFlags.py_type" +
838851
"(self._tab.Offset(" + NumToString(field.value.offset) + "))";
@@ -1599,9 +1612,13 @@ class PythonGenerator : public BaseGenerator {
15991612
}
16001613

16011614
// Generate the receiver for function signatures.
1602-
void GenReceiver(const StructDef& struct_def, std::string* code_ptr) const {
1615+
void GenReceiver(const StructDef& struct_def, std::string* code_ptr,
1616+
bool is_static = false) const {
16031617
auto& code = *code_ptr;
16041618
code += Indent + "# " + namer_.Type(struct_def) + "\n";
1619+
if (is_static) {
1620+
code += Indent + "@staticmethod\n";
1621+
}
16051622
code += Indent + "def ";
16061623
}
16071624

tests/MyGame/Example/ArrayStruct.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@ def BAsNumpy(self):
3535
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Int32Flags, self._tab.Pos + 4, self.BLength())
3636

3737
# ArrayStruct
38-
def BLength(self) -> int:
38+
@staticmethod
39+
def BLength() -> int:
3940
return 15
4041

4142
# ArrayStruct
42-
def BIsNone(self) -> bool:
43+
@staticmethod
44+
def BIsNone() -> bool:
4345
return False
4446

4547
# ArrayStruct
@@ -51,11 +53,13 @@ def D(self, i: int) -> NestedStruct:
5153
return obj
5254

5355
# ArrayStruct
54-
def DLength(self) -> int:
56+
@staticmethod
57+
def DLength() -> int:
5558
return 2
5659

5760
# ArrayStruct
58-
def DIsNone(self) -> bool:
61+
@staticmethod
62+
def DIsNone() -> bool:
5963
return False
6064

6165
# ArrayStruct
@@ -74,11 +78,13 @@ def FAsNumpy(self):
7478
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Int64Flags, self._tab.Pos + 144, self.FLength())
7579

7680
# ArrayStruct
77-
def FLength(self) -> int:
81+
@staticmethod
82+
def FLength() -> int:
7883
return 2
7984

8085
# ArrayStruct
81-
def FIsNone(self) -> bool:
86+
@staticmethod
87+
def FIsNone() -> bool:
8288
return False
8389

8490

tests/MyGame/Example/ArrayStruct.pyi

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,23 @@ class ArrayStruct(object):
1717
def A(self) -> float: ...
1818
def B(self, i: int) -> typing.List[int]: ...
1919
def BAsNumpy(self) -> np.ndarray: ...
20-
def BLength(self) -> int: ...
21-
def BIsNone(self) -> bool: ...
20+
@staticmethod
21+
def BLength() -> int: ...
22+
@staticmethod
23+
def BIsNone() -> bool: ...
2224
def C(self) -> int: ...
2325
def D(self, i: int) -> NestedStruct | None: ...
24-
def DLength(self) -> int: ...
25-
def DIsNone(self) -> bool: ...
26+
@staticmethod
27+
def DLength() -> int: ...
28+
@staticmethod
29+
def DIsNone() -> bool: ...
2630
def E(self) -> int: ...
2731
def F(self, i: int) -> typing.List[int]: ...
2832
def FAsNumpy(self) -> np.ndarray: ...
29-
def FLength(self) -> int: ...
30-
def FIsNone(self) -> bool: ...
33+
@staticmethod
34+
def FLength() -> int: ...
35+
@staticmethod
36+
def FIsNone() -> bool: ...
3137
class ArrayStructT(object):
3238
a: float
3339
b: typing.List[int]

tests/MyGame/Example/LargeArrayStruct.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ def DAsNumpy(self):
3333
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Uint8Flags, self._tab.Pos + 0, self.DLength())
3434

3535
# LargeArrayStruct
36-
def DLength(self) -> int:
36+
@staticmethod
37+
def DLength() -> int:
3738
return 64
3839

3940
# LargeArrayStruct
40-
def DIsNone(self) -> bool:
41+
@staticmethod
42+
def DIsNone() -> bool:
4143
return False
4244

4345
# LargeArrayStruct
@@ -54,11 +56,13 @@ def EAsNumpy(self):
5456
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Float32Flags, self._tab.Pos + 64, self.ELength())
5557

5658
# LargeArrayStruct
57-
def ELength(self) -> int:
59+
@staticmethod
60+
def ELength() -> int:
5861
return 64
5962

6063
# LargeArrayStruct
61-
def EIsNone(self) -> bool:
64+
@staticmethod
65+
def EIsNone() -> bool:
6266
return False
6367

6468
# LargeArrayStruct
@@ -75,11 +79,13 @@ def FAsNumpy(self):
7579
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.BoolFlags, self._tab.Pos + 320, self.FLength())
7680

7781
# LargeArrayStruct
78-
def FLength(self) -> int:
82+
@staticmethod
83+
def FLength() -> int:
7984
return 64
8085

8186
# LargeArrayStruct
82-
def FIsNone(self) -> bool:
87+
@staticmethod
88+
def FIsNone() -> bool:
8389
return False
8490

8591
# LargeArrayStruct
@@ -89,11 +95,13 @@ def G(self, i: int) -> NestedStruct:
8995
return obj
9096

9197
# LargeArrayStruct
92-
def GLength(self) -> int:
98+
@staticmethod
99+
def GLength() -> int:
93100
return 64
94101

95102
# LargeArrayStruct
96-
def GIsNone(self) -> bool:
103+
@staticmethod
104+
def GIsNone() -> bool:
97105
return False
98106

99107
# LargeArrayStruct
@@ -110,11 +118,13 @@ def HAsNumpy(self):
110118
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Int8Flags, self._tab.Pos + 2432, self.HLength())
111119

112120
# LargeArrayStruct
113-
def HLength(self) -> int:
121+
@staticmethod
122+
def HLength() -> int:
114123
return 64
115124

116125
# LargeArrayStruct
117-
def HIsNone(self) -> bool:
126+
@staticmethod
127+
def HIsNone() -> bool:
118128
return False
119129

120130

tests/MyGame/Example/LargeArrayStruct.pyi

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,33 @@ class LargeArrayStruct(object):
1616
def Init(self, buf: bytes, pos: int) -> None: ...
1717
def D(self, i: int) -> typing.List[int]: ...
1818
def DAsNumpy(self) -> np.ndarray: ...
19-
def DLength(self) -> int: ...
20-
def DIsNone(self) -> bool: ...
19+
@staticmethod
20+
def DLength() -> int: ...
21+
@staticmethod
22+
def DIsNone() -> bool: ...
2123
def E(self, i: int) -> typing.List[float]: ...
2224
def EAsNumpy(self) -> np.ndarray: ...
23-
def ELength(self) -> int: ...
24-
def EIsNone(self) -> bool: ...
25+
@staticmethod
26+
def ELength() -> int: ...
27+
@staticmethod
28+
def EIsNone() -> bool: ...
2529
def F(self, i: int) -> typing.List[bool]: ...
2630
def FAsNumpy(self) -> np.ndarray: ...
27-
def FLength(self) -> int: ...
28-
def FIsNone(self) -> bool: ...
31+
@staticmethod
32+
def FLength() -> int: ...
33+
@staticmethod
34+
def FIsNone() -> bool: ...
2935
def G(self, i: int) -> NestedStruct | None: ...
30-
def GLength(self) -> int: ...
31-
def GIsNone(self) -> bool: ...
36+
@staticmethod
37+
def GLength() -> int: ...
38+
@staticmethod
39+
def GIsNone() -> bool: ...
3240
def H(self, i: int) -> typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C]: ...
3341
def HAsNumpy(self) -> np.ndarray: ...
34-
def HLength(self) -> int: ...
35-
def HIsNone(self) -> bool: ...
42+
@staticmethod
43+
def HLength() -> int: ...
44+
@staticmethod
45+
def HIsNone() -> bool: ...
3646
class LargeArrayStructT(object):
3747
d: typing.List[int]
3848
e: typing.List[float]

tests/MyGame/Example/NestedStruct.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@ def AAsNumpy(self):
3232
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Int32Flags, self._tab.Pos + 0, self.ALength())
3333

3434
# NestedStruct
35-
def ALength(self) -> int:
35+
@staticmethod
36+
def ALength() -> int:
3637
return 2
3738

3839
# NestedStruct
39-
def AIsNone(self) -> bool:
40+
@staticmethod
41+
def AIsNone() -> bool:
4042
return False
4143

4244
# NestedStruct
@@ -55,11 +57,13 @@ def CAsNumpy(self):
5557
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Int8Flags, self._tab.Pos + 9, self.CLength())
5658

5759
# NestedStruct
58-
def CLength(self) -> int:
60+
@staticmethod
61+
def CLength() -> int:
5962
return 2
6063

6164
# NestedStruct
62-
def CIsNone(self) -> bool:
65+
@staticmethod
66+
def CIsNone() -> bool:
6367
return False
6468

6569
# NestedStruct
@@ -76,11 +80,13 @@ def DAsNumpy(self):
7680
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Int64Flags, self._tab.Pos + 16, self.DLength())
7781

7882
# NestedStruct
79-
def DLength(self) -> int:
83+
@staticmethod
84+
def DLength() -> int:
8085
return 2
8186

8287
# NestedStruct
83-
def DIsNone(self) -> bool:
88+
@staticmethod
89+
def DIsNone() -> bool:
8490
return False
8591

8692

tests/MyGame/Example/NestedStruct.pyi

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,23 @@ class NestedStruct(object):
1515
def Init(self, buf: bytes, pos: int) -> None: ...
1616
def A(self, i: int) -> typing.List[int]: ...
1717
def AAsNumpy(self) -> np.ndarray: ...
18-
def ALength(self) -> int: ...
19-
def AIsNone(self) -> bool: ...
18+
@staticmethod
19+
def ALength() -> int: ...
20+
@staticmethod
21+
def AIsNone() -> bool: ...
2022
def B(self) -> typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C]: ...
2123
def C(self, i: int) -> typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C]: ...
2224
def CAsNumpy(self) -> np.ndarray: ...
23-
def CLength(self) -> int: ...
24-
def CIsNone(self) -> bool: ...
25+
@staticmethod
26+
def CLength() -> int: ...
27+
@staticmethod
28+
def CIsNone() -> bool: ...
2529
def D(self, i: int) -> typing.List[int]: ...
2630
def DAsNumpy(self) -> np.ndarray: ...
27-
def DLength(self) -> int: ...
28-
def DIsNone(self) -> bool: ...
31+
@staticmethod
32+
def DLength() -> int: ...
33+
@staticmethod
34+
def DIsNone() -> bool: ...
2935
class NestedStructT(object):
3036
a: typing.List[int]
3137
b: typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C]

tests/py_test.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2871,6 +2871,16 @@ def test_finished_bytes_error(self):
28712871

28722872
class TestFixedLengthArrays(unittest.TestCase):
28732873

2874+
def test_fixed_array_metadata_accessors_are_static(self):
2875+
array_struct_type = MyGame.Example.ArrayStruct.ArrayStruct
2876+
2877+
self.assertEqual(array_struct_type.BLength(), 15)
2878+
self.assertFalse(array_struct_type.BIsNone())
2879+
2880+
array_struct = array_struct_type()
2881+
self.assertEqual(array_struct.BLength(), 15)
2882+
self.assertFalse(array_struct.BIsNone())
2883+
28742884
def test_fixed_length_array(self):
28752885
builder = flatbuffers.Builder(0)
28762886

0 commit comments

Comments
 (0)