diff options
29 files changed, 2846 insertions, 86 deletions
diff --git a/docs/source/Compiler.md b/docs/source/Compiler.md index 7889abdc..9eaabf81 100644 --- a/docs/source/Compiler.md +++ b/docs/source/Compiler.md @@ -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. diff --git a/src/flatc.cpp b/src/flatc.cpp index 257afa85..8cc2d3c9 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -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" diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp index 58d0e0fb..bf3b77e0 100644 --- a/src/idl_gen_python.cpp +++ b/src/idl_gen_python.cpp @@ -16,8 +16,11 @@ // 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. diff --git a/tests/MyGame/Example/Ability.py b/tests/MyGame/Example/Ability.py index 3c4776ef..2cc916bd 100644 --- a/tests/MyGame/Example/Ability.py +++ b/tests/MyGame/Example/Ability.py @@ -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) diff --git a/tests/MyGame/Example/Any.py b/tests/MyGame/Example/Any.py index f1b8d519..b10d35df 100644 --- a/tests/MyGame/Example/Any.py +++ b/tests/MyGame/Example/Any.py @@ -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 diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.py b/tests/MyGame/Example/AnyAmbiguousAliases.py index de6e9d0e..3fb4830f 100644 --- a/tests/MyGame/Example/AnyAmbiguousAliases.py +++ b/tests/MyGame/Example/AnyAmbiguousAliases.py @@ -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 diff --git a/tests/MyGame/Example/AnyUniqueAliases.py b/tests/MyGame/Example/AnyUniqueAliases.py index a6da3551..cf89fc29 100644 --- a/tests/MyGame/Example/AnyUniqueAliases.py +++ b/tests/MyGame/Example/AnyUniqueAliases.py @@ -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 diff --git a/tests/MyGame/Example/ArrayStruct.py b/tests/MyGame/Example/ArrayStruct.py index f36ec545..50f136df 100644 --- a/tests/MyGame/Example/ArrayStruct.py +++ b/tests/MyGame/Example/ArrayStruct.py @@ -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) diff --git a/tests/MyGame/Example/ArrayTable.py b/tests/MyGame/Example/ArrayTable.py index 6d583f92..83905e60 100644 --- a/tests/MyGame/Example/ArrayTable.py +++ b/tests/MyGame/Example/ArrayTable.py @@ -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 diff --git a/tests/MyGame/Example/Monster.py b/tests/MyGame/Example/Monster.py index fe5fb489..1f5565e1 100644 --- a/tests/MyGame/Example/Monster.py +++ b/tests/MyGame/Example/Monster.py @@ -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 diff --git a/tests/MyGame/Example/NestedStruct.py b/tests/MyGame/Example/NestedStruct.py index c0099731..a66cee01 100644 --- a/tests/MyGame/Example/NestedStruct.py +++ b/tests/MyGame/Example/NestedStruct.py @@ -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) diff --git a/tests/MyGame/Example/Referrable.py b/tests/MyGame/Example/Referrable.py index eaec09bb..44bf50f4 100644 --- a/tests/MyGame/Example/Referrable.py +++ b/tests/MyGame/Example/Referrable.py @@ -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 diff --git a/tests/MyGame/Example/Stat.py b/tests/MyGame/Example/Stat.py index 0fbd2a7a..7d3362fa 100644 --- a/tests/MyGame/Example/Stat.py +++ b/tests/MyGame/Example/Stat.py @@ -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 diff --git a/tests/MyGame/Example/Test.py b/tests/MyGame/Example/Test.py index 3b2fd45f..576a656e 100644 --- a/tests/MyGame/Example/Test.py +++ b/tests/MyGame/Example/Test.py @@ -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) diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.py b/tests/MyGame/Example/TestSimpleTableWithEnum.py index cb9c631a..d91947a3 100644 --- a/tests/MyGame/Example/TestSimpleTableWithEnum.py +++ b/tests/MyGame/Example/TestSimpleTableWithEnum.py @@ -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 diff --git a/tests/MyGame/Example/TypeAliases.py b/tests/MyGame/Example/TypeAliases.py index 81e9b064..bec87c5e 100644 --- a/tests/MyGame/Example/TypeAliases.py +++ b/tests/MyGame/Example/TypeAliases.py @@ -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 diff --git a/tests/MyGame/Example/Vec3.py b/tests/MyGame/Example/Vec3.py index 1f32390f..5c91a7d3 100644 --- a/tests/MyGame/Example/Vec3.py +++ b/tests/MyGame/Example/Vec3.py @@ -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) diff --git a/tests/MyGame/Example2/Monster.py b/tests/MyGame/Example2/Monster.py index 44cc9061..538b0354 100644 --- a/tests/MyGame/Example2/Monster.py +++ b/tests/MyGame/Example2/Monster.py @@ -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 diff --git a/tests/MyGame/InParentNamespace.py b/tests/MyGame/InParentNamespace.py index 3bfcca70..e78ea6a1 100644 --- a/tests/MyGame/InParentNamespace.py +++ b/tests/MyGame/InParentNamespace.py @@ -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 diff --git a/tests/MyGame/MonsterExtra.py b/tests/MyGame/MonsterExtra.py index 1f7dcb28..29a4e979 100644 --- a/tests/MyGame/MonsterExtra.py +++ b/tests/MyGame/MonsterExtra.py @@ -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 diff --git a/tests/PythonTest.sh b/tests/PythonTest.sh index e4dbe8da..17133b00 100755 --- a/tests/PythonTest.sh +++ b/tests/PythonTest.sh @@ -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> diff --git a/tests/generate_code.bat b/tests/generate_code.bat index 29a029c6..8f260140 100644 --- a/tests/generate_code.bat +++ b/tests/generate_code.bat @@ -15,19 +15,23 @@ 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) ) diff --git a/tests/generate_code.sh b/tests/generate_code.sh index 14b621cc..32aff736 100755 --- a/tests/generate_code.sh +++ b/tests/generate_code.sh @@ -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 diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py index 59cceaa6..db9dcc41 100644 --- a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py +++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py @@ -3,6 +3,8 @@ # namespace: NamespaceB import flatbuffers +from flatbuffers.compat import import_numpy +np = import_numpy() class StructInNestedNS(object): __slots__ = ['_tab'] diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py index d6d16740..020e1899 100644 --- a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py +++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py @@ -3,6 +3,8 @@ # namespace: NamespaceB import flatbuffers +from flatbuffers.compat import import_numpy +np = import_numpy() class TableInNestedNS(object): __slots__ = ['_tab'] diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.py b/tests/namespace_test/NamespaceA/SecondTableInA.py index 20dac3e2..bdcb0698 100644 --- a/tests/namespace_test/NamespaceA/SecondTableInA.py +++ b/tests/namespace_test/NamespaceA/SecondTableInA.py @@ -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 diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.py b/tests/namespace_test/NamespaceA/TableInFirstNS.py index 40cbeba0..6c180459 100644 --- a/tests/namespace_test/NamespaceA/TableInFirstNS.py +++ b/tests/namespace_test/NamespaceA/TableInFirstNS.py @@ -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 diff --git a/tests/namespace_test/NamespaceC/TableInC.py b/tests/namespace_test/NamespaceC/TableInC.py index 90b8736c..76503253 100644 --- a/tests/namespace_test/NamespaceC/TableInC.py +++ b/tests/namespace_test/NamespaceC/TableInC.py @@ -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 diff --git a/tests/py_test.py b/tests/py_test.py index 4550ac7d..ee2fb36b 100644 --- a/tests/py_test.py +++ b/tests/py_test.py @@ -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") |