Flatbuffers Python Object API (#5616)
authorlu-wang-g <47436172+lu-wang-g@users.noreply.github.com>
Mon, 2 Dec 2019 22:11:28 +0000 (14:11 -0800)
committerWouter van Oortmerssen <aardappel@gmail.com>
Mon, 2 Dec 2019 22:11:28 +0000 (14:11 -0800)
* Flatbuffers Python Object API

Implement the logic to generate the Python object API that can
unpack the data from a buf class into an object class, and pack
the data of an object class to a buf class.

* Fix the build issues

Remove unused parameters and replace auto in the for-loop statement
with std::string to make it compatible with VS2010.

* Fix the build issues.

* Add support for Array type

Added logic to handle Array type in Python Object API. Updated the
generated code accordingly.

* Fix the old style casting from int to char

* Fixed another conversion from int to char

* Fixed the import for typing

Importing typing may cause errors when a machine do not have the
moduel typing installed. This PR fixes the issue by guarding
"import typing" with the "try/except" statement.

* Fix issue of iterating the vector of import list

* Update the generated examples using generate_code.sh

* Fix the import order for typing

The import list was stored in unordered_set, so that each generated
codes may have different import order. Therefore, it failed in the
consistency test where two generated copies need to have exactly the
same apperance.

* Optimize unpack using numpy

Use numpy to unpack vector whenever it is possible to improve unpack
performance.

Also, added codegen command for Python specificly in generate_code.sh,
because --no-includes cannot be turn on for Python.

* Fix the import order

* Update generate_code.bat for windows accordingly

* Replace error message with pass

Avoid printing error message for every Python2 users about typing.
Replace it with pass.

29 files changed:
docs/source/Compiler.md
src/flatc.cpp
src/idl_gen_python.cpp
tests/MyGame/Example/Ability.py
tests/MyGame/Example/Any.py
tests/MyGame/Example/AnyAmbiguousAliases.py
tests/MyGame/Example/AnyUniqueAliases.py
tests/MyGame/Example/ArrayStruct.py
tests/MyGame/Example/ArrayTable.py
tests/MyGame/Example/Monster.py
tests/MyGame/Example/NestedStruct.py
tests/MyGame/Example/Referrable.py
tests/MyGame/Example/Stat.py
tests/MyGame/Example/Test.py
tests/MyGame/Example/TestSimpleTableWithEnum.py
tests/MyGame/Example/TypeAliases.py
tests/MyGame/Example/Vec3.py
tests/MyGame/Example2/Monster.py
tests/MyGame/InParentNamespace.py
tests/MyGame/MonsterExtra.py
tests/PythonTest.sh
tests/generate_code.bat
tests/generate_code.sh
tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py
tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py
tests/namespace_test/NamespaceA/SecondTableInA.py
tests/namespace_test/NamespaceA/TableInFirstNS.py
tests/namespace_test/NamespaceC/TableInC.py
tests/py_test.py

index 7889abd..9eaabf8 100644 (file)
@@ -94,7 +94,7 @@ Additional options:
                           statements) use `--no-includes.`
 
 -   `--no-includes` : Don't generate include statements for included schemas the
-    generated file depends on (C++).
+    generated file depends on (C++ / Python).
 
 -   `--gen-mutable` : Generate additional non-const accessors for mutating
     FlatBuffers in-place.
index 257afa8..8cc2d3c 100644 (file)
@@ -94,7 +94,7 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
     "                     If the original behavior is required (no include\n"
     "                     statements) use --no-includes.\n"
     "  --no-includes      Don\'t generate include statements for included\n"
-    "                     schemas the generated file depends on (C++).\n"
+    "                     schemas the generated file depends on (C++ / Python).\n"
     "  --gen-mutable      Generate accessors that can mutate buffers in-place.\n"
     "  --gen-onefile      Generate single output file for C# and Go.\n"
     "  --gen-name-strings Generate type name functions for C++.\n"
index 58d0e0f..bf3b77e 100644 (file)
 
 // independent from idl_parser, since this code is not needed for most clients
 
+#include <cctype>
+#include <set>
 #include <string>
 #include <unordered_set>
+#include <vector>
 
 #include "flatbuffers/code_generators.h"
 #include "flatbuffers/flatbuffers.h"
