forked from BigfootDev/flatbuffers
[Python] Generate .pyi stub files when --python-typing is on. (#8312)
* [Python] Generate `.pyi` stub files when `--python-typing` is on. To support this change, the following modifications were made: - added a new option to disable `numpy` helpers generation; - added a new flag to control the target Python version: `--python-version` can be one of the following: - `0.x.x` – compatible with any Python version; - `2.x.x` – compatible with Python 2; - `3.x.x` – compatible with Python 3. - added codegen utilities for Python; - added a note that the generated .py file is empty. * [Python] Update Bazel build rules. * [Python] Update Bazel build rules. * [Python] Run buildifier on BUILD.bazel files. --------- Co-authored-by: Derek Bailey <derekbailey@google.com>
This commit is contained in:
@@ -37,6 +37,7 @@ filegroup(
|
|||||||
"pnpm-lock.yaml",
|
"pnpm-lock.yaml",
|
||||||
"typescript.bzl",
|
"typescript.bzl",
|
||||||
"//grpc/src/compiler:distribution",
|
"//grpc/src/compiler:distribution",
|
||||||
|
"//include/codegen:distribution",
|
||||||
"//reflection:distribution",
|
"//reflection:distribution",
|
||||||
"//src:distribution",
|
"//src:distribution",
|
||||||
"//ts:distribution",
|
"//ts:distribution",
|
||||||
|
|||||||
@@ -183,6 +183,8 @@ set(FlatBuffers_Compiler_SRCS
|
|||||||
src/bfbs_gen_lua.h
|
src/bfbs_gen_lua.h
|
||||||
src/bfbs_gen_nim.h
|
src/bfbs_gen_nim.h
|
||||||
src/bfbs_namer.h
|
src/bfbs_namer.h
|
||||||
|
include/codegen/python.h
|
||||||
|
include/codegen/python.cc
|
||||||
include/flatbuffers/code_generators.h
|
include/flatbuffers/code_generators.h
|
||||||
src/binary_annotator.h
|
src/binary_annotator.h
|
||||||
src/binary_annotator.cpp
|
src/binary_annotator.cpp
|
||||||
|
|||||||
6
MODULE.bazel
Normal file
6
MODULE.bazel
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
###############################################################################
|
||||||
|
# Bazel now uses Bzlmod by default to manage external dependencies.
|
||||||
|
# Please consider migrating your external dependencies from WORKSPACE to MODULE.bazel.
|
||||||
|
#
|
||||||
|
# For more details, please check https://github.com/bazelbuild/bazel/issues/18958
|
||||||
|
###############################################################################
|
||||||
1632
MODULE.bazel.lock
generated
Normal file
1632
MODULE.bazel.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
24
include/codegen/BUILD.bazel
Normal file
24
include/codegen/BUILD.bazel
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||||
|
|
||||||
|
package(
|
||||||
|
default_visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "distribution",
|
||||||
|
srcs = [
|
||||||
|
"BUILD.bazel",
|
||||||
|
] + glob([
|
||||||
|
"*.cc",
|
||||||
|
"*.h",
|
||||||
|
]),
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "python",
|
||||||
|
srcs = ["python.cc"],
|
||||||
|
hdrs = ["python.h"],
|
||||||
|
strip_include_prefix = "/include",
|
||||||
|
visibility = ["//src:__subpackages__"],
|
||||||
|
)
|
||||||
63
include/codegen/python.cc
Normal file
63
include/codegen/python.cc
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#include "codegen/python.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace flatbuffers {
|
||||||
|
namespace python {
|
||||||
|
Version::Version(const std::string &version) {
|
||||||
|
std::stringstream ss(version);
|
||||||
|
char dot;
|
||||||
|
ss >> major >> dot >> minor >> dot >> micro;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Version::IsValid() const {
|
||||||
|
return (major == 0 || major == 2 || major == 3) && minor >= 0 && micro >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> Keywords(const Version &version) {
|
||||||
|
switch (version.major) {
|
||||||
|
case 2:
|
||||||
|
// https://docs.python.org/2/reference/lexical_analysis.html#keywords
|
||||||
|
return {
|
||||||
|
"and", "as", "assert", "break", "class", "continue", "def",
|
||||||
|
"del", "elif", "else", "except", "exec", "finally", "for",
|
||||||
|
"from", "global", "if", "import", "in", "is", "lambda",
|
||||||
|
"not", "or", "pass", "print", "raise", "return", "try",
|
||||||
|
"while", "with", "yield",
|
||||||
|
};
|
||||||
|
case 0:
|
||||||
|
case 3:
|
||||||
|
// https://docs.python.org/3/reference/lexical_analysis.html#keywords
|
||||||
|
return {
|
||||||
|
"and", "as", "assert", "async", "await", "break",
|
||||||
|
"class", "continue", "def", "del", "elif", "else",
|
||||||
|
"except", "False", "finally", "for", "from", "global",
|
||||||
|
"if", "import", "in", "is", "lambda", "None",
|
||||||
|
"nonlocal", "not", "or", "pass", "raise", "return",
|
||||||
|
"True", "try", "while", "with", "yield",
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const python::Import &python::Imports::Import(const std::string &module) {
|
||||||
|
python::Import import;
|
||||||
|
import.module = module;
|
||||||
|
imports.push_back(std::move(import));
|
||||||
|
return imports.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
const python::Import &python::Imports::Import(const std::string &module,
|
||||||
|
const std::string &name) {
|
||||||
|
python::Import import;
|
||||||
|
import.module = module;
|
||||||
|
import.name = name;
|
||||||
|
imports.push_back(std::move(import));
|
||||||
|
return imports.back();
|
||||||
|
}
|
||||||
|
} // namespace python
|
||||||
|
} // namespace flatbuffers
|
||||||
45
include/codegen/python.h
Normal file
45
include/codegen/python.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef FLATBUFFERS_INCLUDE_CODEGEN_PYTHON_H_
|
||||||
|
#define FLATBUFFERS_INCLUDE_CODEGEN_PYTHON_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace flatbuffers {
|
||||||
|
namespace python {
|
||||||
|
// `Version` represent a Python version.
|
||||||
|
//
|
||||||
|
// The zero value (i.e. `Version{}`) represents both Python2 and Python3.
|
||||||
|
//
|
||||||
|
// https://docs.python.org/3/faq/general.html#how-does-the-python-version-numbering-scheme-work
|
||||||
|
struct Version {
|
||||||
|
explicit Version(const std::string &version);
|
||||||
|
|
||||||
|
bool IsValid() const;
|
||||||
|
|
||||||
|
int16_t major = 0;
|
||||||
|
int16_t minor = 0;
|
||||||
|
int16_t micro = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::set<std::string> Keywords(const Version &version);
|
||||||
|
|
||||||
|
struct Import {
|
||||||
|
bool IsLocal() const { return module == "."; }
|
||||||
|
|
||||||
|
std::string module;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Imports {
|
||||||
|
const python::Import &Import(const std::string &module);
|
||||||
|
const python::Import &Import(const std::string &module,
|
||||||
|
const std::string &name);
|
||||||
|
|
||||||
|
std::vector<python::Import> imports;
|
||||||
|
};
|
||||||
|
} // namespace python
|
||||||
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
#endif // FLATBUFFERS_INCLUDE_CODEGEN_PYTHON_H_
|
||||||
@@ -706,8 +706,26 @@ struct IDLOptions {
|
|||||||
bool no_leak_private_annotations;
|
bool no_leak_private_annotations;
|
||||||
bool require_json_eof;
|
bool require_json_eof;
|
||||||
bool keep_proto_id;
|
bool keep_proto_id;
|
||||||
|
|
||||||
|
/********************************** Python **********************************/
|
||||||
bool python_no_type_prefix_suffix;
|
bool python_no_type_prefix_suffix;
|
||||||
bool python_typing;
|
bool python_typing;
|
||||||
|
|
||||||
|
// The target Python version. Can be one of the following:
|
||||||
|
// - "0"
|
||||||
|
// - "2"
|
||||||
|
// - "3"
|
||||||
|
// - "2.<minor>"
|
||||||
|
// - "3.<minor>"
|
||||||
|
// - "2.<minor>.<micro>"
|
||||||
|
// - "3.<minor>.<micro>"
|
||||||
|
//
|
||||||
|
// https://docs.python.org/3/faq/general.html#how-does-the-python-version-numbering-scheme-work
|
||||||
|
std::string python_version;
|
||||||
|
|
||||||
|
// Whether to generate numpy helpers.
|
||||||
|
bool python_gen_numpy;
|
||||||
|
|
||||||
bool ts_omit_entrypoint;
|
bool ts_omit_entrypoint;
|
||||||
ProtoIdGapAction proto_id_gap_action;
|
ProtoIdGapAction proto_id_gap_action;
|
||||||
|
|
||||||
@@ -828,6 +846,7 @@ struct IDLOptions {
|
|||||||
keep_proto_id(false),
|
keep_proto_id(false),
|
||||||
python_no_type_prefix_suffix(false),
|
python_no_type_prefix_suffix(false),
|
||||||
python_typing(false),
|
python_typing(false),
|
||||||
|
python_gen_numpy(true),
|
||||||
ts_omit_entrypoint(false),
|
ts_omit_entrypoint(false),
|
||||||
proto_id_gap_action(ProtoIdGapAction::WARNING),
|
proto_id_gap_action(ProtoIdGapAction::WARNING),
|
||||||
mini_reflect(IDLOptions::kNone),
|
mini_reflect(IDLOptions::kNone),
|
||||||
|
|||||||
@@ -155,5 +155,6 @@ cc_library(
|
|||||||
"//grpc/src/compiler:python_generator",
|
"//grpc/src/compiler:python_generator",
|
||||||
"//grpc/src/compiler:swift_generator",
|
"//grpc/src/compiler:swift_generator",
|
||||||
"//grpc/src/compiler:ts_generator",
|
"//grpc/src/compiler:ts_generator",
|
||||||
|
"//include/codegen:python",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "annotated_binary_text_gen.h"
|
#include "annotated_binary_text_gen.h"
|
||||||
#include "binary_annotator.h"
|
#include "binary_annotator.h"
|
||||||
@@ -254,6 +255,8 @@ const static FlatCOption flatc_options[] = {
|
|||||||
{ "", "python-no-type-prefix-suffix", "",
|
{ "", "python-no-type-prefix-suffix", "",
|
||||||
"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-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" },
|
||||||
{ "", "file-names-only", "",
|
{ "", "file-names-only", "",
|
||||||
@@ -671,6 +674,18 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
|
|||||||
opts.python_no_type_prefix_suffix = true;
|
opts.python_no_type_prefix_suffix = true;
|
||||||
} else if (arg == "--python-typing") {
|
} else if (arg == "--python-typing") {
|
||||||
opts.python_typing = true;
|
opts.python_typing = true;
|
||||||
|
} else if (arg.rfind("--python-version=", 0) == 0) {
|
||||||
|
opts.python_version =
|
||||||
|
arg.substr(std::string("--python-version=").size());
|
||||||
|
} else if (arg == "--python-version") {
|
||||||
|
if (++argi >= argc) Error("missing value following: " + arg, true);
|
||||||
|
opts.python_version = argv[argi];
|
||||||
|
} else if (arg == "--python-gen-numpy" ||
|
||||||
|
arg == "--python-gen-numpy=true") {
|
||||||
|
opts.python_gen_numpy = true;
|
||||||
|
} else if (arg == "--no-python-gen-numpy" ||
|
||||||
|
arg == "--python-gen-numpy=false") {
|
||||||
|
opts.python_gen_numpy = false;
|
||||||
} else if (arg == "--ts-omit-entrypoint") {
|
} else if (arg == "--ts-omit-entrypoint") {
|
||||||
opts.ts_omit_entrypoint = true;
|
opts.ts_omit_entrypoint = true;
|
||||||
} else if (arg == "--annotate-sparse-vectors") {
|
} else if (arg == "--annotate-sparse-vectors") {
|
||||||
|
|||||||
@@ -19,13 +19,17 @@
|
|||||||
#include "idl_gen_python.h"
|
#include "idl_gen_python.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "codegen/python.h"
|
||||||
#include "flatbuffers/code_generators.h"
|
#include "flatbuffers/code_generators.h"
|
||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "flatbuffers/idl.h"
|
#include "flatbuffers/idl.h"
|
||||||
@@ -40,15 +44,6 @@ namespace {
|
|||||||
typedef std::pair<std::string, std::string> ImportMapEntry;
|
typedef std::pair<std::string, std::string> ImportMapEntry;
|
||||||
typedef std::set<ImportMapEntry> ImportMap;
|
typedef std::set<ImportMapEntry> ImportMap;
|
||||||
|
|
||||||
static std::set<std::string> PythonKeywords() {
|
|
||||||
return { "False", "None", "True", "and", "as", "assert",
|
|
||||||
"break", "class", "continue", "def", "del", "elif",
|
|
||||||
"else", "except", "finally", "for", "from", "global",
|
|
||||||
"if", "import", "in", "is", "lambda", "nonlocal",
|
|
||||||
"not", "or", "pass", "raise", "return", "try",
|
|
||||||
"while", "with", "yield" };
|
|
||||||
}
|
|
||||||
|
|
||||||
static Namer::Config PythonDefaultConfig() {
|
static Namer::Config PythonDefaultConfig() {
|
||||||
return { /*types=*/Case::kKeep,
|
return { /*types=*/Case::kKeep,
|
||||||
/*constants=*/Case::kScreamingSnake,
|
/*constants=*/Case::kScreamingSnake,
|
||||||
@@ -72,21 +67,594 @@ static Namer::Config PythonDefaultConfig() {
|
|||||||
/*filename_extension=*/".py" };
|
/*filename_extension=*/".py" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Namer::Config kStubConfig = {
|
||||||
|
/*types=*/Case::kKeep,
|
||||||
|
/*constants=*/Case::kScreamingSnake,
|
||||||
|
/*methods=*/Case::kUpperCamel,
|
||||||
|
/*functions=*/Case::kUpperCamel,
|
||||||
|
/*fields=*/Case::kLowerCamel,
|
||||||
|
/*variables=*/Case::kLowerCamel,
|
||||||
|
/*variants=*/Case::kKeep,
|
||||||
|
/*enum_variant_seperator=*/".",
|
||||||
|
/*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase,
|
||||||
|
/*namespaces=*/Case::kKeep, // Packages in python.
|
||||||
|
/*namespace_seperator=*/".",
|
||||||
|
/*object_prefix=*/"",
|
||||||
|
/*object_suffix=*/"T",
|
||||||
|
/*keyword_prefix=*/"",
|
||||||
|
/*keyword_suffix=*/"_",
|
||||||
|
/*filenames=*/Case::kKeep,
|
||||||
|
/*directories=*/Case::kKeep,
|
||||||
|
/*output_path=*/"",
|
||||||
|
/*filename_suffix=*/"",
|
||||||
|
/*filename_extension=*/".pyi",
|
||||||
|
};
|
||||||
|
|
||||||
// Hardcode spaces per indentation.
|
// Hardcode spaces per indentation.
|
||||||
static const CommentConfig def_comment = { nullptr, "#", nullptr };
|
static const CommentConfig def_comment = { nullptr, "#", nullptr };
|
||||||
static const std::string Indent = " ";
|
static const std::string Indent = " ";
|
||||||
|
|
||||||
} // namespace
|
class PythonStubGenerator {
|
||||||
|
public:
|
||||||
|
PythonStubGenerator(const Parser &parser, const std::string &path,
|
||||||
|
const Version &version)
|
||||||
|
: parser_{parser},
|
||||||
|
namer_{WithFlagOptions(kStubConfig, parser.opts, path),
|
||||||
|
Keywords(version)},
|
||||||
|
version_(version) {}
|
||||||
|
|
||||||
|
bool Generate() {
|
||||||
|
if (parser_.opts.one_file) {
|
||||||
|
Imports imports;
|
||||||
|
std::stringstream stub;
|
||||||
|
|
||||||
|
DeclareUOffset(stub, &imports);
|
||||||
|
for (const EnumDef *def : parser_.enums_.vec) {
|
||||||
|
if (def->generated) continue;
|
||||||
|
GenerateEnumStub(stub, def, &imports);
|
||||||
|
}
|
||||||
|
for (const StructDef *def : parser_.structs_.vec) {
|
||||||
|
if (def->generated) continue;
|
||||||
|
GenerateStructStub(stub, def, &imports);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string filename =
|
||||||
|
namer_.config_.output_path +
|
||||||
|
StripPath(StripExtension(parser_.file_being_parsed_)) +
|
||||||
|
namer_.config_.filename_suffix + namer_.config_.filename_extension;
|
||||||
|
|
||||||
|
return SaveFile(filename, imports, stub);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const EnumDef *def : parser_.enums_.vec) {
|
||||||
|
if (def->generated) continue;
|
||||||
|
|
||||||
|
Imports imports;
|
||||||
|
std::stringstream stub;
|
||||||
|
|
||||||
|
DeclareUOffset(stub, &imports);
|
||||||
|
GenerateEnumStub(stub, def, &imports);
|
||||||
|
|
||||||
|
std::string filename = namer_.Directories(*def->defined_namespace) +
|
||||||
|
namer_.File(*def, SkipFile::Suffix);
|
||||||
|
if (!SaveFile(filename, imports, stub)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const StructDef *def : parser_.structs_.vec) {
|
||||||
|
if (def->generated) continue;
|
||||||
|
|
||||||
|
Imports imports;
|
||||||
|
std::stringstream stub;
|
||||||
|
|
||||||
|
DeclareUOffset(stub, &imports);
|
||||||
|
GenerateStructStub(stub, def, &imports);
|
||||||
|
|
||||||
|
std::string filename = namer_.Directories(*def->defined_namespace) +
|
||||||
|
namer_.File(*def, SkipFile::Suffix);
|
||||||
|
if (!SaveFile(filename, imports, stub)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool SaveFile(const std::string &filename, const Imports &imports,
|
||||||
|
const std::stringstream &content) {
|
||||||
|
std::stringstream ss;
|
||||||
|
GenerateImports(ss, imports);
|
||||||
|
ss << '\n';
|
||||||
|
ss << content.str() << '\n';
|
||||||
|
|
||||||
|
EnsureDirExists(StripFileName(filename));
|
||||||
|
return flatbuffers::SaveFile(filename.c_str(), ss.str(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DeclareUOffset(std::stringstream &stub, Imports *imports) {
|
||||||
|
imports->Import("flatbuffers");
|
||||||
|
imports->Import("typing");
|
||||||
|
stub << "uoffset: typing.TypeAlias = "
|
||||||
|
"flatbuffers.number_types.UOffsetTFlags.py_type\n"
|
||||||
|
<< '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ModuleForFile(const std::string &file) const {
|
||||||
|
if (parser_.file_being_parsed_ == file) return ".";
|
||||||
|
|
||||||
|
std::string module = parser_.opts.include_prefix + StripExtension(file) +
|
||||||
|
parser_.opts.filename_suffix;
|
||||||
|
std::replace(module.begin(), module.end(), '/', '.');
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string ModuleFor(const T *def) const {
|
||||||
|
if (parser_.opts.one_file) return ModuleForFile(def->file);
|
||||||
|
return namer_.NamespacedType(*def);
|
||||||
|
}
|
||||||
|
|
||||||
|
const StructDef *GetNestedStruct(const FieldDef *field) const {
|
||||||
|
const Value *nested = field->attributes.Lookup("nested_flatbuffer");
|
||||||
|
if (nested == nullptr) return nullptr;
|
||||||
|
|
||||||
|
StructDef *nested_def = parser_.LookupStruct(nested->constant);
|
||||||
|
if (nested_def != nullptr) return nested_def;
|
||||||
|
|
||||||
|
return parser_.LookupStruct(namer_.NamespacedType(
|
||||||
|
parser_.current_namespace_->components, nested->constant));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ScalarType(BaseType type) {
|
||||||
|
if (IsBool(type)) return "bool";
|
||||||
|
if (IsInteger(type)) return "int";
|
||||||
|
if (IsFloat(type)) return "float";
|
||||||
|
FLATBUFFERS_ASSERT(false);
|
||||||
|
return "None";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
std::string UnionType(const EnumDef &enum_def, Imports *imports,
|
||||||
|
F type) const {
|
||||||
|
imports->Import("typing");
|
||||||
|
|
||||||
|
std::string result = "";
|
||||||
|
for (const EnumVal *val : enum_def.Vals()) {
|
||||||
|
if (!result.empty()) result += ", ";
|
||||||
|
|
||||||
|
switch (val->union_type.base_type) {
|
||||||
|
case BASE_TYPE_STRUCT: {
|
||||||
|
Import import = imports->Import(ModuleFor(val->union_type.struct_def),
|
||||||
|
type(*val->union_type.struct_def));
|
||||||
|
result += import.name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_STRING:
|
||||||
|
result += "str";
|
||||||
|
break;
|
||||||
|
case BASE_TYPE_NONE:
|
||||||
|
result += "None";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "typing.Union[" + result + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UnionObjectType(const EnumDef &enum_def, Imports *imports) const {
|
||||||
|
return UnionType(enum_def, imports, [this](const StructDef &struct_def) {
|
||||||
|
return namer_.ObjectType(struct_def);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UnionType(const EnumDef &enum_def, Imports *imports) const {
|
||||||
|
return UnionType(enum_def, imports, [this](const StructDef &struct_def) {
|
||||||
|
return namer_.Type(struct_def);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string EnumType(const EnumDef &enum_def, Imports *imports) const {
|
||||||
|
imports->Import("typing");
|
||||||
|
const Import &import =
|
||||||
|
imports->Import(ModuleFor(&enum_def), namer_.Type(enum_def));
|
||||||
|
|
||||||
|
std::string result = "";
|
||||||
|
for (const EnumVal *val : enum_def.Vals()) {
|
||||||
|
if (!result.empty()) result += ", ";
|
||||||
|
result += import.name + "." + namer_.Variant(*val);
|
||||||
|
}
|
||||||
|
return "typing.Literal[" + result + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TypeOf(const Type &type, Imports *imports) const {
|
||||||
|
if (type.enum_def != nullptr) return EnumType(*type.enum_def, imports);
|
||||||
|
if (IsScalar(type.base_type)) return ScalarType(type.base_type);
|
||||||
|
|
||||||
|
switch (type.base_type) {
|
||||||
|
case BASE_TYPE_STRUCT: {
|
||||||
|
const Import &import = imports->Import(ModuleFor(type.struct_def),
|
||||||
|
namer_.Type(*type.struct_def));
|
||||||
|
return import.name;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_STRING:
|
||||||
|
return "str";
|
||||||
|
case BASE_TYPE_ARRAY:
|
||||||
|
case BASE_TYPE_VECTOR: {
|
||||||
|
imports->Import("typing");
|
||||||
|
return "typing.List[" + TypeOf(type.VectorType(), imports) + "]";
|
||||||
|
}
|
||||||
|
case BASE_TYPE_UNION:
|
||||||
|
return UnionType(*type.enum_def, imports);
|
||||||
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(0);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GenerateObjectFieldStub(const FieldDef *field,
|
||||||
|
Imports *imports) const {
|
||||||
|
std::string field_name = namer_.Field(*field);
|
||||||
|
|
||||||
|
const Type &field_type = field->value.type;
|
||||||
|
if (IsScalar(field_type.base_type)) {
|
||||||
|
std::string result = field_name + ": " + TypeOf(field_type, imports);
|
||||||
|
if (field->IsOptional()) result += " | None";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (field_type.base_type) {
|
||||||
|
case BASE_TYPE_STRUCT: {
|
||||||
|
Import import =
|
||||||
|
imports->Import(ModuleFor(field_type.struct_def),
|
||||||
|
namer_.ObjectType(*field_type.struct_def));
|
||||||
|
return field_name + ": " + import.name + " | None";
|
||||||
|
}
|
||||||
|
case BASE_TYPE_STRING:
|
||||||
|
return field_name + ": str | None";
|
||||||
|
case BASE_TYPE_ARRAY:
|
||||||
|
case BASE_TYPE_VECTOR: {
|
||||||
|
imports->Import("typing");
|
||||||
|
if (field_type.element == BASE_TYPE_STRUCT) {
|
||||||
|
Import import =
|
||||||
|
imports->Import(ModuleFor(field_type.struct_def),
|
||||||
|
namer_.ObjectType(*field_type.struct_def));
|
||||||
|
return field_name + ": typing.List[" + import.name + "]";
|
||||||
|
}
|
||||||
|
if (field_type.element == BASE_TYPE_STRING) {
|
||||||
|
return field_name + ": typing.List[str]";
|
||||||
|
}
|
||||||
|
return field_name + ": typing.List[" +
|
||||||
|
TypeOf(field_type.VectorType(), imports) + "]";
|
||||||
|
}
|
||||||
|
case BASE_TYPE_UNION:
|
||||||
|
return field_name + ": " +
|
||||||
|
UnionObjectType(*field->value.type.enum_def, imports);
|
||||||
|
default:
|
||||||
|
return field_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateObjectStub(std::stringstream &stub, const StructDef *struct_def,
|
||||||
|
Imports *imports) const {
|
||||||
|
std::string name = namer_.ObjectType(*struct_def);
|
||||||
|
|
||||||
|
stub << "class " << name;
|
||||||
|
if (version_.major != 3) stub << "(object)";
|
||||||
|
stub << ":\n";
|
||||||
|
for (const FieldDef *field : struct_def->fields.vec) {
|
||||||
|
if (field->deprecated) continue;
|
||||||
|
stub << " " << GenerateObjectFieldStub(field, imports) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
stub << " @classmethod\n";
|
||||||
|
stub << " def InitFromBuf(cls, buf: bytes, pos: int) -> " << name
|
||||||
|
<< ": ...\n";
|
||||||
|
|
||||||
|
stub << " @classmethod\n";
|
||||||
|
stub << " def InitFromPackedBuf(cls, buf: bytes, pos: int = 0) -> " << name
|
||||||
|
<< ": ...\n";
|
||||||
|
|
||||||
|
const Import &import =
|
||||||
|
imports->Import(ModuleFor(struct_def), namer_.Type(*struct_def));
|
||||||
|
|
||||||
|
stub << " @classmethod\n";
|
||||||
|
stub << " def InitFromObj(cls, " << namer_.Variable(*struct_def)
|
||||||
|
<< ": " + import.name + ") -> " << name << ": ...\n";
|
||||||
|
|
||||||
|
stub << " def _UnPack(self, " << namer_.Variable(*struct_def) << ": "
|
||||||
|
<< import.name << ") -> None: ...\n";
|
||||||
|
|
||||||
|
stub << " def Pack(self, builder: flatbuffers.Builder) -> None: ...\n";
|
||||||
|
|
||||||
|
if (parser_.opts.gen_compare) {
|
||||||
|
stub << " def __eq__(self, other: " << name + ") -> bool: ...\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateStructStub(std::stringstream &stub, const StructDef *struct_def,
|
||||||
|
Imports *imports) const {
|
||||||
|
std::string type = namer_.Type(*struct_def);
|
||||||
|
|
||||||
|
stub << "class " << type;
|
||||||
|
if (version_.major != 3) stub << "(object)";
|
||||||
|
stub << ":\n";
|
||||||
|
if (struct_def->fixed) {
|
||||||
|
stub << " @classmethod\n";
|
||||||
|
stub << " def SizeOf(cls) -> int: ...\n\n";
|
||||||
|
} else {
|
||||||
|
stub << " @classmethod\n";
|
||||||
|
stub << " def GetRootAs(cls, buf: bytes, offset: int) -> " << type
|
||||||
|
<< ": ...\n";
|
||||||
|
|
||||||
|
if (!parser_.opts.python_no_type_prefix_suffix) {
|
||||||
|
stub << " @classmethod\n";
|
||||||
|
stub << " def GetRootAs" << type
|
||||||
|
<< "(cls, buf: bytes, offset: int) -> " << type << ": ...\n";
|
||||||
|
}
|
||||||
|
if (parser_.file_identifier_.length()) {
|
||||||
|
stub << " @classmethod\n";
|
||||||
|
stub << " def " << type
|
||||||
|
<< "BufferHasIdentifier(cls, buf: bytes, offset: int, "
|
||||||
|
"size_prefixed: bool) -> bool: ...\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stub << " def Init(self, buf: bytes, pos: int) -> None: ...\n";
|
||||||
|
|
||||||
|
for (const FieldDef *field : struct_def->fields.vec) {
|
||||||
|
if (field->deprecated) continue;
|
||||||
|
|
||||||
|
std::string name = namer_.Method(*field);
|
||||||
|
|
||||||
|
const Type &field_type = field->value.type;
|
||||||
|
if (IsScalar(field_type.base_type)) {
|
||||||
|
stub << " def " << name << "(self) -> " << TypeOf(field_type, imports);
|
||||||
|
if (field->IsOptional()) stub << " | None";
|
||||||
|
stub << ": ...\n";
|
||||||
|
} else {
|
||||||
|
switch (field_type.base_type) {
|
||||||
|
case BASE_TYPE_STRUCT: {
|
||||||
|
const Import &import =
|
||||||
|
imports->Import(ModuleFor(field_type.struct_def),
|
||||||
|
namer_.Type(*field_type.struct_def));
|
||||||
|
if (struct_def->fixed) {
|
||||||
|
stub << " def " << name << "(self, obj: " << import.name
|
||||||
|
<< ") -> " << import.name << ": ...\n";
|
||||||
|
} else {
|
||||||
|
stub << " def " << name + "(self) -> " << import.name
|
||||||
|
<< " | None: ...\n";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_STRING:
|
||||||
|
stub << " def " << name << "(self) -> str | None: ...\n";
|
||||||
|
break;
|
||||||
|
case BASE_TYPE_ARRAY:
|
||||||
|
case BASE_TYPE_VECTOR: {
|
||||||
|
switch (field_type.element) {
|
||||||
|
case BASE_TYPE_STRUCT: {
|
||||||
|
const Import &import =
|
||||||
|
imports->Import(ModuleFor(field_type.struct_def),
|
||||||
|
namer_.Type(*field_type.struct_def));
|
||||||
|
stub << " def " << name << "(self, i: int) -> " << import.name
|
||||||
|
<< " | None: ...\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_STRING:
|
||||||
|
stub << " def " << name << "(self, i: int) -> str: ...\n";
|
||||||
|
break;
|
||||||
|
default: // scalars
|
||||||
|
stub << " def " << name << "(self, i: int) -> "
|
||||||
|
<< TypeOf(field_type, imports) << ": ...\n";
|
||||||
|
|
||||||
|
if (parser_.opts.python_gen_numpy) {
|
||||||
|
stub << " def " << name
|
||||||
|
<< "AsNumpy(self) -> np.ndarray: ...\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
const StructDef *nested_def = GetNestedStruct(field);
|
||||||
|
if (nested_def != nullptr) {
|
||||||
|
const Import &import = imports->Import(
|
||||||
|
ModuleFor(nested_def), namer_.Type(*nested_def));
|
||||||
|
|
||||||
|
stub << " def " << name + "NestedRoot(self) -> "
|
||||||
|
<< import.name << " | None: ...\n";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stub << " def " << name << "Length(self) -> int: ...\n";
|
||||||
|
stub << " def " << name << "IsNone(self) -> bool: ...\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_UNION: {
|
||||||
|
imports->Import("flatbuffers", "table");
|
||||||
|
stub << " def " << name << "(self) -> table.Table | None: ...\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parser_.opts.generate_object_based_api) {
|
||||||
|
GenerateObjectStub(stub, struct_def, imports);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (struct_def->fixed) {
|
||||||
|
GenerateStructBuilderStub(stub, struct_def, imports);
|
||||||
|
} else {
|
||||||
|
GenerateTableBuilderStub(stub, struct_def, imports);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StructBuilderArgs(const StructDef &struct_def, const std::string prefix,
|
||||||
|
Imports *imports,
|
||||||
|
std::vector<std::string> *args) const {
|
||||||
|
for (const FieldDef *field : struct_def.fields.vec) {
|
||||||
|
const Type type = IsArray(field->value.type)
|
||||||
|
? field->value.type.VectorType()
|
||||||
|
: field->value.type;
|
||||||
|
if (type.base_type == BASE_TYPE_STRUCT) {
|
||||||
|
StructBuilderArgs(*field->value.type.struct_def,
|
||||||
|
prefix + namer_.Field(*field) + "_", imports, args);
|
||||||
|
} else {
|
||||||
|
args->push_back(prefix + namer_.Field(*field) + ": " +
|
||||||
|
TypeOf(type, imports));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateStructBuilderStub(std::stringstream &stub,
|
||||||
|
const StructDef *struct_def,
|
||||||
|
Imports *imports) const {
|
||||||
|
imports->Import("flatbuffers");
|
||||||
|
|
||||||
|
std::vector<std::string> args;
|
||||||
|
StructBuilderArgs(*struct_def, "", imports, &args);
|
||||||
|
|
||||||
|
stub << '\n';
|
||||||
|
stub << "def Create" + namer_.Type(*struct_def)
|
||||||
|
<< "(builder: flatbuffers.Builder";
|
||||||
|
for (const std::string &arg : args) {
|
||||||
|
stub << ", " << arg;
|
||||||
|
}
|
||||||
|
stub << ") -> uoffset: ...\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateTableBuilderStub(std::stringstream &stub,
|
||||||
|
const StructDef *struct_def,
|
||||||
|
Imports *imports) const {
|
||||||
|
std::string type = namer_.Type(*struct_def);
|
||||||
|
|
||||||
|
/**************************** def TableStart ****************************/
|
||||||
|
stub << "def ";
|
||||||
|
if (!parser_.opts.python_no_type_prefix_suffix) stub << type;
|
||||||
|
stub << "Start(builder: flatbuffers.Builder) -> None: ...\n";
|
||||||
|
if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
|
||||||
|
stub << "def Start(builder: flatbuffers.Builder) -> None: ...\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************** def TableAddField ***************************/
|
||||||
|
for (const FieldDef *field : struct_def->fields.vec) {
|
||||||
|
if (field->deprecated) continue;
|
||||||
|
|
||||||
|
stub << "def ";
|
||||||
|
if (!parser_.opts.python_no_type_prefix_suffix) stub << type;
|
||||||
|
stub << "Add" << namer_.Method(*field)
|
||||||
|
<< "(builder: flatbuffers.Builder, "
|
||||||
|
<< namer_.Variable(*field) + ": ";
|
||||||
|
if (IsScalar(field->value.type.base_type)) {
|
||||||
|
stub << TypeOf(field->value.type, imports);
|
||||||
|
} else if (IsArray(field->value.type)) {
|
||||||
|
stub << TypeOf(field->value.type.VectorType(), imports);
|
||||||
|
} else {
|
||||||
|
stub << "uoffset";
|
||||||
|
}
|
||||||
|
stub << ") -> None: ...\n";
|
||||||
|
|
||||||
|
if (IsVector(field->value.type)) {
|
||||||
|
stub << "def ";
|
||||||
|
if (!parser_.opts.python_no_type_prefix_suffix) stub << type;
|
||||||
|
stub << "Start" << namer_.Method(*field)
|
||||||
|
<< "Vector(builder: flatbuffers.Builder, num_elems: int) -> "
|
||||||
|
"uoffset: ...\n";
|
||||||
|
|
||||||
|
if (!parser_.opts.one_file &&
|
||||||
|
!parser_.opts.python_no_type_prefix_suffix) {
|
||||||
|
stub << "def Start" << namer_.Method(*field)
|
||||||
|
<< "Vector(builder: flatbuffers.Builder, num_elems: int) -> "
|
||||||
|
"uoffset: ...\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetNestedStruct(field) != nullptr) {
|
||||||
|
stub << "def " << type << "Make" << namer_.Method(*field)
|
||||||
|
<< "VectorFromBytes(builder: flatbuffers.Builder, buf: "
|
||||||
|
"bytes) -> uoffset: ...\n";
|
||||||
|
if (!parser_.opts.one_file) {
|
||||||
|
stub << "def Make" << namer_.Method(*field)
|
||||||
|
<< "VectorFromBytes(builder: flatbuffers.Builder, buf: "
|
||||||
|
"bytes) -> uoffset: ...\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************** def TableEnd *****************************/
|
||||||
|
stub << "def ";
|
||||||
|
if (!parser_.opts.python_no_type_prefix_suffix) stub << type;
|
||||||
|
stub << "End(builder: flatbuffers.Builder) -> uoffset: ...\n";
|
||||||
|
if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
|
||||||
|
stub << "def End(builder: flatbuffers.Builder) -> uoffset: ...\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateEnumStub(std::stringstream &stub, const EnumDef *enum_def,
|
||||||
|
Imports *imports) const {
|
||||||
|
stub << "class " << namer_.Type(*enum_def);
|
||||||
|
if (version_.major != 3) stub << "(object)";
|
||||||
|
stub << ":\n";
|
||||||
|
for (const EnumVal *val : enum_def->Vals()) {
|
||||||
|
stub << " " << namer_.Variant(*val) << ": "
|
||||||
|
<< ScalarType(enum_def->underlying_type.base_type) << "\n";
|
||||||
|
}
|
||||||
|
if (parser_.opts.generate_object_based_api & enum_def->is_union) {
|
||||||
|
imports->Import("flatbuffers", "table");
|
||||||
|
stub << "def " << namer_.Function(*enum_def)
|
||||||
|
<< "Creator(union_type: " << EnumType(*enum_def, imports)
|
||||||
|
<< ", table: table.Table) -> " << UnionType(*enum_def, imports)
|
||||||
|
<< ": ...\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateImports(std::stringstream &ss, const Imports &imports) {
|
||||||
|
ss << "from __future__ import annotations\n";
|
||||||
|
ss << '\n';
|
||||||
|
ss << "import flatbuffers\n";
|
||||||
|
if (parser_.opts.python_gen_numpy) {
|
||||||
|
ss << "import numpy as np\n";
|
||||||
|
}
|
||||||
|
ss << '\n';
|
||||||
|
|
||||||
|
std::set<std::string> modules;
|
||||||
|
std::map<std::string, std::set<std::string>> names_by_module;
|
||||||
|
for (const Import &import : imports.imports) {
|
||||||
|
if (import.IsLocal()) continue; // skip all local imports
|
||||||
|
if (import.name == "") {
|
||||||
|
modules.insert(import.module);
|
||||||
|
} else {
|
||||||
|
names_by_module[import.module].insert(import.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const std::string &module : modules) {
|
||||||
|
ss << "import " << module << '\n';
|
||||||
|
}
|
||||||
|
for (const auto &import : names_by_module) {
|
||||||
|
ss << "from " << import.first << " import ";
|
||||||
|
size_t i = 0;
|
||||||
|
for (const std::string &name : import.second) {
|
||||||
|
if (i > 0) ss << ", ";
|
||||||
|
ss << name;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
ss << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Parser &parser_;
|
||||||
|
const IdlNamer namer_;
|
||||||
|
const Version version_;
|
||||||
|
};} // namespace
|
||||||
|
|
||||||
class PythonGenerator : public BaseGenerator {
|
class PythonGenerator : public BaseGenerator {
|
||||||
public:
|
public:
|
||||||
PythonGenerator(const Parser &parser, const std::string &path,
|
PythonGenerator(const Parser &parser, const std::string &path,
|
||||||
const std::string &file_name)
|
const std::string &file_name, const Version &version)
|
||||||
: BaseGenerator(parser, path, file_name, "" /* not used */,
|
: BaseGenerator(parser, path, file_name, "" /* not used */,
|
||||||
"" /* not used */, "py"),
|
"" /* not used */, "py"),
|
||||||
float_const_gen_("float('nan')", "float('inf')", "float('-inf')"),
|
float_const_gen_("float('nan')", "float('inf')", "float('-inf')"),
|
||||||
namer_(WithFlagOptions(PythonDefaultConfig(), parser.opts, path),
|
namer_(WithFlagOptions(PythonDefaultConfig(), parser.opts, path),
|
||||||
PythonKeywords()) {}
|
Keywords(version)) {}
|
||||||
|
|
||||||
// Most field accessors need to retrieve and test the field offset first,
|
// Most field accessors need to retrieve and test the field offset first,
|
||||||
// this is the prefix code for that.
|
// this is the prefix code for that.
|
||||||
@@ -940,7 +1508,9 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
GetMemberOfVectorOfStruct(struct_def, field, code_ptr, imports);
|
GetMemberOfVectorOfStruct(struct_def, field, code_ptr, imports);
|
||||||
} else {
|
} else {
|
||||||
GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
|
GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
|
||||||
GetVectorOfNonStructAsNumpy(struct_def, field, code_ptr);
|
if (parser_.opts.python_gen_numpy) {
|
||||||
|
GetVectorOfNonStructAsNumpy(struct_def, field, code_ptr);
|
||||||
|
}
|
||||||
GetVectorAsNestedFlatbuffer(struct_def, field, code_ptr, imports);
|
GetVectorAsNestedFlatbuffer(struct_def, field, code_ptr, imports);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -951,7 +1521,9 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
GetArrayOfStruct(struct_def, field, code_ptr, imports);
|
GetArrayOfStruct(struct_def, field, code_ptr, imports);
|
||||||
} else {
|
} else {
|
||||||
GetArrayOfNonStruct(struct_def, field, code_ptr);
|
GetArrayOfNonStruct(struct_def, field, code_ptr);
|
||||||
GetVectorOfNonStructAsNumpy(struct_def, field, code_ptr);
|
if (parser_.opts.python_gen_numpy) {
|
||||||
|
GetVectorOfNonStructAsNumpy(struct_def, field, code_ptr);
|
||||||
|
}
|
||||||
GetVectorAsNestedFlatbuffer(struct_def, field, code_ptr, imports);
|
GetVectorAsNestedFlatbuffer(struct_def, field, code_ptr, imports);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1480,13 +2052,17 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
code += GenIndents(3) + "if np is None:";
|
if (parser_.opts.python_gen_numpy) {
|
||||||
GenUnpackforScalarVectorHelper(struct_def, field, code_ptr, 4);
|
code += GenIndents(3) + "if np is None:";
|
||||||
|
GenUnpackforScalarVectorHelper(struct_def, field, code_ptr, 4);
|
||||||
|
|
||||||
// If numpy exists, use the AsNumpy method to optimize the unpack speed.
|
// If numpy exists, use the AsNumpy method to optimize the unpack speed.
|
||||||
code += GenIndents(3) + "else:";
|
code += GenIndents(3) + "else:";
|
||||||
code += GenIndents(4) + "self." + field_field + " = " + struct_var + "." +
|
code += GenIndents(4) + "self." + field_field + " = " + struct_var + "." +
|
||||||
field_method + "AsNumpy()";
|
field_method + "AsNumpy()";
|
||||||
|
} else {
|
||||||
|
GenUnpackforScalarVectorHelper(struct_def, field, code_ptr, 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenUnPackForScalar(const StructDef &struct_def, const FieldDef &field,
|
void GenUnPackForScalar(const StructDef &struct_def, const FieldDef &field,
|
||||||
@@ -1685,14 +2261,20 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
code_prefix += GenIndents(3) + "if np is not None and type(self." +
|
if (parser_.opts.python_gen_numpy) {
|
||||||
field_field + ") is np.ndarray:";
|
code_prefix += GenIndents(3) + "if np is not None and type(self." +
|
||||||
code_prefix += GenIndents(4) + field_field +
|
field_field + ") is np.ndarray:";
|
||||||
" = builder.CreateNumpyVector(self." + field_field + ")";
|
code_prefix += GenIndents(4) + field_field +
|
||||||
code_prefix += GenIndents(3) + "else:";
|
" = builder.CreateNumpyVector(self." + field_field + ")";
|
||||||
GenPackForScalarVectorFieldHelper(struct_def, field, code_prefix_ptr, 4);
|
code_prefix += GenIndents(3) + "else:";
|
||||||
code_prefix += "(self." + field_field + "[i])";
|
GenPackForScalarVectorFieldHelper(struct_def, field, code_prefix_ptr, 4);
|
||||||
code_prefix += GenIndents(4) + field_field + " = builder.EndVector()";
|
code_prefix += "(self." + field_field + "[i])";
|
||||||
|
code_prefix += GenIndents(4) + field_field + " = builder.EndVector()";
|
||||||
|
} else {
|
||||||
|
GenPackForScalarVectorFieldHelper(struct_def, field, code_prefix_ptr, 3);
|
||||||
|
code_prefix += "(self." + field_field + "[i])";
|
||||||
|
code_prefix += GenIndents(4) + field_field + " = builder.EndVector()";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenPackForStructField(const StructDef &struct_def, const FieldDef &field,
|
void GenPackForStructField(const StructDef &struct_def, const FieldDef &field,
|
||||||
@@ -2113,7 +2695,9 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
const std::string local_import = "." + mod;
|
const std::string local_import = "." + mod;
|
||||||
|
|
||||||
code += "import flatbuffers\n";
|
code += "import flatbuffers\n";
|
||||||
code += "from flatbuffers.compat import import_numpy\n";
|
if (parser_.opts.python_gen_numpy) {
|
||||||
|
code += "from flatbuffers.compat import import_numpy\n";
|
||||||
|
}
|
||||||
if (parser_.opts.python_typing) {
|
if (parser_.opts.python_typing) {
|
||||||
code += "from typing import Any\n";
|
code += "from typing import Any\n";
|
||||||
|
|
||||||
@@ -2129,7 +2713,9 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
code += "np = import_numpy()\n\n";
|
if (parser_.opts.python_gen_numpy) {
|
||||||
|
code += "np = import_numpy()\n\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2140,6 +2726,7 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
std::string code = "";
|
std::string code = "";
|
||||||
if (classcode.empty()) {
|
if (classcode.empty()) {
|
||||||
BeginFile(LastNamespacePart(ns), false, &code, "", {});
|
BeginFile(LastNamespacePart(ns), false, &code, "", {});
|
||||||
|
code += "# NOTE " + defname + " does not declare any structs or enums\n";
|
||||||
} else {
|
} else {
|
||||||
BeginFile(LastNamespacePart(ns), needs_imports, &code, mod, imports);
|
BeginFile(LastNamespacePart(ns), needs_imports, &code, mod, imports);
|
||||||
code += classcode;
|
code += classcode;
|
||||||
@@ -2169,8 +2756,17 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
static bool GeneratePython(const Parser &parser, const std::string &path,
|
static bool GeneratePython(const Parser &parser, const std::string &path,
|
||||||
const std::string &file_name) {
|
const std::string &file_name) {
|
||||||
python::PythonGenerator generator(parser, path, file_name);
|
python::Version version{parser.opts.python_version};
|
||||||
return generator.generate();
|
if (!version.IsValid()) return false;
|
||||||
|
|
||||||
|
python::PythonGenerator generator(parser, path, file_name, version);
|
||||||
|
if (!generator.generate()) return false;
|
||||||
|
|
||||||
|
if (parser.opts.python_typing) {
|
||||||
|
python::PythonStubGenerator stub_generator(parser, path, version);
|
||||||
|
if (!stub_generator.Generate()) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
|
|
||||||
# namespace: OtherNameSpace
|
# namespace: OtherNameSpace
|
||||||
|
|
||||||
|
# NOTE FromInclude.py does not declare any structs or enums
|
||||||
|
|||||||
50
tests/MyGame/Example/ArrayStruct.pyi
Normal file
50
tests/MyGame/Example/ArrayStruct.pyi
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import typing
|
||||||
|
from MyGame.Example.ArrayStruct import ArrayStruct
|
||||||
|
from MyGame.Example.NestedStruct import NestedStruct, NestedStructT
|
||||||
|
from MyGame.Example.TestEnum import TestEnum
|
||||||
|
|
||||||
|
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||||
|
|
||||||
|
class ArrayStruct(object):
|
||||||
|
@classmethod
|
||||||
|
def SizeOf(cls) -> int: ...
|
||||||
|
|
||||||
|
def Init(self, buf: bytes, pos: int) -> None: ...
|
||||||
|
def A(self) -> float: ...
|
||||||
|
def B(self, i: int) -> typing.List[int]: ...
|
||||||
|
def BAsNumpy(self) -> np.ndarray: ...
|
||||||
|
def BLength(self) -> int: ...
|
||||||
|
def BIsNone(self) -> bool: ...
|
||||||
|
def C(self) -> int: ...
|
||||||
|
def D(self, i: int) -> NestedStruct | None: ...
|
||||||
|
def DLength(self) -> int: ...
|
||||||
|
def DIsNone(self) -> bool: ...
|
||||||
|
def E(self) -> int: ...
|
||||||
|
def F(self, i: int) -> typing.List[int]: ...
|
||||||
|
def FAsNumpy(self) -> np.ndarray: ...
|
||||||
|
def FLength(self) -> int: ...
|
||||||
|
def FIsNone(self) -> bool: ...
|
||||||
|
class ArrayStructT(object):
|
||||||
|
a: float
|
||||||
|
b: typing.List[int]
|
||||||
|
c: int
|
||||||
|
d: typing.List[NestedStructT]
|
||||||
|
e: int
|
||||||
|
f: typing.List[int]
|
||||||
|
@classmethod
|
||||||
|
def InitFromBuf(cls, buf: bytes, pos: int) -> ArrayStructT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromPackedBuf(cls, buf: bytes, pos: int = 0) -> ArrayStructT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromObj(cls, arrayStruct: ArrayStruct) -> ArrayStructT: ...
|
||||||
|
def _UnPack(self, arrayStruct: ArrayStruct) -> None: ...
|
||||||
|
def Pack(self, builder: flatbuffers.Builder) -> None: ...
|
||||||
|
|
||||||
|
def CreateArrayStruct(builder: flatbuffers.Builder, a: float, b: int, c: int, d_a: int, d_b: typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C], d_c: typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C], d_d: int, e: int, f: int) -> uoffset: ...
|
||||||
|
|
||||||
37
tests/MyGame/Example/ArrayTable.pyi
Normal file
37
tests/MyGame/Example/ArrayTable.pyi
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import typing
|
||||||
|
from MyGame.Example.ArrayStruct import ArrayStruct, ArrayStructT
|
||||||
|
from MyGame.Example.ArrayTable import ArrayTable
|
||||||
|
|
||||||
|
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||||
|
|
||||||
|
class ArrayTable(object):
|
||||||
|
@classmethod
|
||||||
|
def GetRootAs(cls, buf: bytes, offset: int) -> ArrayTable: ...
|
||||||
|
@classmethod
|
||||||
|
def GetRootAsArrayTable(cls, buf: bytes, offset: int) -> ArrayTable: ...
|
||||||
|
@classmethod
|
||||||
|
def ArrayTableBufferHasIdentifier(cls, buf: bytes, offset: int, size_prefixed: bool) -> bool: ...
|
||||||
|
def Init(self, buf: bytes, pos: int) -> None: ...
|
||||||
|
def A(self) -> ArrayStruct | None: ...
|
||||||
|
class ArrayTableT(object):
|
||||||
|
a: ArrayStructT | None
|
||||||
|
@classmethod
|
||||||
|
def InitFromBuf(cls, buf: bytes, pos: int) -> ArrayTableT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromPackedBuf(cls, buf: bytes, pos: int = 0) -> ArrayTableT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromObj(cls, arrayTable: ArrayTable) -> ArrayTableT: ...
|
||||||
|
def _UnPack(self, arrayTable: ArrayTable) -> None: ...
|
||||||
|
def Pack(self, builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def ArrayTableStart(builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def Start(builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def ArrayTableAddA(builder: flatbuffers.Builder, a: uoffset) -> None: ...
|
||||||
|
def ArrayTableEnd(builder: flatbuffers.Builder) -> uoffset: ...
|
||||||
|
def End(builder: flatbuffers.Builder) -> uoffset: ...
|
||||||
|
|
||||||
46
tests/MyGame/Example/NestedStruct.pyi
Normal file
46
tests/MyGame/Example/NestedStruct.pyi
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import typing
|
||||||
|
from MyGame.Example.NestedStruct import NestedStruct
|
||||||
|
from MyGame.Example.TestEnum import TestEnum
|
||||||
|
|
||||||
|
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||||
|
|
||||||
|
class NestedStruct(object):
|
||||||
|
@classmethod
|
||||||
|
def SizeOf(cls) -> int: ...
|
||||||
|
|
||||||
|
def Init(self, buf: bytes, pos: int) -> None: ...
|
||||||
|
def A(self, i: int) -> typing.List[int]: ...
|
||||||
|
def AAsNumpy(self) -> np.ndarray: ...
|
||||||
|
def ALength(self) -> int: ...
|
||||||
|
def AIsNone(self) -> bool: ...
|
||||||
|
def B(self) -> typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C]: ...
|
||||||
|
def C(self, i: int) -> typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C]: ...
|
||||||
|
def CAsNumpy(self) -> np.ndarray: ...
|
||||||
|
def CLength(self) -> int: ...
|
||||||
|
def CIsNone(self) -> bool: ...
|
||||||
|
def D(self, i: int) -> typing.List[int]: ...
|
||||||
|
def DAsNumpy(self) -> np.ndarray: ...
|
||||||
|
def DLength(self) -> int: ...
|
||||||
|
def DIsNone(self) -> bool: ...
|
||||||
|
class NestedStructT(object):
|
||||||
|
a: typing.List[int]
|
||||||
|
b: typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C]
|
||||||
|
c: typing.List[typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C]]
|
||||||
|
d: typing.List[int]
|
||||||
|
@classmethod
|
||||||
|
def InitFromBuf(cls, buf: bytes, pos: int) -> NestedStructT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromPackedBuf(cls, buf: bytes, pos: int = 0) -> NestedStructT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromObj(cls, nestedStruct: NestedStruct) -> NestedStructT: ...
|
||||||
|
def _UnPack(self, nestedStruct: NestedStruct) -> None: ...
|
||||||
|
def Pack(self, builder: flatbuffers.Builder) -> None: ...
|
||||||
|
|
||||||
|
def CreateNestedStruct(builder: flatbuffers.Builder, a: int, b: typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C], c: typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C], d: int) -> uoffset: ...
|
||||||
|
|
||||||
20
tests/MyGame/Example/NestedUnion/Any.pyi
Normal file
20
tests/MyGame/Example/NestedUnion/Any.pyi
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import typing
|
||||||
|
from MyGame.Example.NestedUnion.Any import Any
|
||||||
|
from MyGame.Example.NestedUnion.TestSimpleTableWithEnum import TestSimpleTableWithEnum
|
||||||
|
from MyGame.Example.NestedUnion.Vec3 import Vec3
|
||||||
|
from flatbuffers import table
|
||||||
|
|
||||||
|
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||||
|
|
||||||
|
class Any(object):
|
||||||
|
NONE: int
|
||||||
|
Vec3: int
|
||||||
|
TestSimpleTableWithEnum: int
|
||||||
|
def AnyCreator(union_type: typing.Literal[Any.NONE, Any.Vec3, Any.TestSimpleTableWithEnum], table: table.Table) -> typing.Union[None, Vec3, TestSimpleTableWithEnum]: ...
|
||||||
|
|
||||||
15
tests/MyGame/Example/NestedUnion/Color.pyi
Normal file
15
tests/MyGame/Example/NestedUnion/Color.pyi
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import typing
|
||||||
|
|
||||||
|
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||||
|
|
||||||
|
class Color(object):
|
||||||
|
Red: int
|
||||||
|
Green: int
|
||||||
|
Blue: int
|
||||||
|
|
||||||
47
tests/MyGame/Example/NestedUnion/NestedUnionTest.pyi
Normal file
47
tests/MyGame/Example/NestedUnion/NestedUnionTest.pyi
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import typing
|
||||||
|
from MyGame.Example.NestedUnion.Any import Any
|
||||||
|
from MyGame.Example.NestedUnion.NestedUnionTest import NestedUnionTest
|
||||||
|
from MyGame.Example.NestedUnion.TestSimpleTableWithEnum import TestSimpleTableWithEnumT
|
||||||
|
from MyGame.Example.NestedUnion.Vec3 import Vec3T
|
||||||
|
from flatbuffers import table
|
||||||
|
|
||||||
|
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||||
|
|
||||||
|
class NestedUnionTest(object):
|
||||||
|
@classmethod
|
||||||
|
def GetRootAs(cls, buf: bytes, offset: int) -> NestedUnionTest: ...
|
||||||
|
@classmethod
|
||||||
|
def GetRootAsNestedUnionTest(cls, buf: bytes, offset: int) -> NestedUnionTest: ...
|
||||||
|
def Init(self, buf: bytes, pos: int) -> None: ...
|
||||||
|
def Name(self) -> str | None: ...
|
||||||
|
def DataType(self) -> typing.Literal[Any.NONE, Any.Vec3, Any.TestSimpleTableWithEnum]: ...
|
||||||
|
def Data(self) -> table.Table | None: ...
|
||||||
|
def Id(self) -> int: ...
|
||||||
|
class NestedUnionTestT(object):
|
||||||
|
name: str | None
|
||||||
|
dataType: typing.Literal[Any.NONE, Any.Vec3, Any.TestSimpleTableWithEnum]
|
||||||
|
data: typing.Union[None, Vec3T, TestSimpleTableWithEnumT]
|
||||||
|
id: int
|
||||||
|
@classmethod
|
||||||
|
def InitFromBuf(cls, buf: bytes, pos: int) -> NestedUnionTestT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromPackedBuf(cls, buf: bytes, pos: int = 0) -> NestedUnionTestT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromObj(cls, nestedUnionTest: NestedUnionTest) -> NestedUnionTestT: ...
|
||||||
|
def _UnPack(self, nestedUnionTest: NestedUnionTest) -> None: ...
|
||||||
|
def Pack(self, builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def NestedUnionTestStart(builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def Start(builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def NestedUnionTestAddName(builder: flatbuffers.Builder, name: uoffset) -> None: ...
|
||||||
|
def NestedUnionTestAddDataType(builder: flatbuffers.Builder, dataType: typing.Literal[Any.NONE, Any.Vec3, Any.TestSimpleTableWithEnum]) -> None: ...
|
||||||
|
def NestedUnionTestAddData(builder: flatbuffers.Builder, data: uoffset) -> None: ...
|
||||||
|
def NestedUnionTestAddId(builder: flatbuffers.Builder, id: int) -> None: ...
|
||||||
|
def NestedUnionTestEnd(builder: flatbuffers.Builder) -> uoffset: ...
|
||||||
|
def End(builder: flatbuffers.Builder) -> uoffset: ...
|
||||||
|
|
||||||
32
tests/MyGame/Example/NestedUnion/Test.pyi
Normal file
32
tests/MyGame/Example/NestedUnion/Test.pyi
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import typing
|
||||||
|
from MyGame.Example.NestedUnion.Test import Test
|
||||||
|
|
||||||
|
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||||
|
|
||||||
|
class Test(object):
|
||||||
|
@classmethod
|
||||||
|
def SizeOf(cls) -> int: ...
|
||||||
|
|
||||||
|
def Init(self, buf: bytes, pos: int) -> None: ...
|
||||||
|
def A(self) -> int: ...
|
||||||
|
def B(self) -> int: ...
|
||||||
|
class TestT(object):
|
||||||
|
a: int
|
||||||
|
b: int
|
||||||
|
@classmethod
|
||||||
|
def InitFromBuf(cls, buf: bytes, pos: int) -> TestT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromPackedBuf(cls, buf: bytes, pos: int = 0) -> TestT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromObj(cls, test: Test) -> TestT: ...
|
||||||
|
def _UnPack(self, test: Test) -> None: ...
|
||||||
|
def Pack(self, builder: flatbuffers.Builder) -> None: ...
|
||||||
|
|
||||||
|
def CreateTest(builder: flatbuffers.Builder, a: int, b: int) -> uoffset: ...
|
||||||
|
|
||||||
35
tests/MyGame/Example/NestedUnion/TestSimpleTableWithEnum.pyi
Normal file
35
tests/MyGame/Example/NestedUnion/TestSimpleTableWithEnum.pyi
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import typing
|
||||||
|
from MyGame.Example.NestedUnion.Color import Color
|
||||||
|
from MyGame.Example.NestedUnion.TestSimpleTableWithEnum import TestSimpleTableWithEnum
|
||||||
|
|
||||||
|
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||||
|
|
||||||
|
class TestSimpleTableWithEnum(object):
|
||||||
|
@classmethod
|
||||||
|
def GetRootAs(cls, buf: bytes, offset: int) -> TestSimpleTableWithEnum: ...
|
||||||
|
@classmethod
|
||||||
|
def GetRootAsTestSimpleTableWithEnum(cls, buf: bytes, offset: int) -> TestSimpleTableWithEnum: ...
|
||||||
|
def Init(self, buf: bytes, pos: int) -> None: ...
|
||||||
|
def Color(self) -> typing.Literal[Color.Red, Color.Green, Color.Blue]: ...
|
||||||
|
class TestSimpleTableWithEnumT(object):
|
||||||
|
color: typing.Literal[Color.Red, Color.Green, Color.Blue]
|
||||||
|
@classmethod
|
||||||
|
def InitFromBuf(cls, buf: bytes, pos: int) -> TestSimpleTableWithEnumT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromPackedBuf(cls, buf: bytes, pos: int = 0) -> TestSimpleTableWithEnumT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromObj(cls, testSimpleTableWithEnum: TestSimpleTableWithEnum) -> TestSimpleTableWithEnumT: ...
|
||||||
|
def _UnPack(self, testSimpleTableWithEnum: TestSimpleTableWithEnum) -> None: ...
|
||||||
|
def Pack(self, builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def TestSimpleTableWithEnumStart(builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def Start(builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def TestSimpleTableWithEnumAddColor(builder: flatbuffers.Builder, color: typing.Literal[Color.Red, Color.Green, Color.Blue]) -> None: ...
|
||||||
|
def TestSimpleTableWithEnumEnd(builder: flatbuffers.Builder) -> uoffset: ...
|
||||||
|
def End(builder: flatbuffers.Builder) -> uoffset: ...
|
||||||
|
|
||||||
51
tests/MyGame/Example/NestedUnion/Vec3.pyi
Normal file
51
tests/MyGame/Example/NestedUnion/Vec3.pyi
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import typing
|
||||||
|
from MyGame.Example.NestedUnion.Color import Color
|
||||||
|
from MyGame.Example.NestedUnion.Test import Test, TestT
|
||||||
|
from MyGame.Example.NestedUnion.Vec3 import Vec3
|
||||||
|
|
||||||
|
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||||
|
|
||||||
|
class Vec3(object):
|
||||||
|
@classmethod
|
||||||
|
def GetRootAs(cls, buf: bytes, offset: int) -> Vec3: ...
|
||||||
|
@classmethod
|
||||||
|
def GetRootAsVec3(cls, buf: bytes, offset: int) -> Vec3: ...
|
||||||
|
def Init(self, buf: bytes, pos: int) -> None: ...
|
||||||
|
def X(self) -> float: ...
|
||||||
|
def Y(self) -> float: ...
|
||||||
|
def Z(self) -> float: ...
|
||||||
|
def Test1(self) -> float: ...
|
||||||
|
def Test2(self) -> typing.Literal[Color.Red, Color.Green, Color.Blue]: ...
|
||||||
|
def Test3(self) -> Test | None: ...
|
||||||
|
class Vec3T(object):
|
||||||
|
x: float
|
||||||
|
y: float
|
||||||
|
z: float
|
||||||
|
test1: float
|
||||||
|
test2: typing.Literal[Color.Red, Color.Green, Color.Blue]
|
||||||
|
test3: TestT | None
|
||||||
|
@classmethod
|
||||||
|
def InitFromBuf(cls, buf: bytes, pos: int) -> Vec3T: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromPackedBuf(cls, buf: bytes, pos: int = 0) -> Vec3T: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromObj(cls, vec3: Vec3) -> Vec3T: ...
|
||||||
|
def _UnPack(self, vec3: Vec3) -> None: ...
|
||||||
|
def Pack(self, builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def Vec3Start(builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def Start(builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def Vec3AddX(builder: flatbuffers.Builder, x: float) -> None: ...
|
||||||
|
def Vec3AddY(builder: flatbuffers.Builder, y: float) -> None: ...
|
||||||
|
def Vec3AddZ(builder: flatbuffers.Builder, z: float) -> None: ...
|
||||||
|
def Vec3AddTest1(builder: flatbuffers.Builder, test1: float) -> None: ...
|
||||||
|
def Vec3AddTest2(builder: flatbuffers.Builder, test2: typing.Literal[Color.Red, Color.Green, Color.Blue]) -> None: ...
|
||||||
|
def Vec3AddTest3(builder: flatbuffers.Builder, test3: uoffset) -> None: ...
|
||||||
|
def Vec3End(builder: flatbuffers.Builder) -> uoffset: ...
|
||||||
|
def End(builder: flatbuffers.Builder) -> uoffset: ...
|
||||||
|
|
||||||
15
tests/MyGame/Example/TestEnum.pyi
Normal file
15
tests/MyGame/Example/TestEnum.pyi
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import typing
|
||||||
|
|
||||||
|
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||||
|
|
||||||
|
class TestEnum(object):
|
||||||
|
A: int
|
||||||
|
B: int
|
||||||
|
C: int
|
||||||
|
|
||||||
74
tests/MyGame/MonsterExtra.pyi
Normal file
74
tests/MyGame/MonsterExtra.pyi
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import flatbuffers
|
||||||
|
import typing
|
||||||
|
from MyGame.MonsterExtra import MonsterExtra
|
||||||
|
|
||||||
|
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||||
|
|
||||||
|
class MonsterExtra(object):
|
||||||
|
@classmethod
|
||||||
|
def GetRootAs(cls, buf: bytes, offset: int) -> MonsterExtra: ...
|
||||||
|
@classmethod
|
||||||
|
def GetRootAsMonsterExtra(cls, buf: bytes, offset: int) -> MonsterExtra: ...
|
||||||
|
@classmethod
|
||||||
|
def MonsterExtraBufferHasIdentifier(cls, buf: bytes, offset: int, size_prefixed: bool) -> bool: ...
|
||||||
|
def Init(self, buf: bytes, pos: int) -> None: ...
|
||||||
|
def D0(self) -> float: ...
|
||||||
|
def D1(self) -> float: ...
|
||||||
|
def D2(self) -> float: ...
|
||||||
|
def D3(self) -> float: ...
|
||||||
|
def F0(self) -> float: ...
|
||||||
|
def F1(self) -> float: ...
|
||||||
|
def F2(self) -> float: ...
|
||||||
|
def F3(self) -> float: ...
|
||||||
|
def Dvec(self, i: int) -> typing.List[float]: ...
|
||||||
|
def DvecAsNumpy(self) -> np.ndarray: ...
|
||||||
|
def DvecLength(self) -> int: ...
|
||||||
|
def DvecIsNone(self) -> bool: ...
|
||||||
|
def Fvec(self, i: int) -> typing.List[float]: ...
|
||||||
|
def FvecAsNumpy(self) -> np.ndarray: ...
|
||||||
|
def FvecLength(self) -> int: ...
|
||||||
|
def FvecIsNone(self) -> bool: ...
|
||||||
|
class MonsterExtraT(object):
|
||||||
|
d0: float
|
||||||
|
d1: float
|
||||||
|
d2: float
|
||||||
|
d3: float
|
||||||
|
f0: float
|
||||||
|
f1: float
|
||||||
|
f2: float
|
||||||
|
f3: float
|
||||||
|
dvec: typing.List[float]
|
||||||
|
fvec: typing.List[float]
|
||||||
|
@classmethod
|
||||||
|
def InitFromBuf(cls, buf: bytes, pos: int) -> MonsterExtraT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromPackedBuf(cls, buf: bytes, pos: int = 0) -> MonsterExtraT: ...
|
||||||
|
@classmethod
|
||||||
|
def InitFromObj(cls, monsterExtra: MonsterExtra) -> MonsterExtraT: ...
|
||||||
|
def _UnPack(self, monsterExtra: MonsterExtra) -> None: ...
|
||||||
|
def Pack(self, builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def __eq__(self, other: MonsterExtraT) -> bool: ...
|
||||||
|
def MonsterExtraStart(builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def Start(builder: flatbuffers.Builder) -> None: ...
|
||||||
|
def MonsterExtraAddD0(builder: flatbuffers.Builder, d0: float) -> None: ...
|
||||||
|
def MonsterExtraAddD1(builder: flatbuffers.Builder, d1: float) -> None: ...
|
||||||
|
def MonsterExtraAddD2(builder: flatbuffers.Builder, d2: float) -> None: ...
|
||||||
|
def MonsterExtraAddD3(builder: flatbuffers.Builder, d3: float) -> None: ...
|
||||||
|
def MonsterExtraAddF0(builder: flatbuffers.Builder, f0: float) -> None: ...
|
||||||
|
def MonsterExtraAddF1(builder: flatbuffers.Builder, f1: float) -> None: ...
|
||||||
|
def MonsterExtraAddF2(builder: flatbuffers.Builder, f2: float) -> None: ...
|
||||||
|
def MonsterExtraAddF3(builder: flatbuffers.Builder, f3: float) -> None: ...
|
||||||
|
def MonsterExtraAddDvec(builder: flatbuffers.Builder, dvec: uoffset) -> None: ...
|
||||||
|
def MonsterExtraStartDvecVector(builder: flatbuffers.Builder, num_elems: int) -> uoffset: ...
|
||||||
|
def StartDvecVector(builder: flatbuffers.Builder, num_elems: int) -> uoffset: ...
|
||||||
|
def MonsterExtraAddFvec(builder: flatbuffers.Builder, fvec: uoffset) -> None: ...
|
||||||
|
def MonsterExtraStartFvecVector(builder: flatbuffers.Builder, num_elems: int) -> uoffset: ...
|
||||||
|
def StartFvecVector(builder: flatbuffers.Builder, num_elems: int) -> uoffset: ...
|
||||||
|
def MonsterExtraEnd(builder: flatbuffers.Builder) -> uoffset: ...
|
||||||
|
def End(builder: flatbuffers.Builder) -> uoffset: ...
|
||||||
|
|
||||||
@@ -2,3 +2,4 @@
|
|||||||
|
|
||||||
# namespace: OtherNameSpace
|
# namespace: OtherNameSpace
|
||||||
|
|
||||||
|
# NOTE FromInclude.py does not declare any structs or enums
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
|
|
||||||
# namespace: OtherNameSpace
|
# namespace: OtherNameSpace
|
||||||
|
|
||||||
|
# NOTE TableB.py does not declare any structs or enums
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
|
|
||||||
# namespace: OtherNameSpace
|
# namespace: OtherNameSpace
|
||||||
|
|
||||||
|
# NOTE Unused.py does not declare any structs or enums
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
|
|
||||||
# namespace:
|
# namespace:
|
||||||
|
|
||||||
|
# NOTE TableA.py does not declare any structs or enums
|
||||||
|
|||||||
Reference in New Issue
Block a user