Skip to content

Commit

Permalink
Prevent errors
Browse files Browse the repository at this point in the history
caused by defining members with the same name within an enum type.
enthought#525 (comment)
  • Loading branch information
junkmd committed May 16, 2024
1 parent 3657b11 commit 524204c
Showing 1 changed file with 26 additions and 3 deletions.
29 changes: 26 additions & 3 deletions comtypes/tools/codegenerator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Code generator to generate code for everything contained in COM type
# libraries.
from collections import Counter
import keyword
import logging
import os
Expand Down Expand Up @@ -1608,6 +1609,8 @@ def add(self, enum_name: str, member_name: str, value: int) -> None:
>>> assert enums
>>> enums.add('Foo', 'spam', 2)
>>> enums.add('Bar', 'bacon', 3)
>>> enums.add('Bar', 'egg', 4)
>>> enums.add('Bar', 'egg', 5)
>>> assert 'Foo' in enums
>>> assert 'Baz' not in enums
>>> print(enums.to_intflags())
Expand All @@ -1618,6 +1621,8 @@ class Foo(IntFlag):
<BLANKLINE>
class Bar(IntFlag):
bacon = 3
# egg = 4 # duplicated. Perhaps there is a bug in the type library?
egg = 5
>>> print(enums.to_constants())
# values for enumeration 'Foo'
ham = 1
Expand All @@ -1626,6 +1631,8 @@ class Bar(IntFlag):
<BLANKLINE>
# values for enumeration 'Bar'
bacon = 3
egg = 4 # duplicated within the 'Bar'. Perhaps there is a bug?
egg = 5
Bar = c_int # enum
"""
self.data.setdefault(enum_name, []).append((member_name, value))
Expand All @@ -1642,20 +1649,36 @@ def get_symbols(self) -> Set[str]:
def to_constants(self) -> str:
blocks = []
for enum_name, enum_members in self.data.items():
key_counter = Counter(m for m, _ in enum_members)
lines = []
lines.append(f"# values for enumeration '{enum_name}'")
for n, v in enum_members:
lines.append(f"{n} = {v}")
for member_name, value in enum_members:
key_counter[member_name] -= 1
if key_counter[member_name] > 0:
msg = (
f"duplicated within the '{enum_name}'. "
"Perhaps there is a bug?"
)
lines.append(f"{member_name} = {value} # {msg}")
else:
lines.append(f"{member_name} = {value}")
lines.append(f"{enum_name} = c_int # enum")
blocks.append("\n".join(lines))
return "\n\n".join(blocks)

def to_intflags(self) -> str:
blocks = []
for enum_name, enum_members in self.data.items():
key_counter = Counter(m for m, _ in enum_members)
lines = []
lines.append(f"class {enum_name}(IntFlag):")
for member_name, value in enum_members:
lines.append(f" {member_name} = {value}")
key_counter[member_name] -= 1
if key_counter[member_name] > 0:
# Prevent the occurrence of `TypeError: Attempted to reuse key:`.
msg = "duplicated. Perhaps there is a bug in the type library?"
lines.append(f" # {member_name} = {value} # {msg}")
else:
lines.append(f" {member_name} = {value}")
blocks.append("\n".join(lines))
return "\n\n\n".join(blocks)

0 comments on commit 524204c

Please sign in to comment.