Skip to content

Commit

Permalink
[Python] Render enums as Python IntEnum
Browse files Browse the repository at this point in the history
This allows enums to be type check with mypy.
They will still behave like ints ->
> IntEnum is the same as Enum,
> but its members are also integers and can be used anywhere
> that an integer can be used.
> If any integer operation is performed with an IntEnum member,
> the resulting value loses its enumeration status.
https://docs.python.org/3/library/enum.html#enum.IntEnum

Only if the --python-typing flag is set.
  • Loading branch information
fliiiix committed Jun 1, 2024
1 parent 6ede1cc commit 5cb1e2f
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 25 deletions.
10 changes: 8 additions & 2 deletions src/idl_gen_python.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,13 @@ class PythonGenerator : public BaseGenerator {
// Begin enum code with a class declaration.
void BeginEnum(const EnumDef &enum_def, std::string *code_ptr) const {
auto &code = *code_ptr;
code += "class " + namer_.Type(enum_def) + "(object):\n";
if (parser_.opts.python_typing) {
code += "from enum import IntEnum\n";
code += "class " + namer_.Type(enum_def) + "(IntEnum):\n";
}
else {
code += "class " + namer_.Type(enum_def) + "(object):\n";
}
}

// Starts a new line and then indents.
Expand Down Expand Up @@ -2432,7 +2438,7 @@ class PythonGenerator : public BaseGenerator {
auto field_type = namer_.ObjectType(*ev.union_type.struct_def);

code +=
GenIndents(1) + "if unionType == " + union_type + "()." + variant + ":";
GenIndents(1) + "if unionType == " + union_type + "." + variant + ":";
if (parser_.opts.include_dependence_headers) {
auto package_reference = GenPackageReference(ev.union_type);
code += GenIndents(2) + "import " + package_reference;
Expand Down
6 changes: 3 additions & 3 deletions tests/MyGame/Example/Any.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ def AnyCreator(unionType, table):
from flatbuffers.table import Table
if not isinstance(table, Table):
return None
if unionType == Any().Monster:
if unionType == Any.Monster:
import MyGame.Example.Monster
return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
if unionType == Any().TestSimpleTableWithEnum:
if unionType == Any.TestSimpleTableWithEnum:
import MyGame.Example.TestSimpleTableWithEnum
return MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT.InitFromBuf(table.Bytes, table.Pos)
if unionType == Any().MyGame_Example2_Monster:
if unionType == Any.MyGame_Example2_Monster:
import MyGame.Example2.Monster
return MyGame.Example2.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
return None
6 changes: 3 additions & 3 deletions tests/MyGame/Example/AnyAmbiguousAliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ def AnyAmbiguousAliasesCreator(unionType, table):
from flatbuffers.table import Table
if not isinstance(table, Table):
return None
if unionType == AnyAmbiguousAliases().M1:
if unionType == AnyAmbiguousAliases.M1:
import MyGame.Example.Monster
return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
if unionType == AnyAmbiguousAliases().M2:
if unionType == AnyAmbiguousAliases.M2:
import MyGame.Example.Monster
return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
if unionType == AnyAmbiguousAliases().M3:
if unionType == AnyAmbiguousAliases.M3:
import MyGame.Example.Monster
return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
return None
6 changes: 3 additions & 3 deletions tests/MyGame/Example/AnyUniqueAliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ def AnyUniqueAliasesCreator(unionType, table):
from flatbuffers.table import Table
if not isinstance(table, Table):
return None
if unionType == AnyUniqueAliases().M:
if unionType == AnyUniqueAliases.M:
import MyGame.Example.Monster
return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
if unionType == AnyUniqueAliases().TS:
if unionType == AnyUniqueAliases.TS:
import MyGame.Example.TestSimpleTableWithEnum
return MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT.InitFromBuf(table.Bytes, table.Pos)
if unionType == AnyUniqueAliases().M2:
if unionType == AnyUniqueAliases.M2:
import MyGame.Example2.Monster
return MyGame.Example2.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
return None
7 changes: 4 additions & 3 deletions tests/MyGame/Example/NestedUnion/Any.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

# namespace: NestedUnion

class Any(object):
from enum import IntEnum
class Any(IntEnum):
NONE = 0
Vec3 = 1
TestSimpleTableWithEnum = 2
Expand All @@ -11,10 +12,10 @@ def AnyCreator(unionType, table):
from flatbuffers.table import Table
if not isinstance(table, Table):
return None
if unionType == Any().Vec3:
if unionType == Any.Vec3:
import MyGame.Example.NestedUnion.Vec3
return MyGame.Example.NestedUnion.Vec3.Vec3T.InitFromBuf(table.Bytes, table.Pos)
if unionType == Any().TestSimpleTableWithEnum:
if unionType == Any.TestSimpleTableWithEnum:
import MyGame.Example.NestedUnion.TestSimpleTableWithEnum
return MyGame.Example.NestedUnion.TestSimpleTableWithEnum.TestSimpleTableWithEnumT.InitFromBuf(table.Bytes, table.Pos)
return None
3 changes: 2 additions & 1 deletion tests/MyGame/Example/NestedUnion/Color.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
# namespace: NestedUnion

# Composite components of Monster color.
class Color(object):
from enum import IntEnum
class Color(IntEnum):
Red = 1
# \brief color Green
# Green is bit_flag with value (1u << 1)
Expand Down
3 changes: 2 additions & 1 deletion tests/MyGame/Example/TestEnum.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

# namespace: Example

class TestEnum(object):
from enum import IntEnum
class TestEnum(IntEnum):
A = 0
B = 1
C = 2
18 changes: 9 additions & 9 deletions tests/monster_test_generated.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ def AnyCreator(unionType, table):
from flatbuffers.table import Table
if not isinstance(table, Table):
return None
if unionType == Any().Monster:
if unionType == Any.Monster:
return MonsterT.InitFromBuf(table.Bytes, table.Pos)
if unionType == Any().TestSimpleTableWithEnum:
if unionType == Any.TestSimpleTableWithEnum:
return TestSimpleTableWithEnumT.InitFromBuf(table.Bytes, table.Pos)
if unionType == Any().MyGame_Example2_Monster:
if unionType == Any.MyGame_Example2_Monster:
return MonsterT.InitFromBuf(table.Bytes, table.Pos)
return None

Expand All @@ -58,11 +58,11 @@ def AnyUniqueAliasesCreator(unionType, table):
from flatbuffers.table import Table
if not isinstance(table, Table):
return None
if unionType == AnyUniqueAliases().M:
if unionType == AnyUniqueAliases.M:
return MonsterT.InitFromBuf(table.Bytes, table.Pos)
if unionType == AnyUniqueAliases().TS:
if unionType == AnyUniqueAliases.TS:
return TestSimpleTableWithEnumT.InitFromBuf(table.Bytes, table.Pos)
if unionType == AnyUniqueAliases().M2:
if unionType == AnyUniqueAliases.M2:
return MonsterT.InitFromBuf(table.Bytes, table.Pos)
return None

Expand All @@ -77,11 +77,11 @@ def AnyAmbiguousAliasesCreator(unionType, table):
from flatbuffers.table import Table
if not isinstance(table, Table):
return None
if unionType == AnyAmbiguousAliases().M1:
if unionType == AnyAmbiguousAliases.M1:
return MonsterT.InitFromBuf(table.Bytes, table.Pos)
if unionType == AnyAmbiguousAliases().M2:
if unionType == AnyAmbiguousAliases.M2:
return MonsterT.InitFromBuf(table.Bytes, table.Pos)
if unionType == AnyAmbiguousAliases().M3:
if unionType == AnyAmbiguousAliases.M3:
return MonsterT.InitFromBuf(table.Bytes, table.Pos)
return None

Expand Down

0 comments on commit 5cb1e2f

Please sign in to comment.