@@ -59,7 +62,7 @@ class PythonGenerator : public BaseGenerator {
 
   // Begin a class declaration.
   void BeginClass(const StructDef &struct_def, std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     code += "class " + NormalizedName(struct_def) + "(object):\n";
     code += Indent + "__slots__ = ['_tab']";
     code += "\n\n";
@@ -67,7 +70,7 @@ class PythonGenerator : public BaseGenerator {
 
   // Begin enum code with a class declaration.
   void BeginEnum(const std::string &class_name, std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     code += "class " + class_name + "(object):\n";
   }
 
@@ -83,10 +86,27 @@ class PythonGenerator : public BaseGenerator {
     return EscapeKeyword(ev.name);
   }
 
+  // Converts the name of a definition into upper Camel format.
+  std::string MakeUpperCamel(const Definition &definition) const {
+    return MakeCamel(NormalizedName(definition), true);
+  }
+
+  // Converts the name of a definition into lower Camel format.
+  std::string MakeLowerCamel(const Definition &definition) const {
+    auto name = MakeCamel(NormalizedName(definition), false);
+    name[0] = char(tolower(name[0]));
+    return name;
+  }
+
+  // Starts a new line and then indents.
+  std::string GenIndents(int num) {
+    return "\n" + std::string(num * Indent.length(), ' ');
+  }
+
   // A single enum member.
   void EnumMember(const EnumDef &enum_def, const EnumVal &ev,
                   std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     code += Indent;
     code += NormalizedName(ev);
     code += " = ";
@@ -95,14 +115,14 @@ class PythonGenerator : public BaseGenerator {
 
   // End enum code.
   void EndEnum(std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     code += "\n";
   }
 
   // Initialize a new struct or table from existing data.
   void NewRootTypeFromBuffer(const StructDef &struct_def,
                              std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
 
     code += Indent + "@classmethod\n";
     code += Indent + "def GetRootAs";
@@ -119,8 +139,9 @@ class PythonGenerator : public BaseGenerator {
   }
 
   // Initialize an existing object with other data, to avoid an allocation.
-  void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) {
-    std::string &code = *code_ptr;
+  void InitializeExisting(const StructDef &struct_def,
+                          std::string *code_ptr) {
+    auto &code = *code_ptr;
 
     GenReceiver(struct_def, code_ptr);
     code += "Init(self, buf, pos):\n";
@@ -131,7 +152,7 @@ class PythonGenerator : public BaseGenerator {
   // Get the length of a vector.
   void GetVectorLen(const StructDef &struct_def, const FieldDef &field,
                     std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
 
     GenReceiver(struct_def, code_ptr);
     code += MakeCamel(NormalizedName(field)) + "Length(self";
@@ -140,10 +161,26 @@ class PythonGenerator : public BaseGenerator {
     code += Indent + Indent + "return 0\n\n";
   }
 
+  // Determines whether a vector is none or not.
+  void GetVectorIsNone(const StructDef &struct_def, const FieldDef &field,
+                       std::string *code_ptr) {
+    auto &code = *code_ptr;
+
+    GenReceiver(struct_def, code_ptr);
+    code += MakeCamel(NormalizedName(field)) + "IsNone(self";
+    code += "):";
+    code += GenIndents(2) +
+            "o = flatbuffers.number_types.UOffsetTFlags.py_type" +
+            "(self._tab.Offset(" + NumToString(field.value.offset) + "))";
+    code += GenIndents(2) + "return o == 0";
+    code += "\n\n";
+  }
+
   // Get the value of a struct's scalar.
   void GetScalarFieldOfStruct(const StructDef &struct_def,
-                              const FieldDef &field, std::string *code_ptr) {
-    std::string &code = *code_ptr;
+                              const FieldDef &field,
+                              std::string *code_ptr) {
+    auto &code = *code_ptr;
     std::string getter = GenGetter(field.value.type);
     GenReceiver(struct_def, code_ptr);
     code += MakeCamel(NormalizedName(field));
@@ -155,7 +192,7 @@ class PythonGenerator : public BaseGenerator {
   // Get the value of a table's scalar.
   void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field,
                              std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     std::string getter = GenGetter(field.value.type);
     GenReceiver(struct_def, code_ptr);
     code += MakeCamel(NormalizedName(field));
@@ -179,8 +216,9 @@ class PythonGenerator : public BaseGenerator {
   // Get a struct by initializing an existing struct.
   // Specific to Struct.
   void GetStructFieldOfStruct(const StructDef &struct_def,
-                              const FieldDef &field, std::string *code_ptr) {
-    std::string &code = *code_ptr;
+                              const FieldDef &field,
+                              std::string *code_ptr) {
+    auto &code = *code_ptr;
     GenReceiver(struct_def, code_ptr);
     code += MakeCamel(NormalizedName(field));
     code += "(self, obj):\n";
@@ -192,7 +230,7 @@ class PythonGenerator : public BaseGenerator {
   // Get the value of a fixed size array.
   void GetArrayOfStruct(const StructDef &struct_def, const FieldDef &field,
                         std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     const auto vec_type = field.value.type.VectorType();
     GenReceiver(struct_def, code_ptr);
     code += MakeCamel(NormalizedName(field));
@@ -217,7 +255,7 @@ class PythonGenerator : public BaseGenerator {
   // Specific to Table.
   void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field,
                              std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     GenReceiver(struct_def, code_ptr);
     code += MakeCamel(NormalizedName(field));
     code += "(self):";
@@ -228,8 +266,11 @@ class PythonGenerator : public BaseGenerator {
       code += Indent + Indent + Indent;
       code += "x = self._tab.Indirect(o + self._tab.Pos)\n";
     }
-    code += Indent + Indent + Indent;
-    code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
+    if (parser_.opts.include_dependence_headers) {
+      code += Indent + Indent + Indent;
+      code += "from " + GenPackageReference(field.value.type) + " import " +
+              TypeName(field) + "\n";
+    }
     code += Indent + Indent + Indent + "obj = " + TypeName(field) + "()\n";
     code += Indent + Indent + Indent + "obj.Init(self._tab.Bytes, x)\n";
     code += Indent + Indent + Indent + "return obj\n";
@@ -239,7 +280,7 @@ class PythonGenerator : public BaseGenerator {
   // Get the value of a string.
   void GetStringField(const StructDef &struct_def, const FieldDef &field,
                       std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     GenReceiver(struct_def, code_ptr);
     code += MakeCamel(NormalizedName(field));
     code += "(self):";
@@ -252,7 +293,7 @@ class PythonGenerator : public BaseGenerator {
   // Get the value of a union from an object.
   void GetUnionField(const StructDef &struct_def, const FieldDef &field,
                      std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     GenReceiver(struct_def, code_ptr);
     code += MakeCamel(NormalizedName(field)) + "(self):";
     code += OffsetPrefix(field);
@@ -260,11 +301,11 @@ class PythonGenerator : public BaseGenerator {
     // TODO(rw): this works and is not the good way to it:
     bool is_native_table = TypeName(field) == "*flatbuffers.Table";
     if (is_native_table) {
-      code +=
-          Indent + Indent + Indent + "from flatbuffers.table import Table\n";
-    } else {
+      code += Indent + Indent + Indent + "from flatbuffers.table import Table\n";
+    } else if (parser_.opts.include_dependence_headers) {
       code += Indent + Indent + Indent;
-      code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
+      code += "from " + GenPackageReference(field.value.type) + " import " +
+              TypeName(field) + "\n";
     }
     code += Indent + Indent + Indent + "obj = Table(bytearray(), 0)\n";
     code += Indent + Indent + Indent + GenGetter(field.value.type);
@@ -272,10 +313,26 @@ class PythonGenerator : public BaseGenerator {
     code += Indent + Indent + "return None\n\n";
   }
 
+  // Generate the package reference when importing a struct or enum from its
+  // module.
+  std::string GenPackageReference(const Type &type) {
+    Namespace *namespaces;
+    if (type.struct_def) {
+      namespaces = type.struct_def->defined_namespace;
+    } else if (type.enum_def) {
+      namespaces = type.enum_def->defined_namespace;
+    } else {
+      return "." + GenTypeGet(type);
+    }
+
+    return namespaces->GetFullyQualifiedName(GenTypeGet(type));
+  }
+
   // Get the value of a vector's struct member.
   void GetMemberOfVectorOfStruct(const StructDef &struct_def,
-                                 const FieldDef &field, std::string *code_ptr) {
-    std::string &code = *code_ptr;
+                                 const FieldDef &field,
+                                 std::string *code_ptr) {
+    auto &code = *code_ptr;
     auto vectortype = field.value.type.VectorType();
 
     GenReceiver(struct_def, code_ptr);
@@ -288,8 +345,11 @@ class PythonGenerator : public BaseGenerator {
     if (!(vectortype.struct_def->fixed)) {
       code += Indent + Indent + Indent + "x = self._tab.Indirect(x)\n";
     }
-    code += Indent + Indent + Indent;
-    code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
+    if (parser_.opts.include_dependence_headers) {
+      code += Indent + Indent + Indent;
+      code += "from " + GenPackageReference(field.value.type) + " import " +
+              TypeName(field) + "\n";
+    }
     code += Indent + Indent + Indent + "obj = " + TypeName(field) + "()\n";
     code += Indent + Indent + Indent + "obj.Init(self._tab.Bytes, x)\n";
     code += Indent + Indent + Indent + "return obj\n";
@@ -301,7 +361,7 @@ class PythonGenerator : public BaseGenerator {
   void GetMemberOfVectorOfNonStruct(const StructDef &struct_def,
                                     const FieldDef &field,
                                     std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     auto vectortype = field.value.type.VectorType();
 
     GenReceiver(struct_def, code_ptr);
@@ -326,7 +386,7 @@ class PythonGenerator : public BaseGenerator {
   void GetVectorOfNonStructAsNumpy(const StructDef &struct_def,
                                    const FieldDef &field,
                                    std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     auto vectortype = field.value.type.VectorType();
 
     // Currently, we only support accessing as numpy array if
@@ -352,8 +412,9 @@ class PythonGenerator : public BaseGenerator {
   }
 
   // Begin the creator function signature.
-  void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) {
-    std::string &code = *code_ptr;
+  void BeginBuilderArgs(const StructDef &struct_def,
+                        std::string *code_ptr) {
+    auto &code = *code_ptr;
 
     code += "\n";
     code += "def Create" + NormalizedName(struct_def);
@@ -362,7 +423,10 @@ class PythonGenerator : public BaseGenerator {
 
   // Recursively generate arguments for a constructor, to deal with nested
   // structs.
-  void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix,
+  void StructBuilderArgs(const StructDef &struct_def,
+                         const std::string nameprefix,
+                         const std::string namesuffix, bool has_field_name,
+                         const std::string fieldname_suffix,
                          std::string *code_ptr) {
     for (auto it = struct_def.fields.vec.begin();
          it != struct_def.fields.vec.end(); ++it) {
@@ -374,20 +438,26 @@ class PythonGenerator : public BaseGenerator {
         // Generate arguments for a struct inside a struct. To ensure names
         // don't clash, and to make it obvious these arguments are constructing
         // a nested struct, prefix the name with the field name.
-        StructBuilderArgs(*field_type.struct_def,
-                          (nameprefix + (NormalizedName(field) + "_")).c_str(),
-                          code_ptr);
+        auto subprefix = nameprefix;
+        if (has_field_name) {
+          subprefix += NormalizedName(field) + fieldname_suffix;
+        }
+        StructBuilderArgs(*field.value.type.struct_def, subprefix, namesuffix,
+                          has_field_name, fieldname_suffix, code_ptr);
       } else {
-        std::string &code = *code_ptr;
+        auto &code = *code_ptr;
         code += std::string(", ") + nameprefix;
-        code += MakeCamel(NormalizedName(field), false);
+        if (has_field_name) {
+          code += MakeCamel(NormalizedName(field), false);
+        }
+        code += namesuffix;
       }
     }
   }
 
   // End the creator function signature.
   void EndBuilderArgs(std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     code += "):\n";
   }
 
@@ -396,7 +466,7 @@ class PythonGenerator : public BaseGenerator {
   void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
                          std::string *code_ptr, size_t index = 0,
                          bool in_array = false) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     std::string indent(index * 4, ' ');
     code +=
         indent + "    builder.Prep(" + NumToString(struct_def.minalign) + ", ";
@@ -442,13 +512,14 @@ class PythonGenerator : public BaseGenerator {
   }
 
   void EndBuilderBody(std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     code += "    return builder.Offset()\n";
   }
 
   // Get the value of a table's starting offset.
-  void GetStartOfTable(const StructDef &struct_def, std::string *code_ptr) {
-    std::string &code = *code_ptr;
+  void GetStartOfTable(const StructDef &struct_def,
+                       std::string *code_ptr) {
+    auto &code = *code_ptr;
     code += "def " + NormalizedName(struct_def) + "Start";
     code += "(builder): ";
     code += "builder.StartObject(";
@@ -457,11 +528,11 @@ class PythonGenerator : public BaseGenerator {
   }
 
   // Set the value of a table's field.
-  void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field,
-                         const size_t offset, std::string *code_ptr) {
-    std::string &code = *code_ptr;
-    code += "def " + NormalizedName(struct_def) + "Add" +
-            MakeCamel(NormalizedName(field));
+  void BuildFieldOfTable(const StructDef &struct_def,
+                         const FieldDef &field, const size_t offset,
+                         std::string *code_ptr) {
+    auto &code = *code_ptr;
+    code += "def " + NormalizedName(struct_def) + "Add" + MakeCamel(NormalizedName(field));
     code += "(builder, ";
     code += MakeCamel(NormalizedName(field), false);
     code += "): ";
@@ -483,9 +554,9 @@ class PythonGenerator : public BaseGenerator {
   }
 
   // Set the value of one of the members of a table's vector.
-  void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
-                          std::string *code_ptr) {
-    std::string &code = *code_ptr;
+  void BuildVectorOfTable(const StructDef &struct_def,
+                          const FieldDef &field, std::string *code_ptr) {
+    auto &code = *code_ptr;
     code += "def " + NormalizedName(struct_def) + "Start";
     code += MakeCamel(NormalizedName(field));
     code += "Vector(builder, numElems): return builder.StartVector(";
@@ -498,8 +569,9 @@ class PythonGenerator : public BaseGenerator {
   }
 
   // Get the offset of the end of a table.
-  void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
-    std::string &code = *code_ptr;
+  void GetEndOffsetOnTable(const StructDef &struct_def,
+                           std::string *code_ptr) {
+    auto &code = *code_ptr;
     code += "def " + NormalizedName(struct_def) + "End";
     code += "(builder): ";
     code += "return builder.EndObject()\n";
@@ -507,7 +579,7 @@ class PythonGenerator : public BaseGenerator {
 
   // Generate the receiver for function signatures.
   void GenReceiver(const StructDef &struct_def, std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     code += Indent + "# " + NormalizedName(struct_def) + "\n";
     code += Indent + "def ";
   }
@@ -550,8 +622,10 @@ class PythonGenerator : public BaseGenerator {
         default: FLATBUFFERS_ASSERT(0);
       }
     }
-    if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+    if (field.value.type.base_type == BASE_TYPE_VECTOR ||
+        field.value.type.base_type == BASE_TYPE_ARRAY) {
       GetVectorLen(struct_def, field, code_ptr);
+      GetVectorIsNone(struct_def, field, code_ptr);
     }
   }
 
@@ -577,7 +651,7 @@ class PythonGenerator : public BaseGenerator {
   // Generate function to check for proper file identifier
   void GenHasFileIdentifier(const StructDef &struct_def,
                             std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     std::string escapedID;
     // In the event any of file_identifier characters are special(NULL, \, etc),
     // problems occur. To prevent this, convert all chars to their hex-escaped
@@ -598,7 +672,7 @@ class PythonGenerator : public BaseGenerator {
     code += "\n";
   }
 
-  // Generate struct or table methods.
+  // Generates struct or table methods.
   void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
     if (struct_def.generated) return;
 
@@ -613,7 +687,7 @@ class PythonGenerator : public BaseGenerator {
         GenHasFileIdentifier(struct_def, code_ptr);
       }
     }
-    // Generate the Init method that sets the field in a pre-existing
+    // Generates the Init method that sets the field in a pre-existing
     // accessor object. This is to allow object reuse.
     InitializeExisting(struct_def, code_ptr);
     for (auto it = struct_def.fields.vec.begin();
@@ -625,14 +699,823 @@ class PythonGenerator : public BaseGenerator {
     }
 
     if (struct_def.fixed) {
-      // create a struct constructor function
+      // creates a struct constructor function
       GenStructBuilder(struct_def, code_ptr);
     } else {
-      // Create a set of functions that allow table construction.
+      // Creates a set of functions that allow table construction.
       GenTableBuilders(struct_def, code_ptr);
     }
   }
 
+  void GenReceiverForObjectAPI(const StructDef &struct_def,
+                               std::string *code_ptr) {
+    auto &code = *code_ptr;
+    code += GenIndents(1) + "# " + NormalizedName(struct_def) + "T";
+    code += GenIndents(1) + "def ";
+  }
+
+  void BeginClassForObjectAPI(const StructDef &struct_def,
+                              std::string *code_ptr) {
+    auto &code = *code_ptr;
+    code += "\n";
+    code += "class " + NormalizedName(struct_def) + "T(object):";
+    code += "\n";
+  }
+
+  // Gets the accoresponding python builtin type of a BaseType for scalars and
+  // string.
+  std::string GetBasePythonTypeForScalarAndString(const BaseType &base_type) {
+    if (IsBool(base_type)) {
+      return "bool";
+    } else if (IsFloat(base_type)) {
+      return "float";
+    } else if (IsInteger(base_type)) {
+      return "int";
+    } else if (base_type == BASE_TYPE_STRING) {
+      return "str";
+    } else {
+      FLATBUFFERS_ASSERT(false && "base_type is not a scalar or string type.");
+      return "";
+    }
+  }
+
+  std::string GetDefaultValue(const FieldDef &field) {
+    BaseType base_type = field.value.type.base_type;
+    if (IsBool(base_type)) {
+      return field.value.constant == "0" ? "False" : "True";
+    } else if (IsFloat(base_type)) {
+      return float_const_gen_.GenFloatConstant(field);
+    } else if (IsInteger(base_type)) {
+      return field.value.constant;
+    } else {
+      // For string, struct, and table.
+      return "None";
+    }
+  }
+
+  void GenUnionInit(const FieldDef &field, std::string *field_types_ptr,
+                    std::set<std::string> *import_list,
+                    std::set<std::string> *import_typing_list) {
+    // Gets all possible types in the union.
+    import_typing_list->insert("Union");
+    auto &field_types = *field_types_ptr;
+    field_types = "Union[";
+
+    std::string separator_string = ", ";
+    auto enum_def = field.value.type.enum_def;
+    for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end();
+         ++it) {
+      auto &ev = **it;
+      // Union only supports string and table.
+      std::string field_type;
+      switch (ev.union_type.base_type) {
+        case BASE_TYPE_STRUCT:
+          field_type = GenTypeGet(ev.union_type) + "T";
+          if (parser_.opts.include_dependence_headers) {
+            auto package_reference = GenPackageReference(ev.union_type);
+            field_type = package_reference + "." + field_type;
+            import_list->insert("import " + package_reference);
+          }
+          break;
+        case BASE_TYPE_STRING:
+          field_type += "str";
+          break;
+        case BASE_TYPE_NONE:
+          field_type += "None";
+          break;
+        default:
+          break;
+      }
+      field_types += field_type + separator_string;
+    }
+
+    // Removes the last separator_string.
+    field_types.erase(field_types.length() - separator_string.size());
+    field_types += "]";
+
+    // Gets the import lists for the union.
+    if (parser_.opts.include_dependence_headers) {
+      // The package reference is generated based on enum_def, instead
+      // of struct_def in field.type. That's why GenPackageReference() is
+      // not used.
+      Namespace *namespaces = field.value.type.enum_def->defined_namespace;
+      auto package_reference = namespaces->GetFullyQualifiedName(
+          MakeUpperCamel(*(field.value.type.enum_def)));
+      auto union_name = MakeUpperCamel(*(field.value.type.enum_def));
+      import_list->insert("import " + package_reference);
+    }
+  }
+
+  void GenStructInit(const FieldDef &field,
+                     std::string *field_type_ptr,
+                     std::set<std::string> *import_list,
+                     std::set<std::string> *import_typing_list) {
+    import_typing_list->insert("Optional");
+    auto &field_type = *field_type_ptr;
+    if (parser_.opts.include_dependence_headers) {
+      auto package_reference = GenPackageReference(field.value.type);
+      field_type = package_reference + "." + TypeName(field) + "T]";
+      import_list->insert("import " + package_reference);
+    } else {
+      field_type = TypeName(field) + "T]";
+    }
+    field_type = "Optional[" + field_type;
+  }
+
+  void GenVectorInit(const FieldDef &field, std::string *field_type_ptr,
+                     std::set<std::string> *import_list,
+                     std::set<std::string> *import_typing_list) {
+    import_typing_list->insert("List");
+    auto &field_type = *field_type_ptr;
+    auto base_type = field.value.type.VectorType().base_type;
+    if (base_type == BASE_TYPE_STRUCT) {
+      field_type = GenTypeGet(field.value.type.VectorType()) + "T]";
+      if (parser_.opts.include_dependence_headers) {
+        auto package_reference =
+            GenPackageReference(field.value.type.VectorType());
+        field_type = package_reference + "." +
+                     GenTypeGet(field.value.type.VectorType()) + "T]";
+        import_list->insert("import " + package_reference);
+      }
+      field_type = "List[" + field_type;
+    } else {
+      field_type =
+          "List[" + GetBasePythonTypeForScalarAndString(base_type) + "]";
+    }
+  }
+
+  void GenInitialize(const StructDef &struct_def, std::string *code_ptr,
+                     std::set<std::string> *import_list) {
+    std::string code;
+    std::set<std::string> import_typing_list;
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      // Determines field type, default value, and typing imports.
+      auto base_type = field.value.type.base_type;
+      std::string field_type;
+      switch (base_type) {
+        case BASE_TYPE_UNION: {
+          GenUnionInit(field, &field_type, import_list, &import_typing_list);
+          break;
+        }
+        case BASE_TYPE_STRUCT: {
+          GenStructInit(field, &field_type, import_list, &import_typing_list);
+          break;
+        }
+        case BASE_TYPE_VECTOR:
+        case BASE_TYPE_ARRAY: {
+          GenVectorInit(field, &field_type, import_list, &import_typing_list);
+          break;
+        }
+        default:
+          // Scalar or sting fields.
+          field_type = GetBasePythonTypeForScalarAndString(base_type);
+          break;
+      }
+
+      auto default_value = GetDefaultValue(field);
+      // Wrties the init statement.
+      auto field_instance_name = MakeLowerCamel(field);
+      code += GenIndents(2) + "self." + field_instance_name + " = " +
+              default_value + "  # type: " + field_type;
+    }
+
+    // Writes __init__ method.
+    auto &code_base = *code_ptr;
+    GenReceiverForObjectAPI(struct_def, code_ptr);
+    code_base += "__init__(self):";
+    if (code.empty()) {
+      code_base += GenIndents(2) + "pass";
+    } else {
+      code_base += code;
+    }
+    code_base += "\n";
+
+    // Merges the typing imports into import_list.
+    if (!import_typing_list.empty()) {
+      // Adds the try statement.
+      std::string typing_imports = "try:";
+      typing_imports += GenIndents(1) + "from typing import ";
+      std::string separator_string = ", ";
+      for (auto it = import_typing_list.begin(); it != import_typing_list.end();
+           ++it) {
+        const std::string &im = *it;
+        typing_imports += im + separator_string;
+      }
+      // Removes the last separator_string.
+      typing_imports.erase(typing_imports.length() - separator_string.size());
+
+      // Adds the except statement.
+      typing_imports += "\n";
+      typing_imports += "except:";
+      typing_imports += GenIndents(1) + "pass";
+      import_list->insert(typing_imports);
+    }
+
+    // Removes the import of the struct itself, if applied.
+    auto package_reference =
+        struct_def.defined_namespace->GetFullyQualifiedName(
+            MakeUpperCamel(struct_def));
+    auto struct_import = "import " + package_reference;
+    import_list->erase(struct_import);
+  }
+
+  void InitializeFromBuf(const StructDef &struct_def, std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto instance_name = MakeLowerCamel(struct_def);
+    auto struct_name = NormalizedName(struct_def);
+
+    code += GenIndents(1) + "@classmethod";
+    code += GenIndents(1) + "def InitFromBuf(cls, buf, pos):";
+    code += GenIndents(2) + instance_name + " = " + struct_name + "()";
+    code += GenIndents(2) + instance_name + ".Init(buf, pos)";
+    code += GenIndents(2) + "return cls.InitFromObj(" + instance_name + ")";
+    code += "\n";
+  }
+
+  void InitializeFromObjForObject(const StructDef &struct_def,
+                                  std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto instance_name = MakeLowerCamel(struct_def);
+    auto struct_name = NormalizedName(struct_def);
+
+    code += GenIndents(1) + "@classmethod";
+    code += GenIndents(1) + "def InitFromObj(cls, " + instance_name + "):";
+    code += GenIndents(2) + "x = " + struct_name + "T()";
+    code += GenIndents(2) + "x._UnPack(" + instance_name + ")";
+    code += GenIndents(2) + "return x";
+    code += "\n";
+  }
+
+  void GenUnPackForStruct(const StructDef &struct_def, const FieldDef &field,
+                          std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto struct_instance_name = MakeLowerCamel(struct_def);
+    auto field_instance_name = MakeLowerCamel(field);
+    auto field_accessor_name = MakeUpperCamel(field);
+    auto field_type = TypeName(field);
+
+    if (parser_.opts.include_dependence_headers) {
+      auto package_reference = GenPackageReference(field.value.type);
+      field_type = package_reference + "." + TypeName(field);
+    }
+
+    code += GenIndents(2) + "if " + struct_instance_name + "." +
+            field_accessor_name + "(";
+    // if field is a struct, we need to create an instance for it first.
+    if (struct_def.fixed && field.value.type.base_type == BASE_TYPE_STRUCT) {
+      code += field_type + "()";
+    }
+    code += ") is not None:";
+    code += GenIndents(3) + "self." + field_instance_name + " = " + field_type +
+            "T.InitFromObj(" + struct_instance_name + "." +
+            field_accessor_name + "(";
+    // A struct's accessor requires a struct buf instance.
+    if (struct_def.fixed && field.value.type.base_type == BASE_TYPE_STRUCT) {
+      code += field_type + "()";
+    }
+    code += "))";
+  }
+
+  void GenUnPackForUnion(const StructDef &struct_def, const FieldDef &field,
+                         std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto field_instance_name = MakeLowerCamel(field);
+    auto field_accessor_name = MakeUpperCamel(field);
+    auto struct_instance_name = MakeLowerCamel(struct_def);
+    auto union_name = MakeUpperCamel(*(field.value.type.enum_def));
+
+    if (parser_.opts.include_dependence_headers) {
+      Namespace *namespaces = field.value.type.enum_def->defined_namespace;
+      auto package_reference = namespaces->GetFullyQualifiedName(
+          MakeUpperCamel(*(field.value.type.enum_def)));
+      union_name = package_reference + "." + union_name;
+    }
+    code += GenIndents(2) + "self." + field_instance_name + " = " + union_name +
+            "Creator(" + "self." + field_instance_name + "Type, " +
+            struct_instance_name + "." + field_accessor_name + "())";
+  }
+
+  void GenUnPackForStructVector(const StructDef &struct_def,
+                                const FieldDef &field, std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto field_instance_name = MakeLowerCamel(field);
+    auto field_accessor_name = MakeUpperCamel(field);
+    auto struct_instance_name = MakeLowerCamel(struct_def);
+
+    code += GenIndents(2) + "if not " + struct_instance_name + "." +
+            field_accessor_name + "IsNone():";
+    code += GenIndents(3) + "self." + field_instance_name + " = []";
+    code += GenIndents(3) + "for i in range(" + struct_instance_name + "." +
+            field_accessor_name + "Length()):";
+
+    auto field_type_name = TypeName(field);
+    auto one_instance = field_type_name + "_";
+    one_instance[0] = char(tolower(one_instance[0]));
+
+    if (parser_.opts.include_dependence_headers) {
+      auto package_reference = GenPackageReference(field.value.type);
+      field_type_name = package_reference + "." + TypeName(field);
+    }
+
+    code += GenIndents(4) + "if " + struct_instance_name + "." +
+            field_accessor_name + "(i) is None:";
+    code += GenIndents(5) + "self." + field_instance_name + ".append(None)";
+    code += GenIndents(4) + "else:";
+    code += GenIndents(5) + one_instance + " = " + field_type_name +
+            "T.InitFromObj(" + struct_instance_name + "." +
+            field_accessor_name + "(i))";
+    code += GenIndents(5) + "self." + field_instance_name + ".append(" +
+            one_instance + ")";
+  }
+
+  void GenUnpackforScalarVectorHelper(const StructDef &struct_def,
+                                      const FieldDef &field,
+                                      std::string *code_ptr, int indents) {
+    auto &code = *code_ptr;
+    auto field_instance_name = MakeLowerCamel(field);
+    auto field_accessor_name = MakeUpperCamel(field);
+    auto struct_instance_name = MakeLowerCamel(struct_def);
+
+    code += GenIndents(indents) + "self." + field_instance_name + " = []";
+    code += GenIndents(indents) + "for i in range(" + struct_instance_name +
+            "." + field_accessor_name + "Length()):";
+    code += GenIndents(indents + 1) + "self." + field_instance_name +
+            ".append(" + struct_instance_name + "." + field_accessor_name +
+            "(i))";
+  }
+
+  void GenUnPackForScalarVector(const StructDef &struct_def,
+                                const FieldDef &field, std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto field_instance_name = MakeLowerCamel(field);
+    auto field_accessor_name = MakeUpperCamel(field);
+    auto struct_instance_name = MakeLowerCamel(struct_def);
+
+    code += GenIndents(2) + "if not " + struct_instance_name + "." +
+            field_accessor_name + "IsNone():";
+
+    // String does not have the AsNumpy method.
+    if (!(IsScalar(field.value.type.VectorType().base_type))) {
+      GenUnpackforScalarVectorHelper(struct_def, field, code_ptr, 3);
+      return;
+    }
+
+    code += GenIndents(3) + "if np is None:";
+    GenUnpackforScalarVectorHelper(struct_def, field, code_ptr, 4);
+
+    // If numpy exists, use the AsNumpy method to optimize the unpack speed.
+    code += GenIndents(3) + "else:";
+    code += GenIndents(4) + "self." + field_instance_name + " = " +
+            struct_instance_name + "." + field_accessor_name + "AsNumpy()";
+  }
+
+  void GenUnPackForScalar(const StructDef &struct_def, const FieldDef &field,
+                          std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto field_instance_name = MakeLowerCamel(field);
+    auto field_accessor_name = MakeUpperCamel(field);
+    auto struct_instance_name = MakeLowerCamel(struct_def);
+
+    code += GenIndents(2) + "self." + field_instance_name + " = " +
+            struct_instance_name + "." + field_accessor_name + "()";
+  }
+
+  // Generates the UnPack method for the object class.
+  void GenUnPack(const StructDef &struct_def, std::string *code_ptr) {
+    std::string code;
+    // Items that needs to be imported. No duplicate modules will be imported.
+    std::set<std::string> import_list;
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      auto field_type = TypeName(field);
+      switch (field.value.type.base_type) {
+        case BASE_TYPE_STRUCT: {
+          GenUnPackForStruct(struct_def, field, &code);
+          break;
+        }
+        case BASE_TYPE_UNION: {
+          GenUnPackForUnion(struct_def, field, &code);
+          break;
+        }
+        case BASE_TYPE_VECTOR: {
+          auto vectortype = field.value.type.VectorType();
+          if (vectortype.base_type == BASE_TYPE_STRUCT) {
+            GenUnPackForStructVector(struct_def, field, &code);
+          } else {
+            GenUnPackForScalarVector(struct_def, field, &code);
+          }
+          break;
+        }
+        case BASE_TYPE_ARRAY: {
+          GenUnPackForScalarVector(struct_def, field, &code);
+          break;
+        }
+        default:
+          GenUnPackForScalar(struct_def, field, &code);
+      }
+    }
+
+    // Writes import statements and code into the generated file.
+    auto &code_base = *code_ptr;
+    auto struct_instance_name = MakeLowerCamel(struct_def);
+    auto struct_name = MakeUpperCamel(struct_def);
+
+    GenReceiverForObjectAPI(struct_def, code_ptr);
+    code_base += "_UnPack(self, " + struct_instance_name + "):";
+    code_base += GenIndents(2) + "if " + struct_instance_name + " is None:";
+    code_base += GenIndents(3) + "return";
+
+    // Write the import statements.
+    for (std::set<std::string>::iterator it = import_list.begin();
+         it != import_list.end(); ++it) {
+      code_base += GenIndents(2) + *it;
+    }
+
+    // Write the code.
+    code_base += code;
+    code_base += "\n";
+  }
+
+  void GenPackForStruct(const StructDef &struct_def, std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto struct_name = MakeUpperCamel(struct_def);
+
+    GenReceiverForObjectAPI(struct_def, code_ptr);
+    code += "Pack(self, builder):";
+    code += GenIndents(2) + "return Create" + struct_name + "(builder";
+
+    StructBuilderArgs(struct_def,
+                      /* nameprefix = */ "self.",
+                      /* namesuffix = */ "",
+                      /* has_field_name = */ true,
+                      /* fieldname_suffix = */ ".", code_ptr);
+    code += ")\n";
+  }
+
+  void GenPackForStructVectorField(const StructDef &struct_def,
+                                   const FieldDef &field,
+                                   std::string *code_prefix_ptr,
+                                   std::string *code_ptr) {
+    auto &code_prefix = *code_prefix_ptr;
+    auto &code = *code_ptr;
+    auto field_instance_name = MakeLowerCamel(field);
+    auto struct_name = NormalizedName(struct_def);
+    auto field_accessor_name = MakeUpperCamel(field);
+
+    // Creates the field.
+    code_prefix +=
+        GenIndents(2) + "if self." + field_instance_name + " is not None:";
+    if (field.value.type.struct_def->fixed) {
+      code_prefix += GenIndents(3) + struct_name + "Start" +
+                     field_accessor_name + "Vector(builder, len(self." +
+                     field_instance_name + "))";
+      code_prefix += GenIndents(3) + "for i in reversed(range(len(self." +
+                     field_instance_name + "))):";
+      code_prefix +=
+          GenIndents(4) + "self." + field_instance_name + "[i].Pack(builder)";
+      code_prefix += GenIndents(3) + field_instance_name +
+                     " = builder.EndVector(len(self." + field_instance_name +
+                     "))";
+    } else {
+      // If the vector is a struct vector, we need to first build accessor for
+      // each struct element.
+      code_prefix += GenIndents(3) + field_instance_name + "list = []";
+      code_prefix += GenIndents(3);
+      code_prefix += "for i in range(len(self." + field_instance_name + ")):";
+      code_prefix += GenIndents(4) + field_instance_name + "list.append(self." +
+                     field_instance_name + "[i].Pack(builder))";
+
+      code_prefix += GenIndents(3) + struct_name + "Start" +
+                     field_accessor_name + "Vector(builder, len(self." +
+                     field_instance_name + "))";
+      code_prefix += GenIndents(3) + "for i in reversed(range(len(self." +
+                     field_instance_name + "))):";
+      code_prefix += GenIndents(4) + "builder.PrependUOffsetTRelative" + "(" +
+                     field_instance_name + "list[i])";
+      code_prefix += GenIndents(3) + field_instance_name +
+                     " =  builder.EndVector(len(self." + field_instance_name +
+                     "))";
+    }
+
+    // Adds the field into the struct.
+    code += GenIndents(2) + "if self." + field_instance_name + " is not None:";
+    code += GenIndents(3) + struct_name + "Add" + field_accessor_name +
+            "(builder, " + field_instance_name + ")";
+  }
+
+  void GenPackForScalarVectorField(const StructDef &struct_def,
+                                   const FieldDef &field,
+                                   std::string *code_prefix_ptr,
+                                   std::string *code_ptr) {
+    auto &code_prefix = *code_prefix_ptr;
+    auto &code = *code_ptr;
+    auto field_instance_name = MakeLowerCamel(field);
+
+    auto field_accessor_name = MakeUpperCamel(field);
+    auto struct_name = NormalizedName(struct_def);
+
+    // Creates the field.
+    code_prefix +=
+        GenIndents(2) + "if self." + field_instance_name + " is not None:";
+    // If the vector is a string vector, we need to first build accessor for
+    // each string element. And this generated code, needs to be
+    // placed ahead of code+prefix.
+    auto vectortype = field.value.type.VectorType();
+    if (vectortype.base_type == BASE_TYPE_STRING) {
+      code_prefix += GenIndents(3) + MakeLowerCamel(field) + "list = []";
+      code_prefix += GenIndents(3);
+      code_prefix += "for i in range(len(self." + field_instance_name + ")):";
+      code_prefix += GenIndents(4) + MakeLowerCamel(field) +
+                     "list.append(builder.CreateString(self." +
+                     field_instance_name + "[i]))";
+    }
+
+    code_prefix += GenIndents(3) + struct_name + "Start" + field_accessor_name +
+                   "Vector(builder, len(self." + field_instance_name + "))";
+    code_prefix += GenIndents(3) + "for i in reversed(range(len(self." +
+                   field_instance_name + "))):";
+    code_prefix += GenIndents(4) + "builder.Prepend";
+
+    std::string type_name;
+    switch (vectortype.base_type) {
+      case BASE_TYPE_BOOL:
+        type_name = "Bool";
+        break;
+      case BASE_TYPE_CHAR:
+        type_name = "Byte";
+        break;
+      case BASE_TYPE_UCHAR:
+        type_name = "Uint8";
+        break;
+      case BASE_TYPE_SHORT:
+        type_name = "Int16";
+        break;
+      case BASE_TYPE_USHORT:
+        type_name = "Uint16";
+        break;
+      case BASE_TYPE_INT:
+        type_name = "Int32";
+        break;
+      case BASE_TYPE_UINT:
+        type_name = "Uint32";
+        break;
+      case BASE_TYPE_LONG:
+        type_name = "Int64";
+        break;
+      case BASE_TYPE_ULONG:
+        type_name = "Uint64";
+        break;
+      case BASE_TYPE_FLOAT:
+        type_name = "Float32";
+        break;
+      case BASE_TYPE_DOUBLE:
+        type_name = "Float64";
+        break;
+      case BASE_TYPE_STRING:
+        type_name = "UOffsetTRelative";
+        break;
+      default:
+        type_name = "VOffsetT";
+        break;
+    }
+
+    if (vectortype.base_type == BASE_TYPE_STRING) {
+      code_prefix += type_name + "(" + MakeLowerCamel(field) + "list[i])";
+    } else {
+      code_prefix += type_name + "(self." + field_instance_name + "[i])";
+    }
+    code_prefix += GenIndents(3) + field_instance_name +
+                   " =  builder.EndVector(len(self." + field_instance_name +
+                   "))";
+
+    // Adds the field into the struct.
+    code += GenIndents(2) + "if self." + field_instance_name + " is not None:";
+    code += GenIndents(3) + struct_name + "Add" + field_accessor_name +
+            "(builder, " + field_instance_name + ")";
+  }
+
+  void GenPackForStructField(const StructDef &struct_def, const FieldDef &field,
+                             std::string *code_prefix_ptr,
+                             std::string *code_ptr) {
+    auto &code_prefix = *code_prefix_ptr;
+    auto &code = *code_ptr;
+    auto field_instance_name = MakeLowerCamel(field);
+
+    auto field_accessor_name = MakeUpperCamel(field);
+    auto struct_name = NormalizedName(struct_def);
+
+    if (field.value.type.struct_def->fixed) {
+      // Pure struct fields need to be created along with their parent
+      // structs.
+      code +=
+          GenIndents(2) + "if self." + field_instance_name + " is not None:";
+      code += GenIndents(3) + field_instance_name + " = self." +
+              field_instance_name + ".Pack(builder)";
+    } else {
+      // Tables need to be created before their parent structs are created.
+      code_prefix +=
+          GenIndents(2) + "if self." + field_instance_name + " is not None:";
+      code_prefix += GenIndents(3) + field_instance_name + " = self." +
+                     field_instance_name + ".Pack(builder)";
+      code +=
+          GenIndents(2) + "if self." + field_instance_name + " is not None:";
+    }
+
+    code += GenIndents(3) + struct_name + "Add" + field_accessor_name +
+            "(builder, " + field_instance_name + ")";
+  }
+
+  void GenPackForUnionField(const StructDef &struct_def, const FieldDef &field,
+                            std::string *code_prefix_ptr,
+                            std::string *code_ptr) {
+    auto &code_prefix = *code_prefix_ptr;
+    auto &code = *code_ptr;
+    auto field_instance_name = MakeLowerCamel(field);
+
+    auto field_accessor_name = MakeUpperCamel(field);
+    auto struct_name = NormalizedName(struct_def);
+
+    // TODO(luwa): TypeT should be moved under the None check as well.
+    code_prefix +=
+        GenIndents(2) + "if self." + field_instance_name + " is not None:";
+    code_prefix += GenIndents(3) + field_instance_name + " = self." +
+                   field_instance_name + ".Pack(builder)";
+    code += GenIndents(2) + "if self." + field_instance_name + " is not None:";
+    code += GenIndents(3) + struct_name + "Add" + field_accessor_name +
+            "(builder, " + field_instance_name + ")";
+  }
+
+  void GenPackForTable(const StructDef &struct_def, std::string *code_ptr) {
+    auto &code_base = *code_ptr;
+    std::string code, code_prefix;
+    auto struct_instance_name = MakeLowerCamel(struct_def);
+    auto struct_name = NormalizedName(struct_def);
+
+    GenReceiverForObjectAPI(struct_def, code_ptr);
+    code_base += "Pack(self, builder):";
+    code += GenIndents(2) + struct_name + "Start(builder)";
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      auto field_accessor_name = MakeUpperCamel(field);
+      auto field_instance_name = MakeLowerCamel(field);
+
+      switch (field.value.type.base_type) {
+        case BASE_TYPE_STRUCT: {
+          GenPackForStructField(struct_def, field, &code_prefix, &code);
+          break;
+        }
+        case BASE_TYPE_UNION: {
+          GenPackForUnionField(struct_def, field, &code_prefix, &code);
+          break;
+        }
+        case BASE_TYPE_VECTOR: {
+          auto vectortype = field.value.type.VectorType();
+          if (vectortype.base_type == BASE_TYPE_STRUCT) {
+            GenPackForStructVectorField(struct_def, field, &code_prefix, &code);
+          } else {
+            GenPackForScalarVectorField(struct_def, field, &code_prefix, &code);
+          }
+          break;
+        }
+        case BASE_TYPE_ARRAY: {
+          GenPackForScalarVectorField(struct_def, field, &code_prefix, &code);
+          break;
+        }
+        case BASE_TYPE_STRING: {
+          code_prefix += GenIndents(2) + "if self." + field_instance_name +
+                         " is not None:";
+          code_prefix += GenIndents(3) + field_instance_name +
+                         " = builder.CreateString(self." + field_instance_name +
+                         ")";
+          code += GenIndents(2) + "if self." + field_instance_name +
+                  " is not None:";
+          code += GenIndents(3) + struct_name + "Add" + field_accessor_name +
+                  "(builder, " + field_instance_name + ")";
+          break;
+        }
+        default:
+          // Generates code for scalar values. If the value equals to the
+          // default value, builder will automatically ignore it. So we don't
+          // need to check the value ahead.
+          code += GenIndents(2) + struct_name + "Add" + field_accessor_name +
+                  "(builder, self." + field_instance_name + ")";
+          break;
+      }
+    }
+
+    code += GenIndents(2) + struct_instance_name + " = " + struct_name +
+            "End(builder)";
+    code += GenIndents(2) + "return " + struct_instance_name;
+
+    code_base += code_prefix + code;
+    code_base += "\n";
+  }
+
+  void GenStructForObjectAPI(const StructDef &struct_def,
+                             std::string *code_ptr) {
+    if (struct_def.generated) return;
+
+    std::set<std::string> import_list;
+    std::string code;
+
+    // Creates an object class for a struct or a table
+    BeginClassForObjectAPI(struct_def, &code);
+
+    GenInitialize(struct_def, &code, &import_list);
+
+    InitializeFromBuf(struct_def, &code);
+
+    InitializeFromObjForObject(struct_def, &code);
+
+    GenUnPack(struct_def, &code);
+
+    if (struct_def.fixed) {
+      GenPackForStruct(struct_def, &code);
+    } else {
+      GenPackForTable(struct_def, &code);
+    }
+
+    // Adds the imports at top.
+    auto &code_base = *code_ptr;
+    code_base += "\n";
+    for (auto it = import_list.begin(); it != import_list.end(); it++) {
+      auto im = *it;
+      code_base += im + "\n";
+    }
+    code_base += code;
+  }
+
+  void GenUnionCreatorForStruct(const EnumDef &enum_def, const EnumVal &ev,
+                                std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto union_name = NormalizedName(enum_def);
+    auto field_name = NormalizedName(ev);
+    auto field_type = GenTypeGet(ev.union_type) + "T";
+
+    code += GenIndents(1) + "if unionType == " + union_name + "()." +
+            field_name + ":";
+    if (parser_.opts.include_dependence_headers) {
+      auto package_reference = GenPackageReference(ev.union_type);
+      code += GenIndents(2) + "import " + package_reference;
+      field_type = package_reference + "." + field_type;
+    }
+    code += GenIndents(2) + "return " + field_type +
+            ".InitFromBuf(table.Bytes, table.Pos)";
+  }
+
+  void GenUnionCreatorForString(const EnumDef &enum_def, const EnumVal &ev,
+                                std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto union_name = NormalizedName(enum_def);
+    auto field_name = NormalizedName(ev);
+
+    code += GenIndents(1) + "if unionType == " + union_name + "()." +
+            field_name + ":";
+    code += GenIndents(2) + "tab = Table(table.Bytes, table.Pos)";
+    code += GenIndents(2) + "union = tab.String(table.Pos)";
+    code += GenIndents(2) + "return union";
+  }
+
+  // Creates an union object based on union type.
+  void GenUnionCreator(const EnumDef &enum_def, std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto union_name = MakeUpperCamel(enum_def);
+
+    code += "\n";
+    code += "def " + union_name + "Creator(unionType, table):";
+    code += GenIndents(1) + "from flatbuffers.table import Table";
+    code += GenIndents(1) + "if not isinstance(table, Table):";
+    code += GenIndents(2) + "return None";
+
+    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+      auto &ev = **it;
+      // Union only supports string and table.
+      switch (ev.union_type.base_type) {
+        case BASE_TYPE_STRUCT:
+          GenUnionCreatorForStruct(enum_def, ev, &code);
+          break;
+        case BASE_TYPE_STRING:
+          GenUnionCreatorForString(enum_def, ev, &code);
+          break;
+        default:
+          break;
+      }
+    }
+    code += GenIndents(1) + "return None";
+    code += "\n";
+  }
+
   // Generate enum declarations.
   void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
     if (enum_def.generated) return;
@@ -702,7 +1585,11 @@ class PythonGenerator : public BaseGenerator {
   // Create a struct with a builder and the struct's arguments.
   void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
     BeginBuilderArgs(struct_def, code_ptr);
-    StructBuilderArgs(struct_def, "", code_ptr);
+    StructBuilderArgs(struct_def,
+                      /* nameprefix = */ "",
+                      /* namesuffix = */ "",
+                      /* has_field_name = */ true,
+                      /* fieldname_suffix = */ "_", code_ptr);
     EndBuilderArgs(code_ptr);
 
     StructBuilderBody(struct_def, "", code_ptr);
@@ -722,6 +1609,9 @@ class PythonGenerator : public BaseGenerator {
       auto &enum_def = **it;
       std::string enumcode;
       GenEnum(enum_def, &enumcode);
+      if (parser_.opts.generate_object_based_api & enum_def.is_union) {
+        GenUnionCreator(enum_def, &enumcode);
+      }
       if (!SaveType(enum_def, enumcode, false)) return false;
     }
     return true;
@@ -733,6 +1623,9 @@ class PythonGenerator : public BaseGenerator {
       auto &struct_def = **it;
       std::string declcode;
       GenStruct(struct_def, &declcode);
+      if (parser_.opts.generate_object_based_api) {
+        GenStructForObjectAPI(struct_def, &declcode);
+      }
       if (!SaveType(struct_def, declcode, true)) return false;
     }
     return true;
@@ -741,10 +1634,14 @@ class PythonGenerator : public BaseGenerator {
   // Begin by declaring namespace and imports.
   void BeginFile(const std::string &name_space_name, const bool needs_imports,
                  std::string *code_ptr) {
-    std::string &code = *code_ptr;
+    auto &code = *code_ptr;
     code = code + "# " + FlatBuffersGeneratedWarning() + "\n\n";
     code += "# namespace: " + name_space_name + "\n\n";
-    if (needs_imports) { code += "import flatbuffers\n\n"; }
+    if (needs_imports) {
+      code += "import flatbuffers\n";
+      code += "from flatbuffers.compat import import_numpy\n";
+      code += "np = import_numpy()\n\n";
+    }
   }
 
   // Save out the generated code for a Python Table type.
index 3c4776e..2cc916b 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: Example
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class Ability(object):
     __slots__ = ['_tab']
@@ -21,3 +23,34 @@ def CreateAbility(builder, id, distance):
     builder.PrependUint32(distance)
     builder.PrependUint32(id)
     return builder.Offset()
+
+
+class AbilityT(object):
+
+    # AbilityT
+    def __init__(self):
+        self.id = 0  # type: int
+        self.distance = 0  # type: int
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        ability = Ability()
+        ability.Init(buf, pos)
+        return cls.InitFromObj(ability)
+
+    @classmethod
+    def InitFromObj(cls, ability):
+        x = AbilityT()
+        x._UnPack(ability)
+        return x
+
+    # AbilityT
+    def _UnPack(self, ability):
+        if ability is None:
+            return
+        self.id = ability.Id()
+        self.distance = ability.Distance()
+
+    # AbilityT
+    def Pack(self, builder):
+        return CreateAbility(builder, self.id, self.distance)
index f1b8d51..b10d35d 100644 (file)
@@ -8,3 +8,18 @@ class Any(object):
     TestSimpleTableWithEnum = 2
     MyGame_Example2_Monster = 3
 
+
+def AnyCreator(unionType, table):
+    from flatbuffers.table import Table
+    if not isinstance(table, Table):
+        return None
+    if unionType == Any().Monster:
+        import MyGame.Example.Monster
+        return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+    if unionType == Any().TestSimpleTableWithEnum:
+        import MyGame.Example.TestSimpleTableWithEnum
+        return MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT.InitFromBuf(table.Bytes, table.Pos)
+    if unionType == Any().MyGame_Example2_Monster:
+        import MyGame.Example2.Monster
+        return MyGame.Example2.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+    return None
index de6e9d0..3fb4830 100644 (file)
@@ -8,3 +8,18 @@ class AnyAmbiguousAliases(object):
     M2 = 2
     M3 = 3
 
+
+def AnyAmbiguousAliasesCreator(unionType, table):
+    from flatbuffers.table import Table
+    if not isinstance(table, Table):
+        return None
+    if unionType == AnyAmbiguousAliases().M1:
+        import MyGame.Example.Monster
+        return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+    if unionType == AnyAmbiguousAliases().M2:
+        import MyGame.Example.Monster
+        return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+    if unionType == AnyAmbiguousAliases().M3:
+        import MyGame.Example.Monster
+        return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+    return None
index a6da355..cf89fc2 100644 (file)
@@ -8,3 +8,18 @@ class AnyUniqueAliases(object):
     TS = 2
     M2 = 3
 
+
+def AnyUniqueAliasesCreator(unionType, table):
+    from flatbuffers.table import Table
+    if not isinstance(table, Table):
+        return None
+    if unionType == AnyUniqueAliases().M:
+        import MyGame.Example.Monster
+        return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+    if unionType == AnyUniqueAliases().TS:
+        import MyGame.Example.TestSimpleTableWithEnum
+        return MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT.InitFromBuf(table.Bytes, table.Pos)
+    if unionType == AnyUniqueAliases().M2:
+        import MyGame.Example2.Monster
+        return MyGame.Example2.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+    return None
index f36ec54..50f136d 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: Example
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class ArrayStruct(object):
     __slots__ = ['_tab']
@@ -16,6 +18,18 @@ class ArrayStruct(object):
     # ArrayStruct
     def B(self): return [self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4 + i * 4)) for i in range(15)]
     # ArrayStruct
+    def BLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # ArrayStruct
+    def BIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+        return o == 0
+
+    # ArrayStruct
     def C(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(64))
     # ArrayStruct
     def D(self, obj, i):
@@ -23,9 +37,33 @@ class ArrayStruct(object):
         return obj
 
     # ArrayStruct
+    def DLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(72))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # ArrayStruct
+    def DIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(72))
+        return o == 0
+
+    # ArrayStruct
     def E(self): return self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(136))
     # ArrayStruct
     def F(self): return [self._tab.Get(flatbuffers.number_types.Int64Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(144 + i * 8)) for i in range(2)]
+    # ArrayStruct
+    def FLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(144))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # ArrayStruct
+    def FIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(144))
+        return o == 0
+
 
 def CreateArrayStruct(builder, a, b, c, d_a, d_b, d_c, d_d, e, f):
     builder.Prep(8, 160)
@@ -49,3 +87,62 @@ def CreateArrayStruct(builder, a, b, c, d_a, d_b, d_c, d_d, e, f):
         builder.PrependInt32(b[_idx0-1])
     builder.PrependFloat32(a)
     return builder.Offset()
+
+import MyGame.Example.NestedStruct
+try:
+    from typing import List
+except:
+    pass
+
+class ArrayStructT(object):
+
+    # ArrayStructT
+    def __init__(self):
+        self.a = 0.0  # type: float
+        self.b = None  # type: List[int]
+        self.c = 0  # type: int
+        self.d = None  # type: List[MyGame.Example.NestedStruct.NestedStructT]
+        self.e = 0  # type: int
+        self.f = None  # type: List[int]
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        arrayStruct = ArrayStruct()
+        arrayStruct.Init(buf, pos)
+        return cls.InitFromObj(arrayStruct)
+
+    @classmethod
+    def InitFromObj(cls, arrayStruct):
+        x = ArrayStructT()
+        x._UnPack(arrayStruct)
+        return x
+
+    # ArrayStructT
+    def _UnPack(self, arrayStruct):
+        if arrayStruct is None:
+            return
+        self.a = arrayStruct.A()
+        if not arrayStruct.BIsNone():
+            if np is None:
+                self.b = []
+                for i in range(arrayStruct.BLength()):
+                    self.b.append(arrayStruct.B(i))
+            else:
+                self.b = arrayStruct.BAsNumpy()
+        self.c = arrayStruct.C()
+        if not arrayStruct.DIsNone():
+            self.d = []
+            for i in range(arrayStruct.DLength()):
+                self.d.append(arrayStruct.D(i))
+        self.e = arrayStruct.E()
+        if not arrayStruct.FIsNone():
+            if np is None:
+                self.f = []
+                for i in range(arrayStruct.FLength()):
+                    self.f.append(arrayStruct.F(i))
+            else:
+                self.f = arrayStruct.FAsNumpy()
+
+    # ArrayStructT
+    def Pack(self, builder):
+        return CreateArrayStruct(builder, self.a, self.b, self.c, self.d.a, self.d.b, self.d.c, self.d.d, self.e, self.f)
index 6d583f9..83905e6 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: Example
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class ArrayTable(object):
     __slots__ = ['_tab']
@@ -27,7 +29,7 @@ class ArrayTable(object):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
         if o != 0:
             x = o + self._tab.Pos
-            from .ArrayStruct import ArrayStruct
+            from MyGame.Example.ArrayStruct import ArrayStruct
             obj = ArrayStruct()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -36,3 +38,43 @@ class ArrayTable(object):
 def ArrayTableStart(builder): builder.StartObject(1)
 def ArrayTableAddA(builder, a): builder.PrependStructSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(a), 0)
 def ArrayTableEnd(builder): return builder.EndObject()
+
+import MyGame.Example.ArrayStruct
+try:
+    from typing import Optional
+except:
+    pass
+
+class ArrayTableT(object):
+
+    # ArrayTableT
+    def __init__(self):
+        self.a = None  # type: Optional[MyGame.Example.ArrayStruct.ArrayStructT]
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        arrayTable = ArrayTable()
+        arrayTable.Init(buf, pos)
+        return cls.InitFromObj(arrayTable)
+
+    @classmethod
+    def InitFromObj(cls, arrayTable):
+        x = ArrayTableT()
+        x._UnPack(arrayTable)
+        return x
+
+    # ArrayTableT
+    def _UnPack(self, arrayTable):
+        if arrayTable is None:
+            return
+        if arrayTable.A() is not None:
+            self.a = MyGame.Example.ArrayStruct.ArrayStructT.InitFromObj(arrayTable.A())
+
+    # ArrayTableT
+    def Pack(self, builder):
+        ArrayTableStart(builder)
+        if self.a is not None:
+            a = self.a.Pack(builder)
+            ArrayTableAddA(builder, a)
+        arrayTable = ArrayTableEnd(builder)
+        return arrayTable
index fe5fb48..1f5565e 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: Example
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 # an example documentation comment: monster object
 class Monster(object):
@@ -28,7 +30,7 @@ class Monster(object):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
         if o != 0:
             x = o + self._tab.Pos
-            from .Vec3 import Vec3
+            from MyGame.Example.Vec3 import Vec3
             obj = Vec3()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -78,6 +80,11 @@ class Monster(object):
         return 0
 
     # Monster
+    def InventoryIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+        return o == 0
+
+    # Monster
     def Color(self):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
         if o != 0:
@@ -107,7 +114,7 @@ class Monster(object):
         if o != 0:
             x = self._tab.Vector(o)
             x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
-            from .Test import Test
+            from MyGame.Example.Test import Test
             obj = Test()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -121,6 +128,11 @@ class Monster(object):
         return 0
 
     # Monster
+    def Test4IsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        return o == 0
+
+    # Monster
     def Testarrayofstring(self, j):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
         if o != 0:
@@ -135,6 +147,11 @@ class Monster(object):
             return self._tab.VectorLen(o)
         return 0
 
+    # Monster
+    def TestarrayofstringIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+        return o == 0
+
     # an example documentation comment: this will end up in the generated code
     # multiline too
     # Monster
@@ -144,7 +161,7 @@ class Monster(object):
             x = self._tab.Vector(o)
             x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
             x = self._tab.Indirect(x)
-            from .Monster import Monster
+            from MyGame.Example.Monster import Monster
             obj = Monster()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -158,11 +175,16 @@ class Monster(object):
         return 0
 
     # Monster
+    def TestarrayoftablesIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+        return o == 0
+
+    # Monster
     def Enemy(self):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(28))
         if o != 0:
             x = self._tab.Indirect(o + self._tab.Pos)
-            from .Monster import Monster
+            from MyGame.Example.Monster import Monster
             obj = Monster()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -191,11 +213,16 @@ class Monster(object):
         return 0
 
     # Monster
+    def TestnestedflatbufferIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
+        return o == 0
+
+    # Monster
     def Testempty(self):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(32))
         if o != 0:
             x = self._tab.Indirect(o + self._tab.Pos)
-            from .Stat import Stat
+            from MyGame.Example.Stat import Stat
             obj = Stat()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -287,6 +314,11 @@ class Monster(object):
         return 0
 
     # Monster
+    def TestarrayofboolsIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
+        return o == 0
+
+    # Monster
     def Testf(self):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(54))
         if o != 0:
@@ -323,12 +355,17 @@ class Monster(object):
         return 0
 
     # Monster
+    def Testarrayofstring2IsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
+        return o == 0
+
+    # Monster
     def Testarrayofsortedstruct(self, j):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
         if o != 0:
             x = self._tab.Vector(o)
             x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 8
-            from .Ability import Ability
+            from MyGame.Example.Ability import Ability
             obj = Ability()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -342,6 +379,11 @@ class Monster(object):
         return 0
 
     # Monster
+    def TestarrayofsortedstructIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
+        return o == 0
+
+    # Monster
     def Flex(self, j):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
         if o != 0:
@@ -364,12 +406,17 @@ class Monster(object):
         return 0
 
     # Monster
+    def FlexIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
+        return o == 0
+
+    # Monster
     def Test5(self, j):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
         if o != 0:
             x = self._tab.Vector(o)
             x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
-            from .Test import Test
+            from MyGame.Example.Test import Test
             obj = Test()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -383,6 +430,11 @@ class Monster(object):
         return 0
 
     # Monster
+    def Test5IsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
+        return o == 0
+
+    # Monster
     def VectorOfLongs(self, j):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
         if o != 0:
@@ -405,6 +457,11 @@ class Monster(object):
         return 0
 
     # Monster
+    def VectorOfLongsIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
+        return o == 0
+
+    # Monster
     def VectorOfDoubles(self, j):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
         if o != 0:
@@ -427,11 +484,16 @@ class Monster(object):
         return 0
 
     # Monster
+    def VectorOfDoublesIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
+        return o == 0
+
+    # Monster
     def ParentNamespaceTest(self):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(72))
         if o != 0:
             x = self._tab.Indirect(o + self._tab.Pos)
-            from .InParentNamespace import InParentNamespace
+            from MyGame.InParentNamespace import InParentNamespace
             obj = InParentNamespace()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -444,7 +506,7 @@ class Monster(object):
             x = self._tab.Vector(o)
             x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
             x = self._tab.Indirect(x)
-            from .Referrable import Referrable
+            from MyGame.Example.Referrable import Referrable
             obj = Referrable()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -458,6 +520,11 @@ class Monster(object):
         return 0
 
     # Monster
+    def VectorOfReferrablesIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
+        return o == 0
+
+    # Monster
     def SingleWeakReference(self):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(76))
         if o != 0:
@@ -487,13 +554,18 @@ class Monster(object):
         return 0
 
     # Monster
+    def VectorOfWeakReferencesIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
+        return o == 0
+
+    # Monster
     def VectorOfStrongReferrables(self, j):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
         if o != 0:
             x = self._tab.Vector(o)
             x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
             x = self._tab.Indirect(x)
-            from .Referrable import Referrable
+            from MyGame.Example.Referrable import Referrable
             obj = Referrable()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -507,6 +579,11 @@ class Monster(object):
         return 0
 
     # Monster
+    def VectorOfStrongReferrablesIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
+        return o == 0
+
+    # Monster
     def CoOwningReference(self):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(82))
         if o != 0:
@@ -536,6 +613,11 @@ class Monster(object):
         return 0
 
     # Monster
+    def VectorOfCoOwningReferencesIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
+        return o == 0
+
+    # Monster
     def NonOwningReference(self):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(86))
         if o != 0:
@@ -565,6 +647,11 @@ class Monster(object):
         return 0
 
     # Monster
+    def VectorOfNonOwningReferencesIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
+        return o == 0
+
+    # Monster
     def AnyUniqueType(self):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(90))
         if o != 0:
@@ -621,6 +708,11 @@ class Monster(object):
         return 0
 
     # Monster
+    def VectorOfEnumsIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
+        return o == 0
+
+    # Monster
     def SignedEnum(self):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(100))
         if o != 0:
@@ -695,3 +787,449 @@ def MonsterAddVectorOfEnums(builder, vectorOfEnums): builder.PrependUOffsetTRela
 def MonsterStartVectorOfEnumsVector(builder, numElems): return builder.StartVector(1, numElems, 1)
 def MonsterAddSignedEnum(builder, signedEnum): builder.PrependInt8Slot(48, signedEnum, -1)
 def MonsterEnd(builder): return builder.EndObject()
+
+import MyGame.Example.Ability
+import MyGame.Example.Any
+import MyGame.Example.AnyAmbiguousAliases
+import MyGame.Example.AnyUniqueAliases
+import MyGame.Example.Referrable
+import MyGame.Example.Stat
+import MyGame.Example.Test
+import MyGame.Example.TestSimpleTableWithEnum
+import MyGame.Example.Vec3
+import MyGame.Example2.Monster
+import MyGame.InParentNamespace
+try:
+    from typing import List, Optional, Union
+except:
+    pass
+
+class MonsterT(object):
+
+    # MonsterT
+    def __init__(self):
+        self.pos = None  # type: Optional[MyGame.Example.Vec3.Vec3T]
+        self.mana = 150  # type: int
+        self.hp = 100  # type: int
+        self.name = None  # type: str
+        self.inventory = None  # type: List[int]
+        self.color = 8  # type: int
+        self.testType = 0  # type: int
+        self.test = None  # type: Union[None, MyGame.Example.Monster.MonsterT, MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT, MyGame.Example2.Monster.MonsterT]
+        self.test4 = None  # type: List[MyGame.Example.Test.TestT]
+        self.testarrayofstring = None  # type: List[str]
+        self.testarrayoftables = None  # type: List[MyGame.Example.Monster.MonsterT]
+        self.enemy = None  # type: Optional[MyGame.Example.Monster.MonsterT]
+        self.testnestedflatbuffer = None  # type: List[int]
+        self.testempty = None  # type: Optional[MyGame.Example.Stat.StatT]
+        self.testbool = False  # type: bool
+        self.testhashs32Fnv1 = 0  # type: int
+        self.testhashu32Fnv1 = 0  # type: int
+        self.testhashs64Fnv1 = 0  # type: int
+        self.testhashu64Fnv1 = 0  # type: int
+        self.testhashs32Fnv1a = 0  # type: int
+        self.testhashu32Fnv1a = 0  # type: int
+        self.testhashs64Fnv1a = 0  # type: int
+        self.testhashu64Fnv1a = 0  # type: int
+        self.testarrayofbools = None  # type: List[bool]
+        self.testf = 3.14159  # type: float
+        self.testf2 = 3.0  # type: float
+        self.testf3 = 0.0  # type: float
+        self.testarrayofstring2 = None  # type: List[str]
+        self.testarrayofsortedstruct = None  # type: List[MyGame.Example.Ability.AbilityT]
+        self.flex = None  # type: List[int]
+        self.test5 = None  # type: List[MyGame.Example.Test.TestT]
+        self.vectorOfLongs = None  # type: List[int]
+        self.vectorOfDoubles = None  # type: List[float]
+        self.parentNamespaceTest = None  # type: Optional[MyGame.InParentNamespace.InParentNamespaceT]
+        self.vectorOfReferrables = None  # type: List[MyGame.Example.Referrable.ReferrableT]
+        self.singleWeakReference = 0  # type: int
+        self.vectorOfWeakReferences = None  # type: List[int]
+        self.vectorOfStrongReferrables = None  # type: List[MyGame.Example.Referrable.ReferrableT]
+        self.coOwningReference = 0  # type: int
+        self.vectorOfCoOwningReferences = None  # type: List[int]
+        self.nonOwningReference = 0  # type: int
+        self.vectorOfNonOwningReferences = None  # type: List[int]
+        self.anyUniqueType = 0  # type: int
+        self.anyUnique = None  # type: Union[None, MyGame.Example.Monster.MonsterT, MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT, MyGame.Example2.Monster.MonsterT]
+        self.anyAmbiguousType = 0  # type: int
+        self.anyAmbiguous = None  # type: Union[None, MyGame.Example.Monster.MonsterT, MyGame.Example.Monster.MonsterT, MyGame.Example.Monster.MonsterT]
+        self.vectorOfEnums = None  # type: List[int]
+        self.signedEnum = -1  # type: int
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        monster = Monster()
+        monster.Init(buf, pos)
+        return cls.InitFromObj(monster)
+
+    @classmethod
+    def InitFromObj(cls, monster):
+        x = MonsterT()
+        x._UnPack(monster)
+        return x
+
+    # MonsterT
+    def _UnPack(self, monster):
+        if monster is None:
+            return
+        if monster.Pos() is not None:
+            self.pos = MyGame.Example.Vec3.Vec3T.InitFromObj(monster.Pos())
+        self.mana = monster.Mana()
+        self.hp = monster.Hp()
+        self.name = monster.Name()
+        if not monster.InventoryIsNone():
+            if np is None:
+                self.inventory = []
+                for i in range(monster.InventoryLength()):
+                    self.inventory.append(monster.Inventory(i))
+            else:
+                self.inventory = monster.InventoryAsNumpy()
+        self.color = monster.Color()
+        self.testType = monster.TestType()
+        self.test = MyGame.Example.Any.AnyCreator(self.testType, monster.Test())
+        if not monster.Test4IsNone():
+            self.test4 = []
+            for i in range(monster.Test4Length()):
+                if monster.Test4(i) is None:
+                    self.test4.append(None)
+                else:
+                    test_ = MyGame.Example.Test.TestT.InitFromObj(monster.Test4(i))
+                    self.test4.append(test_)
+        if not monster.TestarrayofstringIsNone():
+            self.testarrayofstring = []
+            for i in range(monster.TestarrayofstringLength()):
+                self.testarrayofstring.append(monster.Testarrayofstring(i))
+        if not monster.TestarrayoftablesIsNone():
+            self.testarrayoftables = []
+            for i in range(monster.TestarrayoftablesLength()):
+                if monster.Testarrayoftables(i) is None:
+                    self.testarrayoftables.append(None)
+                else:
+                    monster_ = MyGame.Example.Monster.MonsterT.InitFromObj(monster.Testarrayoftables(i))
+                    self.testarrayoftables.append(monster_)
+        if monster.Enemy() is not None:
+            self.enemy = MyGame.Example.Monster.MonsterT.InitFromObj(monster.Enemy())
+        if not monster.TestnestedflatbufferIsNone():
+            if np is None:
+                self.testnestedflatbuffer = []
+                for i in range(monster.TestnestedflatbufferLength()):
+                    self.testnestedflatbuffer.append(monster.Testnestedflatbuffer(i))
+            else:
+                self.testnestedflatbuffer = monster.TestnestedflatbufferAsNumpy()
+        if monster.Testempty() is not None:
+            self.testempty = MyGame.Example.Stat.StatT.InitFromObj(monster.Testempty())
+        self.testbool = monster.Testbool()
+        self.testhashs32Fnv1 = monster.Testhashs32Fnv1()
+        self.testhashu32Fnv1 = monster.Testhashu32Fnv1()
+        self.testhashs64Fnv1 = monster.Testhashs64Fnv1()
+        self.testhashu64Fnv1 = monster.Testhashu64Fnv1()
+        self.testhashs32Fnv1a = monster.Testhashs32Fnv1a()
+        self.testhashu32Fnv1a = monster.Testhashu32Fnv1a()
+        self.testhashs64Fnv1a = monster.Testhashs64Fnv1a()
+        self.testhashu64Fnv1a = monster.Testhashu64Fnv1a()
+        if not monster.TestarrayofboolsIsNone():
+            if np is None:
+                self.testarrayofbools = []
+                for i in range(monster.TestarrayofboolsLength()):
+                    self.testarrayofbools.append(monster.Testarrayofbools(i))
+            else:
+                self.testarrayofbools = monster.TestarrayofboolsAsNumpy()
+        self.testf = monster.Testf()
+        self.testf2 = monster.Testf2()
+        self.testf3 = monster.Testf3()
+        if not monster.Testarrayofstring2IsNone():
+            self.testarrayofstring2 = []
+            for i in range(monster.Testarrayofstring2Length()):
+                self.testarrayofstring2.append(monster.Testarrayofstring2(i))
+        if not monster.TestarrayofsortedstructIsNone():
+            self.testarrayofsortedstruct = []
+            for i in range(monster.TestarrayofsortedstructLength()):
+                if monster.Testarrayofsortedstruct(i) is None:
+                    self.testarrayofsortedstruct.append(None)
+                else:
+                    ability_ = MyGame.Example.Ability.AbilityT.InitFromObj(monster.Testarrayofsortedstruct(i))
+                    self.testarrayofsortedstruct.append(ability_)
+        if not monster.FlexIsNone():
+            if np is None:
+                self.flex = []
+                for i in range(monster.FlexLength()):
+                    self.flex.append(monster.Flex(i))
+            else:
+                self.flex = monster.FlexAsNumpy()
+        if not monster.Test5IsNone():
+            self.test5 = []
+            for i in range(monster.Test5Length()):
+                if monster.Test5(i) is None:
+                    self.test5.append(None)
+                else:
+                    test_ = MyGame.Example.Test.TestT.InitFromObj(monster.Test5(i))
+                    self.test5.append(test_)
+        if not monster.VectorOfLongsIsNone():
+            if np is None:
+                self.vectorOfLongs = []
+                for i in range(monster.VectorOfLongsLength()):
+                    self.vectorOfLongs.append(monster.VectorOfLongs(i))
+            else:
+                self.vectorOfLongs = monster.VectorOfLongsAsNumpy()
+        if not monster.VectorOfDoublesIsNone():
+            if np is None:
+                self.vectorOfDoubles = []
+                for i in range(monster.VectorOfDoublesLength()):
+                    self.vectorOfDoubles.append(monster.VectorOfDoubles(i))
+            else:
+                self.vectorOfDoubles = monster.VectorOfDoublesAsNumpy()
+        if monster.ParentNamespaceTest() is not None:
+            self.parentNamespaceTest = MyGame.InParentNamespace.InParentNamespaceT.InitFromObj(monster.ParentNamespaceTest())
+        if not monster.VectorOfReferrablesIsNone():
+            self.vectorOfReferrables = []
+            for i in range(monster.VectorOfReferrablesLength()):
+                if monster.VectorOfReferrables(i) is None:
+                    self.vectorOfReferrables.append(None)
+                else:
+                    referrable_ = MyGame.Example.Referrable.ReferrableT.InitFromObj(monster.VectorOfReferrables(i))
+                    self.vectorOfReferrables.append(referrable_)
+        self.singleWeakReference = monster.SingleWeakReference()
+        if not monster.VectorOfWeakReferencesIsNone():
+            if np is None:
+                self.vectorOfWeakReferences = []
+                for i in range(monster.VectorOfWeakReferencesLength()):
+                    self.vectorOfWeakReferences.append(monster.VectorOfWeakReferences(i))
+            else:
+                self.vectorOfWeakReferences = monster.VectorOfWeakReferencesAsNumpy()
+        if not monster.VectorOfStrongReferrablesIsNone():
+            self.vectorOfStrongReferrables = []
+            for i in range(monster.VectorOfStrongReferrablesLength()):
+                if monster.VectorOfStrongReferrables(i) is None:
+                    self.vectorOfStrongReferrables.append(None)
+                else:
+                    referrable_ = MyGame.Example.Referrable.ReferrableT.InitFromObj(monster.VectorOfStrongReferrables(i))
+                    self.vectorOfStrongReferrables.append(referrable_)
+        self.coOwningReference = monster.CoOwningReference()
+        if not monster.VectorOfCoOwningReferencesIsNone():
+            if np is None:
+                self.vectorOfCoOwningReferences = []
+                for i in range(monster.VectorOfCoOwningReferencesLength()):
+                    self.vectorOfCoOwningReferences.append(monster.VectorOfCoOwningReferences(i))
+            else:
+                self.vectorOfCoOwningReferences = monster.VectorOfCoOwningReferencesAsNumpy()
+        self.nonOwningReference = monster.NonOwningReference()
+        if not monster.VectorOfNonOwningReferencesIsNone():
+            if np is None:
+                self.vectorOfNonOwningReferences = []
+                for i in range(monster.VectorOfNonOwningReferencesLength()):
+                    self.vectorOfNonOwningReferences.append(monster.VectorOfNonOwningReferences(i))
+            else:
+                self.vectorOfNonOwningReferences = monster.VectorOfNonOwningReferencesAsNumpy()
+        self.anyUniqueType = monster.AnyUniqueType()
+        self.anyUnique = MyGame.Example.AnyUniqueAliases.AnyUniqueAliasesCreator(self.anyUniqueType, monster.AnyUnique())
+        self.anyAmbiguousType = monster.AnyAmbiguousType()
+        self.anyAmbiguous = MyGame.Example.AnyAmbiguousAliases.AnyAmbiguousAliasesCreator(self.anyAmbiguousType, monster.AnyAmbiguous())
+        if not monster.VectorOfEnumsIsNone():
+            if np is None:
+                self.vectorOfEnums = []
+                for i in range(monster.VectorOfEnumsLength()):
+                    self.vectorOfEnums.append(monster.VectorOfEnums(i))
+            else:
+                self.vectorOfEnums = monster.VectorOfEnumsAsNumpy()
+        self.signedEnum = monster.SignedEnum()
+
+    # MonsterT
+    def Pack(self, builder):
+        if self.name is not None:
+            name = builder.CreateString(self.name)
+        if self.inventory is not None:
+            MonsterStartInventoryVector(builder, len(self.inventory))
+            for i in reversed(range(len(self.inventory))):
+                builder.PrependUint8(self.inventory[i])
+            inventory =  builder.EndVector(len(self.inventory))
+        if self.test is not None:
+            test = self.test.Pack(builder)
+        if self.test4 is not None:
+            MonsterStartTest4Vector(builder, len(self.test4))
+            for i in reversed(range(len(self.test4))):
+                self.test4[i].Pack(builder)
+            test4 = builder.EndVector(len(self.test4))
+        if self.testarrayofstring is not None:
+            testarrayofstringlist = []
+            for i in range(len(self.testarrayofstring)):
+                testarrayofstringlist.append(builder.CreateString(self.testarrayofstring[i]))
+            MonsterStartTestarrayofstringVector(builder, len(self.testarrayofstring))
+            for i in reversed(range(len(self.testarrayofstring))):
+                builder.PrependUOffsetTRelative(testarrayofstringlist[i])
+            testarrayofstring =  builder.EndVector(len(self.testarrayofstring))
+        if self.testarrayoftables is not None:
+            testarrayoftableslist = []
+            for i in range(len(self.testarrayoftables)):
+                testarrayoftableslist.append(self.testarrayoftables[i].Pack(builder))
+            MonsterStartTestarrayoftablesVector(builder, len(self.testarrayoftables))
+            for i in reversed(range(len(self.testarrayoftables))):
+                builder.PrependUOffsetTRelative(testarrayoftableslist[i])
+            testarrayoftables =  builder.EndVector(len(self.testarrayoftables))
+        if self.enemy is not None:
+            enemy = self.enemy.Pack(builder)
+        if self.testnestedflatbuffer is not None:
+            MonsterStartTestnestedflatbufferVector(builder, len(self.testnestedflatbuffer))
+            for i in reversed(range(len(self.testnestedflatbuffer))):
+                builder.PrependUint8(self.testnestedflatbuffer[i])
+            testnestedflatbuffer =  builder.EndVector(len(self.testnestedflatbuffer))
+        if self.testempty is not None:
+            testempty = self.testempty.Pack(builder)
+        if self.testarrayofbools is not None:
+            MonsterStartTestarrayofboolsVector(builder, len(self.testarrayofbools))
+            for i in reversed(range(len(self.testarrayofbools))):
+                builder.PrependBool(self.testarrayofbools[i])
+            testarrayofbools =  builder.EndVector(len(self.testarrayofbools))
+        if self.testarrayofstring2 is not None:
+            testarrayofstring2list = []
+            for i in range(len(self.testarrayofstring2)):
+                testarrayofstring2list.append(builder.CreateString(self.testarrayofstring2[i]))
+            MonsterStartTestarrayofstring2Vector(builder, len(self.testarrayofstring2))
+            for i in reversed(range(len(self.testarrayofstring2))):
+                builder.PrependUOffsetTRelative(testarrayofstring2list[i])
+            testarrayofstring2 =  builder.EndVector(len(self.testarrayofstring2))
+        if self.testarrayofsortedstruct is not None:
+            MonsterStartTestarrayofsortedstructVector(builder, len(self.testarrayofsortedstruct))
+            for i in reversed(range(len(self.testarrayofsortedstruct))):
+                self.testarrayofsortedstruct[i].Pack(builder)
+            testarrayofsortedstruct = builder.EndVector(len(self.testarrayofsortedstruct))
+        if self.flex is not None:
+            MonsterStartFlexVector(builder, len(self.flex))
+            for i in reversed(range(len(self.flex))):
+                builder.PrependUint8(self.flex[i])
+            flex =  builder.EndVector(len(self.flex))
+        if self.test5 is not None:
+            MonsterStartTest5Vector(builder, len(self.test5))
+            for i in reversed(range(len(self.test5))):
+                self.test5[i].Pack(builder)
+            test5 = builder.EndVector(len(self.test5))
+        if self.vectorOfLongs is not None:
+            MonsterStartVectorOfLongsVector(builder, len(self.vectorOfLongs))
+            for i in reversed(range(len(self.vectorOfLongs))):
+                builder.PrependInt64(self.vectorOfLongs[i])
+            vectorOfLongs =  builder.EndVector(len(self.vectorOfLongs))
+        if self.vectorOfDoubles is not None:
+            MonsterStartVectorOfDoublesVector(builder, len(self.vectorOfDoubles))
+            for i in reversed(range(len(self.vectorOfDoubles))):
+                builder.PrependFloat64(self.vectorOfDoubles[i])
+            vectorOfDoubles =  builder.EndVector(len(self.vectorOfDoubles))
+        if self.parentNamespaceTest is not None:
+            parentNamespaceTest = self.parentNamespaceTest.Pack(builder)
+        if self.vectorOfReferrables is not None:
+            vectorOfReferrableslist = []
+            for i in range(len(self.vectorOfReferrables)):
+                vectorOfReferrableslist.append(self.vectorOfReferrables[i].Pack(builder))
+            MonsterStartVectorOfReferrablesVector(builder, len(self.vectorOfReferrables))
+            for i in reversed(range(len(self.vectorOfReferrables))):
+                builder.PrependUOffsetTRelative(vectorOfReferrableslist[i])
+            vectorOfReferrables =  builder.EndVector(len(self.vectorOfReferrables))
+        if self.vectorOfWeakReferences is not None:
+            MonsterStartVectorOfWeakReferencesVector(builder, len(self.vectorOfWeakReferences))
+            for i in reversed(range(len(self.vectorOfWeakReferences))):
+                builder.PrependUint64(self.vectorOfWeakReferences[i])
+            vectorOfWeakReferences =  builder.EndVector(len(self.vectorOfWeakReferences))
+        if self.vectorOfStrongReferrables is not None:
+            vectorOfStrongReferrableslist = []
+            for i in range(len(self.vectorOfStrongReferrables)):
+                vectorOfStrongReferrableslist.append(self.vectorOfStrongReferrables[i].Pack(builder))
+            MonsterStartVectorOfStrongReferrablesVector(builder, len(self.vectorOfStrongReferrables))
+            for i in reversed(range(len(self.vectorOfStrongReferrables))):
+                builder.PrependUOffsetTRelative(vectorOfStrongReferrableslist[i])
+            vectorOfStrongReferrables =  builder.EndVector(len(self.vectorOfStrongReferrables))
+        if self.vectorOfCoOwningReferences is not None:
+            MonsterStartVectorOfCoOwningReferencesVector(builder, len(self.vectorOfCoOwningReferences))
+            for i in reversed(range(len(self.vectorOfCoOwningReferences))):
+                builder.PrependUint64(self.vectorOfCoOwningReferences[i])
+            vectorOfCoOwningReferences =  builder.EndVector(len(self.vectorOfCoOwningReferences))
+        if self.vectorOfNonOwningReferences is not None:
+            MonsterStartVectorOfNonOwningReferencesVector(builder, len(self.vectorOfNonOwningReferences))
+            for i in reversed(range(len(self.vectorOfNonOwningReferences))):
+                builder.PrependUint64(self.vectorOfNonOwningReferences[i])
+            vectorOfNonOwningReferences =  builder.EndVector(len(self.vectorOfNonOwningReferences))
+        if self.anyUnique is not None:
+            anyUnique = self.anyUnique.Pack(builder)
+        if self.anyAmbiguous is not None:
+            anyAmbiguous = self.anyAmbiguous.Pack(builder)
+        if self.vectorOfEnums is not None:
+            MonsterStartVectorOfEnumsVector(builder, len(self.vectorOfEnums))
+            for i in reversed(range(len(self.vectorOfEnums))):
+                builder.PrependUint8(self.vectorOfEnums[i])
+            vectorOfEnums =  builder.EndVector(len(self.vectorOfEnums))
+        MonsterStart(builder)
+        if self.pos is not None:
+            pos = self.pos.Pack(builder)
+            MonsterAddPos(builder, pos)
+        MonsterAddMana(builder, self.mana)
+        MonsterAddHp(builder, self.hp)
+        if self.name is not None:
+            MonsterAddName(builder, name)
+        if self.inventory is not None:
+            MonsterAddInventory(builder, inventory)
+        MonsterAddColor(builder, self.color)
+        MonsterAddTestType(builder, self.testType)
+        if self.test is not None:
+            MonsterAddTest(builder, test)
+        if self.test4 is not None:
+            MonsterAddTest4(builder, test4)
+        if self.testarrayofstring is not None:
+            MonsterAddTestarrayofstring(builder, testarrayofstring)
+        if self.testarrayoftables is not None:
+            MonsterAddTestarrayoftables(builder, testarrayoftables)
+        if self.enemy is not None:
+            MonsterAddEnemy(builder, enemy)
+        if self.testnestedflatbuffer is not None:
+            MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer)
+        if self.testempty is not None:
+            MonsterAddTestempty(builder, testempty)
+        MonsterAddTestbool(builder, self.testbool)
+        MonsterAddTesthashs32Fnv1(builder, self.testhashs32Fnv1)
+        MonsterAddTesthashu32Fnv1(builder, self.testhashu32Fnv1)
+        MonsterAddTesthashs64Fnv1(builder, self.testhashs64Fnv1)
+        MonsterAddTesthashu64Fnv1(builder, self.testhashu64Fnv1)
+        MonsterAddTesthashs32Fnv1a(builder, self.testhashs32Fnv1a)
+        MonsterAddTesthashu32Fnv1a(builder, self.testhashu32Fnv1a)
+        MonsterAddTesthashs64Fnv1a(builder, self.testhashs64Fnv1a)
+        MonsterAddTesthashu64Fnv1a(builder, self.testhashu64Fnv1a)
+        if self.testarrayofbools is not None:
+            MonsterAddTestarrayofbools(builder, testarrayofbools)
+        MonsterAddTestf(builder, self.testf)
+        MonsterAddTestf2(builder, self.testf2)
+        MonsterAddTestf3(builder, self.testf3)
+        if self.testarrayofstring2 is not None:
+            MonsterAddTestarrayofstring2(builder, testarrayofstring2)
+        if self.testarrayofsortedstruct is not None:
+            MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct)
+        if self.flex is not None:
+            MonsterAddFlex(builder, flex)
+        if self.test5 is not None:
+            MonsterAddTest5(builder, test5)
+        if self.vectorOfLongs is not None:
+            MonsterAddVectorOfLongs(builder, vectorOfLongs)
+        if self.vectorOfDoubles is not None:
+            MonsterAddVectorOfDoubles(builder, vectorOfDoubles)
+        if self.parentNamespaceTest is not None:
+            MonsterAddParentNamespaceTest(builder, parentNamespaceTest)
+        if self.vectorOfReferrables is not None:
+            MonsterAddVectorOfReferrables(builder, vectorOfReferrables)
+        MonsterAddSingleWeakReference(builder, self.singleWeakReference)
+        if self.vectorOfWeakReferences is not None:
+            MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferences)
+        if self.vectorOfStrongReferrables is not None:
+            MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrables)
+        MonsterAddCoOwningReference(builder, self.coOwningReference)
+        if self.vectorOfCoOwningReferences is not None:
+            MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences)
+        MonsterAddNonOwningReference(builder, self.nonOwningReference)
+        if self.vectorOfNonOwningReferences is not None:
+            MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences)
+        MonsterAddAnyUniqueType(builder, self.anyUniqueType)
+        if self.anyUnique is not None:
+            MonsterAddAnyUnique(builder, anyUnique)
+        MonsterAddAnyAmbiguousType(builder, self.anyAmbiguousType)
+        if self.anyAmbiguous is not None:
+            MonsterAddAnyAmbiguous(builder, anyAmbiguous)
+        if self.vectorOfEnums is not None:
+            MonsterAddVectorOfEnums(builder, vectorOfEnums)
+        MonsterAddSignedEnum(builder, self.signedEnum)
+        monster = MonsterEnd(builder)
+        return monster
index c009973..a66cee0 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: Example
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class NestedStruct(object):
     __slots__ = ['_tab']
@@ -14,11 +16,47 @@ class NestedStruct(object):
     # NestedStruct
     def A(self): return [self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0 + i * 4)) for i in range(2)]
     # NestedStruct
+    def ALength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(0))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # NestedStruct
+    def AIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(0))
+        return o == 0
+
+    # NestedStruct
     def B(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(8))
     # NestedStruct
     def C(self): return [self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(9 + i * 1)) for i in range(2)]
     # NestedStruct
+    def CLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(9))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # NestedStruct
+    def CIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(9))
+        return o == 0
+
+    # NestedStruct
     def D(self): return [self._tab.Get(flatbuffers.number_types.Int64Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(16 + i * 8)) for i in range(2)]
+    # NestedStruct
+    def DLength(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
+        if o != 0:
+            return self._tab.VectorLen(o)
+        return 0
+
+    # NestedStruct
+    def DIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
+        return o == 0
+
 
 def CreateNestedStruct(builder, a, b, c, d):
     builder.Prep(8, 32)
@@ -31,3 +69,60 @@ def CreateNestedStruct(builder, a, b, c, d):
     for _idx0 in range(2 , 0, -1):
         builder.PrependInt32(a[_idx0-1])
     return builder.Offset()
+
+try:
+    from typing import List
+except:
+    pass
+
+class NestedStructT(object):
+
+    # NestedStructT
+    def __init__(self):
+        self.a = None  # type: List[int]
+        self.b = 0  # type: int
+        self.c = None  # type: List[int]
+        self.d = None  # type: List[int]
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        nestedStruct = NestedStruct()
+        nestedStruct.Init(buf, pos)
+        return cls.InitFromObj(nestedStruct)
+
+    @classmethod
+    def InitFromObj(cls, nestedStruct):
+        x = NestedStructT()
+        x._UnPack(nestedStruct)
+        return x
+
+    # NestedStructT
+    def _UnPack(self, nestedStruct):
+        if nestedStruct is None:
+            return
+        if not nestedStruct.AIsNone():
+            if np is None:
+                self.a = []
+                for i in range(nestedStruct.ALength()):
+                    self.a.append(nestedStruct.A(i))
+            else:
+                self.a = nestedStruct.AAsNumpy()
+        self.b = nestedStruct.B()
+        if not nestedStruct.CIsNone():
+            if np is None:
+                self.c = []
+                for i in range(nestedStruct.CLength()):
+                    self.c.append(nestedStruct.C(i))
+            else:
+                self.c = nestedStruct.CAsNumpy()
+        if not nestedStruct.DIsNone():
+            if np is None:
+                self.d = []
+                for i in range(nestedStruct.DLength()):
+                    self.d.append(nestedStruct.D(i))
+            else:
+                self.d = nestedStruct.DAsNumpy()
+
+    # NestedStructT
+    def Pack(self, builder):
+        return CreateNestedStruct(builder, self.a, self.b, self.c, self.d)
index eaec09b..44bf50f 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: Example
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class Referrable(object):
     __slots__ = ['_tab']
@@ -32,3 +34,35 @@ class Referrable(object):
 def ReferrableStart(builder): builder.StartObject(1)
 def ReferrableAddId(builder, id): builder.PrependUint64Slot(0, id, 0)
 def ReferrableEnd(builder): return builder.EndObject()
+
+
+class ReferrableT(object):
+
+    # ReferrableT
+    def __init__(self):
+        self.id = 0  # type: int
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        referrable = Referrable()
+        referrable.Init(buf, pos)
+        return cls.InitFromObj(referrable)
+
+    @classmethod
+    def InitFromObj(cls, referrable):
+        x = ReferrableT()
+        x._UnPack(referrable)
+        return x
+
+    # ReferrableT
+    def _UnPack(self, referrable):
+        if referrable is None:
+            return
+        self.id = referrable.Id()
+
+    # ReferrableT
+    def Pack(self, builder):
+        ReferrableStart(builder)
+        ReferrableAddId(builder, self.id)
+        referrable = ReferrableEnd(builder)
+        return referrable
index 0fbd2a7..7d3362f 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: Example
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class Stat(object):
     __slots__ = ['_tab']
@@ -48,3 +50,44 @@ def StatAddId(builder, id): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.n
 def StatAddVal(builder, val): builder.PrependInt64Slot(1, val, 0)
 def StatAddCount(builder, count): builder.PrependUint16Slot(2, count, 0)
 def StatEnd(builder): return builder.EndObject()
+
+
+class StatT(object):
+
+    # StatT
+    def __init__(self):
+        self.id = None  # type: str
+        self.val = 0  # type: int
+        self.count = 0  # type: int
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        stat = Stat()
+        stat.Init(buf, pos)
+        return cls.InitFromObj(stat)
+
+    @classmethod
+    def InitFromObj(cls, stat):
+        x = StatT()
+        x._UnPack(stat)
+        return x
+
+    # StatT
+    def _UnPack(self, stat):
+        if stat is None:
+            return
+        self.id = stat.Id()
+        self.val = stat.Val()
+        self.count = stat.Count()
+
+    # StatT
+    def Pack(self, builder):
+        if self.id is not None:
+            id = builder.CreateString(self.id)
+        StatStart(builder)
+        if self.id is not None:
+            StatAddId(builder, id)
+        StatAddVal(builder, self.val)
+        StatAddCount(builder, self.count)
+        stat = StatEnd(builder)
+        return stat
index 3b2fd45..576a656 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: Example
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class Test(object):
     __slots__ = ['_tab']
@@ -22,3 +24,34 @@ def CreateTest(builder, a, b):
     builder.PrependInt8(b)
     builder.PrependInt16(a)
     return builder.Offset()
+
+
+class TestT(object):
+
+    # TestT
+    def __init__(self):
+        self.a = 0  # type: int
+        self.b = 0  # type: int
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        test = Test()
+        test.Init(buf, pos)
+        return cls.InitFromObj(test)
+
+    @classmethod
+    def InitFromObj(cls, test):
+        x = TestT()
+        x._UnPack(test)
+        return x
+
+    # TestT
+    def _UnPack(self, test):
+        if test is None:
+            return
+        self.a = test.A()
+        self.b = test.B()
+
+    # TestT
+    def Pack(self, builder):
+        return CreateTest(builder, self.a, self.b)
index cb9c631..d91947a 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: Example
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class TestSimpleTableWithEnum(object):
     __slots__ = ['_tab']
@@ -32,3 +34,35 @@ class TestSimpleTableWithEnum(object):
 def TestSimpleTableWithEnumStart(builder): builder.StartObject(1)
 def TestSimpleTableWithEnumAddColor(builder, color): builder.PrependUint8Slot(0, color, 2)
 def TestSimpleTableWithEnumEnd(builder): return builder.EndObject()
+
+
+class TestSimpleTableWithEnumT(object):
+
+    # TestSimpleTableWithEnumT
+    def __init__(self):
+        self.color = 2  # type: int
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        testSimpleTableWithEnum = TestSimpleTableWithEnum()
+        testSimpleTableWithEnum.Init(buf, pos)
+        return cls.InitFromObj(testSimpleTableWithEnum)
+
+    @classmethod
+    def InitFromObj(cls, testSimpleTableWithEnum):
+        x = TestSimpleTableWithEnumT()
+        x._UnPack(testSimpleTableWithEnum)
+        return x
+
+    # TestSimpleTableWithEnumT
+    def _UnPack(self, testSimpleTableWithEnum):
+        if testSimpleTableWithEnum is None:
+            return
+        self.color = testSimpleTableWithEnum.Color()
+
+    # TestSimpleTableWithEnumT
+    def Pack(self, builder):
+        TestSimpleTableWithEnumStart(builder)
+        TestSimpleTableWithEnumAddColor(builder, self.color)
+        testSimpleTableWithEnum = TestSimpleTableWithEnumEnd(builder)
+        return testSimpleTableWithEnum
index 81e9b06..bec87c5 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: Example
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class TypeAliases(object):
     __slots__ = ['_tab']
@@ -115,6 +117,11 @@ class TypeAliases(object):
         return 0
 
     # TypeAliases
+    def V8IsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+        return o == 0
+
+    # TypeAliases
     def Vf64(self, j):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
         if o != 0:
@@ -136,6 +143,11 @@ class TypeAliases(object):
             return self._tab.VectorLen(o)
         return 0
 
+    # TypeAliases
+    def Vf64IsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+        return o == 0
+
 def TypeAliasesStart(builder): builder.StartObject(12)
 def TypeAliasesAddI8(builder, i8): builder.PrependInt8Slot(0, i8, 0)
 def TypeAliasesAddU8(builder, u8): builder.PrependUint8Slot(1, u8, 0)
@@ -152,3 +164,96 @@ def TypeAliasesStartV8Vector(builder, numElems): return builder.StartVector(1, n
 def TypeAliasesAddVf64(builder, vf64): builder.PrependUOffsetTRelativeSlot(11, flatbuffers.number_types.UOffsetTFlags.py_type(vf64), 0)
 def TypeAliasesStartVf64Vector(builder, numElems): return builder.StartVector(8, numElems, 8)
 def TypeAliasesEnd(builder): return builder.EndObject()
+
+try:
+    from typing import List
+except:
+    pass
+
+class TypeAliasesT(object):
+
+    # TypeAliasesT
+    def __init__(self):
+        self.i8 = 0  # type: int
+        self.u8 = 0  # type: int
+        self.i16 = 0  # type: int
+        self.u16 = 0  # type: int
+        self.i32 = 0  # type: int
+        self.u32 = 0  # type: int
+        self.i64 = 0  # type: int
+        self.u64 = 0  # type: int
+        self.f32 = 0.0  # type: float
+        self.f64 = 0.0  # type: float
+        self.v8 = None  # type: List[int]
+        self.vf64 = None  # type: List[float]
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        typeAliases = TypeAliases()
+        typeAliases.Init(buf, pos)
+        return cls.InitFromObj(typeAliases)
+
+    @classmethod
+    def InitFromObj(cls, typeAliases):
+        x = TypeAliasesT()
+        x._UnPack(typeAliases)
+        return x
+
+    # TypeAliasesT
+    def _UnPack(self, typeAliases):
+        if typeAliases is None:
+            return
+        self.i8 = typeAliases.I8()
+        self.u8 = typeAliases.U8()
+        self.i16 = typeAliases.I16()
+        self.u16 = typeAliases.U16()
+        self.i32 = typeAliases.I32()
+        self.u32 = typeAliases.U32()
+        self.i64 = typeAliases.I64()
+        self.u64 = typeAliases.U64()
+        self.f32 = typeAliases.F32()
+        self.f64 = typeAliases.F64()
+        if not typeAliases.V8IsNone():
+            if np is None:
+                self.v8 = []
+                for i in range(typeAliases.V8Length()):
+                    self.v8.append(typeAliases.V8(i))
+            else:
+                self.v8 = typeAliases.V8AsNumpy()
+        if not typeAliases.Vf64IsNone():
+            if np is None:
+                self.vf64 = []
+                for i in range(typeAliases.Vf64Length()):
+                    self.vf64.append(typeAliases.Vf64(i))
+            else:
+                self.vf64 = typeAliases.Vf64AsNumpy()
+
+    # TypeAliasesT
+    def Pack(self, builder):
+        if self.v8 is not None:
+            TypeAliasesStartV8Vector(builder, len(self.v8))
+            for i in reversed(range(len(self.v8))):
+                builder.PrependByte(self.v8[i])
+            v8 =  builder.EndVector(len(self.v8))
+        if self.vf64 is not None:
+            TypeAliasesStartVf64Vector(builder, len(self.vf64))
+            for i in reversed(range(len(self.vf64))):
+                builder.PrependFloat64(self.vf64[i])
+            vf64 =  builder.EndVector(len(self.vf64))
+        TypeAliasesStart(builder)
+        TypeAliasesAddI8(builder, self.i8)
+        TypeAliasesAddU8(builder, self.u8)
+        TypeAliasesAddI16(builder, self.i16)
+        TypeAliasesAddU16(builder, self.u16)
+        TypeAliasesAddI32(builder, self.i32)
+        TypeAliasesAddU32(builder, self.u32)
+        TypeAliasesAddI64(builder, self.i64)
+        TypeAliasesAddU64(builder, self.u64)
+        TypeAliasesAddF32(builder, self.f32)
+        TypeAliasesAddF64(builder, self.f64)
+        if self.v8 is not None:
+            TypeAliasesAddV8(builder, v8)
+        if self.vf64 is not None:
+            TypeAliasesAddVf64(builder, vf64)
+        typeAliases = TypeAliasesEnd(builder)
+        return typeAliases
index 1f32390..5c91a7d 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: Example
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class Vec3(object):
     __slots__ = ['_tab']
@@ -42,3 +44,48 @@ def CreateVec3(builder, x, y, z, test1, test2, test3_a, test3_b):
     builder.PrependFloat32(y)
     builder.PrependFloat32(x)
     return builder.Offset()
+
+import MyGame.Example.Test
+try:
+    from typing import Optional
+except:
+    pass
+
+class Vec3T(object):
+
+    # Vec3T
+    def __init__(self):
+        self.x = 0.0  # type: float
+        self.y = 0.0  # type: float
+        self.z = 0.0  # type: float
+        self.test1 = 0.0  # type: float
+        self.test2 = 0  # type: int
+        self.test3 = None  # type: Optional[MyGame.Example.Test.TestT]
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        vec3 = Vec3()
+        vec3.Init(buf, pos)
+        return cls.InitFromObj(vec3)
+
+    @classmethod
+    def InitFromObj(cls, vec3):
+        x = Vec3T()
+        x._UnPack(vec3)
+        return x
+
+    # Vec3T
+    def _UnPack(self, vec3):
+        if vec3 is None:
+            return
+        self.x = vec3.X()
+        self.y = vec3.Y()
+        self.z = vec3.Z()
+        self.test1 = vec3.Test1()
+        self.test2 = vec3.Test2()
+        if vec3.Test3(MyGame.Example.Test.Test()) is not None:
+            self.test3 = MyGame.Example.Test.TestT.InitFromObj(vec3.Test3(MyGame.Example.Test.Test()))
+
+    # Vec3T
+    def Pack(self, builder):
+        return CreateVec3(builder, self.x, self.y, self.z, self.test1, self.test2, self.test3.a, self.test3.b)
index 44cc906..538b035 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: Example2
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class Monster(object):
     __slots__ = ['_tab']
@@ -24,3 +26,33 @@ class Monster(object):
 
 def MonsterStart(builder): builder.StartObject(0)
 def MonsterEnd(builder): return builder.EndObject()
+
+
+class MonsterT(object):
+
+    # MonsterT
+    def __init__(self):
+        pass
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        monster = Monster()
+        monster.Init(buf, pos)
+        return cls.InitFromObj(monster)
+
+    @classmethod
+    def InitFromObj(cls, monster):
+        x = MonsterT()
+        x._UnPack(monster)
+        return x
+
+    # MonsterT
+    def _UnPack(self, monster):
+        if monster is None:
+            return
+
+    # MonsterT
+    def Pack(self, builder):
+        MonsterStart(builder)
+        monster = MonsterEnd(builder)
+        return monster
index 3bfcca7..e78ea6a 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: MyGame
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class InParentNamespace(object):
     __slots__ = ['_tab']
@@ -24,3 +26,33 @@ class InParentNamespace(object):
 
 def InParentNamespaceStart(builder): builder.StartObject(0)
 def InParentNamespaceEnd(builder): return builder.EndObject()
+
+
+class InParentNamespaceT(object):
+
+    # InParentNamespaceT
+    def __init__(self):
+        pass
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        inParentNamespace = InParentNamespace()
+        inParentNamespace.Init(buf, pos)
+        return cls.InitFromObj(inParentNamespace)
+
+    @classmethod
+    def InitFromObj(cls, inParentNamespace):
+        x = InParentNamespaceT()
+        x._UnPack(inParentNamespace)
+        return x
+
+    # InParentNamespaceT
+    def _UnPack(self, inParentNamespace):
+        if inParentNamespace is None:
+            return
+
+    # InParentNamespaceT
+    def Pack(self, builder):
+        InParentNamespaceStart(builder)
+        inParentNamespace = InParentNamespaceEnd(builder)
+        return inParentNamespace
index 1f7dcb2..29a4e97 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: MyGame
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class MonsterExtra(object):
     __slots__ = ['_tab']
@@ -101,6 +103,11 @@ class MonsterExtra(object):
         return 0
 
     # MonsterExtra
+    def DvecIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+        return o == 0
+
+    # MonsterExtra
     def Fvec(self, j):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
         if o != 0:
@@ -122,6 +129,11 @@ class MonsterExtra(object):
             return self._tab.VectorLen(o)
         return 0
 
+    # MonsterExtra
+    def FvecIsNone(self):
+        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+        return o == 0
+
 def MonsterExtraStart(builder): builder.StartObject(10)
 def MonsterExtraAddD0(builder, d0): builder.PrependFloat64Slot(0, d0, float('nan'))
 def MonsterExtraAddD1(builder, d1): builder.PrependFloat64Slot(1, d1, float('nan'))
@@ -136,3 +148,90 @@ def MonsterExtraStartDvecVector(builder, numElems): return builder.StartVector(8
 def MonsterExtraAddFvec(builder, fvec): builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(fvec), 0)
 def MonsterExtraStartFvecVector(builder, numElems): return builder.StartVector(4, numElems, 4)
 def MonsterExtraEnd(builder): return builder.EndObject()
+
+try:
+    from typing import List
+except:
+    pass
+
+class MonsterExtraT(object):
+
+    # MonsterExtraT
+    def __init__(self):
+        self.d0 = float('nan')  # type: float
+        self.d1 = float('nan')  # type: float
+        self.d2 = float('inf')  # type: float
+        self.d3 = float('-inf')  # type: float
+        self.f0 = float('nan')  # type: float
+        self.f1 = float('nan')  # type: float
+        self.f2 = float('inf')  # type: float
+        self.f3 = float('-inf')  # type: float
+        self.dvec = None  # type: List[float]
+        self.fvec = None  # type: List[float]
+
+    @classmethod
+    def InitFromBuf(cls, buf, pos):
+        monsterExtra = MonsterExtra()
+        monsterExtra.Init(buf, pos)
+        return cls.InitFromObj(monsterExtra)
+
+    @classmethod
+    def InitFromObj(cls, monsterExtra):
+        x = MonsterExtraT()
+        x._UnPack(monsterExtra)
+        return x
+
+    # MonsterExtraT
+    def _UnPack(self, monsterExtra):
+        if monsterExtra is None:
+            return
+        self.d0 = monsterExtra.D0()
+        self.d1 = monsterExtra.D1()
+        self.d2 = monsterExtra.D2()
+        self.d3 = monsterExtra.D3()
+        self.f0 = monsterExtra.F0()
+        self.f1 = monsterExtra.F1()
+        self.f2 = monsterExtra.F2()
+        self.f3 = monsterExtra.F3()
+        if not monsterExtra.DvecIsNone():
+            if np is None:
+                self.dvec = []
+                for i in range(monsterExtra.DvecLength()):
+                    self.dvec.append(monsterExtra.Dvec(i))
+            else:
+                self.dvec = monsterExtra.DvecAsNumpy()
+        if not monsterExtra.FvecIsNone():
+            if np is None:
+                self.fvec = []
+                for i in range(monsterExtra.FvecLength()):
+                    self.fvec.append(monsterExtra.Fvec(i))
+            else:
+                self.fvec = monsterExtra.FvecAsNumpy()
+
+    # MonsterExtraT
+    def Pack(self, builder):
+        if self.dvec is not None:
+            MonsterExtraStartDvecVector(builder, len(self.dvec))
+            for i in reversed(range(len(self.dvec))):
+                builder.PrependFloat64(self.dvec[i])
+            dvec =  builder.EndVector(len(self.dvec))
+        if self.fvec is not None:
+            MonsterExtraStartFvecVector(builder, len(self.fvec))
+            for i in reversed(range(len(self.fvec))):
+                builder.PrependFloat32(self.fvec[i])
+            fvec =  builder.EndVector(len(self.fvec))
+        MonsterExtraStart(builder)
+        MonsterExtraAddD0(builder, self.d0)
+        MonsterExtraAddD1(builder, self.d1)
+        MonsterExtraAddD2(builder, self.d2)
+        MonsterExtraAddD3(builder, self.d3)
+        MonsterExtraAddF0(builder, self.f0)
+        MonsterExtraAddF1(builder, self.f1)
+        MonsterExtraAddF2(builder, self.f2)
+        MonsterExtraAddF3(builder, self.f3)
+        if self.dvec is not None:
+            MonsterExtraAddDvec(builder, dvec)
+        if self.fvec is not None:
+            MonsterExtraAddFvec(builder, fvec)
+        monsterExtra = MonsterExtraEnd(builder)
+        return monsterExtra
index e4dbe8d..17133b0 100755 (executable)
@@ -20,7 +20,7 @@ gen_code_path=${test_dir}
 runtime_library_dir=${test_dir}/../python
 
 # Emit Python code for the example schema in the test dir:
-${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_test.fbs
+${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_test.fbs --gen-object-api
 
 # Syntax: run_tests <interpreter> <benchmark vtable dedupes>
 #                   <benchmark read count> <benchmark build count>
index 29a029c..8f26014 100644 (file)
 set buildtype=Release
 if "%1"=="-b" set buildtype=%2
 
-..\%buildtype%\flatc.exe --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr  --no-fb-import -I include_test monster_test.fbs monsterdata_test.json || goto FAIL
+..\%buildtype%\flatc.exe --cpp --java --csharp --dart --go --binary --lobster --lua --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr  --no-fb-import -I include_test monster_test.fbs monsterdata_test.json || goto FAIL
+..\%buildtype%\flatc.exe --python --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr  --no-fb-import -I include_test monster_test.fbs monsterdata_test.json || goto FAIL
 ..\%buildtype%\flatc.exe --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr  -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs || goto FAIL
 ..\%buildtype%\flatc.exe --cpp --java --csharp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs || goto FAIL
 ..\%buildtype%\flatc.exe --cpp --scoped-enums -o evolution_test ./evolution_test/evolution_v1.fbs ./evolution_test/evolution_v2.fbs|| goto FAIL
 ..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs || goto FAIL
 ..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs || goto FAIL
 ..\%buildtype%\flatc.exe --jsonschema --schema -I include_test monster_test.fbs || goto FAIL
-..\%buildtype%\flatc.exe --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --scoped-enums --jsonschema --cpp-ptr-type flatbuffers::unique_ptr arrays_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe --cpp --java --csharp --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --scoped-enums --jsonschema --cpp-ptr-type flatbuffers::unique_ptr arrays_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe --python --gen-mutable --reflect-names --gen-object-api --gen-compare --scoped-enums --jsonschema --cpp-ptr-type flatbuffers::unique_ptr arrays_test.fbs || goto FAIL
 ..\%buildtype%\flatc.exe --cpp --gen-mutable --gen-object-api --reflect-names --cpp-ptr-type flatbuffers::unique_ptr native_type_test.fbs || goto FAIL
 
 IF NOT "%MONSTER_EXTRA%"=="skip" (
   @echo Generate MosterExtra
-  ..\%buildtype%\flatc.exe --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr monster_extra.fbs monsterdata_extra.json || goto FAIL
+  ..\%buildtype%\flatc.exe --cpp --java --csharp --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr monster_extra.fbs monsterdata_extra.json || goto FAIL
+  ..\%buildtype%\flatc.exe --python --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr monster_extra.fbs monsterdata_extra.json || goto FAIL
+
 ) else (
   @echo monster_extra.fbs skipped (the strtod function from MSVC2013 or older doesn't support NaN/Inf arguments)
 )
index 14b621c..32aff73 100755 (executable)
@@ -15,7 +15,8 @@
 # limitations under the License.
 set -e
 
-../flatc --cpp --java --kotlin  --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr  --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
+../flatc --cpp --java --kotlin  --csharp --dart --go --binary --lobster --lua --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr  --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
+../flatc --python --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr  --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
 ../flatc --cpp --java --kotlin --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr  -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
 ../flatc --cpp --java --kotlin --csharp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
 ../flatc --cpp --scoped-enums -o evolution_test ./evolution_test/evolution_v*.fbs
@@ -23,7 +24,8 @@ set -e
 ../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs
 ../flatc --jsonschema --schema -I include_test monster_test.fbs
 ../flatc --cpp --java --kotlin --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr monster_extra.fbs monsterdata_extra.json
-../flatc --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --scoped-enums --jsonschema --cpp-ptr-type flatbuffers::unique_ptr arrays_test.fbs
+../flatc --cpp --java --csharp --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --scoped-enums --jsonschema --cpp-ptr-type flatbuffers::unique_ptr arrays_test.fbs
+../flatc --python --gen-mutable --reflect-names --gen-object-api --gen-compare --scoped-enums --jsonschema --cpp-ptr-type flatbuffers::unique_ptr arrays_test.fbs
 cd ../samples
 ../flatc --cpp --lobster --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
 ../flatc -b --schema --bfbs-comments --bfbs-builtins monster.fbs
index 59cceaa..db9dcc4 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: NamespaceB
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class StructInNestedNS(object):
     __slots__ = ['_tab']
index d6d1674..020e189 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: NamespaceB
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class TableInNestedNS(object):
     __slots__ = ['_tab']
index 20dac3e..bdcb069 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: NamespaceA
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class SecondTableInA(object):
     __slots__ = ['_tab']
@@ -23,7 +25,7 @@ class SecondTableInA(object):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
         if o != 0:
             x = self._tab.Indirect(o + self._tab.Pos)
-            from .TableInC import TableInC
+            from NamespaceC.TableInC import TableInC
             obj = TableInC()
             obj.Init(self._tab.Bytes, x)
             return obj
index 40cbeba..6c18045 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: NamespaceA
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class TableInFirstNS(object):
     __slots__ = ['_tab']
@@ -23,7 +25,7 @@ class TableInFirstNS(object):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
         if o != 0:
             x = self._tab.Indirect(o + self._tab.Pos)
-            from .TableInNestedNS import TableInNestedNS
+            from NamespaceA.NamespaceB.TableInNestedNS import TableInNestedNS
             obj = TableInNestedNS()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -41,7 +43,7 @@ class TableInFirstNS(object):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
         if o != 0:
             x = o + self._tab.Pos
-            from .StructInNestedNS import StructInNestedNS
+            from NamespaceA.NamespaceB.StructInNestedNS import StructInNestedNS
             obj = StructInNestedNS()
             obj.Init(self._tab.Bytes, x)
             return obj
index 90b8736..7650325 100644 (file)
@@ -3,6 +3,8 @@
 # namespace: NamespaceC
 
 import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
 
 class TableInC(object):
     __slots__ = ['_tab']
@@ -23,7 +25,7 @@ class TableInC(object):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
         if o != 0:
             x = self._tab.Indirect(o + self._tab.Pos)
-            from .TableInFirstNS import TableInFirstNS
+            from NamespaceA.TableInFirstNS import TableInFirstNS
             obj = TableInFirstNS()
             obj.Init(self._tab.Bytes, x)
             return obj
@@ -34,7 +36,7 @@ class TableInC(object):
         o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
         if o != 0:
             x = self._tab.Indirect(o + self._tab.Pos)
-            from .SecondTableInA import SecondTableInA
+            from NamespaceA.SecondTableInA import SecondTableInA
             obj = SecondTableInA()
             obj.Init(self._tab.Bytes, x)
             return obj
index 4550ac7..ee2fb36 100644 (file)
@@ -42,6 +42,7 @@ import MyGame.Example.Test  # refers to generated code
 import MyGame.Example.Stat  # refers to generated code
 import MyGame.Example.Vec3  # refers to generated code
 import MyGame.MonsterExtra  # refers to generated code
+import MyGame.InParentNamespace # refers to generated code
 import MyGame.Example.ArrayTable  # refers to generated code
 import MyGame.Example.ArrayStruct  # refers to generated code
 import MyGame.Example.NestedStruct  # refers to generated code
@@ -83,6 +84,449 @@ class TestWireFormat(unittest.TestCase):
         f.close()
 
 
+class TestObjectBasedAPI(unittest.TestCase):
+    ''' Tests the generated object based API.'''
+
+    def test_consistenty_with_repeated_pack_and_unpack(self):
+        ''' Checks the serialization and deserialization between a buffer and
+        its python object. It tests in the same way as the C++ object API test,
+        ObjectFlatBuffersTest in test.cpp. '''
+
+        buf, off = make_monster_from_generated_code()
+
+        # Turns a buffer into Python object (T class).
+        monster1 = MyGame.Example.Monster.Monster.GetRootAsMonster(buf, off)
+        monsterT1 = MyGame.Example.Monster.MonsterT.InitFromObj(monster1)
+
+        for sizePrefix in [True, False]:
+            # Re-serialize the data into a buffer.
+            b1 = flatbuffers.Builder(0)
+            if sizePrefix:
+                b1.FinishSizePrefixed(monsterT1.Pack(b1))
+            else:
+                b1.Finish(monsterT1.Pack(b1))
+            CheckReadBuffer(b1.Bytes, b1.Head(), sizePrefix)
+
+        # Deserializes the buffer into Python object again.
+        monster2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b1.Bytes,
+                                                                   b1.Head())
+        # Re-serializes the data into a buffer for one more time.
+        monsterT2 = MyGame.Example.Monster.MonsterT.InitFromObj(monster2)
+        for sizePrefix in [True, False]:
+            # Re-serializes the data into a buffer
+            b2 = flatbuffers.Builder(0)
+            if sizePrefix:
+                b2.FinishSizePrefixed(monsterT2.Pack(b2))
+            else:
+                b2.Finish(monsterT2.Pack(b2))
+            CheckReadBuffer(b2.Bytes, b2.Head(), sizePrefix)
+
+    def test_default_values_with_pack_and_unpack(self):
+        ''' Serializes and deserializes between a buffer with default values (no
+        specific values are filled when the buffer is created) and its python
+        object. '''
+        # Creates a flatbuffer with default values.
+        b1 = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStart(b1)
+        gen_mon = MyGame.Example.Monster.MonsterEnd(b1)
+        b1.Finish(gen_mon)
+
+        # Converts the flatbuffer into the object class.
+        monster1 = MyGame.Example.Monster.Monster.GetRootAsMonster(b1.Bytes,
+                                                                   b1.Head())
+        monsterT1 = MyGame.Example.Monster.MonsterT.InitFromObj(monster1)
+
+        # Packs the object class into another flatbuffer.
+        b2 = flatbuffers.Builder(0)
+        b2.Finish(monsterT1.Pack(b2))
+        monster2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b2.Bytes,
+                                                                   b2.Head())
+        # Checks the default values.
+        self.assertTrue(monster2.Pos() is None)
+        self.assertEqual(monster2.Mana(),150)
+        self.assertEqual(monster2.Hp(), 100)
+        self.assertTrue(monster2.Name() is None)
+        self.assertEqual(monster2.Inventory(0), 0)
+        self.assertEqual(monster2.InventoryAsNumpy(), 0)
+        self.assertEqual(monster2.InventoryLength(), 0)
+        self.assertTrue(monster2.InventoryIsNone())
+        self.assertTrue(monster2.Color() is 8)
+        self.assertEqual(monster2.TestType(), 0)
+        self.assertTrue(monster2.Test() is None)
+        self.assertTrue(monster2.Test4(0) is None)
+        self.assertEqual(monster2.Test4Length(), 0)
+        self.assertTrue(monster2.Test4IsNone())
+        self.assertTrue(monster2.Testarrayofstring(0) is "")
+        self.assertEqual(monster2.TestarrayofstringLength(), 0)
+        self.assertTrue(monster2.TestarrayofstringIsNone())
+        self.assertTrue(monster2.Testarrayoftables(0) is None)
+        self.assertEqual(monster2.TestarrayoftablesLength(), 0)
+        self.assertTrue(monster2.TestarrayoftablesIsNone())
+        self.assertTrue(monster2.Enemy() is None)
+        self.assertEqual(monster2.Testnestedflatbuffer(0), 0)
+        self.assertEqual(monster2.TestnestedflatbufferAsNumpy(), 0)
+        self.assertEqual(monster2.TestnestedflatbufferLength(), 0)
+        self.assertTrue(monster2.TestnestedflatbufferIsNone())
+        self.assertTrue(monster2.Testempty() is None)
+        self.assertTrue(monster2.Testbool() is False)
+        self.assertEqual(monster2.Testhashs32Fnv1(), 0)
+        self.assertEqual(monster2.Testhashu32Fnv1(), 0)
+        self.assertEqual(monster2.Testhashs64Fnv1(), 0)
+        self.assertEqual(monster2.Testhashu64Fnv1(), 0)
+        self.assertEqual(monster2.Testhashs32Fnv1a(), 0)
+        self.assertEqual(monster2.Testhashu32Fnv1a(), 0)
+        self.assertEqual(monster2.Testhashs64Fnv1a(), 0)
+        self.assertEqual(monster2.Testhashu64Fnv1a(), 0)
+        self.assertEqual(monster2.Testarrayofbools(0), 0)
+        self.assertEqual(monster2.TestarrayofboolsAsNumpy(), 0)
+        self.assertEqual(monster2.TestarrayofboolsLength(), 0)
+        self.assertTrue(monster2.TestarrayofboolsIsNone())
+        self.assertEqual(monster2.Testf(), 3.14159)
+        self.assertEqual(monster2.Testf2(), 3.0)
+        self.assertEqual(monster2.Testf3(), 0.0)
+        self.assertTrue(monster2.Testarrayofstring2(0) is "")
+        self.assertEqual(monster2.Testarrayofstring2Length(), 0)
+        self.assertTrue(monster2.Testarrayofstring2IsNone())
+        self.assertTrue(monster2.Testarrayofsortedstruct(0) is None)
+        self.assertEqual(monster2.TestarrayofsortedstructLength(), 0)
+        self.assertTrue(monster2.TestarrayofsortedstructIsNone())
+        self.assertEqual(monster2.Flex(0), 0)
+        self.assertEqual(monster2.FlexAsNumpy(), 0)
+        self.assertEqual(monster2.FlexLength(), 0)
+        self.assertTrue(monster2.FlexIsNone())
+        self.assertTrue(monster2.Test5(0) is None)
+        self.assertEqual(monster2.Test5Length(), 0)
+        self.assertTrue(monster2.Test5IsNone())
+        self.assertEqual(monster2.VectorOfLongs(0), 0)
+        self.assertEqual(monster2.VectorOfLongsAsNumpy(), 0)
+        self.assertEqual(monster2.VectorOfLongsLength(), 0)
+        self.assertTrue(monster2.VectorOfLongsIsNone())
+        self.assertEqual(monster2.VectorOfDoubles(0), 0)
+        self.assertEqual(monster2.VectorOfDoublesAsNumpy(), 0)
+        self.assertEqual(monster2.VectorOfDoublesLength(), 0)
+        self.assertTrue(monster2.VectorOfDoublesIsNone())
+        self.assertTrue(monster2.ParentNamespaceTest() is None)
+        self.assertTrue(monster2.VectorOfReferrables(0) is None)
+        self.assertEqual(monster2.VectorOfReferrablesLength(), 0)
+        self.assertTrue(monster2.VectorOfReferrablesIsNone())
+        self.assertEqual(monster2.SingleWeakReference(), 0)
+        self.assertEqual(monster2.VectorOfWeakReferences(0), 0)
+        self.assertEqual(monster2.VectorOfWeakReferencesAsNumpy(), 0)
+        self.assertEqual(monster2.VectorOfWeakReferencesLength(), 0)
+        self.assertTrue(monster2.VectorOfWeakReferencesIsNone())
+        self.assertTrue(monster2.VectorOfStrongReferrables(0) is None)
+        self.assertEqual(monster2.VectorOfStrongReferrablesLength(), 0)
+        self.assertTrue(monster2.VectorOfStrongReferrablesIsNone())
+        self.assertEqual(monster2.CoOwningReference(), 0)
+        self.assertEqual(monster2.VectorOfCoOwningReferences(0), 0)
+        self.assertEqual(monster2.VectorOfCoOwningReferencesAsNumpy(), 0)
+        self.assertEqual(monster2.VectorOfCoOwningReferencesLength(), 0)
+        self.assertTrue(monster2.VectorOfCoOwningReferencesIsNone())
+        self.assertEqual(monster2.NonOwningReference(), 0)
+        self.assertEqual(monster2.VectorOfNonOwningReferences(0), 0)
+        self.assertEqual(monster2.VectorOfNonOwningReferencesAsNumpy(), 0)
+        self.assertEqual(monster2.VectorOfNonOwningReferencesLength(), 0)
+        self.assertTrue(monster2.VectorOfNonOwningReferencesIsNone())
+        self.assertEqual(monster2.AnyUniqueType(), 0)
+        self.assertTrue(monster2.AnyUnique() is None)
+        self.assertEqual(monster2.AnyAmbiguousType(), 0)
+        self.assertTrue(monster2.AnyAmbiguous() is None)
+        self.assertEqual(monster2.VectorOfEnums(0), 0)
+        self.assertEqual(monster2.VectorOfEnumsAsNumpy(), 0)
+        self.assertEqual(monster2.VectorOfEnumsLength(), 0)
+        self.assertTrue(monster2.VectorOfEnumsIsNone())
+
+
+class TestAllMutableCodePathsOfExampleSchema(unittest.TestCase):
+    ''' Tests the object API generated for monster_test.fbs for mutation
+        purposes. In each test, the default values will be changed through the
+        object API. We'll then pack the object class into the buf class and read
+        the updated values out from it to validate if the values are mutated as
+        expected.'''
+
+    def setUp(self, *args, **kwargs):
+        super(TestAllMutableCodePathsOfExampleSchema, self).setUp(*args,
+                                                                  **kwargs)
+        # Creates an empty monster flatbuffer, and loads it into the object
+        # class for future tests.
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        self.monsterT = self._create_and_load_object_class(b)
+
+    def _pack_and_load_buf_class(self, monsterT):
+        ''' Packs the object class into a flatbuffer and loads it into a buf
+        class.'''
+        b = flatbuffers.Builder(0)
+        b.Finish(monsterT.Pack(b))
+        monster = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                                  b.Head())
+        return monster
+
+    def _create_and_load_object_class(self, b):
+        ''' Finishs the creation of a monster flatbuffer and loads it into an
+        object class.'''
+        gen_mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(gen_mon)
+        monster = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                                  b.Head())
+        monsterT = MyGame.Example.Monster.MonsterT()
+        monsterT.InitFromObj(monster)
+        return monsterT
+
+    def test_mutate_pos(self):
+        posT = MyGame.Example.Vec3.Vec3T()
+        posT.x = 4.0
+        posT.y = 5.0
+        posT.z = 6.0
+        posT.test1 = 6.0
+        posT.test2 = 7
+        test3T = MyGame.Example.Test.TestT()
+        test3T.a = 8
+        test3T.b = 9
+        posT.test3 = test3T
+        self.monsterT.pos = posT
+
+        # Packs the updated values.
+        monster = self._pack_and_load_buf_class(self.monsterT)
+
+        # Checks if values are loaded correctly into the object class.
+        pos = monster.Pos()
+
+        # Verifies the properties of the Vec3.
+        self.assertEqual(pos.X(), 4.0)
+        self.assertEqual(pos.Y(), 5.0)
+        self.assertEqual(pos.Z(), 6.0)
+        self.assertEqual(pos.Test1(), 6.0)
+        self.assertEqual(pos.Test2(), 7)
+        t3 = MyGame.Example.Test.Test()
+        t3 = pos.Test3(t3)
+        self.assertEqual(t3.A(), 8)
+        self.assertEqual(t3.B(), 9)
+
+    def test_mutate_mana(self):
+        self.monsterT.mana = 200
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.Mana(), 200)
+
+    def test_mutate_hp(self):
+        self.monsterT.hp = 200
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.Hp(), 200)
+
+    def test_mutate_name(self):
+        self.monsterT.name = "MyMonster"
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.Name(), b"MyMonster")
+
+    def test_mutate_inventory(self):
+        self.monsterT.inventory = [1, 7, 8]
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.Inventory(0), 1)
+        self.assertEqual(monster.Inventory(1), 7)
+        self.assertEqual(monster.Inventory(2), 8)
+
+    def test_empty_inventory(self):
+        self.monsterT.inventory = []
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertFalse(monster.InventoryIsNone())
+
+    def test_mutate_color(self):
+        self.monsterT.color = MyGame.Example.Color.Color.Red
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.Color(), MyGame.Example.Color.Color.Red)
+
+    def test_mutate_testtype(self):
+        self.monsterT.testType = MyGame.Example.Any.Any.Monster
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.TestType(), MyGame.Example.Any.Any.Monster)
+
+    def test_mutate_test(self):
+        testT = MyGame.Example.Monster.MonsterT()
+        testT.hp = 200
+        self.monsterT.test = testT
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        # Initializes a Table from a union field Test(...).
+        table = monster.Test()
+
+        # Initializes a Monster from the Table from the union.
+        test_monster = MyGame.Example.Monster.Monster()
+        test_monster.Init(table.Bytes, table.Pos)
+        self.assertEqual(test_monster.Hp(), 200)
+
+    def test_mutate_test4(self):
+        test0T = MyGame.Example.Test.TestT()
+        test0T.a = 10
+        test0T.b = 20
+        test1T = MyGame.Example.Test.TestT()
+        test1T.a = 30
+        test1T.b = 40
+        self.monsterT.test4 = [test0T, test1T]
+
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        test0 = monster.Test4(0)
+        self.assertEqual(test0.A(), 10)
+        self.assertEqual(test0.B(), 20)
+        test1 = monster.Test4(1)
+        self.assertEqual(test1.A(), 30)
+        self.assertEqual(test1.B(), 40)
+
+    def test_empty_test4(self):
+        self.monsterT.test4 = []
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertFalse(monster.Test4IsNone())
+
+    def test_mutate_testarrayofstring(self):
+        self.monsterT.testarrayofstring = []
+        self.monsterT.testarrayofstring.append("test1")
+        self.monsterT.testarrayofstring.append("test2")
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.Testarrayofstring(0), b"test1")
+        self.assertEqual(monster.Testarrayofstring(1), b"test2")
+
+    def test_empty_testarrayofstring(self):
+        self.monsterT.testarrayofstring = []
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertFalse(monster.TestarrayofstringIsNone())
+
+    def test_mutate_testarrayoftables(self):
+        monsterT0 = MyGame.Example.Monster.MonsterT()
+        monsterT0.hp = 200
+        monsterT1 = MyGame.Example.Monster.MonsterT()
+        monsterT1.hp = 400
+        self.monsterT.testarrayoftables = []
+        self.monsterT.testarrayoftables.append(monsterT0)
+        self.monsterT.testarrayoftables.append(monsterT1)
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.Testarrayoftables(0).Hp(), 200)
+        self.assertEqual(monster.Testarrayoftables(1).Hp(), 400)
+
+    def test_empty_testarrayoftables(self):
+        self.monsterT.testarrayoftables = []
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertFalse(monster.TestarrayoftablesIsNone())
+
+    def test_mutate_enemy(self):
+        monsterT = MyGame.Example.Monster.MonsterT()
+        monsterT.hp = 200
+        self.monsterT.enemy = monsterT
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.Enemy().Hp(), 200)
+
+    def test_mutate_testnestedflatbuffer(self):
+        self.monsterT.testnestedflatbuffer = [8, 2, 4]
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.Testnestedflatbuffer(0), 8)
+        self.assertEqual(monster.Testnestedflatbuffer(1), 2)
+        self.assertEqual(monster.Testnestedflatbuffer(2), 4)
+
+    def test_empty_testnestedflatbuffer(self):
+        self.monsterT.testnestedflatbuffer = []
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertFalse(monster.TestnestedflatbufferIsNone())
+
+    def test_mutate_testbool(self):
+        self.monsterT.testbool = True
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertTrue(monster.Testbool())
+
+    def test_mutate_testhashes(self):
+        self.monsterT.testhashs32Fnv1 = 1
+        self.monsterT.testhashu32Fnv1 = 2
+        self.monsterT.testhashs64Fnv1 = 3
+        self.monsterT.testhashu64Fnv1 = 4
+        self.monsterT.testhashs32Fnv1a = 5
+        self.monsterT.testhashu32Fnv1a = 6
+        self.monsterT.testhashs64Fnv1a = 7
+        self.monsterT.testhashu64Fnv1a = 8
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.Testhashs32Fnv1(), 1)
+        self.assertEqual(monster.Testhashu32Fnv1(), 2)
+        self.assertEqual(monster.Testhashs64Fnv1(), 3)
+        self.assertEqual(monster.Testhashu64Fnv1(), 4)
+        self.assertEqual(monster.Testhashs32Fnv1a(), 5)
+        self.assertEqual(monster.Testhashu32Fnv1a(), 6)
+        self.assertEqual(monster.Testhashs64Fnv1a(), 7)
+        self.assertEqual(monster.Testhashu64Fnv1a(), 8)
+
+    def test_mutate_testarrayofbools(self):
+        self.monsterT.testarrayofbools = []
+        self.monsterT.testarrayofbools.append(True)
+        self.monsterT.testarrayofbools.append(True)
+        self.monsterT.testarrayofbools.append(False)
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.Testarrayofbools(0), True)
+        self.assertEqual(monster.Testarrayofbools(1), True)
+        self.assertEqual(monster.Testarrayofbools(2), False)
+
+    def test_empty_testarrayofbools(self):
+        self.monsterT.testarrayofbools = []
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertFalse(monster.TestarrayofboolsIsNone())
+
+    def test_mutate_testf(self):
+        self.monsterT.testf = 2.0
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.Testf(), 2.0)
+
+    def test_mutate_vectoroflongs(self):
+        self.monsterT.vectorOfLongs = []
+        self.monsterT.vectorOfLongs.append(1)
+        self.monsterT.vectorOfLongs.append(100)
+        self.monsterT.vectorOfLongs.append(10000)
+        self.monsterT.vectorOfLongs.append(1000000)
+        self.monsterT.vectorOfLongs.append(100000000)
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.VectorOfLongs(0), 1)
+        self.assertEqual(monster.VectorOfLongs(1), 100)
+        self.assertEqual(monster.VectorOfLongs(2), 10000)
+        self.assertEqual(monster.VectorOfLongs(3), 1000000)
+        self.assertEqual(monster.VectorOfLongs(4), 100000000)
+
+    def test_empty_vectoroflongs(self):
+        self.monsterT.vectorOfLongs = []
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertFalse(monster.VectorOfLongsIsNone())
+
+    def test_mutate_vectorofdoubles(self):
+        self.monsterT.vectorOfDoubles = []
+        self.monsterT.vectorOfDoubles.append(-1.7976931348623157e+308)
+        self.monsterT.vectorOfDoubles.append(0)
+        self.monsterT.vectorOfDoubles.append(1.7976931348623157e+308)
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.VectorOfDoubles(0), -1.7976931348623157e+308)
+        self.assertEqual(monster.VectorOfDoubles(1), 0)
+        self.assertEqual(monster.VectorOfDoubles(2), 1.7976931348623157e+308)
+
+    def test_empty_vectorofdoubles(self):
+        self.monsterT.vectorOfDoubles = []
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertFalse(monster.VectorOfDoublesIsNone())
+
+    def test_mutate_parentnamespacetest(self):
+        self.monsterT.parentNamespaceTest = MyGame.InParentNamespace.InParentNamespaceT()
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertTrue(isinstance(monster.ParentNamespaceTest(),
+                                   MyGame.InParentNamespace.InParentNamespace))
+
+    def test_mutate_vectorofEnums(self):
+        self.monsterT.vectorOfEnums = []
+        self.monsterT.vectorOfEnums.append(MyGame.Example.Color.Color.Red)
+        self.monsterT.vectorOfEnums.append(MyGame.Example.Color.Color.Blue)
+        self.monsterT.vectorOfEnums.append(MyGame.Example.Color.Color.Red)
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertEqual(monster.VectorOfEnums(0),
+                         MyGame.Example.Color.Color.Red)
+        self.assertEqual(monster.VectorOfEnums(1),
+                         MyGame.Example.Color.Color.Blue)
+        self.assertEqual(monster.VectorOfEnums(2),
+                         MyGame.Example.Color.Color.Red)
+
+    def test_empty_vectorofEnums(self):
+        self.monsterT.vectorOfEnums = []
+        monster = self._pack_and_load_buf_class(self.monsterT)
+        self.assertFalse(monster.VectorOfEnumsIsNone())
+
+
 def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
     ''' CheckReadBuffer checks that the given buffer is evaluated correctly
         as the example Monster. '''
