Decode bytes to strings in Python Object API (#8551)

This commit is contained in:
Seth Raymond
2025-06-29 04:40:10 -04:00
committed by GitHub
parent 31beb0fb2f
commit 75556437cc
5 changed files with 29 additions and 1 deletions

View File

@@ -710,6 +710,7 @@ struct IDLOptions {
/********************************** Python **********************************/ /********************************** Python **********************************/
bool python_no_type_prefix_suffix; bool python_no_type_prefix_suffix;
bool python_typing; bool python_typing;
bool python_decode_obj_api_strings=false;
// The target Python version. Can be one of the following: // The target Python version. Can be one of the following:
// - "0" // - "0"

View File

@@ -104,7 +104,7 @@ JAVA_OPTS = ["--java"]
KOTLIN_OPTS = ["--kotlin"] KOTLIN_OPTS = ["--kotlin"]
PHP_OPTS = ["--php"] PHP_OPTS = ["--php"]
DART_OPTS = ["--dart"] 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"] BINARY_OPTS = ["-b", "--schema", "--bfbs-comments", "--bfbs-builtins"]
PROTO_OPTS = ["--proto"] PROTO_OPTS = ["--proto"]

View File

@@ -256,6 +256,7 @@ const static FlatCOption flatc_options[] = {
"Skip emission of Python functions that are prefixed with typenames" }, "Skip emission of Python functions that are prefixed with typenames" },
{ "", "python-typing", "", "Generate Python type annotations" }, { "", "python-typing", "", "Generate Python type annotations" },
{ "", "python-version", "", "Generate code for the given Python version." }, { "", "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." }, { "", "python-gen-numpy", "", "Whether to generate numpy helpers." },
{ "", "ts-omit-entrypoint", "", { "", "ts-omit-entrypoint", "",
"Omit emission of namespace entrypoint file" }, "Omit emission of namespace entrypoint file" },
@@ -682,6 +683,8 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
} else if (arg == "--python-version") { } else if (arg == "--python-version") {
if (++argi >= argc) Error("missing value following: " + arg, true); if (++argi >= argc) Error("missing value following: " + arg, true);
opts.python_version = argv[argi]; 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" || } else if (arg == "--python-gen-numpy" ||
arg == "--python-gen-numpy=true") { arg == "--python-gen-numpy=true") {
opts.python_gen_numpy = true; opts.python_gen_numpy = true;

View File

@@ -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, void GenUnPackForScalar(const StructDef &struct_def, const FieldDef &field,
std::string *code_ptr) const { std::string *code_ptr) const {
auto &code = *code_ptr; auto &code = *code_ptr;
@@ -2070,6 +2084,14 @@ class PythonGenerator : public BaseGenerator {
} }
break; 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); default: GenUnPackForScalar(struct_def, field, &code);
} }
} }

View File

@@ -132,6 +132,8 @@ class NestedUnionTestT(object):
if nestedUnionTest is None: if nestedUnionTest is None:
return return
self.name = nestedUnionTest.Name() self.name = nestedUnionTest.Name()
if self.name is not None:
self.name = self.name.decode('utf-8')
self.dataType = nestedUnionTest.DataType() self.dataType = nestedUnionTest.DataType()
self.data = MyGame.Example.NestedUnion.Any.AnyCreator(self.dataType, nestedUnionTest.Data()) self.data = MyGame.Example.NestedUnion.Any.AnyCreator(self.dataType, nestedUnionTest.Data())
self.id = nestedUnionTest.Id() self.id = nestedUnionTest.Id()