diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index c84999a5485..c6aeecb14a4 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -710,6 +710,7 @@ struct IDLOptions { /********************************** Python **********************************/ bool python_no_type_prefix_suffix; bool python_typing; + bool python_decode_obj_api_strings=false; // The target Python version. Can be one of the following: // - "0" diff --git a/scripts/generate_code.py b/scripts/generate_code.py index 7f63db6d0b5..a846be7ce0a 100755 --- a/scripts/generate_code.py +++ b/scripts/generate_code.py @@ -104,7 +104,7 @@ def glob(path, pattern): KOTLIN_OPTS = ["--kotlin"] PHP_OPTS = ["--php"] DART_OPTS = ["--dart"] -PYTHON_OPTS = ["--python", "--python-typing"] +PYTHON_OPTS = ["--python", "--python-typing", "--python-decode-obj-api-string"] BINARY_OPTS = ["-b", "--schema", "--bfbs-comments", "--bfbs-builtins"] PROTO_OPTS = ["--proto"] diff --git a/src/flatc.cpp b/src/flatc.cpp index d06e858a11d..b306b46406c 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -256,6 +256,7 @@ const static FlatCOption flatc_options[] = { "Skip emission of Python functions that are prefixed with typenames" }, { "", "python-typing", "", "Generate Python type annotations" }, { "", "python-version", "", "Generate code for the given Python version." }, + { "", "python-decode-obj-api-strings", "", "Decode bytes to strings for the Python Object API"}, { "", "python-gen-numpy", "", "Whether to generate numpy helpers." }, { "", "ts-omit-entrypoint", "", "Omit emission of namespace entrypoint file" }, @@ -682,6 +683,8 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc, } else if (arg == "--python-version") { if (++argi >= argc) Error("missing value following: " + arg, true); opts.python_version = argv[argi]; + } else if (arg == "--python-decode-obj-api-strings") { + opts.python_decode_obj_api_strings = true; } else if (arg == "--python-gen-numpy" || arg == "--python-gen-numpy=true") { opts.python_gen_numpy = true; diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp index 1c814cd53cf..46715d8ecc5 100644 --- a/src/idl_gen_python.cpp +++ b/src/idl_gen_python.cpp @@ -2028,6 +2028,20 @@ class PythonGenerator : public BaseGenerator { } } + void GenUnPackForString(const StructDef &struct_def, const FieldDef &field, + std::string *code_ptr) const { + auto &code = *code_ptr; + const auto field_field = namer_.Field(field); + const auto field_method = namer_.Method(field); + const auto struct_var = namer_.Variable(struct_def); + + code += GenIndents(2) + "self." + field_field + " = " + struct_var + "." + + field_method + "()"; + code += GenIndents(2) + "if self." + field_field + " is not None:"; + code += GenIndents(3) + "self." + field_field + " = self." + field_field + + ".decode('utf-8')"; + } + void GenUnPackForScalar(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) const { auto &code = *code_ptr; @@ -2070,6 +2084,14 @@ class PythonGenerator : public BaseGenerator { } break; } + case BASE_TYPE_STRING: { + if (parser_.opts.python_decode_obj_api_strings) { + GenUnPackForString(struct_def, field, &code); + } else { + GenUnPackForScalar(struct_def, field, &code); + } + break; + } default: GenUnPackForScalar(struct_def, field, &code); } } diff --git a/tests/MyGame/Example/NestedUnion/NestedUnionTest.py b/tests/MyGame/Example/NestedUnion/NestedUnionTest.py index 7540b6e8ad6..286d1858dbb 100644 --- a/tests/MyGame/Example/NestedUnion/NestedUnionTest.py +++ b/tests/MyGame/Example/NestedUnion/NestedUnionTest.py @@ -132,6 +132,8 @@ def _UnPack(self, nestedUnionTest): if nestedUnionTest is None: return self.name = nestedUnionTest.Name() + if self.name is not None: + self.name = self.name.decode('utf-8') self.dataType = nestedUnionTest.DataType() self.data = MyGame.Example.NestedUnion.Any.AnyCreator(self.dataType, nestedUnionTest.Data()) self.id = nestedUnionTest.Id()