bpo-42901: [Enum] move member creation to `__set_name__` (GH-24196)
`type.__new__` calls `__set_name__` and `__init_subclass__`, which means
that any work metaclasses do after calling `super().__new__()` will not
be available to those two methods. In particular, `Enum` classes that
want to make use of `__init_subclass__` will not see any members.
Almost all customization is therefore moved to before the
`type.__new__()` call, including changing all members to a proto member
descriptor with a `__set_name__` that will do the final conversion of a
member to be an instance of the `Enum` class.
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index 196438a..3ea623e 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -1677,6 +1677,13 @@ def test(self):
class Test(Base):
test = 1
self.assertEqual(Test.test.test, 'dynamic')
+ class Base2(Enum):
+ @enum.property
+ def flash(self):
+ return 'flashy dynamic'
+ class Test(Base2):
+ flash = 1
+ self.assertEqual(Test.flash.flash, 'flashy dynamic')
def test_no_duplicates(self):
class UniqueEnum(Enum):
@@ -2118,7 +2125,7 @@ class ThirdFailedStrEnum(StrEnum):
class ThirdFailedStrEnum(StrEnum):
one = '1'
two = b'2', 'ascii', 9
-
+
@unittest.skipUnless(
@@ -3269,7 +3276,7 @@ def test_inspect_getmembers(self):
('value', Enum.__dict__['value']),
))
result = dict(inspect.getmembers(self.Color))
- self.assertEqual(values.keys(), result.keys())
+ self.assertEqual(set(values.keys()), set(result.keys()))
failed = False
for k in values.keys():
if result[k] != values[k]:
@@ -3306,6 +3313,10 @@ def test_inspect_classify_class_attrs(self):
values.sort(key=lambda item: item.name)
result = list(inspect.classify_class_attrs(self.Color))
result.sort(key=lambda item: item.name)
+ self.assertEqual(
+ len(values), len(result),
+ "%s != %s" % ([a.name for a in values], [a.name for a in result])
+ )
failed = False
for v, r in zip(values, result):
if r != v: