• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# coding=utf-8
2# Copyright 2014 Google Inc. All rights reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import os.path
17import sys
18import imp
19PY_VERSION = sys.version_info[:2]
20
21import ctypes
22from collections import defaultdict
23import math
24import random
25import timeit
26import unittest
27
28from flatbuffers import compat
29from flatbuffers import util
30from flatbuffers.compat import range_func as compat_range
31from flatbuffers.compat import NumpyRequiredForThisFeature
32
33import flatbuffers
34from flatbuffers import number_types as N
35
36import MyGame  # refers to generated code
37import MyGame.Example  # refers to generated code
38import MyGame.Example.Any  # refers to generated code
39import MyGame.Example.Color  # refers to generated code
40import MyGame.Example.Monster  # refers to generated code
41import MyGame.Example.Test  # refers to generated code
42import MyGame.Example.Stat  # refers to generated code
43import MyGame.Example.Vec3  # refers to generated code
44import MyGame.MonsterExtra  # refers to generated code
45import MyGame.InParentNamespace  # refers to generated code
46import MyGame.Example.ArrayTable  # refers to generated code
47import MyGame.Example.ArrayStruct  # refers to generated code
48import MyGame.Example.NestedStruct  # refers to generated code
49import MyGame.Example.TestEnum  # refers to generated code
50import monster_test_generated  # the one-file version
51import optional_scalars
52import optional_scalars.ScalarStuff
53
54
55def create_namespace_shortcut(is_onefile):
56  # Create shortcut from either the one-file format or the multi-file format
57  global _ANY
58  global _COLOR
59  global _MONSTER
60  global _TEST
61  global _STAT
62  global _VEC3
63  global _IN_PARENT_NAMESPACE
64  if is_onefile:
65    print('Testing with the one-file generated code')
66    _ANY = monster_test_generated
67    _COLOR = monster_test_generated
68    _MONSTER = monster_test_generated
69    _TEST = monster_test_generated
70    _STAT = monster_test_generated
71    _VEC3 = monster_test_generated
72    _IN_PARENT_NAMESPACE = monster_test_generated
73  else:
74    print('Testing with multi-file generated code')
75    _ANY = MyGame.Example.Any
76    _COLOR = MyGame.Example.Color
77    _MONSTER = MyGame.Example.Monster
78    _TEST = MyGame.Example.Test
79    _STAT = MyGame.Example.Stat
80    _VEC3 = MyGame.Example.Vec3
81    _IN_PARENT_NAMESPACE = MyGame.InParentNamespace
82
83
84def assertRaises(test_case, fn, exception_class):
85  """ Backwards-compatible assertion for exceptions raised. """
86
87  exc = None
88  try:
89    fn()
90  except Exception as e:
91    exc = e
92  test_case.assertTrue(exc is not None)
93  test_case.assertTrue(isinstance(exc, exception_class))
94
95
96class TestWireFormat(unittest.TestCase):
97
98  def test_wire_format(self):
99    # Verify that using the generated Python code builds a buffer without
100    # returning errors, and is interpreted correctly, for size prefixed
101    # representation and regular:
102    for sizePrefix in [True, False]:
103      for file_identifier in [None, b'MONS']:
104        gen_buf, gen_off = make_monster_from_generated_code(
105            sizePrefix=sizePrefix, file_identifier=file_identifier)
106        CheckReadBuffer(
107            gen_buf,
108            gen_off,
109            sizePrefix=sizePrefix,
110            file_identifier=file_identifier)
111
112    # Verify that the canonical flatbuffer file is readable by the
113    # generated Python code. Note that context managers are not part of
114    # Python 2.5, so we use the simpler open/close methods here:
115    f = open('monsterdata_test.mon', 'rb')
116    canonicalWireData = f.read()
117    f.close()
118    CheckReadBuffer(bytearray(canonicalWireData), 0, file_identifier=b'MONS')
119
120    # Write the generated buffer out to a file:
121    f = open('monsterdata_python_wire.mon', 'wb')
122    f.write(gen_buf[gen_off:])
123    f.close()
124
125
126class TestObjectBasedAPI(unittest.TestCase):
127  """ Tests the generated object based API."""
128
129  def test_consistenty_with_repeated_pack_and_unpack(self):
130    """ Checks the serialization and deserialization between a buffer and
131
132        its python object. It tests in the same way as the C++ object API test,
133        ObjectFlatBuffersTest in test.cpp.
134    """
135
136    buf, off = make_monster_from_generated_code()
137
138    # Turns a buffer into Python object (T class).
139    monster1 = _MONSTER.Monster.GetRootAs(buf, off)
140    monsterT1 = _MONSTER.MonsterT.InitFromObj(monster1)
141
142    for sizePrefix in [True, False]:
143      # Re-serialize the data into a buffer.
144      b1 = flatbuffers.Builder(0)
145      if sizePrefix:
146        b1.FinishSizePrefixed(monsterT1.Pack(b1))
147      else:
148        b1.Finish(monsterT1.Pack(b1))
149      CheckReadBuffer(b1.Bytes, b1.Head(), sizePrefix)
150
151    # Deserializes the buffer into Python object again.
152    monster2 = _MONSTER.Monster.GetRootAs(b1.Bytes, b1.Head())
153    # Re-serializes the data into a buffer for one more time.
154    monsterT2 = _MONSTER.MonsterT.InitFromObj(monster2)
155    for sizePrefix in [True, False]:
156      # Re-serializes the data into a buffer
157      b2 = flatbuffers.Builder(0)
158      if sizePrefix:
159        b2.FinishSizePrefixed(monsterT2.Pack(b2))
160      else:
161        b2.Finish(monsterT2.Pack(b2))
162      CheckReadBuffer(b2.Bytes, b2.Head(), sizePrefix)
163
164  def test_default_values_with_pack_and_unpack(self):
165    """ Serializes and deserializes between a buffer with default values (no
166
167        specific values are filled when the buffer is created) and its python
168        object.
169    """
170    # Creates a flatbuffer with default values.
171    b1 = flatbuffers.Builder(0)
172    _MONSTER.MonsterStart(b1)
173    gen_mon = _MONSTER.MonsterEnd(b1)
174    b1.Finish(gen_mon)
175
176    # Converts the flatbuffer into the object class.
177    monster1 = _MONSTER.Monster.GetRootAs(b1.Bytes, b1.Head())
178    monsterT1 = _MONSTER.MonsterT.InitFromObj(monster1)
179
180    # Packs the object class into another flatbuffer.
181    b2 = flatbuffers.Builder(0)
182    b2.Finish(monsterT1.Pack(b2))
183    monster2 = _MONSTER.Monster.GetRootAs(b2.Bytes, b2.Head())
184    # Checks the default values.
185    self.assertTrue(monster2.Pos() is None)
186    self.assertEqual(monster2.Mana(), 150)
187    self.assertEqual(monster2.Hp(), 100)
188    self.assertTrue(monster2.Name() is None)
189    self.assertEqual(monster2.Inventory(0), 0)
190    self.assertEqual(monster2.InventoryAsNumpy(), 0)
191    self.assertEqual(monster2.InventoryLength(), 0)
192    self.assertTrue(monster2.InventoryIsNone())
193    self.assertTrue(monster2.Color() is 8)
194    self.assertEqual(monster2.TestType(), 0)
195    self.assertTrue(monster2.Test() is None)
196    self.assertTrue(monster2.Test4(0) is None)
197    self.assertEqual(monster2.Test4Length(), 0)
198    self.assertTrue(monster2.Test4IsNone())
199    self.assertTrue(monster2.Testarrayofstring(0) is '')
200    self.assertEqual(monster2.TestarrayofstringLength(), 0)
201    self.assertTrue(monster2.TestarrayofstringIsNone())
202    self.assertTrue(monster2.Testarrayoftables(0) is None)
203    self.assertEqual(monster2.TestarrayoftablesLength(), 0)
204    self.assertTrue(monster2.TestarrayoftablesIsNone())
205    self.assertTrue(monster2.Enemy() is None)
206    self.assertEqual(monster2.Testnestedflatbuffer(0), 0)
207    self.assertEqual(monster2.TestnestedflatbufferAsNumpy(), 0)
208    self.assertEqual(monster2.TestnestedflatbufferLength(), 0)
209    self.assertTrue(monster2.TestnestedflatbufferIsNone())
210    self.assertTrue(monster2.Testempty() is None)
211    self.assertTrue(monster2.Testbool() is False)
212    self.assertEqual(monster2.Testhashs32Fnv1(), 0)
213    self.assertEqual(monster2.Testhashu32Fnv1(), 0)
214    self.assertEqual(monster2.Testhashs64Fnv1(), 0)
215    self.assertEqual(monster2.Testhashu64Fnv1(), 0)
216    self.assertEqual(monster2.Testhashs32Fnv1a(), 0)
217    self.assertEqual(monster2.Testhashu32Fnv1a(), 0)
218    self.assertEqual(monster2.Testhashs64Fnv1a(), 0)
219    self.assertEqual(monster2.Testhashu64Fnv1a(), 0)
220    self.assertEqual(monster2.Testarrayofbools(0), 0)
221    self.assertEqual(monster2.TestarrayofboolsAsNumpy(), 0)
222    self.assertEqual(monster2.TestarrayofboolsLength(), 0)
223    self.assertTrue(monster2.TestarrayofboolsIsNone())
224    self.assertEqual(monster2.Testf(), 3.14159)
225    self.assertEqual(monster2.Testf2(), 3.0)
226    self.assertEqual(monster2.Testf3(), 0.0)
227    self.assertTrue(monster2.Testarrayofstring2(0) is '')
228    self.assertEqual(monster2.Testarrayofstring2Length(), 0)
229    self.assertTrue(monster2.Testarrayofstring2IsNone())
230    self.assertTrue(monster2.Testarrayofsortedstruct(0) is None)
231    self.assertEqual(monster2.TestarrayofsortedstructLength(), 0)
232    self.assertTrue(monster2.TestarrayofsortedstructIsNone())
233    self.assertEqual(monster2.Flex(0), 0)
234    self.assertEqual(monster2.FlexAsNumpy(), 0)
235    self.assertEqual(monster2.FlexLength(), 0)
236    self.assertTrue(monster2.FlexIsNone())
237    self.assertTrue(monster2.Test5(0) is None)
238    self.assertEqual(monster2.Test5Length(), 0)
239    self.assertTrue(monster2.Test5IsNone())
240    self.assertEqual(monster2.VectorOfLongs(0), 0)
241    self.assertEqual(monster2.VectorOfLongsAsNumpy(), 0)
242    self.assertEqual(monster2.VectorOfLongsLength(), 0)
243    self.assertTrue(monster2.VectorOfLongsIsNone())
244    self.assertEqual(monster2.VectorOfDoubles(0), 0)
245    self.assertEqual(monster2.VectorOfDoublesAsNumpy(), 0)
246    self.assertEqual(monster2.VectorOfDoublesLength(), 0)
247    self.assertTrue(monster2.VectorOfDoublesIsNone())
248    self.assertTrue(monster2.ParentNamespaceTest() is None)
249    self.assertTrue(monster2.VectorOfReferrables(0) is None)
250    self.assertEqual(monster2.VectorOfReferrablesLength(), 0)
251    self.assertTrue(monster2.VectorOfReferrablesIsNone())
252    self.assertEqual(monster2.SingleWeakReference(), 0)
253    self.assertEqual(monster2.VectorOfWeakReferences(0), 0)
254    self.assertEqual(monster2.VectorOfWeakReferencesAsNumpy(), 0)
255    self.assertEqual(monster2.VectorOfWeakReferencesLength(), 0)
256    self.assertTrue(monster2.VectorOfWeakReferencesIsNone())
257    self.assertTrue(monster2.VectorOfStrongReferrables(0) is None)
258    self.assertEqual(monster2.VectorOfStrongReferrablesLength(), 0)
259    self.assertTrue(monster2.VectorOfStrongReferrablesIsNone())
260    self.assertEqual(monster2.CoOwningReference(), 0)
261    self.assertEqual(monster2.VectorOfCoOwningReferences(0), 0)
262    self.assertEqual(monster2.VectorOfCoOwningReferencesAsNumpy(), 0)
263    self.assertEqual(monster2.VectorOfCoOwningReferencesLength(), 0)
264    self.assertTrue(monster2.VectorOfCoOwningReferencesIsNone())
265    self.assertEqual(monster2.NonOwningReference(), 0)
266    self.assertEqual(monster2.VectorOfNonOwningReferences(0), 0)
267    self.assertEqual(monster2.VectorOfNonOwningReferencesAsNumpy(), 0)
268    self.assertEqual(monster2.VectorOfNonOwningReferencesLength(), 0)
269    self.assertTrue(monster2.VectorOfNonOwningReferencesIsNone())
270    self.assertEqual(monster2.AnyUniqueType(), 0)
271    self.assertTrue(monster2.AnyUnique() is None)
272    self.assertEqual(monster2.AnyAmbiguousType(), 0)
273    self.assertTrue(monster2.AnyAmbiguous() is None)
274    self.assertEqual(monster2.VectorOfEnums(0), 0)
275    self.assertEqual(monster2.VectorOfEnumsAsNumpy(), 0)
276    self.assertEqual(monster2.VectorOfEnumsLength(), 0)
277    self.assertTrue(monster2.VectorOfEnumsIsNone())
278
279  def test_optional_scalars_with_pack_and_unpack(self):
280    """ Serializes and deserializes between a buffer with optional values (no
281        specific values are filled when the buffer is created) and its python
282        object.
283    """
284    # Creates a flatbuffer with optional values.
285    b1 = flatbuffers.Builder(0)
286    optional_scalars.ScalarStuff.ScalarStuffStart(b1)
287    gen_opt = optional_scalars.ScalarStuff.ScalarStuffEnd(b1)
288    b1.Finish(gen_opt)
289
290    # Converts the flatbuffer into the object class.
291    opts1 = optional_scalars.ScalarStuff.ScalarStuff.GetRootAs(b1.Bytes, b1.Head())
292    optsT1 = optional_scalars.ScalarStuff.ScalarStuffT.InitFromObj(opts1)
293
294    # Packs the object class into another flatbuffer.
295    b2 = flatbuffers.Builder(0)
296    b2.Finish(optsT1.Pack(b2))
297    opts2 = optional_scalars.ScalarStuff.ScalarStuff.GetRootAs(b2.Bytes, b2.Head())
298    optsT2 = optional_scalars.ScalarStuff.ScalarStuffT.InitFromObj(opts2)
299    # Checks the default values.
300    self.assertTrue(opts2.JustI8() == 0)
301    self.assertTrue(opts2.MaybeF32() is None)
302    self.assertTrue(opts2.DefaultBool() is True)
303    self.assertTrue(optsT2.justU16 == 0)
304    self.assertTrue(optsT2.maybeEnum is None)
305    self.assertTrue(optsT2.defaultU64 == 42)
306
307
308
309class TestAllMutableCodePathsOfExampleSchema(unittest.TestCase):
310  """ Tests the object API generated for monster_test.fbs for mutation
311
312        purposes. In each test, the default values will be changed through the
313        object API. We'll then pack the object class into the buf class and read
314        the updated values out from it to validate if the values are mutated as
315        expected.
316  """
317
318  def setUp(self, *args, **kwargs):
319    super(TestAllMutableCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
320    # Creates an empty monster flatbuffer, and loads it into the object
321    # class for future tests.
322    b = flatbuffers.Builder(0)
323    _MONSTER.MonsterStart(b)
324    self.monsterT = self._create_and_load_object_class(b)
325
326  def _pack_and_load_buf_class(self, monsterT):
327    """ Packs the object class into a flatbuffer and loads it into a buf
328
329        class.
330    """
331    b = flatbuffers.Builder(0)
332    b.Finish(monsterT.Pack(b))
333    monster = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
334    return monster
335
336  def _create_and_load_object_class(self, b):
337    """ Finishs the creation of a monster flatbuffer and loads it into an
338
339        object class.
340    """
341    gen_mon = _MONSTER.MonsterEnd(b)
342    b.Finish(gen_mon)
343    monster = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
344    monsterT = _MONSTER.MonsterT()
345    monsterT.InitFromObj(monster)
346    return monsterT
347
348  def test_mutate_pos(self):
349    posT = _VEC3.Vec3T()
350    posT.x = 4.0
351    posT.y = 5.0
352    posT.z = 6.0
353    posT.test1 = 6.0
354    posT.test2 = 7
355    test3T = _TEST.TestT()
356    test3T.a = 8
357    test3T.b = 9
358    posT.test3 = test3T
359    self.monsterT.pos = posT
360
361    # Packs the updated values.
362    monster = self._pack_and_load_buf_class(self.monsterT)
363
364    # Checks if values are loaded correctly into the object class.
365    pos = monster.Pos()
366
367    # Verifies the properties of the Vec3.
368    self.assertEqual(pos.X(), 4.0)
369    self.assertEqual(pos.Y(), 5.0)
370    self.assertEqual(pos.Z(), 6.0)
371    self.assertEqual(pos.Test1(), 6.0)
372    self.assertEqual(pos.Test2(), 7)
373    t3 = _TEST.Test()
374    t3 = pos.Test3(t3)
375    self.assertEqual(t3.A(), 8)
376    self.assertEqual(t3.B(), 9)
377
378  def test_mutate_mana(self):
379    self.monsterT.mana = 200
380    monster = self._pack_and_load_buf_class(self.monsterT)
381    self.assertEqual(monster.Mana(), 200)
382
383  def test_mutate_hp(self):
384    self.monsterT.hp = 200
385    monster = self._pack_and_load_buf_class(self.monsterT)
386    self.assertEqual(monster.Hp(), 200)
387
388  def test_mutate_name(self):
389    self.monsterT.name = 'MyMonster'
390    monster = self._pack_and_load_buf_class(self.monsterT)
391    self.assertEqual(monster.Name(), b'MyMonster')
392
393  def test_mutate_inventory(self):
394    self.monsterT.inventory = [1, 7, 8]
395    monster = self._pack_and_load_buf_class(self.monsterT)
396    self.assertEqual(monster.Inventory(0), 1)
397    self.assertEqual(monster.Inventory(1), 7)
398    self.assertEqual(monster.Inventory(2), 8)
399
400  def test_empty_inventory(self):
401    self.monsterT.inventory = []
402    monster = self._pack_and_load_buf_class(self.monsterT)
403    self.assertFalse(monster.InventoryIsNone())
404
405  def test_mutate_color(self):
406    self.monsterT.color = _COLOR.Color.Red
407    monster = self._pack_and_load_buf_class(self.monsterT)
408    self.assertEqual(monster.Color(), _COLOR.Color.Red)
409
410  def test_mutate_testtype(self):
411    self.monsterT.testType = _ANY.Any.Monster
412    monster = self._pack_and_load_buf_class(self.monsterT)
413    self.assertEqual(monster.TestType(), _ANY.Any.Monster)
414
415  def test_mutate_test(self):
416    testT = _MONSTER.MonsterT()
417    testT.hp = 200
418    self.monsterT.test = testT
419    monster = self._pack_and_load_buf_class(self.monsterT)
420    # Initializes a Table from a union field Test(...).
421    table = monster.Test()
422
423    # Initializes a Monster from the Table from the union.
424    test_monster = _MONSTER.Monster()
425    test_monster.Init(table.Bytes, table.Pos)
426    self.assertEqual(test_monster.Hp(), 200)
427
428  def test_mutate_test4(self):
429    test0T = _TEST.TestT()
430    test0T.a = 10
431    test0T.b = 20
432    test1T = _TEST.TestT()
433    test1T.a = 30
434    test1T.b = 40
435    self.monsterT.test4 = [test0T, test1T]
436
437    monster = self._pack_and_load_buf_class(self.monsterT)
438    test0 = monster.Test4(0)
439    self.assertEqual(test0.A(), 10)
440    self.assertEqual(test0.B(), 20)
441    test1 = monster.Test4(1)
442    self.assertEqual(test1.A(), 30)
443    self.assertEqual(test1.B(), 40)
444
445  def test_empty_test4(self):
446    self.monsterT.test4 = []
447    monster = self._pack_and_load_buf_class(self.monsterT)
448    self.assertFalse(monster.Test4IsNone())
449
450  def test_mutate_testarrayofstring(self):
451    self.monsterT.testarrayofstring = []
452    self.monsterT.testarrayofstring.append('test1')
453    self.monsterT.testarrayofstring.append('test2')
454    monster = self._pack_and_load_buf_class(self.monsterT)
455    self.assertEqual(monster.Testarrayofstring(0), b'test1')
456    self.assertEqual(monster.Testarrayofstring(1), b'test2')
457
458  def test_empty_testarrayofstring(self):
459    self.monsterT.testarrayofstring = []
460    monster = self._pack_and_load_buf_class(self.monsterT)
461    self.assertFalse(monster.TestarrayofstringIsNone())
462
463  def test_mutate_testarrayoftables(self):
464    monsterT0 = _MONSTER.MonsterT()
465    monsterT0.hp = 200
466    monsterT1 = _MONSTER.MonsterT()
467    monsterT1.hp = 400
468    self.monsterT.testarrayoftables = []
469    self.monsterT.testarrayoftables.append(monsterT0)
470    self.monsterT.testarrayoftables.append(monsterT1)
471    monster = self._pack_and_load_buf_class(self.monsterT)
472    self.assertEqual(monster.Testarrayoftables(0).Hp(), 200)
473    self.assertEqual(monster.Testarrayoftables(1).Hp(), 400)
474
475  def test_empty_testarrayoftables(self):
476    self.monsterT.testarrayoftables = []
477    monster = self._pack_and_load_buf_class(self.monsterT)
478    self.assertFalse(monster.TestarrayoftablesIsNone())
479
480  def test_mutate_enemy(self):
481    monsterT = _MONSTER.MonsterT()
482    monsterT.hp = 200
483    self.monsterT.enemy = monsterT
484    monster = self._pack_and_load_buf_class(self.monsterT)
485    self.assertEqual(monster.Enemy().Hp(), 200)
486
487  def test_mutate_testnestedflatbuffer(self):
488    self.monsterT.testnestedflatbuffer = [8, 2, 4]
489    monster = self._pack_and_load_buf_class(self.monsterT)
490    self.assertEqual(monster.Testnestedflatbuffer(0), 8)
491    self.assertEqual(monster.Testnestedflatbuffer(1), 2)
492    self.assertEqual(monster.Testnestedflatbuffer(2), 4)
493
494  def test_empty_testnestedflatbuffer(self):
495    self.monsterT.testnestedflatbuffer = []
496    monster = self._pack_and_load_buf_class(self.monsterT)
497    self.assertFalse(monster.TestnestedflatbufferIsNone())
498
499  def test_mutate_testbool(self):
500    self.monsterT.testbool = True
501    monster = self._pack_and_load_buf_class(self.monsterT)
502    self.assertTrue(monster.Testbool())
503
504  def test_mutate_testhashes(self):
505    self.monsterT.testhashs32Fnv1 = 1
506    self.monsterT.testhashu32Fnv1 = 2
507    self.monsterT.testhashs64Fnv1 = 3
508    self.monsterT.testhashu64Fnv1 = 4
509    self.monsterT.testhashs32Fnv1a = 5
510    self.monsterT.testhashu32Fnv1a = 6
511    self.monsterT.testhashs64Fnv1a = 7
512    self.monsterT.testhashu64Fnv1a = 8
513    monster = self._pack_and_load_buf_class(self.monsterT)
514    self.assertEqual(monster.Testhashs32Fnv1(), 1)
515    self.assertEqual(monster.Testhashu32Fnv1(), 2)
516    self.assertEqual(monster.Testhashs64Fnv1(), 3)
517    self.assertEqual(monster.Testhashu64Fnv1(), 4)
518    self.assertEqual(monster.Testhashs32Fnv1a(), 5)
519    self.assertEqual(monster.Testhashu32Fnv1a(), 6)
520    self.assertEqual(monster.Testhashs64Fnv1a(), 7)
521    self.assertEqual(monster.Testhashu64Fnv1a(), 8)
522
523  def test_mutate_testarrayofbools(self):
524    self.monsterT.testarrayofbools = []
525    self.monsterT.testarrayofbools.append(True)
526    self.monsterT.testarrayofbools.append(True)
527    self.monsterT.testarrayofbools.append(False)
528    monster = self._pack_and_load_buf_class(self.monsterT)
529    self.assertEqual(monster.Testarrayofbools(0), True)
530    self.assertEqual(monster.Testarrayofbools(1), True)
531    self.assertEqual(monster.Testarrayofbools(2), False)
532
533  def test_empty_testarrayofbools(self):
534    self.monsterT.testarrayofbools = []
535    monster = self._pack_and_load_buf_class(self.monsterT)
536    self.assertFalse(monster.TestarrayofboolsIsNone())
537
538  def test_mutate_testf(self):
539    self.monsterT.testf = 2.0
540    monster = self._pack_and_load_buf_class(self.monsterT)
541    self.assertEqual(monster.Testf(), 2.0)
542
543  def test_mutate_vectoroflongs(self):
544    self.monsterT.vectorOfLongs = []
545    self.monsterT.vectorOfLongs.append(1)
546    self.monsterT.vectorOfLongs.append(100)
547    self.monsterT.vectorOfLongs.append(10000)
548    self.monsterT.vectorOfLongs.append(1000000)
549    self.monsterT.vectorOfLongs.append(100000000)
550    monster = self._pack_and_load_buf_class(self.monsterT)
551    self.assertEqual(monster.VectorOfLongs(0), 1)
552    self.assertEqual(monster.VectorOfLongs(1), 100)
553    self.assertEqual(monster.VectorOfLongs(2), 10000)
554    self.assertEqual(monster.VectorOfLongs(3), 1000000)
555    self.assertEqual(monster.VectorOfLongs(4), 100000000)
556
557  def test_empty_vectoroflongs(self):
558    self.monsterT.vectorOfLongs = []
559    monster = self._pack_and_load_buf_class(self.monsterT)
560    self.assertFalse(monster.VectorOfLongsIsNone())
561
562  def test_mutate_vectorofdoubles(self):
563    self.monsterT.vectorOfDoubles = []
564    self.monsterT.vectorOfDoubles.append(-1.7976931348623157e+308)
565    self.monsterT.vectorOfDoubles.append(0)
566    self.monsterT.vectorOfDoubles.append(1.7976931348623157e+308)
567    monster = self._pack_and_load_buf_class(self.monsterT)
568    self.assertEqual(monster.VectorOfDoubles(0), -1.7976931348623157e+308)
569    self.assertEqual(monster.VectorOfDoubles(1), 0)
570    self.assertEqual(monster.VectorOfDoubles(2), 1.7976931348623157e+308)
571
572  def test_empty_vectorofdoubles(self):
573    self.monsterT.vectorOfDoubles = []
574    monster = self._pack_and_load_buf_class(self.monsterT)
575    self.assertFalse(monster.VectorOfDoublesIsNone())
576
577  def test_mutate_parentnamespacetest(self):
578    self.monsterT.parentNamespaceTest = _IN_PARENT_NAMESPACE.InParentNamespaceT(
579    )
580    monster = self._pack_and_load_buf_class(self.monsterT)
581    self.assertTrue(
582        isinstance(monster.ParentNamespaceTest(),
583                   _IN_PARENT_NAMESPACE.InParentNamespace))
584
585  def test_mutate_vectorofEnums(self):
586    self.monsterT.vectorOfEnums = []
587    self.monsterT.vectorOfEnums.append(_COLOR.Color.Red)
588    self.monsterT.vectorOfEnums.append(_COLOR.Color.Blue)
589    self.monsterT.vectorOfEnums.append(_COLOR.Color.Red)
590    monster = self._pack_and_load_buf_class(self.monsterT)
591    self.assertEqual(monster.VectorOfEnums(0), _COLOR.Color.Red)
592    self.assertEqual(monster.VectorOfEnums(1), _COLOR.Color.Blue)
593    self.assertEqual(monster.VectorOfEnums(2), _COLOR.Color.Red)
594
595  def test_empty_vectorofEnums(self):
596    self.monsterT.vectorOfEnums = []
597    monster = self._pack_and_load_buf_class(self.monsterT)
598    self.assertFalse(monster.VectorOfEnumsIsNone())
599
600
601def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
602  """ CheckReadBuffer checks that the given buffer is evaluated correctly
603
604        as the example Monster.
605  """
606
607  def asserter(stmt):
608    """ An assertion helper that is separated from TestCase classes. """
609    if not stmt:
610      raise AssertionError('CheckReadBuffer case failed')
611
612  if file_identifier:
613    # test prior to removal of size_prefix
614    asserter(
615        util.GetBufferIdentifier(buf, offset, size_prefixed=sizePrefix) ==
616        file_identifier)
617    asserter(
618        util.BufferHasIdentifier(
619            buf,
620            offset,
621            file_identifier=file_identifier,
622            size_prefixed=sizePrefix))
623    asserter(
624        _MONSTER.Monster.MonsterBufferHasIdentifier(
625            buf, offset, size_prefixed=sizePrefix))
626  if sizePrefix:
627    size = util.GetSizePrefix(buf, offset)
628    asserter(size == len(buf[offset:]) - 4)
629    buf, offset = util.RemoveSizePrefix(buf, offset)
630  if file_identifier:
631    asserter(_MONSTER.Monster.MonsterBufferHasIdentifier(buf, offset))
632  else:
633    asserter(not _MONSTER.Monster.MonsterBufferHasIdentifier(buf, offset))
634  monster = _MONSTER.Monster.GetRootAs(buf, offset)
635
636  asserter(monster.Hp() == 80)
637  asserter(monster.Mana() == 150)
638  asserter(monster.Name() == b'MyMonster')
639
640  # initialize a Vec3 from Pos()
641  vec = monster.Pos()
642  asserter(vec is not None)
643
644  # verify the properties of the Vec3
645  asserter(vec.X() == 1.0)
646  asserter(vec.Y() == 2.0)
647  asserter(vec.Z() == 3.0)
648  asserter(vec.Test1() == 3.0)
649  asserter(vec.Test2() == 2)
650
651  # initialize a Test from Test3(...)
652  t = _TEST.Test()
653  t = vec.Test3(t)
654  asserter(t is not None)
655
656  # verify the properties of the Test
657  asserter(t.A() == 5)
658  asserter(t.B() == 6)
659
660  # verify that the enum code matches the enum declaration:
661  union_type = _ANY.Any
662  asserter(monster.TestType() == union_type.Monster)
663
664  # initialize a Table from a union field Test(...)
665  table2 = monster.Test()
666  asserter(type(table2) is flatbuffers.table.Table)
667
668  # initialize a Monster from the Table from the union
669  monster2 = _MONSTER.Monster()
670  monster2.Init(table2.Bytes, table2.Pos)
671
672  asserter(monster2.Name() == b'Fred')
673
674  # iterate through the first monster's inventory:
675  asserter(monster.InventoryLength() == 5)
676  asserter(not monster.InventoryIsNone())
677
678  invsum = 0
679  for i in compat_range(monster.InventoryLength()):
680    v = monster.Inventory(i)
681    invsum += int(v)
682  asserter(invsum == 10)
683
684  for i in range(5):
685    asserter(monster.VectorOfLongs(i) == 10**(i * 2))
686
687  asserter(not monster.VectorOfDoublesIsNone())
688  asserter(([-1.7976931348623157e+308, 0, 1.7976931348623157e+308] == [
689      monster.VectorOfDoubles(i) for i in range(monster.VectorOfDoublesLength())
690  ]))
691
692  try:
693    imp.find_module('numpy')
694    # if numpy exists, then we should be able to get the
695    # vector as a numpy array
696    import numpy as np
697
698    asserter(monster.InventoryAsNumpy().sum() == 10)
699    asserter(monster.InventoryAsNumpy().dtype == np.dtype('uint8'))
700
701    VectorOfLongs = monster.VectorOfLongsAsNumpy()
702    asserter(VectorOfLongs.dtype == np.dtype('int64'))
703    for i in range(5):
704      asserter(VectorOfLongs[i] == 10**(i * 2))
705
706    VectorOfDoubles = monster.VectorOfDoublesAsNumpy()
707    asserter(VectorOfDoubles.dtype == np.dtype('float64'))
708    asserter(VectorOfDoubles[0] == np.finfo('float64').min)
709    asserter(VectorOfDoubles[1] == 0.0)
710    asserter(VectorOfDoubles[2] == np.finfo('float64').max)
711
712  except ImportError:
713    # If numpy does not exist, trying to get vector as numpy
714    # array should raise NumpyRequiredForThisFeature. The way
715    # assertRaises has been implemented prevents us from
716    # asserting this error is raised outside of a test case.
717    pass
718
719  asserter(monster.Test4Length() == 2)
720  asserter(not monster.Test4IsNone())
721
722  # create a 'Test' object and populate it:
723  test0 = monster.Test4(0)
724  asserter(type(test0) is _TEST.Test)
725
726  test1 = monster.Test4(1)
727  asserter(type(test1) is _TEST.Test)
728
729  # the position of test0 and test1 are swapped in monsterdata_java_wire
730  # and monsterdata_test_wire, so ignore ordering
731  v0 = test0.A()
732  v1 = test0.B()
733  v2 = test1.A()
734  v3 = test1.B()
735  sumtest12 = int(v0) + int(v1) + int(v2) + int(v3)
736
737  asserter(sumtest12 == 100)
738
739  asserter(not monster.TestarrayofstringIsNone())
740  asserter(monster.TestarrayofstringLength() == 2)
741  asserter(monster.Testarrayofstring(0) == b'test1')
742  asserter(monster.Testarrayofstring(1) == b'test2')
743
744  asserter(monster.TestarrayoftablesIsNone())
745  asserter(monster.TestarrayoftablesLength() == 0)
746  asserter(monster.TestnestedflatbufferIsNone())
747  asserter(monster.TestnestedflatbufferLength() == 0)
748  asserter(monster.Testempty() is None)
749
750
751class TestFuzz(unittest.TestCase):
752  """ Low level stress/fuzz test: serialize/deserialize a variety of
753
754        different kinds of data in different combinations
755  """
756
757  binary_type = compat.binary_types[0]  # this will always exist
758  ofInt32Bytes = binary_type([0x83, 0x33, 0x33, 0x33])
759  ofInt64Bytes = binary_type([0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44])
760  overflowingInt32Val = flatbuffers.encode.Get(flatbuffers.packer.int32,
761                                               ofInt32Bytes, 0)
762  overflowingInt64Val = flatbuffers.encode.Get(flatbuffers.packer.int64,
763                                               ofInt64Bytes, 0)
764
765  # Values we're testing against: chosen to ensure no bits get chopped
766  # off anywhere, and also be different from eachother.
767  boolVal = True
768  int8Val = N.Int8Flags.py_type(-127)  # 0x81
769  uint8Val = N.Uint8Flags.py_type(0xFF)
770  int16Val = N.Int16Flags.py_type(-32222)  # 0x8222
771  uint16Val = N.Uint16Flags.py_type(0xFEEE)
772  int32Val = N.Int32Flags.py_type(overflowingInt32Val)
773  uint32Val = N.Uint32Flags.py_type(0xFDDDDDDD)
774  int64Val = N.Int64Flags.py_type(overflowingInt64Val)
775  uint64Val = N.Uint64Flags.py_type(0xFCCCCCCCCCCCCCCC)
776  # Python uses doubles, so force it here
777  float32Val = N.Float32Flags.py_type(ctypes.c_float(3.14159).value)
778  float64Val = N.Float64Flags.py_type(3.14159265359)
779
780  def test_fuzz(self):
781    return self.check_once(11, 100)
782
783  def check_once(self, fuzzFields, fuzzObjects):
784    testValuesMax = 11  # hardcoded to the number of scalar types
785
786    builder = flatbuffers.Builder(0)
787    l = LCG()
788
789    objects = [0 for _ in compat_range(fuzzObjects)]
790
791    # Generate fuzzObjects random objects each consisting of
792    # fuzzFields fields, each of a random type.
793    for i in compat_range(fuzzObjects):
794      builder.StartObject(fuzzFields)
795
796      for j in compat_range(fuzzFields):
797        choice = int(l.Next()) % testValuesMax
798        if choice == 0:
799          builder.PrependBoolSlot(int(j), self.boolVal, False)
800        elif choice == 1:
801          builder.PrependInt8Slot(int(j), self.int8Val, 0)
802        elif choice == 2:
803          builder.PrependUint8Slot(int(j), self.uint8Val, 0)
804        elif choice == 3:
805          builder.PrependInt16Slot(int(j), self.int16Val, 0)
806        elif choice == 4:
807          builder.PrependUint16Slot(int(j), self.uint16Val, 0)
808        elif choice == 5:
809          builder.PrependInt32Slot(int(j), self.int32Val, 0)
810        elif choice == 6:
811          builder.PrependUint32Slot(int(j), self.uint32Val, 0)
812        elif choice == 7:
813          builder.PrependInt64Slot(int(j), self.int64Val, 0)
814        elif choice == 8:
815          builder.PrependUint64Slot(int(j), self.uint64Val, 0)
816        elif choice == 9:
817          builder.PrependFloat32Slot(int(j), self.float32Val, 0)
818        elif choice == 10:
819          builder.PrependFloat64Slot(int(j), self.float64Val, 0)
820        else:
821          raise RuntimeError('unreachable')
822
823      off = builder.EndObject()
824
825      # store the offset from the end of the builder buffer,
826      # since it will keep growing:
827      objects[i] = off
828
829    # Do some bookkeeping to generate stats on fuzzes:
830    stats = defaultdict(int)
831
832    def check(table, desc, want, got):
833      stats[desc] += 1
834      self.assertEqual(want, got, '%s != %s, %s' % (want, got, desc))
835
836    l = LCG()  # Reset.
837
838    # Test that all objects we generated are readable and return the
839    # expected values. We generate random objects in the same order
840    # so this is deterministic.
841    for i in compat_range(fuzzObjects):
842
843      table = flatbuffers.table.Table(builder.Bytes,
844                                      len(builder.Bytes) - objects[i])
845
846      for j in compat_range(fuzzFields):
847        field_count = flatbuffers.builder.VtableMetadataFields + j
848        f = N.VOffsetTFlags.py_type(field_count * N.VOffsetTFlags.bytewidth)
849        choice = int(l.Next()) % testValuesMax
850
851        if choice == 0:
852          check(table, 'bool', self.boolVal,
853                table.GetSlot(f, False, N.BoolFlags))
854        elif choice == 1:
855          check(table, 'int8', self.int8Val, table.GetSlot(f, 0, N.Int8Flags))
856        elif choice == 2:
857          check(table, 'uint8', self.uint8Val,
858                table.GetSlot(f, 0, N.Uint8Flags))
859        elif choice == 3:
860          check(table, 'int16', self.int16Val,
861                table.GetSlot(f, 0, N.Int16Flags))
862        elif choice == 4:
863          check(table, 'uint16', self.uint16Val,
864                table.GetSlot(f, 0, N.Uint16Flags))
865        elif choice == 5:
866          check(table, 'int32', self.int32Val,
867                table.GetSlot(f, 0, N.Int32Flags))
868        elif choice == 6:
869          check(table, 'uint32', self.uint32Val,
870                table.GetSlot(f, 0, N.Uint32Flags))
871        elif choice == 7:
872          check(table, 'int64', self.int64Val,
873                table.GetSlot(f, 0, N.Int64Flags))
874        elif choice == 8:
875          check(table, 'uint64', self.uint64Val,
876                table.GetSlot(f, 0, N.Uint64Flags))
877        elif choice == 9:
878          check(table, 'float32', self.float32Val,
879                table.GetSlot(f, 0, N.Float32Flags))
880        elif choice == 10:
881          check(table, 'float64', self.float64Val,
882                table.GetSlot(f, 0, N.Float64Flags))
883        else:
884          raise RuntimeError('unreachable')
885
886    # If enough checks were made, verify that all scalar types were used:
887    self.assertEqual(testValuesMax, len(stats),
888                     'fuzzing failed to test all scalar types: %s' % stats)
889
890
891class TestByteLayout(unittest.TestCase):
892  """ TestByteLayout checks the bytes of a Builder in various scenarios. """
893
894  def assertBuilderEquals(self, builder, want_chars_or_ints):
895
896    def integerize(x):
897      if isinstance(x, compat.string_types):
898        return ord(x)
899      return x
900
901    want_ints = list(map(integerize, want_chars_or_ints))
902    want = bytearray(want_ints)
903    got = builder.Bytes[builder.Head():]  # use the buffer directly
904    self.assertEqual(want, got)
905
906  def test_numbers(self):
907    b = flatbuffers.Builder(0)
908    self.assertBuilderEquals(b, [])
909    b.PrependBool(True)
910    self.assertBuilderEquals(b, [1])
911    b.PrependInt8(-127)
912    self.assertBuilderEquals(b, [129, 1])
913    b.PrependUint8(255)
914    self.assertBuilderEquals(b, [255, 129, 1])
915    b.PrependInt16(-32222)
916    self.assertBuilderEquals(b, [0x22, 0x82, 0, 255, 129, 1])  # first pad
917    b.PrependUint16(0xFEEE)
918    # no pad this time:
919    self.assertBuilderEquals(b, [0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1])
920    b.PrependInt32(-53687092)
921    self.assertBuilderEquals(
922        b, [204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1])
923    b.PrependUint32(0x98765432)
924    self.assertBuilderEquals(b, [
925        0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0,
926        255, 129, 1
927    ])
928
929  def test_numbers64(self):
930    b = flatbuffers.Builder(0)
931    b.PrependUint64(0x1122334455667788)
932    self.assertBuilderEquals(b,
933                             [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11])
934
935    b = flatbuffers.Builder(0)
936    b.PrependInt64(0x1122334455667788)
937    self.assertBuilderEquals(b,
938                             [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11])
939
940  def test_1xbyte_vector(self):
941    b = flatbuffers.Builder(0)
942    self.assertBuilderEquals(b, [])
943    b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 1, 1)
944    self.assertBuilderEquals(b, [0, 0, 0])  # align to 4bytes
945    b.PrependByte(1)
946    self.assertBuilderEquals(b, [1, 0, 0, 0])
947    b.EndVector()
948    self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0])  # padding
949
950  def test_2xbyte_vector(self):
951    b = flatbuffers.Builder(0)
952    b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 2, 1)
953    self.assertBuilderEquals(b, [0, 0])  # align to 4bytes
954    b.PrependByte(1)
955    self.assertBuilderEquals(b, [1, 0, 0])
956    b.PrependByte(2)
957    self.assertBuilderEquals(b, [2, 1, 0, 0])
958    b.EndVector()
959    self.assertBuilderEquals(b, [2, 0, 0, 0, 2, 1, 0, 0])  # padding
960
961  def test_1xuint16_vector(self):
962    b = flatbuffers.Builder(0)
963    b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 1, 1)
964    self.assertBuilderEquals(b, [0, 0])  # align to 4bytes
965    b.PrependUint16(1)
966    self.assertBuilderEquals(b, [1, 0, 0, 0])
967    b.EndVector()
968    self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0])  # padding
969
970  def test_2xuint16_vector(self):
971    b = flatbuffers.Builder(0)
972    b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 2, 1)
973    self.assertBuilderEquals(b, [])  # align to 4bytes
974    b.PrependUint16(0xABCD)
975    self.assertBuilderEquals(b, [0xCD, 0xAB])
976    b.PrependUint16(0xDCBA)
977    self.assertBuilderEquals(b, [0xBA, 0xDC, 0xCD, 0xAB])
978    b.EndVector()
979    self.assertBuilderEquals(b, [2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB])
980
981  def test_create_ascii_string(self):
982    b = flatbuffers.Builder(0)
983    b.CreateString(u'foo', encoding='ascii')
984
985    # 0-terminated, no pad:
986    self.assertBuilderEquals(b, [3, 0, 0, 0, 'f', 'o', 'o', 0])
987    b.CreateString(u'moop', encoding='ascii')
988    # 0-terminated, 3-byte pad:
989    self.assertBuilderEquals(b, [
990        4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, 3, 0, 0, 0, 'f', 'o', 'o', 0
991    ])
992
993  def test_create_utf8_string(self):
994    b = flatbuffers.Builder(0)
995    b.CreateString(u'Цлїςσδε')
996    self.assertBuilderEquals(b, '\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97' \
997        '\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00')
998
999    b.CreateString(u'フムアムカモケモ')
1000    self.assertBuilderEquals(b, '\x18\x00\x00\x00\xef\xbe\x8c\xef\xbe\x91' \
1001        '\xef\xbd\xb1\xef\xbe\x91\xef\xbd\xb6\xef\xbe\x93\xef\xbd\xb9\xef' \
1002        '\xbe\x93\x00\x00\x00\x00\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97' \
1003        '\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00')
1004
1005  def test_create_arbitrary_string(self):
1006    b = flatbuffers.Builder(0)
1007    s = '\x01\x02\x03'
1008    b.CreateString(s)  # Default encoding is utf-8.
1009    # 0-terminated, no pad:
1010    self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
1011    s2 = '\x04\x05\x06\x07'
1012    b.CreateString(s2)  # Default encoding is utf-8.
1013    # 0-terminated, 3-byte pad:
1014    self.assertBuilderEquals(
1015        b, [4, 0, 0, 0, 4, 5, 6, 7, 0, 0, 0, 0, 3, 0, 0, 0, 1, 2, 3, 0])
1016
1017  def test_create_byte_vector(self):
1018    b = flatbuffers.Builder(0)
1019    b.CreateByteVector(b'')
1020    # 0-byte pad:
1021    self.assertBuilderEquals(b, [0, 0, 0, 0])
1022
1023    b = flatbuffers.Builder(0)
1024    b.CreateByteVector(b'\x01\x02\x03')
1025    # 1-byte pad:
1026    self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
1027
1028  def test_create_numpy_vector_int8(self):
1029    try:
1030      imp.find_module('numpy')
1031      # if numpy exists, then we should be able to get the
1032      # vector as a numpy array
1033      import numpy as np
1034
1035      # Systems endian:
1036      b = flatbuffers.Builder(0)
1037      x = np.array([1, 2, -3], dtype=np.int8)
1038      b.CreateNumpyVector(x)
1039      self.assertBuilderEquals(
1040          b,
1041          [
1042              3,
1043              0,
1044              0,
1045              0,  # vector length
1046              1,
1047              2,
1048              256 - 3,
1049              0  # vector value + padding
1050          ])
1051
1052      # Reverse endian:
1053      b = flatbuffers.Builder(0)
1054      x_other_endian = x.byteswap().newbyteorder()
1055      b.CreateNumpyVector(x_other_endian)
1056      self.assertBuilderEquals(
1057          b,
1058          [
1059              3,
1060              0,
1061              0,
1062              0,  # vector length
1063              1,
1064              2,
1065              256 - 3,
1066              0  # vector value + padding
1067          ])
1068    except ImportError:
1069      b = flatbuffers.Builder(0)
1070      x = 0
1071      assertRaises(self, lambda: b.CreateNumpyVector(x),
1072                   NumpyRequiredForThisFeature)
1073
1074  def test_create_numpy_vector_uint16(self):
1075    try:
1076      imp.find_module('numpy')
1077      # if numpy exists, then we should be able to get the
1078      # vector as a numpy array
1079      import numpy as np
1080
1081      # Systems endian:
1082      b = flatbuffers.Builder(0)
1083      x = np.array([1, 2, 312], dtype=np.uint16)
1084      b.CreateNumpyVector(x)
1085      self.assertBuilderEquals(
1086          b,
1087          [
1088              3,
1089              0,
1090              0,
1091              0,  # vector length
1092              1,
1093              0,  # 1
1094              2,
1095              0,  # 2
1096              312 - 256,
1097              1,  # 312
1098              0,
1099              0  # padding
1100          ])
1101
1102      # Reverse endian:
1103      b = flatbuffers.Builder(0)
1104      x_other_endian = x.byteswap().newbyteorder()
1105      b.CreateNumpyVector(x_other_endian)
1106      self.assertBuilderEquals(
1107          b,
1108          [
1109              3,
1110              0,
1111              0,
1112              0,  # vector length
1113              1,
1114              0,  # 1
1115              2,
1116              0,  # 2
1117              312 - 256,
1118              1,  # 312
1119              0,
1120              0  # padding
1121          ])
1122    except ImportError:
1123      b = flatbuffers.Builder(0)
1124      x = 0
1125      assertRaises(self, lambda: b.CreateNumpyVector(x),
1126                   NumpyRequiredForThisFeature)
1127
1128  def test_create_numpy_vector_int64(self):
1129    try:
1130      imp.find_module('numpy')
1131      # if numpy exists, then we should be able to get the
1132      # vector as a numpy array
1133      import numpy as np
1134
1135      # Systems endian:
1136      b = flatbuffers.Builder(0)
1137      x = np.array([1, 2, -12], dtype=np.int64)
1138      b.CreateNumpyVector(x)
1139      self.assertBuilderEquals(
1140          b,
1141          [
1142              3,
1143              0,
1144              0,
1145              0,  # vector length
1146              1,
1147              0,
1148              0,
1149              0,
1150              0,
1151              0,
1152              0,
1153              0,  # 1
1154              2,
1155              0,
1156              0,
1157              0,
1158              0,
1159              0,
1160              0,
1161              0,  # 2
1162              256 - 12,
1163              255,
1164              255,
1165              255,
1166              255,
1167              255,
1168              255,
1169              255  # -12
1170          ])
1171
1172      # Reverse endian:
1173      b = flatbuffers.Builder(0)
1174      x_other_endian = x.byteswap().newbyteorder()
1175      b.CreateNumpyVector(x_other_endian)
1176      self.assertBuilderEquals(
1177          b,
1178          [
1179              3,
1180              0,
1181              0,
1182              0,  # vector length
1183              1,
1184              0,
1185              0,
1186              0,
1187              0,
1188              0,
1189              0,
1190              0,  # 1
1191              2,
1192              0,
1193              0,
1194              0,
1195              0,
1196              0,
1197              0,
1198              0,  # 2
1199              256 - 12,
1200              255,
1201              255,
1202              255,
1203              255,
1204              255,
1205              255,
1206              255  # -12
1207          ])
1208
1209    except ImportError:
1210      b = flatbuffers.Builder(0)
1211      x = 0
1212      assertRaises(self, lambda: b.CreateNumpyVector(x),
1213                   NumpyRequiredForThisFeature)
1214
1215  def test_create_numpy_vector_float32(self):
1216    try:
1217      imp.find_module('numpy')
1218      # if numpy exists, then we should be able to get the
1219      # vector as a numpy array
1220      import numpy as np
1221
1222      # Systems endian:
1223      b = flatbuffers.Builder(0)
1224      x = np.array([1, 2, -12], dtype=np.float32)
1225      b.CreateNumpyVector(x)
1226      self.assertBuilderEquals(
1227          b,
1228          [
1229              3,
1230              0,
1231              0,
1232              0,  # vector length
1233              0,
1234              0,
1235              128,
1236              63,  # 1
1237              0,
1238              0,
1239              0,
1240              64,  # 2
1241              0,
1242              0,
1243              64,
1244              193  # -12
1245          ])
1246
1247      # Reverse endian:
1248      b = flatbuffers.Builder(0)
1249      x_other_endian = x.byteswap().newbyteorder()
1250      b.CreateNumpyVector(x_other_endian)
1251      self.assertBuilderEquals(
1252          b,
1253          [
1254              3,
1255              0,
1256              0,
1257              0,  # vector length
1258              0,
1259              0,
1260              128,
1261              63,  # 1
1262              0,
1263              0,
1264              0,
1265              64,  # 2
1266              0,
1267              0,
1268              64,
1269              193  # -12
1270          ])
1271
1272    except ImportError:
1273      b = flatbuffers.Builder(0)
1274      x = 0
1275      assertRaises(self, lambda: b.CreateNumpyVector(x),
1276                   NumpyRequiredForThisFeature)
1277
1278  def test_create_numpy_vector_float64(self):
1279    try:
1280      imp.find_module('numpy')
1281      # if numpy exists, then we should be able to get the
1282      # vector as a numpy array
1283      import numpy as np
1284
1285      # Systems endian:
1286      b = flatbuffers.Builder(0)
1287      x = np.array([1, 2, -12], dtype=np.float64)
1288      b.CreateNumpyVector(x)
1289      self.assertBuilderEquals(
1290          b,
1291          [
1292              3,
1293              0,
1294              0,
1295              0,  # vector length
1296              0,
1297              0,
1298              0,
1299              0,
1300              0,
1301              0,
1302              240,
1303              63,  # 1
1304              0,
1305              0,
1306              0,
1307              0,
1308              0,
1309              0,
1310              0,
1311              64,  # 2
1312              0,
1313              0,
1314              0,
1315              0,
1316              0,
1317              0,
1318              40,
1319              192  # -12
1320          ])
1321
1322      # Reverse endian:
1323      b = flatbuffers.Builder(0)
1324      x_other_endian = x.byteswap().newbyteorder()
1325      b.CreateNumpyVector(x_other_endian)
1326      self.assertBuilderEquals(
1327          b,
1328          [
1329              3,
1330              0,
1331              0,
1332              0,  # vector length
1333              0,
1334              0,
1335              0,
1336              0,
1337              0,
1338              0,
1339              240,
1340              63,  # 1
1341              0,
1342              0,
1343              0,
1344              0,
1345              0,
1346              0,
1347              0,
1348              64,  # 2
1349              0,
1350              0,
1351              0,
1352              0,
1353              0,
1354              0,
1355              40,
1356              192  # -12
1357          ])
1358
1359    except ImportError:
1360      b = flatbuffers.Builder(0)
1361      x = 0
1362      assertRaises(self, lambda: b.CreateNumpyVector(x),
1363                   NumpyRequiredForThisFeature)
1364
1365  def test_create_numpy_vector_bool(self):
1366    try:
1367      imp.find_module('numpy')
1368      # if numpy exists, then we should be able to get the
1369      # vector as a numpy array
1370      import numpy as np
1371
1372      # Systems endian:
1373      b = flatbuffers.Builder(0)
1374      x = np.array([True, False, True], dtype=np.bool)
1375      b.CreateNumpyVector(x)
1376      self.assertBuilderEquals(
1377          b,
1378          [
1379              3,
1380              0,
1381              0,
1382              0,  # vector length
1383              1,
1384              0,
1385              1,
1386              0  # vector values + padding
1387          ])
1388
1389      # Reverse endian:
1390      b = flatbuffers.Builder(0)
1391      x_other_endian = x.byteswap().newbyteorder()
1392      b.CreateNumpyVector(x_other_endian)
1393      self.assertBuilderEquals(
1394          b,
1395          [
1396              3,
1397              0,
1398              0,
1399              0,  # vector length
1400              1,
1401              0,
1402              1,
1403              0  # vector values + padding
1404          ])
1405
1406    except ImportError:
1407      b = flatbuffers.Builder(0)
1408      x = 0
1409      assertRaises(self, lambda: b.CreateNumpyVector(x),
1410                   NumpyRequiredForThisFeature)
1411
1412  def test_create_numpy_vector_reject_strings(self):
1413    try:
1414      imp.find_module('numpy')
1415      # if numpy exists, then we should be able to get the
1416      # vector as a numpy array
1417      import numpy as np
1418
1419      # Create String array
1420      b = flatbuffers.Builder(0)
1421      x = np.array(['hello', 'fb', 'testing'])
1422      assertRaises(self, lambda: b.CreateNumpyVector(x), TypeError)
1423
1424    except ImportError:
1425      b = flatbuffers.Builder(0)
1426      x = 0
1427      assertRaises(self, lambda: b.CreateNumpyVector(x),
1428                   NumpyRequiredForThisFeature)
1429
1430  def test_create_numpy_vector_reject_object(self):
1431    try:
1432      imp.find_module('numpy')
1433      # if numpy exists, then we should be able to get the
1434      # vector as a numpy array
1435      import numpy as np
1436
1437      # Create String array
1438      b = flatbuffers.Builder(0)
1439      x = np.array([{'m': 0}, {'as': -2.1, 'c': 'c'}])
1440      assertRaises(self, lambda: b.CreateNumpyVector(x), TypeError)
1441
1442    except ImportError:
1443      b = flatbuffers.Builder(0)
1444      x = 0
1445      assertRaises(self, lambda: b.CreateNumpyVector(x),
1446                   NumpyRequiredForThisFeature)
1447
1448  def test_empty_vtable(self):
1449    b = flatbuffers.Builder(0)
1450    b.StartObject(0)
1451    self.assertBuilderEquals(b, [])
1452    b.EndObject()
1453    self.assertBuilderEquals(b, [4, 0, 4, 0, 4, 0, 0, 0])
1454
1455  def test_vtable_with_one_true_bool(self):
1456    b = flatbuffers.Builder(0)
1457    self.assertBuilderEquals(b, [])
1458    b.StartObject(1)
1459    self.assertBuilderEquals(b, [])
1460    b.PrependBoolSlot(0, True, False)
1461    b.EndObject()
1462    self.assertBuilderEquals(
1463        b,
1464        [
1465            6,
1466            0,  # vtable bytes
1467            8,
1468            0,  # length of object including vtable offset
1469            7,
1470            0,  # start of bool value
1471            6,
1472            0,
1473            0,
1474            0,  # offset for start of vtable (int32)
1475            0,
1476            0,
1477            0,  # padded to 4 bytes
1478            1,  # bool value
1479        ])
1480
1481  def test_vtable_with_one_default_bool(self):
1482    b = flatbuffers.Builder(0)
1483    self.assertBuilderEquals(b, [])
1484    b.StartObject(1)
1485    self.assertBuilderEquals(b, [])
1486    b.PrependBoolSlot(0, False, False)
1487    b.EndObject()
1488    self.assertBuilderEquals(
1489        b,
1490        [
1491            4,
1492            0,  # vtable bytes
1493            4,
1494            0,  # end of object from here
1495            # entry 1 is zero and not stored
1496            4,
1497            0,
1498            0,
1499            0,  # offset for start of vtable (int32)
1500        ])
1501
1502  def test_vtable_with_one_int16(self):
1503    b = flatbuffers.Builder(0)
1504    b.StartObject(1)
1505    b.PrependInt16Slot(0, 0x789A, 0)
1506    b.EndObject()
1507    self.assertBuilderEquals(
1508        b,
1509        [
1510            6,
1511            0,  # vtable bytes
1512            8,
1513            0,  # end of object from here
1514            6,
1515            0,  # offset to value
1516            6,
1517            0,
1518            0,
1519            0,  # offset for start of vtable (int32)
1520            0,
1521            0,  # padding to 4 bytes
1522            0x9A,
1523            0x78,
1524        ])
1525
1526  def test_vtable_with_two_int16(self):
1527    b = flatbuffers.Builder(0)
1528    b.StartObject(2)
1529    b.PrependInt16Slot(0, 0x3456, 0)
1530    b.PrependInt16Slot(1, 0x789A, 0)
1531    b.EndObject()
1532    self.assertBuilderEquals(
1533        b,
1534        [
1535            8,
1536            0,  # vtable bytes
1537            8,
1538            0,  # end of object from here
1539            6,
1540            0,  # offset to value 0
1541            4,
1542            0,  # offset to value 1
1543            8,
1544            0,
1545            0,
1546            0,  # offset for start of vtable (int32)
1547            0x9A,
1548            0x78,  # value 1
1549            0x56,
1550            0x34,  # value 0
1551        ])
1552
1553  def test_vtable_with_int16_and_bool(self):
1554    b = flatbuffers.Builder(0)
1555    b.StartObject(2)
1556    b.PrependInt16Slot(0, 0x3456, 0)
1557    b.PrependBoolSlot(1, True, False)
1558    b.EndObject()
1559    self.assertBuilderEquals(
1560        b,
1561        [
1562            8,
1563            0,  # vtable bytes
1564            8,
1565            0,  # end of object from here
1566            6,
1567            0,  # offset to value 0
1568            5,
1569            0,  # offset to value 1
1570            8,
1571            0,
1572            0,
1573            0,  # offset for start of vtable (int32)
1574            0,  # padding
1575            1,  # value 1
1576            0x56,
1577            0x34,  # value 0
1578        ])
1579
1580  def test_vtable_with_empty_vector(self):
1581    b = flatbuffers.Builder(0)
1582    b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
1583    vecend = b.EndVector()
1584    b.StartObject(1)
1585    b.PrependUOffsetTRelativeSlot(0, vecend, 0)
1586    b.EndObject()
1587    self.assertBuilderEquals(
1588        b,
1589        [
1590            6,
1591            0,  # vtable bytes
1592            8,
1593            0,
1594            4,
1595            0,  # offset to vector offset
1596            6,
1597            0,
1598            0,
1599            0,  # offset for start of vtable (int32)
1600            4,
1601            0,
1602            0,
1603            0,
1604            0,
1605            0,
1606            0,
1607            0,  # length of vector (not in struct)
1608        ])
1609
1610  def test_vtable_with_empty_vector_of_byte_and_some_scalars(self):
1611    b = flatbuffers.Builder(0)
1612    b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
1613    vecend = b.EndVector()
1614    b.StartObject(2)
1615    b.PrependInt16Slot(0, 55, 0)
1616    b.PrependUOffsetTRelativeSlot(1, vecend, 0)
1617    b.EndObject()
1618    self.assertBuilderEquals(
1619        b,
1620        [
1621            8,
1622            0,  # vtable bytes
1623            12,
1624            0,
1625            10,
1626            0,  # offset to value 0
1627            4,
1628            0,  # offset to vector offset
1629            8,
1630            0,
1631            0,
1632            0,  # vtable loc
1633            8,
1634            0,
1635            0,
1636            0,  # value 1
1637            0,
1638            0,
1639            55,
1640            0,  # value 0
1641            0,
1642            0,
1643            0,
1644            0,  # length of vector (not in struct)
1645        ])
1646
1647  def test_vtable_with_1_int16_and_2vector_of_int16(self):
1648    b = flatbuffers.Builder(0)
1649    b.StartVector(flatbuffers.number_types.Int16Flags.bytewidth, 2, 1)
1650    b.PrependInt16(0x1234)
1651    b.PrependInt16(0x5678)
1652    vecend = b.EndVector()
1653    b.StartObject(2)
1654    b.PrependUOffsetTRelativeSlot(1, vecend, 0)
1655    b.PrependInt16Slot(0, 55, 0)
1656    b.EndObject()
1657    self.assertBuilderEquals(
1658        b,
1659        [
1660            8,
1661            0,  # vtable bytes
1662            12,
1663            0,  # length of object
1664            6,
1665            0,  # start of value 0 from end of vtable
1666            8,
1667            0,  # start of value 1 from end of buffer
1668            8,
1669            0,
1670            0,
1671            0,  # offset for start of vtable (int32)
1672            0,
1673            0,  # padding
1674            55,
1675            0,  # value 0
1676            4,
1677            0,
1678            0,
1679            0,  # vector position from here
1680            2,
1681            0,
1682            0,
1683            0,  # length of vector (uint32)
1684            0x78,
1685            0x56,  # vector value 1
1686            0x34,
1687            0x12,  # vector value 0
1688        ])
1689
1690  def test_vtable_with_1_struct_of_1_int8__1_int16__1_int32(self):
1691    b = flatbuffers.Builder(0)
1692    b.StartObject(1)
1693    b.Prep(4 + 4 + 4, 0)
1694    b.PrependInt8(55)
1695    b.Pad(3)
1696    b.PrependInt16(0x1234)
1697    b.Pad(2)
1698    b.PrependInt32(0x12345678)
1699    structStart = b.Offset()
1700    b.PrependStructSlot(0, structStart, 0)
1701    b.EndObject()
1702    self.assertBuilderEquals(
1703        b,
1704        [
1705            6,
1706            0,  # vtable bytes
1707            16,
1708            0,  # end of object from here
1709            4,
1710            0,  # start of struct from here
1711            6,
1712            0,
1713            0,
1714            0,  # offset for start of vtable (int32)
1715            0x78,
1716            0x56,
1717            0x34,
1718            0x12,  # value 2
1719            0,
1720            0,  # padding
1721            0x34,
1722            0x12,  # value 1
1723            0,
1724            0,
1725            0,  # padding
1726            55,  # value 0
1727        ])
1728
1729  def test_vtable_with_1_vector_of_2_struct_of_2_int8(self):
1730    b = flatbuffers.Builder(0)
1731    b.StartVector(flatbuffers.number_types.Int8Flags.bytewidth * 2, 2, 1)
1732    b.PrependInt8(33)
1733    b.PrependInt8(44)
1734    b.PrependInt8(55)
1735    b.PrependInt8(66)
1736    vecend = b.EndVector()
1737    b.StartObject(1)
1738    b.PrependUOffsetTRelativeSlot(0, vecend, 0)
1739    b.EndObject()
1740    self.assertBuilderEquals(
1741        b,
1742        [
1743            6,
1744            0,  # vtable bytes
1745            8,
1746            0,
1747            4,
1748            0,  # offset of vector offset
1749            6,
1750            0,
1751            0,
1752            0,  # offset for start of vtable (int32)
1753            4,
1754            0,
1755            0,
1756            0,  # vector start offset
1757            2,
1758            0,
1759            0,
1760            0,  # vector length
1761            66,  # vector value 1,1
1762            55,  # vector value 1,0
1763            44,  # vector value 0,1
1764            33,  # vector value 0,0
1765        ])
1766
1767  def test_table_with_some_elements(self):
1768    b = flatbuffers.Builder(0)
1769    b.StartObject(2)
1770    b.PrependInt8Slot(0, 33, 0)
1771    b.PrependInt16Slot(1, 66, 0)
1772    off = b.EndObject()
1773    b.Finish(off)
1774
1775    self.assertBuilderEquals(
1776        b,
1777        [
1778            12,
1779            0,
1780            0,
1781            0,  # root of table: points to vtable offset
1782            8,
1783            0,  # vtable bytes
1784            8,
1785            0,  # end of object from here
1786            7,
1787            0,  # start of value 0
1788            4,
1789            0,  # start of value 1
1790            8,
1791            0,
1792            0,
1793            0,  # offset for start of vtable (int32)
1794            66,
1795            0,  # value 1
1796            0,  # padding
1797            33,  # value 0
1798        ])
1799
1800  def test__one_unfinished_table_and_one_finished_table(self):
1801    b = flatbuffers.Builder(0)
1802    b.StartObject(2)
1803    b.PrependInt8Slot(0, 33, 0)
1804    b.PrependInt8Slot(1, 44, 0)
1805    off = b.EndObject()
1806    b.Finish(off)
1807
1808    b.StartObject(3)
1809    b.PrependInt8Slot(0, 55, 0)
1810    b.PrependInt8Slot(1, 66, 0)
1811    b.PrependInt8Slot(2, 77, 0)
1812    off = b.EndObject()
1813    b.Finish(off)
1814
1815    self.assertBuilderEquals(
1816        b,
1817        [
1818            16,
1819            0,
1820            0,
1821            0,  # root of table: points to object
1822            0,
1823            0,  # padding
1824            10,
1825            0,  # vtable bytes
1826            8,
1827            0,  # size of object
1828            7,
1829            0,  # start of value 0
1830            6,
1831            0,  # start of value 1
1832            5,
1833            0,  # start of value 2
1834            10,
1835            0,
1836            0,
1837            0,  # offset for start of vtable (int32)
1838            0,  # padding
1839            77,  # value 2
1840            66,  # value 1
1841            55,  # value 0
1842            12,
1843            0,
1844            0,
1845            0,  # root of table: points to object
1846            8,
1847            0,  # vtable bytes
1848            8,
1849            0,  # size of object
1850            7,
1851            0,  # start of value 0
1852            6,
1853            0,  # start of value 1
1854            8,
1855            0,
1856            0,
1857            0,  # offset for start of vtable (int32)
1858            0,
1859            0,  # padding
1860            44,  # value 1
1861            33,  # value 0
1862        ])
1863
1864  def test_a_bunch_of_bools(self):
1865    b = flatbuffers.Builder(0)
1866    b.StartObject(8)
1867    b.PrependBoolSlot(0, True, False)
1868    b.PrependBoolSlot(1, True, False)
1869    b.PrependBoolSlot(2, True, False)
1870    b.PrependBoolSlot(3, True, False)
1871    b.PrependBoolSlot(4, True, False)
1872    b.PrependBoolSlot(5, True, False)
1873    b.PrependBoolSlot(6, True, False)
1874    b.PrependBoolSlot(7, True, False)
1875    off = b.EndObject()
1876    b.Finish(off)
1877
1878    self.assertBuilderEquals(
1879        b,
1880        [
1881            24,
1882            0,
1883            0,
1884            0,  # root of table: points to vtable offset
1885            20,
1886            0,  # vtable bytes
1887            12,
1888            0,  # size of object
1889            11,
1890            0,  # start of value 0
1891            10,
1892            0,  # start of value 1
1893            9,
1894            0,  # start of value 2
1895            8,
1896            0,  # start of value 3
1897            7,
1898            0,  # start of value 4
1899            6,
1900            0,  # start of value 5
1901            5,
1902            0,  # start of value 6
1903            4,
1904            0,  # start of value 7
1905            20,
1906            0,
1907            0,
1908            0,  # vtable offset
1909            1,  # value 7
1910            1,  # value 6
1911            1,  # value 5
1912            1,  # value 4
1913            1,  # value 3
1914            1,  # value 2
1915            1,  # value 1
1916            1,  # value 0
1917        ])
1918
1919  def test_three_bools(self):
1920    b = flatbuffers.Builder(0)
1921    b.StartObject(3)
1922    b.PrependBoolSlot(0, True, False)
1923    b.PrependBoolSlot(1, True, False)
1924    b.PrependBoolSlot(2, True, False)
1925    off = b.EndObject()
1926    b.Finish(off)
1927
1928    self.assertBuilderEquals(
1929        b,
1930        [
1931            16,
1932            0,
1933            0,
1934            0,  # root of table: points to vtable offset
1935            0,
1936            0,  # padding
1937            10,
1938            0,  # vtable bytes
1939            8,
1940            0,  # size of object
1941            7,
1942            0,  # start of value 0
1943            6,
1944            0,  # start of value 1
1945            5,
1946            0,  # start of value 2
1947            10,
1948            0,
1949            0,
1950            0,  # vtable offset from here
1951            0,  # padding
1952            1,  # value 2
1953            1,  # value 1
1954            1,  # value 0
1955        ])
1956
1957  def test_some_floats(self):
1958    b = flatbuffers.Builder(0)
1959    b.StartObject(1)
1960    b.PrependFloat32Slot(0, 1.0, 0.0)
1961    off = b.EndObject()
1962
1963    self.assertBuilderEquals(
1964        b,
1965        [
1966            6,
1967            0,  # vtable bytes
1968            8,
1969            0,  # size of object
1970            4,
1971            0,  # start of value 0
1972            6,
1973            0,
1974            0,
1975            0,  # vtable offset
1976            0,
1977            0,
1978            128,
1979            63,  # value 0
1980        ])
1981
1982
1983def make_monster_from_generated_code(sizePrefix=False, file_identifier=None):
1984  """ Use generated code to build the example Monster. """
1985
1986  b = flatbuffers.Builder(0)
1987  string = b.CreateString('MyMonster')
1988  test1 = b.CreateString('test1')
1989  test2 = b.CreateString('test2')
1990  fred = b.CreateString('Fred')
1991
1992  _MONSTER.MonsterStartInventoryVector(b, 5)
1993  b.PrependByte(4)
1994  b.PrependByte(3)
1995  b.PrependByte(2)
1996  b.PrependByte(1)
1997  b.PrependByte(0)
1998  inv = b.EndVector()
1999
2000  _MONSTER.MonsterStart(b)
2001  _MONSTER.MonsterAddName(b, fred)
2002  mon2 = _MONSTER.MonsterEnd(b)
2003
2004  _MONSTER.MonsterStartTest4Vector(b, 2)
2005  _TEST.CreateTest(b, 10, 20)
2006  _TEST.CreateTest(b, 30, 40)
2007  test4 = b.EndVector()
2008
2009  _MONSTER.MonsterStartTestarrayofstringVector(b, 2)
2010  b.PrependUOffsetTRelative(test2)
2011  b.PrependUOffsetTRelative(test1)
2012  testArrayOfString = b.EndVector()
2013
2014  _MONSTER.MonsterStartVectorOfLongsVector(b, 5)
2015  b.PrependInt64(100000000)
2016  b.PrependInt64(1000000)
2017  b.PrependInt64(10000)
2018  b.PrependInt64(100)
2019  b.PrependInt64(1)
2020  VectorOfLongs = b.EndVector()
2021
2022  _MONSTER.MonsterStartVectorOfDoublesVector(b, 3)
2023  b.PrependFloat64(1.7976931348623157e+308)
2024  b.PrependFloat64(0)
2025  b.PrependFloat64(-1.7976931348623157e+308)
2026  VectorOfDoubles = b.EndVector()
2027
2028  _MONSTER.MonsterStart(b)
2029
2030  pos = _VEC3.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 2, 5, 6)
2031  _MONSTER.MonsterAddPos(b, pos)
2032
2033  _MONSTER.MonsterAddHp(b, 80)
2034  _MONSTER.MonsterAddName(b, string)
2035  _MONSTER.MonsterAddInventory(b, inv)
2036  _MONSTER.MonsterAddTestType(b, 1)
2037  _MONSTER.MonsterAddTest(b, mon2)
2038  _MONSTER.MonsterAddTest4(b, test4)
2039  _MONSTER.MonsterAddTestarrayofstring(b, testArrayOfString)
2040  _MONSTER.MonsterAddVectorOfLongs(b, VectorOfLongs)
2041  _MONSTER.MonsterAddVectorOfDoubles(b, VectorOfDoubles)
2042  mon = _MONSTER.MonsterEnd(b)
2043
2044  if sizePrefix:
2045    b.FinishSizePrefixed(mon, file_identifier)
2046  else:
2047    b.Finish(mon, file_identifier)
2048
2049  return b.Bytes, b.Head()
2050
2051
2052class TestBuilderForceDefaults(unittest.TestCase):
2053  """Verify that the builder adds default values when forced."""
2054
2055  test_flags = [N.BoolFlags(), N.Uint8Flags(), N.Uint16Flags(), \
2056                N.Uint32Flags(), N.Uint64Flags(), N.Int8Flags(), \
2057                N.Int16Flags(), N.Int32Flags(), N.Int64Flags(), \
2058                N.Float32Flags(), N.Float64Flags(), N.UOffsetTFlags()]
2059
2060  def test_default_force_defaults(self):
2061    for flag in self.test_flags:
2062      b = flatbuffers.Builder(0)
2063      b.StartObject(1)
2064      stored_offset = b.Offset()
2065      if flag != N.UOffsetTFlags():
2066        b.PrependSlot(flag, 0, 0, 0)
2067      else:
2068        b.PrependUOffsetTRelativeSlot(0, 0, 0)
2069      end_offset = b.Offset()
2070      b.EndObject()
2071      self.assertEqual(0, end_offset - stored_offset)
2072
2073  def test_force_defaults_true(self):
2074    for flag in self.test_flags:
2075      b = flatbuffers.Builder(0)
2076      b.ForceDefaults(True)
2077      b.StartObject(1)
2078      stored_offset = b.Offset()
2079      if flag != N.UOffsetTFlags():
2080        b.PrependSlot(flag, 0, 0, 0)
2081      else:
2082        b.PrependUOffsetTRelativeSlot(0, 0, 0)
2083      end_offset = b.Offset()
2084      b.EndObject()
2085      self.assertEqual(flag.bytewidth, end_offset - stored_offset)
2086
2087
2088class TestAllCodePathsOfExampleSchema(unittest.TestCase):
2089
2090  def setUp(self, *args, **kwargs):
2091    super(TestAllCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
2092
2093    b = flatbuffers.Builder(0)
2094    _MONSTER.MonsterStart(b)
2095    gen_mon = _MONSTER.MonsterEnd(b)
2096    b.Finish(gen_mon)
2097
2098    self.mon = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2099
2100  def test_default_monster_pos(self):
2101    self.assertTrue(self.mon.Pos() is None)
2102
2103  def test_nondefault_monster_mana(self):
2104    b = flatbuffers.Builder(0)
2105    _MONSTER.MonsterStart(b)
2106    _MONSTER.MonsterAddMana(b, 50)
2107    mon = _MONSTER.MonsterEnd(b)
2108    b.Finish(mon)
2109
2110    got_mon = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2111    self.assertEqual(50, got_mon.Mana())
2112
2113  def test_default_monster_hp(self):
2114    self.assertEqual(100, self.mon.Hp())
2115
2116  def test_default_monster_name(self):
2117    self.assertEqual(None, self.mon.Name())
2118
2119  def test_default_monster_inventory_item(self):
2120    self.assertEqual(0, self.mon.Inventory(0))
2121
2122  def test_default_monster_inventory_length(self):
2123    self.assertEqual(0, self.mon.InventoryLength())
2124    self.assertTrue(self.mon.InventoryIsNone())
2125
2126  def test_empty_monster_inventory_vector(self):
2127    b = flatbuffers.Builder(0)
2128    _MONSTER.MonsterStartInventoryVector(b, 0)
2129    inv = b.EndVector()
2130    _MONSTER.MonsterStart(b)
2131    _MONSTER.MonsterAddInventory(b, inv)
2132    mon = _MONSTER.MonsterEnd(b)
2133    b.Finish(mon)
2134    mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2135    self.assertFalse(mon2.InventoryIsNone())
2136
2137  def test_default_monster_color(self):
2138    self.assertEqual(_COLOR.Color.Blue, self.mon.Color())
2139
2140  def test_nondefault_monster_color(self):
2141    b = flatbuffers.Builder(0)
2142    color = _COLOR.Color.Red
2143    _MONSTER.MonsterStart(b)
2144    _MONSTER.MonsterAddColor(b, color)
2145    mon = _MONSTER.MonsterEnd(b)
2146    b.Finish(mon)
2147
2148    mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2149    self.assertEqual(_COLOR.Color.Red, mon2.Color())
2150
2151  def test_default_monster_testtype(self):
2152    self.assertEqual(0, self.mon.TestType())
2153
2154  def test_default_monster_test_field(self):
2155    self.assertEqual(None, self.mon.Test())
2156
2157  def test_default_monster_test4_item(self):
2158    self.assertEqual(None, self.mon.Test4(0))
2159
2160  def test_default_monster_test4_length(self):
2161    self.assertEqual(0, self.mon.Test4Length())
2162    self.assertTrue(self.mon.Test4IsNone())
2163
2164  def test_empty_monster_test4_vector(self):
2165    b = flatbuffers.Builder(0)
2166    _MONSTER.MonsterStartTest4Vector(b, 0)
2167    test4 = b.EndVector()
2168    _MONSTER.MonsterStart(b)
2169    _MONSTER.MonsterAddTest4(b, test4)
2170    mon = _MONSTER.MonsterEnd(b)
2171    b.Finish(mon)
2172    mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2173    self.assertFalse(mon2.Test4IsNone())
2174
2175  def test_default_monster_testarrayofstring(self):
2176    self.assertEqual('', self.mon.Testarrayofstring(0))
2177
2178  def test_default_monster_testarrayofstring_length(self):
2179    self.assertEqual(0, self.mon.TestarrayofstringLength())
2180    self.assertTrue(self.mon.TestarrayofstringIsNone())
2181
2182  def test_empty_monster_testarrayofstring_vector(self):
2183    b = flatbuffers.Builder(0)
2184    _MONSTER.MonsterStartTestarrayofstringVector(b, 0)
2185    testarrayofstring = b.EndVector()
2186    _MONSTER.MonsterStart(b)
2187    _MONSTER.MonsterAddTestarrayofstring(b, testarrayofstring)
2188    mon = _MONSTER.MonsterEnd(b)
2189    b.Finish(mon)
2190    mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2191    self.assertFalse(mon2.TestarrayofstringIsNone())
2192
2193  def test_default_monster_testarrayoftables(self):
2194    self.assertEqual(None, self.mon.Testarrayoftables(0))
2195
2196  def test_nondefault_monster_testarrayoftables(self):
2197    b = flatbuffers.Builder(0)
2198
2199    # make a child Monster within a vector of Monsters:
2200    _MONSTER.MonsterStart(b)
2201    _MONSTER.MonsterAddHp(b, 99)
2202    sub_monster = _MONSTER.MonsterEnd(b)
2203
2204    # build the vector:
2205    _MONSTER.MonsterStartTestarrayoftablesVector(b, 1)
2206    b.PrependUOffsetTRelative(sub_monster)
2207    vec = b.EndVector()
2208
2209    # make the parent monster and include the vector of Monster:
2210    _MONSTER.MonsterStart(b)
2211    _MONSTER.MonsterAddTestarrayoftables(b, vec)
2212    mon = _MONSTER.MonsterEnd(b)
2213    b.Finish(mon)
2214
2215    # inspect the resulting data:
2216    mon2 = _MONSTER.Monster.GetRootAs(b.Output(), 0)
2217    self.assertEqual(99, mon2.Testarrayoftables(0).Hp())
2218    self.assertEqual(1, mon2.TestarrayoftablesLength())
2219    self.assertFalse(mon2.TestarrayoftablesIsNone())
2220
2221  def test_default_monster_testarrayoftables_length(self):
2222    self.assertEqual(0, self.mon.TestarrayoftablesLength())
2223    self.assertTrue(self.mon.TestarrayoftablesIsNone())
2224
2225  def test_empty_monster_testarrayoftables_vector(self):
2226    b = flatbuffers.Builder(0)
2227    _MONSTER.MonsterStartTestarrayoftablesVector(b, 0)
2228    testarrayoftables = b.EndVector()
2229    _MONSTER.MonsterStart(b)
2230    _MONSTER.MonsterAddTestarrayoftables(b, testarrayoftables)
2231    mon = _MONSTER.MonsterEnd(b)
2232    b.Finish(mon)
2233    mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2234    self.assertFalse(mon2.TestarrayoftablesIsNone())
2235
2236  def test_default_monster_testarrayoftables_length(self):
2237    self.assertEqual(0, self.mon.TestarrayoftablesLength())
2238
2239  def test_nondefault_monster_enemy(self):
2240    b = flatbuffers.Builder(0)
2241
2242    # make an Enemy object:
2243    _MONSTER.MonsterStart(b)
2244    _MONSTER.MonsterAddHp(b, 88)
2245    enemy = _MONSTER.MonsterEnd(b)
2246    b.Finish(enemy)
2247
2248    # make the parent monster and include the vector of Monster:
2249    _MONSTER.MonsterStart(b)
2250    _MONSTER.MonsterAddEnemy(b, enemy)
2251    mon = _MONSTER.MonsterEnd(b)
2252    b.Finish(mon)
2253
2254    # inspect the resulting data:
2255    mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2256    self.assertEqual(88, mon2.Enemy().Hp())
2257
2258  def test_default_monster_testnestedflatbuffer(self):
2259    self.assertEqual(0, self.mon.Testnestedflatbuffer(0))
2260
2261  def test_default_monster_testnestedflatbuffer_length(self):
2262    self.assertEqual(0, self.mon.TestnestedflatbufferLength())
2263    self.assertTrue(self.mon.TestnestedflatbufferIsNone())
2264
2265  def test_empty_monster_testnestedflatbuffer_vector(self):
2266    b = flatbuffers.Builder(0)
2267    _MONSTER.MonsterStartTestnestedflatbufferVector(b, 0)
2268    testnestedflatbuffer = b.EndVector()
2269    _MONSTER.MonsterStart(b)
2270    _MONSTER.MonsterAddTestnestedflatbuffer(b, testnestedflatbuffer)
2271    mon = _MONSTER.MonsterEnd(b)
2272    b.Finish(mon)
2273    mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2274    self.assertFalse(mon2.TestnestedflatbufferIsNone())
2275
2276  def test_nondefault_monster_testnestedflatbuffer(self):
2277    b = flatbuffers.Builder(0)
2278
2279    _MONSTER.MonsterStartTestnestedflatbufferVector(b, 3)
2280    b.PrependByte(4)
2281    b.PrependByte(2)
2282    b.PrependByte(0)
2283    sub_buf = b.EndVector()
2284
2285    # make the parent monster and include the vector of Monster:
2286    _MONSTER.MonsterStart(b)
2287    _MONSTER.MonsterAddTestnestedflatbuffer(b, sub_buf)
2288    mon = _MONSTER.MonsterEnd(b)
2289    b.Finish(mon)
2290
2291    # inspect the resulting data:
2292    mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2293    self.assertEqual(3, mon2.TestnestedflatbufferLength())
2294    self.assertFalse(mon2.TestnestedflatbufferIsNone())
2295    self.assertEqual(0, mon2.Testnestedflatbuffer(0))
2296    self.assertEqual(2, mon2.Testnestedflatbuffer(1))
2297    self.assertEqual(4, mon2.Testnestedflatbuffer(2))
2298    try:
2299      imp.find_module('numpy')
2300      # if numpy exists, then we should be able to get the
2301      # vector as a numpy array
2302      self.assertEqual([0, 2, 4], mon2.TestnestedflatbufferAsNumpy().tolist())
2303    except ImportError:
2304      assertRaises(self, lambda: mon2.TestnestedflatbufferAsNumpy(),
2305                   NumpyRequiredForThisFeature)
2306
2307  def test_nested_monster_testnestedflatbuffer(self):
2308    b = flatbuffers.Builder(0)
2309
2310    # build another monster to nest inside testnestedflatbuffer
2311    nestedB = flatbuffers.Builder(0)
2312    nameStr = nestedB.CreateString('Nested Monster')
2313    _MONSTER.MonsterStart(nestedB)
2314    _MONSTER.MonsterAddHp(nestedB, 30)
2315    _MONSTER.MonsterAddName(nestedB, nameStr)
2316    nestedMon = _MONSTER.MonsterEnd(nestedB)
2317    nestedB.Finish(nestedMon)
2318
2319    # write the nested FB bytes
2320    sub_buf = _MONSTER.MonsterMakeTestnestedflatbufferVectorFromBytes(
2321        b, nestedB.Output())
2322
2323    # make the parent monster and include the bytes of the nested monster
2324    _MONSTER.MonsterStart(b)
2325    _MONSTER.MonsterAddTestnestedflatbuffer(b, sub_buf)
2326    mon = _MONSTER.MonsterEnd(b)
2327    b.Finish(mon)
2328
2329    # inspect the resulting data:
2330    mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2331    nestedMon2 = mon2.TestnestedflatbufferNestedRoot()
2332    self.assertEqual(b'Nested Monster', nestedMon2.Name())
2333    self.assertEqual(30, nestedMon2.Hp())
2334
2335  def test_nondefault_monster_testempty(self):
2336    b = flatbuffers.Builder(0)
2337
2338    # make a Stat object:
2339    _STAT.StatStart(b)
2340    _STAT.StatAddVal(b, 123)
2341    my_stat = _STAT.StatEnd(b)
2342    b.Finish(my_stat)
2343
2344    # include the stat object in a monster:
2345    _MONSTER.MonsterStart(b)
2346    _MONSTER.MonsterAddTestempty(b, my_stat)
2347    mon = _MONSTER.MonsterEnd(b)
2348    b.Finish(mon)
2349
2350    # inspect the resulting data:
2351    mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2352    self.assertEqual(123, mon2.Testempty().Val())
2353
2354  def test_default_monster_testbool(self):
2355    self.assertFalse(self.mon.Testbool())
2356
2357  def test_nondefault_monster_testbool(self):
2358    b = flatbuffers.Builder(0)
2359    _MONSTER.MonsterStart(b)
2360    _MONSTER.MonsterAddTestbool(b, True)
2361    mon = _MONSTER.MonsterEnd(b)
2362    b.Finish(mon)
2363
2364    # inspect the resulting data:
2365    mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2366    self.assertTrue(mon2.Testbool())
2367
2368  def test_default_monster_testhashes(self):
2369    self.assertEqual(0, self.mon.Testhashs32Fnv1())
2370    self.assertEqual(0, self.mon.Testhashu32Fnv1())
2371    self.assertEqual(0, self.mon.Testhashs64Fnv1())
2372    self.assertEqual(0, self.mon.Testhashu64Fnv1())
2373    self.assertEqual(0, self.mon.Testhashs32Fnv1a())
2374    self.assertEqual(0, self.mon.Testhashu32Fnv1a())
2375    self.assertEqual(0, self.mon.Testhashs64Fnv1a())
2376    self.assertEqual(0, self.mon.Testhashu64Fnv1a())
2377
2378  def test_nondefault_monster_testhashes(self):
2379    b = flatbuffers.Builder(0)
2380    _MONSTER.MonsterStart(b)
2381    _MONSTER.MonsterAddTesthashs32Fnv1(b, 1)
2382    _MONSTER.MonsterAddTesthashu32Fnv1(b, 2)
2383    _MONSTER.MonsterAddTesthashs64Fnv1(b, 3)
2384    _MONSTER.MonsterAddTesthashu64Fnv1(b, 4)
2385    _MONSTER.MonsterAddTesthashs32Fnv1a(b, 5)
2386    _MONSTER.MonsterAddTesthashu32Fnv1a(b, 6)
2387    _MONSTER.MonsterAddTesthashs64Fnv1a(b, 7)
2388    _MONSTER.MonsterAddTesthashu64Fnv1a(b, 8)
2389    mon = _MONSTER.MonsterEnd(b)
2390    b.Finish(mon)
2391
2392    # inspect the resulting data:
2393    mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2394    self.assertEqual(1, mon2.Testhashs32Fnv1())
2395    self.assertEqual(2, mon2.Testhashu32Fnv1())
2396    self.assertEqual(3, mon2.Testhashs64Fnv1())
2397    self.assertEqual(4, mon2.Testhashu64Fnv1())
2398    self.assertEqual(5, mon2.Testhashs32Fnv1a())
2399    self.assertEqual(6, mon2.Testhashu32Fnv1a())
2400    self.assertEqual(7, mon2.Testhashs64Fnv1a())
2401    self.assertEqual(8, mon2.Testhashu64Fnv1a())
2402
2403  def test_default_monster_parent_namespace_test(self):
2404    self.assertEqual(None, self.mon.ParentNamespaceTest())
2405
2406  def test_nondefault_monster_parent_namespace_test(self):
2407    b = flatbuffers.Builder(0)
2408    _IN_PARENT_NAMESPACE.InParentNamespaceStart(b)
2409    parent = _IN_PARENT_NAMESPACE.InParentNamespaceEnd(b)
2410    _MONSTER.MonsterStart(b)
2411    _MONSTER.MonsterAddParentNamespaceTest(b, parent)
2412    mon = _MONSTER.MonsterEnd(b)
2413    b.Finish(mon)
2414
2415    # Inspect the resulting data.
2416    monster = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2417    self.assertTrue(
2418        isinstance(monster.ParentNamespaceTest(),
2419                   _IN_PARENT_NAMESPACE.InParentNamespace))
2420
2421  def test_getrootas_for_nonroot_table(self):
2422    b = flatbuffers.Builder(0)
2423    string = b.CreateString('MyStat')
2424
2425    _STAT.StatStart(b)
2426    _STAT.StatAddId(b, string)
2427    _STAT.StatAddVal(b, 12345678)
2428    _STAT.StatAddCount(b, 12345)
2429    stat = _STAT.StatEnd(b)
2430    b.Finish(stat)
2431
2432    stat2 = _STAT.Stat.GetRootAs(b.Bytes, b.Head())
2433
2434    self.assertEqual(b'MyStat', stat2.Id())
2435    self.assertEqual(12345678, stat2.Val())
2436    self.assertEqual(12345, stat2.Count())
2437
2438
2439class TestAllCodePathsOfMonsterExtraSchema(unittest.TestCase):
2440
2441  def setUp(self, *args, **kwargs):
2442    super(TestAllCodePathsOfMonsterExtraSchema, self).setUp(*args, **kwargs)
2443
2444    b = flatbuffers.Builder(0)
2445    MyGame.MonsterExtra.Start(b)
2446    gen_mon = MyGame.MonsterExtra.End(b)
2447    b.Finish(gen_mon)
2448
2449    self.mon = MyGame.MonsterExtra.MonsterExtra.GetRootAs(b.Bytes, b.Head())
2450
2451  def test_default_nan_inf(self):
2452    self.assertTrue(math.isnan(self.mon.F1()))
2453    self.assertEqual(self.mon.F2(), float('inf'))
2454    self.assertEqual(self.mon.F3(), float('-inf'))
2455
2456    self.assertTrue(math.isnan(self.mon.D1()))
2457    self.assertEqual(self.mon.D2(), float('inf'))
2458    self.assertEqual(self.mon.D3(), float('-inf'))
2459
2460
2461class TestVtableDeduplication(unittest.TestCase):
2462  """ TestVtableDeduplication verifies that vtables are deduplicated. """
2463
2464  def test_vtable_deduplication(self):
2465    b = flatbuffers.Builder(0)
2466
2467    b.StartObject(4)
2468    b.PrependByteSlot(0, 0, 0)
2469    b.PrependByteSlot(1, 11, 0)
2470    b.PrependByteSlot(2, 22, 0)
2471    b.PrependInt16Slot(3, 33, 0)
2472    obj0 = b.EndObject()
2473
2474    b.StartObject(4)
2475    b.PrependByteSlot(0, 0, 0)
2476    b.PrependByteSlot(1, 44, 0)
2477    b.PrependByteSlot(2, 55, 0)
2478    b.PrependInt16Slot(3, 66, 0)
2479    obj1 = b.EndObject()
2480
2481    b.StartObject(4)
2482    b.PrependByteSlot(0, 0, 0)
2483    b.PrependByteSlot(1, 77, 0)
2484    b.PrependByteSlot(2, 88, 0)
2485    b.PrependInt16Slot(3, 99, 0)
2486    obj2 = b.EndObject()
2487
2488    got = b.Bytes[b.Head():]
2489
2490    want = bytearray([
2491        240,
2492        255,
2493        255,
2494        255,  # == -12. offset to dedupped vtable.
2495        99,
2496        0,
2497        88,
2498        77,
2499        248,
2500        255,
2501        255,
2502        255,  # == -8. offset to dedupped vtable.
2503        66,
2504        0,
2505        55,
2506        44,
2507        12,
2508        0,
2509        8,
2510        0,
2511        0,
2512        0,
2513        7,
2514        0,
2515        6,
2516        0,
2517        4,
2518        0,
2519        12,
2520        0,
2521        0,
2522        0,
2523        33,
2524        0,
2525        22,
2526        11,
2527    ])
2528
2529    self.assertEqual((len(want), want), (len(got), got))
2530
2531    table0 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj0)
2532    table1 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj1)
2533    table2 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj2)
2534
2535    def _checkTable(tab, voffsett_value, b, c, d):
2536      # vtable size
2537      got = tab.GetVOffsetTSlot(0, 0)
2538      self.assertEqual(12, got, 'case 0, 0')
2539
2540      # object size
2541      got = tab.GetVOffsetTSlot(2, 0)
2542      self.assertEqual(8, got, 'case 2, 0')
2543
2544      # default value
2545      got = tab.GetVOffsetTSlot(4, 0)
2546      self.assertEqual(voffsett_value, got, 'case 4, 0')
2547
2548      got = tab.GetSlot(6, 0, N.Uint8Flags)
2549      self.assertEqual(b, got, 'case 6, 0')
2550
2551      val = tab.GetSlot(8, 0, N.Uint8Flags)
2552      self.assertEqual(c, val, 'failed 8, 0')
2553
2554      got = tab.GetSlot(10, 0, N.Uint8Flags)
2555      self.assertEqual(d, got, 'failed 10, 0')
2556
2557    _checkTable(table0, 0, 11, 22, 33)
2558    _checkTable(table1, 0, 44, 55, 66)
2559    _checkTable(table2, 0, 77, 88, 99)
2560
2561
2562class TestExceptions(unittest.TestCase):
2563
2564  def test_object_is_nested_error(self):
2565    b = flatbuffers.Builder(0)
2566    b.StartObject(0)
2567    assertRaises(self, lambda: b.StartObject(0),
2568                 flatbuffers.builder.IsNestedError)
2569
2570  def test_object_is_not_nested_error(self):
2571    b = flatbuffers.Builder(0)
2572    assertRaises(self, lambda: b.EndObject(),
2573                 flatbuffers.builder.IsNotNestedError)
2574
2575  def test_struct_is_not_inline_error(self):
2576    b = flatbuffers.Builder(0)
2577    b.StartObject(0)
2578    assertRaises(self, lambda: b.PrependStructSlot(0, 1, 0),
2579                 flatbuffers.builder.StructIsNotInlineError)
2580
2581  def test_unreachable_error(self):
2582    b = flatbuffers.Builder(0)
2583    assertRaises(self, lambda: b.PrependUOffsetTRelative(1),
2584                 flatbuffers.builder.OffsetArithmeticError)
2585
2586  def test_create_string_is_nested_error(self):
2587    b = flatbuffers.Builder(0)
2588    b.StartObject(0)
2589    s = 'test1'
2590    assertRaises(self, lambda: b.CreateString(s),
2591                 flatbuffers.builder.IsNestedError)
2592
2593  def test_create_byte_vector_is_nested_error(self):
2594    b = flatbuffers.Builder(0)
2595    b.StartObject(0)
2596    s = b'test1'
2597    assertRaises(self, lambda: b.CreateByteVector(s),
2598                 flatbuffers.builder.IsNestedError)
2599
2600  def test_finished_bytes_error(self):
2601    b = flatbuffers.Builder(0)
2602    assertRaises(self, lambda: b.Output(),
2603                 flatbuffers.builder.BuilderNotFinishedError)
2604
2605
2606class TestFixedLengthArrays(unittest.TestCase):
2607
2608  def test_fixed_length_array(self):
2609    builder = flatbuffers.Builder(0)
2610
2611    a = 0.5
2612    b = range(0, 15)
2613    c = 1
2614    d_a = [[1, 2], [3, 4]]
2615    d_b = [MyGame.Example.TestEnum.TestEnum.B, \
2616            MyGame.Example.TestEnum.TestEnum.C]
2617    d_c = [[MyGame.Example.TestEnum.TestEnum.A, \
2618            MyGame.Example.TestEnum.TestEnum.B], \
2619            [MyGame.Example.TestEnum.TestEnum.C, \
2620             MyGame.Example.TestEnum.TestEnum.B]]
2621    d_d = [[-1, 1], [-2, 2]]
2622    e = 2
2623    f = [-1, 1]
2624
2625    arrayOffset = MyGame.Example.ArrayStruct.CreateArrayStruct(builder, \
2626        a, b, c, d_a, d_b, d_c, d_d, e, f)
2627
2628    # Create a table with the ArrayStruct.
2629    MyGame.Example.ArrayTable.Start(builder)
2630    MyGame.Example.ArrayTable.AddA(builder, arrayOffset)
2631    tableOffset = MyGame.Example.ArrayTable.End(builder)
2632
2633    builder.Finish(tableOffset)
2634
2635    buf = builder.Output()
2636
2637    table = MyGame.Example.ArrayTable.ArrayTable.GetRootAs(buf)
2638
2639    # Verify structure.
2640    nested = MyGame.Example.NestedStruct.NestedStruct()
2641    self.assertEqual(table.A().A(), 0.5)
2642    self.assertEqual(table.A().B(), \
2643        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
2644    self.assertEqual(table.A().C(), 1)
2645    self.assertEqual(table.A().D(nested, 0).A(), [1, 2])
2646    self.assertEqual(table.A().D(nested, 1).A(), [3, 4])
2647    self.assertEqual(table.A().D(nested, 0).B(), \
2648        MyGame.Example.TestEnum.TestEnum.B)
2649    self.assertEqual(table.A().D(nested, 1).B(), \
2650        MyGame.Example.TestEnum.TestEnum.C)
2651    self.assertEqual(table.A().D(nested, 0).C(), \
2652        [MyGame.Example.TestEnum.TestEnum.A, \
2653         MyGame.Example.TestEnum.TestEnum.B])
2654    self.assertEqual(table.A().D(nested, 1).C(), \
2655        [MyGame.Example.TestEnum.TestEnum.C, \
2656         MyGame.Example.TestEnum.TestEnum.B])
2657    self.assertEqual(table.A().D(nested, 0).D(), [-1, 1])
2658    self.assertEqual(table.A().D(nested, 1).D(), [-2, 2])
2659    self.assertEqual(table.A().E(), 2)
2660    self.assertEqual(table.A().F(), [-1, 1])
2661
2662
2663def CheckAgainstGoldDataGo():
2664  try:
2665    gen_buf, gen_off = make_monster_from_generated_code()
2666    fn = 'monsterdata_go_wire.mon'
2667    if not os.path.exists(fn):
2668      print('Go-generated data does not exist, failed.')
2669      return False
2670
2671    # would like to use a context manager here, but it's less
2672    # backwards-compatible:
2673    f = open(fn, 'rb')
2674    go_wire_data = f.read()
2675    f.close()
2676
2677    CheckReadBuffer(bytearray(go_wire_data), 0)
2678    if not bytearray(gen_buf[gen_off:]) == bytearray(go_wire_data):
2679      raise AssertionError('CheckAgainstGoldDataGo failed')
2680  except:
2681    print('Failed to test against Go-generated test data.')
2682    return False
2683
2684  print(
2685      'Can read Go-generated test data, and Python generates bytewise identical data.'
2686  )
2687  return True
2688
2689
2690def CheckAgainstGoldDataJava():
2691  try:
2692    gen_buf, gen_off = make_monster_from_generated_code()
2693    fn = 'monsterdata_java_wire.mon'
2694    if not os.path.exists(fn):
2695      print('Java-generated data does not exist, failed.')
2696      return False
2697    f = open(fn, 'rb')
2698    java_wire_data = f.read()
2699    f.close()
2700
2701    CheckReadBuffer(bytearray(java_wire_data), 0)
2702  except:
2703    print('Failed to read Java-generated test data.')
2704    return False
2705
2706  print('Can read Java-generated test data.')
2707  return True
2708
2709
2710class LCG(object):
2711  """ Include simple random number generator to ensure results will be the
2712
2713        same cross platform.
2714        http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
2715        """
2716
2717  __slots__ = ['n']
2718
2719  InitialLCGSeed = 48271
2720
2721  def __init__(self):
2722    self.n = self.InitialLCGSeed
2723
2724  def Reset(self):
2725    self.n = self.InitialLCGSeed
2726
2727  def Next(self):
2728    self.n = ((self.n * 279470273) % 4294967291) & 0xFFFFFFFF
2729    return self.n
2730
2731
2732def BenchmarkVtableDeduplication(count):
2733  """
2734    BenchmarkVtableDeduplication measures the speed of vtable deduplication
2735    by creating `prePop` vtables, then populating `count` objects with a
2736    different single vtable.
2737
2738    When count is large (as in long benchmarks), memory usage may be high.
2739    """
2740
2741  for prePop in (1, 10, 100, 1000):
2742    builder = flatbuffers.Builder(0)
2743    n = 1 + int(math.log(prePop, 1.5))
2744
2745    # generate some layouts:
2746    layouts = set()
2747    r = list(compat_range(n))
2748    while len(layouts) < prePop:
2749      layouts.add(tuple(sorted(random.sample(r, int(max(1, n / 2))))))
2750
2751    layouts = list(layouts)
2752
2753    # pre-populate vtables:
2754    for layout in layouts:
2755      builder.StartObject(n)
2756      for j in layout:
2757        builder.PrependInt16Slot(j, j, 0)
2758      builder.EndObject()
2759
2760    # benchmark deduplication of a new vtable:
2761    def f():
2762      layout = random.choice(layouts)
2763      builder.StartObject(n)
2764      for j in layout:
2765        builder.PrependInt16Slot(j, j, 0)
2766      builder.EndObject()
2767
2768    duration = timeit.timeit(stmt=f, number=count)
2769    rate = float(count) / duration
2770    print(('vtable deduplication rate (n=%d, vtables=%d): %.2f sec' %
2771           (prePop, len(builder.vtables), rate)))
2772
2773
2774def BenchmarkCheckReadBuffer(count, buf, off):
2775  """
2776    BenchmarkCheckReadBuffer measures the speed of flatbuffer reading
2777    by re-using the CheckReadBuffer function with the gold data.
2778    """
2779
2780  def f():
2781    CheckReadBuffer(buf, off)
2782
2783  duration = timeit.timeit(stmt=f, number=count)
2784  rate = float(count) / duration
2785  data = float(len(buf) * count) / float(1024 * 1024)
2786  data_rate = data / float(duration)
2787
2788  print(('traversed %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec') %
2789        (count, len(buf), duration, rate, data_rate))
2790
2791
2792def BenchmarkMakeMonsterFromGeneratedCode(count, length):
2793  """
2794    BenchmarkMakeMonsterFromGeneratedCode measures the speed of flatbuffer
2795    creation by re-using the make_monster_from_generated_code function for
2796    generating gold data examples.
2797    """
2798
2799  duration = timeit.timeit(stmt=make_monster_from_generated_code, number=count)
2800  rate = float(count) / duration
2801  data = float(length * count) / float(1024 * 1024)
2802  data_rate = data / float(duration)
2803
2804  print(('built %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec' % \
2805         (count, length, duration, rate, data_rate)))
2806
2807
2808def backward_compatible_run_tests(**kwargs):
2809  if PY_VERSION < (2, 6):
2810    sys.stderr.write('Python version less than 2.6 are not supported')
2811    sys.stderr.flush()
2812    return False
2813
2814  # python2.6 has a reduced-functionality unittest.main function:
2815  if PY_VERSION == (2, 6):
2816    try:
2817      unittest.main(**kwargs)
2818    except SystemExit as e:
2819      if not e.code == 0:
2820        return False
2821    return True
2822
2823  # python2.7 and above let us not exit once unittest.main is run:
2824  kwargs['exit'] = False
2825  kwargs['verbosity'] = 0
2826  ret = unittest.main(**kwargs)
2827  if ret.result.errors or ret.result.failures:
2828    return False
2829
2830  return True
2831
2832
2833def main():
2834  import os
2835  import sys
2836  if not len(sys.argv) == 5:
2837    sys.stderr.write('Usage: %s <benchmark vtable count> '
2838                     '<benchmark read count> <benchmark build count> '
2839                     '<is_onefile>\n' % sys.argv[0])
2840    sys.stderr.write('       Provide COMPARE_GENERATED_TO_GO=1   to check'
2841                     'for bytewise comparison to Go data.\n')
2842    sys.stderr.write('       Provide COMPARE_GENERATED_TO_JAVA=1 to check'
2843                     'for bytewise comparison to Java data.\n')
2844    sys.stderr.flush()
2845    sys.exit(1)
2846
2847  kwargs = dict(argv=sys.argv[:-4])
2848
2849  create_namespace_shortcut(sys.argv[4].lower() == 'true')
2850
2851  # show whether numpy is present, as it changes the test logic:
2852  try:
2853    import numpy
2854    print('numpy available')
2855  except ImportError:
2856    print('numpy not available')
2857
2858  # run tests, and run some language comparison checks if needed:
2859  success = backward_compatible_run_tests(**kwargs)
2860  if success and os.environ.get('COMPARE_GENERATED_TO_GO', 0) == '1':
2861    success = success and CheckAgainstGoldDataGo()
2862  if success and os.environ.get('COMPARE_GENERATED_TO_JAVA', 0) == '1':
2863    success = success and CheckAgainstGoldDataJava()
2864
2865  if not success:
2866    sys.stderr.write('Tests failed, skipping benchmarks.\n')
2867    sys.stderr.flush()
2868    sys.exit(1)
2869
2870  # run benchmarks (if 0, they will be a noop):
2871  bench_vtable = int(sys.argv[1])
2872  bench_traverse = int(sys.argv[2])
2873  bench_build = int(sys.argv[3])
2874  if bench_vtable:
2875    BenchmarkVtableDeduplication(bench_vtable)
2876  if bench_traverse:
2877    buf, off = make_monster_from_generated_code()
2878    BenchmarkCheckReadBuffer(bench_traverse, buf, off)
2879  if bench_build:
2880    buf, off = make_monster_from_generated_code()
2881    BenchmarkMakeMonsterFromGeneratedCode(bench_build, len(buf))
2882
2883
2884if __name__ == '__main__':
2885  main()
2886