Skip to content

Commit dbe252e

Browse files
ethanfurmanadorilson
authored andcommitted
pythongh-115821: [Enum] better error message for calling super().__new__() (pythonGH-116063)
docs now state to not call super().__new__ if super().__new__ is called, a better error message is now used
1 parent 69c759e commit dbe252e

File tree

4 files changed

+22
-1
lines changed

4 files changed

+22
-1
lines changed

Doc/library/enum.rst

+3
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,9 @@ Data Types
400400

401401
results in the call ``int('1a', 16)`` and a value of ``17`` for the member.
402402

403+
..note:: When writing a custom ``__new__``, do not use ``super().__new__`` --
404+
call the appropriate ``__new__`` instead.
405+
403406
.. method:: Enum.__repr__(self)
404407

405408
Returns the string used for *repr()* calls. By default, returns the

Lib/enum.py

+5
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,10 @@ def __new__(metacls, cls, bases, classdict, *, boundary=None, _simple=False, **k
547547
classdict['_inverted_'] = None
548548
try:
549549
exc = None
550+
classdict['_%s__in_progress' % cls] = True
550551
enum_class = super().__new__(metacls, cls, bases, classdict, **kwds)
552+
classdict['_%s__in_progress' % cls] = False
553+
delattr(enum_class, '_%s__in_progress' % cls)
551554
except Exception as e:
552555
# since 3.12 the line "Error calling __set_name__ on '_proto_member' instance ..."
553556
# is tacked on to the error instead of raising a RuntimeError
@@ -1155,6 +1158,8 @@ def __new__(cls, value):
11551158
# still not found -- verify that members exist, in-case somebody got here mistakenly
11561159
# (such as via super when trying to override __new__)
11571160
if not cls._member_map_:
1161+
if getattr(cls, '_%s__in_progress' % cls.__name__, False):
1162+
raise TypeError('do not use `super().__new__; call the appropriate __new__ directly') from None
11581163
raise TypeError("%r has no members defined" % cls)
11591164
#
11601165
# still not found -- try _missing_ hook

Lib/test/test_enum.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ def spam(cls):
447447
def test_bad_new_super(self):
448448
with self.assertRaisesRegex(
449449
TypeError,
450-
'has no members defined',
450+
'do not use .super...__new__;',
451451
):
452452
class BadSuper(self.enum_type):
453453
def __new__(cls, value):
@@ -3409,6 +3409,17 @@ def __new__(cls, int_value, *value_aliases):
34093409
self.assertIs(Types(2), Types.NetList)
34103410
self.assertIs(Types('nl'), Types.NetList)
34113411

3412+
def test_no_members(self):
3413+
with self.assertRaisesRegex(
3414+
TypeError,
3415+
'has no members',
3416+
):
3417+
Enum(7)
3418+
with self.assertRaisesRegex(
3419+
TypeError,
3420+
'has no members',
3421+
):
3422+
Flag(7)
34123423

34133424
class TestOrder(unittest.TestCase):
34143425
"test usage of the `_order_` attribute"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[Enum] Improve error message when calling super().__new__() in custom
2+
__new__.

0 commit comments

Comments
 (0)