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.
This commit is contained in:
Ethan Furman 2021-01-12 23:47:57 -08:00 committed by GitHub
parent c47c78b878
commit c314e60388
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 207 additions and 110 deletions

View file

@ -1677,6 +1677,13 @@ class TestEnum(unittest.TestCase):
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 TestEnum(unittest.TestCase):
class ThirdFailedStrEnum(StrEnum):
one = '1'
two = b'2', 'ascii', 9
@unittest.skipUnless(
@ -3269,7 +3276,7 @@ class TestStdLib(unittest.TestCase):
('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 @@ class TestStdLib(unittest.TestCase):
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: