mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-02 20:15:34 +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);
|
||||
|
||||
Reference in New Issue
Block a user