@@ -145,6 +589,7 @@ def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
 
     # iterate through the first monster's inventory:
     asserter(monster.InventoryLength() == 5)
+    asserter(not monster.InventoryIsNone())
 
     invsum = 0
     for i in compat_range(monster.InventoryLength()):
@@ -155,6 +600,7 @@ def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
     for i in range(5):
         asserter(monster.VectorOfLongs(i) == 10 ** (i * 2))
 
+    asserter(not monster.VectorOfDoublesIsNone())
     asserter(([-1.7976931348623157e+308, 0, 1.7976931348623157e+308]
               == [monster.VectorOfDoubles(i)
                   for i in range(monster.VectorOfDoublesLength())]))
@@ -187,6 +633,7 @@ def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
         pass
 
     asserter(monster.Test4Length() == 2)
+    asserter(not monster.Test4IsNone())
 
     # create a 'Test' object and populate it:
     test0 = monster.Test4(0)
@@ -205,11 +652,14 @@ def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
 
     asserter(sumtest12 == 100)
 
+    asserter(not monster.TestarrayofstringIsNone())
     asserter(monster.TestarrayofstringLength() == 2)
     asserter(monster.Testarrayofstring(0) == b"test1")
     asserter(monster.Testarrayofstring(1) == b"test2")
 
