Skip to content

Commit

Permalink
gh-115821: [Enum] better error message for calling super().__new__() (G…
Browse files Browse the repository at this point in the history
…H-116063)

docs now state to not call super().__new__
if super().__new__ is called, a better error message is now used
  • Loading branch information
ethanfurman committed Feb 28, 2024
1 parent 4d1d35b commit 3ea78fd
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Doc/library/enum.rst
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,9 @@ Data Types

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

..note:: When writing a custom ``__new__``, do not use ``super().__new__`` --
call the appropriate ``__new__`` instead.

.. method:: Enum.__repr__(self)

Returns the string used for *repr()* calls. By default, returns the
Expand Down
5 changes: 5 additions & 0 deletions Lib/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,10 @@ def __new__(metacls, cls, bases, classdict, *, boundary=None, _simple=False, **k
classdict['_inverted_'] = None
try:
exc = None
classdict['_%s__in_progress' % cls] = True
enum_class = super().__new__(metacls, cls, bases, classdict, **kwds)
classdict['_%s__in_progress' % cls] = False
delattr(enum_class, '_%s__in_progress' % cls)
except Exception as e:
# since 3.12 the line "Error calling __set_name__ on '_proto_member' instance ..."
# is tacked on to the error instead of raising a RuntimeError
Expand Down Expand Up @@ -1155,6 +1158,8 @@ def __new__(cls, value):
# still not found -- verify that members exist, in-case somebody got here mistakenly
# (such as via super when trying to override __new__)
if not cls._member_map_:
if getattr(cls, '_%s__in_progress' % cls.__name__, False):
raise TypeError('do not use `super().__new__; call the appropriate __new__ directly') from None
raise TypeError("%r has no members defined" % cls)
#
# still not found -- try _missing_ hook
Expand Down
13 changes: 12 additions & 1 deletion Lib/test/test_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ def spam(cls):
def test_bad_new_super(self):
with self.assertRaisesRegex(
TypeError,
'has no members defined',
'do not use .super...__new__;',
):
class BadSuper(self.enum_type):
def __new__(cls, value):
Expand Down Expand Up @@ -3409,6 +3409,17 @@ def __new__(cls, int_value, *value_aliases):
self.assertIs(Types(2), Types.NetList)
self.assertIs(Types('nl'), Types.NetList)

def test_no_members(self):
with self.assertRaisesRegex(
TypeError,
'has no members',
):
Enum(7)
with self.assertRaisesRegex(
TypeError,
'has no members',
):
Flag(7)

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

0 comments on commit 3ea78fd

Please sign in to comment.