From 958ba177f5ea9cbc42fd0e70a02445e751bba8b1 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 3 Jan 2022 16:25:55 +0300 Subject: [PATCH 1/3] bpo-46242: better error message for extending `Enum` with members --- Lib/enum.py | 7 +++++-- Lib/test/test_enum.py | 2 ++ .../next/Library/2022-01-03-16-25-06.bpo-46242.f4l_CL.rst | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-01-03-16-25-06.bpo-46242.f4l_CL.rst diff --git a/Lib/enum.py b/Lib/enum.py index 8efc38c3d78dbc..2c12d65f7fa68a 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -767,7 +767,7 @@ def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, s """ metacls = cls.__class__ bases = (cls, ) if type is None else (type, cls) - _, first_enum = cls._get_mixins_(cls, bases) + _, first_enum = cls._get_mixins_(class_name, bases) classdict = metacls.__prepare__(class_name, bases) # special processing needed for names? @@ -896,7 +896,10 @@ def _find_data_type(bases): "`EnumName([mixin_type, ...] [data_type,] enum_type)`") member_type = _find_data_type(bases) or object if first_enum._member_names_: - raise TypeError("Cannot extend enumerations") + raise TypeError( + "%s: cannot extend enumeration %r" + % (class_name, first_enum.__name__) + ) return member_type, first_enum @staticmethod diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index eecb9fd4835c40..22737700fa3103 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -1423,6 +1423,8 @@ class MoreColor(Color): with self.assertRaisesRegex(TypeError, "EvenMoreColor: cannot extend enumeration 'Color'"): class EvenMoreColor(Color, IntEnum): chartruese = 7 + with self.assertRaisesRegex(TypeError, "Foo: cannot extend enumeration 'Color'"): + Color('Foo', ('pink', 'black')) def test_exclude_methods(self): class whatever(Enum): diff --git a/Misc/NEWS.d/next/Library/2022-01-03-16-25-06.bpo-46242.f4l_CL.rst b/Misc/NEWS.d/next/Library/2022-01-03-16-25-06.bpo-46242.f4l_CL.rst new file mode 100644 index 00000000000000..5c5fe1d3205c0d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-03-16-25-06.bpo-46242.f4l_CL.rst @@ -0,0 +1 @@ +Improve error message when creating a new :class:`enum.Enum` type subclassing an existing ``Enum`` with ``_member_names_`` using :method:`enum.Enum.__call__`. From 19772acf56f71f6a6207377ef58e6a22a5682266 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Mon, 3 Jan 2022 16:45:17 +0300 Subject: [PATCH 2/3] Update 2022-01-03-16-25-06.bpo-46242.f4l_CL.rst --- .../next/Library/2022-01-03-16-25-06.bpo-46242.f4l_CL.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2022-01-03-16-25-06.bpo-46242.f4l_CL.rst b/Misc/NEWS.d/next/Library/2022-01-03-16-25-06.bpo-46242.f4l_CL.rst index 5c5fe1d3205c0d..6a5b5fdffda40b 100644 --- a/Misc/NEWS.d/next/Library/2022-01-03-16-25-06.bpo-46242.f4l_CL.rst +++ b/Misc/NEWS.d/next/Library/2022-01-03-16-25-06.bpo-46242.f4l_CL.rst @@ -1 +1 @@ -Improve error message when creating a new :class:`enum.Enum` type subclassing an existing ``Enum`` with ``_member_names_`` using :method:`enum.Enum.__call__`. +Improve error message when creating a new :class:`enum.Enum` type subclassing an existing ``Enum`` with ``_member_names_`` using :meth:`enum.Enum.__call__`. From 9e7d02ce1dbb3b421b25ce37aadd3e98c70881d0 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 3 Jan 2022 17:33:42 +0300 Subject: [PATCH 3/3] Try to use `cls._check_for_existing_members` --- Lib/enum.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Lib/enum.py b/Lib/enum.py index 2c12d65f7fa68a..ad24fa118f6fa1 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -852,8 +852,8 @@ def _check_for_existing_members(class_name, bases): % (class_name, base.__name__) ) - @staticmethod - def _get_mixins_(class_name, bases): + @classmethod + def _get_mixins_(cls, class_name, bases): """ Returns the type for creating enum members, and the first inherited enum class. @@ -894,12 +894,8 @@ def _find_data_type(bases): if not issubclass(first_enum, Enum): raise TypeError("new enumerations should be created as " "`EnumName([mixin_type, ...] [data_type,] enum_type)`") + cls._check_for_existing_members(class_name, bases) member_type = _find_data_type(bases) or object - if first_enum._member_names_: - raise TypeError( - "%s: cannot extend enumeration %r" - % (class_name, first_enum.__name__) - ) return member_type, first_enum @staticmethod