+    asserter(monster.TestarrayoftablesIsNone())
     asserter(monster.TestarrayoftablesLength() == 0)
+    asserter(monster.TestnestedflatbufferIsNone())
     asserter(monster.TestnestedflatbufferLength() == 0)
     asserter(monster.Testempty() is None)
 
@@ -1231,6 +1681,19 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
 
     def test_default_monster_inventory_length(self):
         self.assertEqual(0, self.mon.InventoryLength())
+        self.assertTrue(self.mon.InventoryIsNone())
+
+    def test_empty_monster_inventory_vector(self):
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStartInventoryVector(b, 0)
+        inv = b.EndVector(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddInventory(b, inv)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertFalse(mon2.InventoryIsNone())
 
     def test_default_monster_color(self):
         self.assertEqual(MyGame.Example.Color.Color.Blue, self.mon.Color())
@@ -1258,12 +1721,38 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
 
     def test_default_monster_test4_length(self):
         self.assertEqual(0, self.mon.Test4Length())
+        self.assertTrue(self.mon.Test4IsNone())
+
+    def test_empty_monster_test4_vector(self):
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStartTest4Vector(b, 0)
+        test4 = b.EndVector(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTest4(b, test4)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertFalse(mon2.Test4IsNone())
 
     def test_default_monster_testarrayofstring(self):
         self.assertEqual("", self.mon.Testarrayofstring(0))
 
     def test_default_monster_testarrayofstring_length(self):
         self.assertEqual(0, self.mon.TestarrayofstringLength())
+        self.assertTrue(self.mon.TestarrayofstringIsNone())
+
+    def test_empty_monster_testarrayofstring_vector(self):
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStartTestarrayofstringVector(b, 0)
+        testarrayofstring = b.EndVector(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTestarrayofstring(b, testarrayofstring)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertFalse(mon2.TestarrayofstringIsNone())
 
     def test_default_monster_testarrayoftables(self):
         self.assertEqual(None, self.mon.Testarrayoftables(0))
@@ -1291,6 +1780,23 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
         mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Output(), 0)
         self.assertEqual(99, mon2.Testarrayoftables(0).Hp())
         self.assertEqual(1, mon2.TestarrayoftablesLength())
+        self.assertFalse(mon2.TestarrayoftablesIsNone())
+
+    def test_default_monster_testarrayoftables_length(self):
+        self.assertEqual(0, self.mon.TestarrayoftablesLength())
+        self.assertTrue(self.mon.TestarrayoftablesIsNone())
+
+    def test_empty_monster_testarrayoftables_vector(self):
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStartTestarrayoftablesVector(b, 0)
+        testarrayoftables = b.EndVector(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTestarrayoftables(b, testarrayoftables)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertFalse(mon2.TestarrayoftablesIsNone())
 
     def test_default_monster_testarrayoftables_length(self):
         self.assertEqual(0, self.mon.TestarrayoftablesLength())
@@ -1320,6 +1826,19 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
 
     def test_default_monster_testnestedflatbuffer_length(self):
         self.assertEqual(0, self.mon.TestnestedflatbufferLength())
+        self.assertTrue(self.mon.TestnestedflatbufferIsNone())
+
+    def test_empty_monster_testnestedflatbuffer_vector(self):
+        b = flatbuffers.Builder(0)
+        MyGame.Example.Monster.MonsterStartTestnestedflatbufferVector(b, 0)
+        testnestedflatbuffer = b.EndVector(0)
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddTestnestedflatbuffer(b, testnestedflatbuffer)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+        mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                               b.Head())
+        self.assertFalse(mon2.TestnestedflatbufferIsNone())
 
     def test_nondefault_monster_testnestedflatbuffer(self):
         b = flatbuffers.Builder(0)
@@ -1340,6 +1859,7 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
         mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
                                                                b.Head())
         self.assertEqual(3, mon2.TestnestedflatbufferLength())
+        self.assertFalse(mon2.TestnestedflatbufferIsNone())
         self.assertEqual(0, mon2.Testnestedflatbuffer(0))
         self.assertEqual(2, mon2.Testnestedflatbuffer(1))
         self.assertEqual(4, mon2.Testnestedflatbuffer(2))
@@ -1424,6 +1944,24 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
         self.assertEqual(7, mon2.Testhashs64Fnv1a())
         self.assertEqual(8, mon2.Testhashu64Fnv1a())
 
+    def test_default_monster_parent_namespace_test(self):
+        self.assertEqual(None, self.mon.ParentNamespaceTest())
+
+    def test_nondefault_monster_parent_namespace_test(self):
+        b = flatbuffers.Builder(0)
+        MyGame.InParentNamespace.InParentNamespaceStart(b)
+        parent = MyGame.InParentNamespace.InParentNamespaceEnd(b)
+        MyGame.Example.Monster.MonsterStart(b)
+        MyGame.Example.Monster.MonsterAddParentNamespaceTest(b, parent)
+        mon = MyGame.Example.Monster.MonsterEnd(b)
+        b.Finish(mon)
+
+        # Inspect the resulting data.
+        monster = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+                                                                  b.Head())
+        self.assertTrue(isinstance(monster.ParentNamespaceTest(),
+                                   MyGame.InParentNamespace.InParentNamespace))
+
     def test_getrootas_for_nonroot_table(self):
         b = flatbuffers.Builder(0)
         string = b.CreateString("MyStat")