https://github.com/python/cpython/commit/3ea78fd5bc93fc339ef743e6a5dfde35f04d972e
commit: 3ea78fd5bc93fc339ef743e6a5dfde35f04d972e
branch: main
author: Ethan Furman <[email protected]>
committer: ethanfurman <[email protected]>
date: 2024-02-28T15:17:49-08:00
summary:
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
files:
A Misc/NEWS.d/next/Library/2024-02-28-12-14-31.gh-issue-115821.YO2vKA.rst
M Doc/library/enum.rst
M Lib/enum.py
M Lib/test/test_enum.py
diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst
index 30d80ce8d488cc..6e7de004cd52a1 100644
--- a/Doc/library/enum.rst
+++ b/Doc/library/enum.rst
@@ -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
diff --git a/Lib/enum.py b/Lib/enum.py
index d10b99615981ba..22963cca4466f2 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -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
@@ -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
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index cf3e042de1a4b4..27f8bbaf952afc 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -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):
@@ -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"
diff --git
a/Misc/NEWS.d/next/Library/2024-02-28-12-14-31.gh-issue-115821.YO2vKA.rst
b/Misc/NEWS.d/next/Library/2024-02-28-12-14-31.gh-issue-115821.YO2vKA.rst
new file mode 100644
index 00000000000000..7512a09a37cd46
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-02-28-12-14-31.gh-issue-115821.YO2vKA.rst
@@ -0,0 +1,2 @@
+[Enum] Improve error message when calling super().__new__() in custom
+__new__.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]