diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp index 9e1627592..a6bc0f51e 100644 --- a/src/idl_gen_python.cpp +++ b/src/idl_gen_python.cpp @@ -18,7 +18,9 @@ #include "idl_gen_python.h" +#include #include +#include #include #include #include @@ -56,7 +58,7 @@ static Namer::Config PythonDefaultConfig() { /*variable=*/Case::kLowerCamel, /*variants=*/Case::kKeep, /*enum_variant_seperator=*/".", - /*escape_keywords=*/Namer::Config::Escape::BeforeConvertingCase, + /*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase, /*namespaces=*/Case::kKeep, // Packages in python. /*namespace_seperator=*/".", /*object_prefix=*/"", @@ -424,16 +426,29 @@ class PythonGenerator : public BaseGenerator { code += Indent + Indent + "return None\n\n"; } + template + std::string ModuleFor(const T *def) const { + if (!parser_.opts.one_file) { + return namer_.NamespacedType(*def); + } + + std::string filename = + StripExtension(def->file) + parser_.opts.filename_suffix; + if (parser_.file_being_parsed_ == def->file) { + return "." + StripPath(filename); // make it a "local" import + } + + std::string module = parser_.opts.include_prefix + filename; + std::replace(module.begin(), module.end(), '/', '.'); + return module; + } + // Generate the package reference when importing a struct or enum from its // module. std::string GenPackageReference(const Type &type) const { - if (type.struct_def) { - return namer_.NamespacedType(*type.struct_def); - } else if (type.enum_def) { - return namer_.NamespacedType(*type.enum_def); - } else { - return "." + GenTypeGet(type); - } + if (type.struct_def) return ModuleFor(type.struct_def); + if (type.enum_def) return ModuleFor(type.enum_def); + return "." + GenTypeGet(type); } // Get the value of a vector's struct member. @@ -2021,7 +2036,7 @@ class PythonGenerator : public BaseGenerator { if (!generateStructs(&one_file_code, one_file_imports)) return false; if (parser_.opts.one_file) { - const std::string mod = file_name_ + "_generated"; + const std::string mod = file_name_ + parser_.opts.filename_suffix; // Legacy file format uses keep casing. return SaveType(mod + ".py", *parser_.current_namespace_, one_file_code, @@ -2122,11 +2137,13 @@ class PythonGenerator : public BaseGenerator { bool SaveType(const std::string &defname, const Namespace &ns, const std::string &classcode, const ImportMap &imports, const std::string &mod, bool needs_imports) const { - if (!classcode.length()) return true; - std::string code = ""; - BeginFile(LastNamespacePart(ns), needs_imports, &code, mod, imports); - code += classcode; + if (classcode.empty()) { + BeginFile(LastNamespacePart(ns), false, &code, "", {}); + } else { + BeginFile(LastNamespacePart(ns), needs_imports, &code, mod, imports); + code += classcode; + } const std::string directories = parser_.opts.one_file ? path_ : namer_.Directories(ns.components); diff --git a/tests/FromInclude.py b/tests/FromInclude.py new file mode 100644 index 000000000..047601700 --- /dev/null +++ b/tests/FromInclude.py @@ -0,0 +1,4 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: OtherNameSpace + diff --git a/tests/MyGame/OtherNameSpace/FromInclude.py b/tests/MyGame/OtherNameSpace/FromInclude.py new file mode 100644 index 000000000..047601700 --- /dev/null +++ b/tests/MyGame/OtherNameSpace/FromInclude.py @@ -0,0 +1,4 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: OtherNameSpace + diff --git a/tests/MyGame/OtherNameSpace/TableB.py b/tests/MyGame/OtherNameSpace/TableB.py new file mode 100644 index 000000000..047601700 --- /dev/null +++ b/tests/MyGame/OtherNameSpace/TableB.py @@ -0,0 +1,4 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: OtherNameSpace + diff --git a/tests/MyGame/OtherNameSpace/Unused.py b/tests/MyGame/OtherNameSpace/Unused.py new file mode 100644 index 000000000..047601700 --- /dev/null +++ b/tests/MyGame/OtherNameSpace/Unused.py @@ -0,0 +1,4 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: OtherNameSpace + diff --git a/tests/MyGame/OtherNameSpace/__init__.py b/tests/MyGame/OtherNameSpace/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/PythonTest.sh b/tests/PythonTest.sh index 84e82019d..e7199b877 100755 --- a/tests/PythonTest.sh +++ b/tests/PythonTest.sh @@ -24,9 +24,9 @@ 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 --gen-object-api ${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_test.fbs --gen-object-api --gen-onefile -${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_extra.fbs --gen-object-api -${test_dir}/../flatc -p -o ${gen_code_path} -I include_test arrays_test.fbs --gen-object-api -${test_dir}/../flatc -p -o ${gen_code_path} -I include_test nested_union_test.fbs --gen-object-api +${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_extra.fbs --gen-object-api --python-typing --gen-compare +${test_dir}/../flatc -p -o ${gen_code_path} -I include_test arrays_test.fbs --gen-object-api --python-typing +${test_dir}/../flatc -p -o ${gen_code_path} -I include_test nested_union_test.fbs --gen-object-api --python-typing # Syntax: run_tests # diff --git a/tests/TableA.py b/tests/TableA.py new file mode 100644 index 000000000..ca9b83e34 --- /dev/null +++ b/tests/TableA.py @@ -0,0 +1,4 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: + diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb