mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
gh-115821: [Enum] better error message for calling super().__new__() (GH-116063)
docs now state to not call super().__new__ if super().__new__ is called, a better error message is now used
This commit is contained in:
parent
4d1d35b906
commit
3ea78fd5bc
4 changed files with 22 additions and 1 deletions
|
@ -400,6 +400,9 @@ Data Types
|
||||||
|
|
||||||
results in the call ``int('1a', 16)`` and a value of ``17`` for the member.
|
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)
|
.. method:: Enum.__repr__(self)
|
||||||
|
|
||||||
Returns the string used for *repr()* calls. By default, returns the
|
Returns the string used for *repr()* calls. By default, returns the
|
||||||
|
|
|
@ -547,7 +547,10 @@ class EnumType(type):
|
||||||
classdict['_inverted_'] = None
|
classdict['_inverted_'] = None
|
||||||
try:
|
try:
|
||||||
exc = None
|
exc = None
|
||||||
|
classdict['_%s__in_progress' % cls] = True
|
||||||
enum_class = super().__new__(metacls, cls, bases, classdict, **kwds)
|
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:
|
except Exception as e:
|
||||||
# since 3.12 the line "Error calling __set_name__ on '_proto_member' instance ..."
|
# since 3.12 the line "Error calling __set_name__ on '_proto_member' instance ..."
|
||||||
# is tacked on to the error instead of raising a RuntimeError
|
# is tacked on to the error instead of raising a RuntimeError
|
||||||
|
@ -1155,6 +1158,8 @@ class Enum(metaclass=EnumType):
|
||||||
# still not found -- verify that members exist, in-case somebody got here mistakenly
|
# still not found -- verify that members exist, in-case somebody got here mistakenly
|
||||||
# (such as via super when trying to override __new__)
|
# (such as via super when trying to override __new__)
|
||||||
if not cls._member_map_:
|
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)
|
raise TypeError("%r has no members defined" % cls)
|
||||||
#
|
#
|
||||||
# still not found -- try _missing_ hook
|
# still not found -- try _missing_ hook
|
||||||
|
|
|
@ -447,7 +447,7 @@ class _EnumTests:
|
||||||
def test_bad_new_super(self):
|
def test_bad_new_super(self):
|
||||||
with self.assertRaisesRegex(
|
with self.assertRaisesRegex(
|
||||||
TypeError,
|
TypeError,
|
||||||
'has no members defined',
|
'do not use .super...__new__;',
|
||||||
):
|
):
|
||||||
class BadSuper(self.enum_type):
|
class BadSuper(self.enum_type):
|
||||||
def __new__(cls, value):
|
def __new__(cls, value):
|
||||||
|
@ -3409,6 +3409,17 @@ class TestSpecial(unittest.TestCase):
|
||||||
self.assertIs(Types(2), Types.NetList)
|
self.assertIs(Types(2), Types.NetList)
|
||||||
self.assertIs(Types('nl'), 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):
|
class TestOrder(unittest.TestCase):
|
||||||
"test usage of the `_order_` attribute"
|
"test usage of the `_order_` attribute"
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[Enum] Improve error message when calling super().__new__() in custom
|
||||||
|
__new__.
|
Loading…
Add table
Add a link
Reference in a new issue