From 62e4da6fadc9999bf896ad9b8b08b227d4e3c4b8 Mon Sep 17 00:00:00 2001 From: fliiiix Date: Tue, 24 Jun 2025 08:26:35 +0200 Subject: [PATCH] [Python] Avoid include own type This prevents the include of the type defined in the pyi, otherwise this leads to error message like this: error: Name XYZ already defined (possibly by an import) [no-redef] --- include/codegen/python.cc | 16 ++++++++++ include/codegen/python.h | 5 +++ src/idl_gen_python.cpp | 31 ++++++++++++++----- tests/MyGame/Example/ArrayStruct.pyi | 1 - tests/MyGame/Example/ArrayTable.pyi | 1 - tests/MyGame/Example/NestedStruct.pyi | 1 - tests/MyGame/Example/NestedUnion/Any.pyi | 1 - .../Example/NestedUnion/NestedUnionTest.pyi | 1 - tests/MyGame/Example/NestedUnion/Test.pyi | 1 - .../NestedUnion/TestSimpleTableWithEnum.pyi | 1 - tests/MyGame/Example/NestedUnion/Vec3.pyi | 1 - tests/MyGame/MonsterExtra.pyi | 1 - 12 files changed, 45 insertions(+), 16 deletions(-) diff --git a/include/codegen/python.cc b/include/codegen/python.cc index cea95889193..ae6c82b94d9 100644 --- a/include/codegen/python.cc +++ b/include/codegen/python.cc @@ -59,5 +59,21 @@ const python::Import &python::Imports::Import(const std::string &module, imports.push_back(std::move(import)); return imports.back(); } + +const python::Import &python::Imports::Export(const std::string &module) { + python::Import import; + import.module = module; + exports.push_back(std::move(import)); + return exports.back(); +} + +const python::Import &python::Imports::Export(const std::string &module, + const std::string &name) { + python::Import import; + import.module = module; + import.name = name; + exports.push_back(std::move(import)); + return exports.back(); +} } // namespace python } // namespace flatbuffers diff --git a/include/codegen/python.h b/include/codegen/python.h index 778eacfc4e5..b79e37cd55b 100644 --- a/include/codegen/python.h +++ b/include/codegen/python.h @@ -85,7 +85,12 @@ struct Imports { const python::Import &Import(const std::string &module, const std::string &name); + const python::Import &Export(const std::string &module); + const python::Import &Export(const std::string &module, + const std::string &name); + std::vector imports; + std::vector exports; }; } // namespace python } // namespace flatbuffers diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp index 2ea1e8c1560..30cfc211da4 100644 --- a/src/idl_gen_python.cpp +++ b/src/idl_gen_python.cpp @@ -290,6 +290,7 @@ class PythonStubGenerator { void GenerateObjectStub(std::stringstream &stub, const StructDef *struct_def, Imports *imports) const { std::string name = namer_.ObjectType(*struct_def); + imports->Export(ModuleFor(struct_def), namer_.Type(*struct_def)); stub << "class " << name; if (version_.major != 3) stub << "(object)"; @@ -327,6 +328,7 @@ class PythonStubGenerator { void GenerateStructStub(std::stringstream &stub, const StructDef *struct_def, Imports *imports) const { std::string type = namer_.Type(*struct_def); + imports->Export(ModuleFor(struct_def), namer_.Type(*struct_def)); stub << "class " << type; if (version_.major != 3) stub << "(object)"; @@ -545,6 +547,7 @@ class PythonStubGenerator { void GenerateEnumStub(std::stringstream &stub, const EnumDef *enum_def, Imports *imports) const { stub << "class " << namer_.Type(*enum_def); + imports->Export(ModuleFor(enum_def), namer_.Type(*enum_def)); if (version_.major == 3){ imports->Import("enum", "IntEnum"); @@ -589,18 +592,32 @@ class PythonStubGenerator { } } + // Remove imports from exports + for (const Import &import : imports.exports) { + if (import.name == "") { + modules.erase(import.module); + } else { + auto search = names_by_module.find(import.module); + if (search != names_by_module.end()) { + search->second.erase(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; + if (!import.second.empty()) { + 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'; } - ss << '\n'; } } diff --git a/tests/MyGame/Example/ArrayStruct.pyi b/tests/MyGame/Example/ArrayStruct.pyi index 29bb83c6762..6c5cbefb2df 100644 --- a/tests/MyGame/Example/ArrayStruct.pyi +++ b/tests/MyGame/Example/ArrayStruct.pyi @@ -5,7 +5,6 @@ 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 diff --git a/tests/MyGame/Example/ArrayTable.pyi b/tests/MyGame/Example/ArrayTable.pyi index 10f2af31951..5d713418d46 100644 --- a/tests/MyGame/Example/ArrayTable.pyi +++ b/tests/MyGame/Example/ArrayTable.pyi @@ -6,7 +6,6 @@ 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 diff --git a/tests/MyGame/Example/NestedStruct.pyi b/tests/MyGame/Example/NestedStruct.pyi index 09e6fc68927..7fe982ce3d3 100644 --- a/tests/MyGame/Example/NestedStruct.pyi +++ b/tests/MyGame/Example/NestedStruct.pyi @@ -5,7 +5,6 @@ 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 diff --git a/tests/MyGame/Example/NestedUnion/Any.pyi b/tests/MyGame/Example/NestedUnion/Any.pyi index dee0f7f2e38..f4809211b19 100644 --- a/tests/MyGame/Example/NestedUnion/Any.pyi +++ b/tests/MyGame/Example/NestedUnion/Any.pyi @@ -5,7 +5,6 @@ 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 diff --git a/tests/MyGame/Example/NestedUnion/NestedUnionTest.pyi b/tests/MyGame/Example/NestedUnion/NestedUnionTest.pyi index 06a906d4024..97a742dd974 100644 --- a/tests/MyGame/Example/NestedUnion/NestedUnionTest.pyi +++ b/tests/MyGame/Example/NestedUnion/NestedUnionTest.pyi @@ -6,7 +6,6 @@ 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 diff --git a/tests/MyGame/Example/NestedUnion/Test.pyi b/tests/MyGame/Example/NestedUnion/Test.pyi index 2fa64aa8202..f1cfa321f3a 100644 --- a/tests/MyGame/Example/NestedUnion/Test.pyi +++ b/tests/MyGame/Example/NestedUnion/Test.pyi @@ -5,7 +5,6 @@ import numpy as np import flatbuffers import typing -from MyGame.Example.NestedUnion.Test import Test uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type diff --git a/tests/MyGame/Example/NestedUnion/TestSimpleTableWithEnum.pyi b/tests/MyGame/Example/NestedUnion/TestSimpleTableWithEnum.pyi index 117b19d532d..4c8b6dff317 100644 --- a/tests/MyGame/Example/NestedUnion/TestSimpleTableWithEnum.pyi +++ b/tests/MyGame/Example/NestedUnion/TestSimpleTableWithEnum.pyi @@ -6,7 +6,6 @@ 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 diff --git a/tests/MyGame/Example/NestedUnion/Vec3.pyi b/tests/MyGame/Example/NestedUnion/Vec3.pyi index c570c20b4c1..9205c5fe304 100644 --- a/tests/MyGame/Example/NestedUnion/Vec3.pyi +++ b/tests/MyGame/Example/NestedUnion/Vec3.pyi @@ -7,7 +7,6 @@ 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 diff --git a/tests/MyGame/MonsterExtra.pyi b/tests/MyGame/MonsterExtra.pyi index 693cc512673..5088cd2765b 100644 --- a/tests/MyGame/MonsterExtra.pyi +++ b/tests/MyGame/MonsterExtra.pyi @@ -5,7 +5,6 @@ import numpy as np import flatbuffers import typing -from MyGame.MonsterExtra import MonsterExtra uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type