mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-01 19:58:15 +00:00
[Python] Fix various codegen problems (#8292)
* [Python] Fix various codegen problems. This includes: - escaping keywords happens **after** converting the case: - currently, `table ClassT` generate `class = Class()` which is invalid Python; - imports in `one_file` mode use the filename rather than the type name when resolving module names; - use `filename_suffix` instead of the hardcoded `_generated` one; - generate empty files if no structs or enums are available. This makes the set of output files more predictable for Bazel. * [Python] Fix various codegen problems. This includes: - escaping keywords happens **after** converting the case: - currently, `table ClassT` generate `class = Class()` which is invalid Python; - imports in `one_file` mode use the filename rather than the type name when resolving module names; - use `filename_suffix` instead of the hardcoded `_generated` one; - generate empty files if no structs or enums are available. This makes the set of output files more predictable for Bazel.
This commit is contained in:
@@ -18,7 +18,9 @@
|
||||
|
||||
#include "idl_gen_python.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
@@ -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 <typename T>
|
||||
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);
|
||||
|
||||
4
tests/FromInclude.py
Normal file
4
tests/FromInclude.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace: OtherNameSpace
|
||||
|
||||
4
tests/MyGame/OtherNameSpace/FromInclude.py
Normal file
4
tests/MyGame/OtherNameSpace/FromInclude.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace: OtherNameSpace
|
||||
|
||||
4
tests/MyGame/OtherNameSpace/TableB.py
Normal file
4
tests/MyGame/OtherNameSpace/TableB.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace: OtherNameSpace
|
||||
|
||||
4
tests/MyGame/OtherNameSpace/Unused.py
Normal file
4
tests/MyGame/OtherNameSpace/Unused.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace: OtherNameSpace
|
||||
|
||||
0
tests/MyGame/OtherNameSpace/__init__.py
Normal file
0
tests/MyGame/OtherNameSpace/__init__.py
Normal file
@@ -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 <interpreter> <benchmark vtable dedupes>
|
||||
# <benchmark read count> <benchmark build count>
|
||||
|
||||
4
tests/TableA.py
Normal file
4
tests/TableA.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace:
|
||||
|
||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
Reference in New Issue
Block a user