From 27ac85647702e075bd670f247016a9fcd8723702 Mon Sep 17 00:00:00 2001 From: Rafael Weingartner-Ortner Date: Sun, 12 Oct 2025 08:34:26 +0200 Subject: [PATCH 1/3] Add supported sunder names to Enum `__dir__` This change adds the sunder names `_generate_next_value_` and `_missing_` to the `__dir__` method of `EnumType` and `Enum`. In Addition, The instance level sunder names `_add_alias_` and `_add_value_alias_` are added to `Enum.__dir__`. With the sunder names exposed in the `dir()` method, the REPL autocomplete will also show them. Co-Authored-By: SimonGPrs <107691772+SimonGPrs@users.noreply.github.com> --- Doc/library/enum.rst | 4 ++-- Lib/enum.py | 5 ++++- Lib/test/test_enum.py | 10 +++++++++- .../2025-10-12-08-46-26.gh-issue-139398.hESOMl.rst | 2 ++ 4 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-10-12-08-46-26.gh-issue-139398.hESOMl.rst diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index a8a7e671aadca2..c48e3c479d870f 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -221,7 +221,7 @@ Data Types names of the members in *cls*:: >>> dir(Color) - ['BLUE', 'GREEN', 'RED', '__class__', '__contains__', '__doc__', '__getitem__', '__init_subclass__', '__iter__', '__len__', '__members__', '__module__', '__name__', '__qualname__'] + ['BLUE', 'GREEN', 'RED', '__class__', '__contains__', '__doc__', '__getitem__', '__init_subclass__', '__iter__', '__len__', '__members__', '__module__', '__name__', '__qualname__', '_generate_next_value_', '_missing_'] .. method:: EnumType.__getitem__(cls, name) @@ -330,7 +330,7 @@ Data Types ... print('today is %s' % cls(date.today().isoweekday()).name) ... >>> dir(Weekday.SATURDAY) - ['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'today', 'value'] + ['__class__', '__doc__', '__eq__', '__hash__', '__module__', '_add_alias_', '_add_value_alias_', '_generate_next_value_', '_missing_', 'name', 'today', 'value'] .. method:: Enum._generate_next_value_(name, start, count, last_values) diff --git a/Lib/enum.py b/Lib/enum.py index c00ae85d2f8efe..e6ffccb01fa786 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -777,6 +777,8 @@ def __dir__(cls): '__class__', '__contains__', '__doc__', '__getitem__', '__iter__', '__len__', '__members__', '__module__', '__name__', '__qualname__', + # Supported sunder names of Enum class + '_generate_next_value_', '_missing_', ] + cls._member_names_ ) @@ -1290,7 +1292,8 @@ def __dir__(self): """ Returns public methods and other interesting attributes. """ - interesting = set() + # Initialize with supported sunder names + interesting = set(('_generate_next_value_', '_missing_', '_add_alias_', '_add_value_alias_')) if self.__class__._member_type_ is not object: interesting = set(object.__dir__(self)) for name in getattr(self, '__dict__', []): diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 7e509be0994248..dc1161f25dbc8a 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -5105,6 +5105,8 @@ def test_inspect_getmembers(self): ('__qualname__', 'TestStdLib.Color'), ('__init_subclass__', getattr(self.Color, '__init_subclass__')), ('__iter__', self.Color.__iter__), + ('_missing_', self.Color._missing_), + ('_generate_next_value_', self.Color._generate_next_value_), )) result = dict(inspect.getmembers(self.Color)) self.assertEqual(set(values.keys()), set(result.keys())) @@ -5147,6 +5149,10 @@ def test_inspect_classify_class_attrs(self): defining_class=self.Color, object='Color'), Attribute(name='__qualname__', kind='data', defining_class=self.Color, object='TestStdLib.Color'), + Attribute(name='_missing_', kind='class method', + defining_class=Enum, object=self.Color._missing_), + Attribute(name='_generate_next_value_', kind='static method', + defining_class=self.Color, object=staticmethod(self.Color._generate_next_value_)), Attribute(name='YELLOW', kind='data', defining_class=self.Color, object=self.Color.YELLOW), Attribute(name='MAGENTA', kind='data', @@ -5533,6 +5539,7 @@ def enum_dir(cls): '__class__', '__contains__', '__doc__', '__getitem__', '__iter__', '__len__', '__members__', '__module__', '__name__', '__qualname__', + '_generate_next_value_', '_missing_', ] + cls._member_names_ ) @@ -5548,7 +5555,8 @@ def enum_dir(cls): def member_dir(member): if member.__class__._member_type_ is object: - allowed = set(['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'value']) + allowed = set(['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'value', + '_generate_next_value_', '_missing_', '_add_alias_', '_add_value_alias_']) else: allowed = set(dir(member)) for cls in member.__class__.mro(): diff --git a/Misc/NEWS.d/next/Library/2025-10-12-08-46-26.gh-issue-139398.hESOMl.rst b/Misc/NEWS.d/next/Library/2025-10-12-08-46-26.gh-issue-139398.hESOMl.rst new file mode 100644 index 00000000000000..96b32bff1a9ae3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-12-08-46-26.gh-issue-139398.hESOMl.rst @@ -0,0 +1,2 @@ +Add supported ``_sunder_`` names to the :func:`dir` method of the :mod:`Enum` module +to support them in :term:`REPL` autocompletion. From 0d9fedf0f8adccd72a4e268c183c939f9630ab46 Mon Sep 17 00:00:00 2001 From: Rafael Weingartner-Ortner Date: Sun, 12 Oct 2025 08:39:47 +0200 Subject: [PATCH 2/3] Improve printed output of test for Enum attributes This change highlights which of the attributes were expected versus were actually there. --- Lib/test/test_enum.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index dc1161f25dbc8a..a80f538d05f8c1 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -5184,10 +5184,10 @@ def test_inspect_classify_class_attrs(self): # __doc__ is too big to check exactly, so treat the same as __init_subclass__ for name in ('name','kind','defining_class'): if getattr(v, name) != getattr(r, name): - print('\n%s\n%s\n%s\n%s\n' % ('=' * 75, r, v, '=' * 75), sep='') + print('\n%s\nexpected: %s\nactual: %s\n%s\n' % ('=' * 75, r, v, '=' * 75), sep='') failed = True elif r != v: - print('\n%s\n%s\n%s\n%s\n' % ('=' * 75, r, v, '=' * 75), sep='') + print('\n%s\nexpected: %s\nactual: %s\n%s\n' % ('=' * 75, r, v, '=' * 75), sep='') failed = True if failed: self.fail("result does not equal expected, see print above") From 1354d4639cd229682f54fd2695c3cd6c58619e81 Mon Sep 17 00:00:00 2001 From: Rafael Weingartner-Ortner Date: Sun, 12 Oct 2025 10:29:23 +0200 Subject: [PATCH 3/3] Fix case of enum directive in news entry --- .../next/Library/2025-10-12-08-46-26.gh-issue-139398.hESOMl.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-10-12-08-46-26.gh-issue-139398.hESOMl.rst b/Misc/NEWS.d/next/Library/2025-10-12-08-46-26.gh-issue-139398.hESOMl.rst index 96b32bff1a9ae3..201b682d177c01 100644 --- a/Misc/NEWS.d/next/Library/2025-10-12-08-46-26.gh-issue-139398.hESOMl.rst +++ b/Misc/NEWS.d/next/Library/2025-10-12-08-46-26.gh-issue-139398.hESOMl.rst @@ -1,2 +1,2 @@ -Add supported ``_sunder_`` names to the :func:`dir` method of the :mod:`Enum` module +Add supported ``_sunder_`` names to the :func:`dir` method of the :mod:`enum` module to support them in :term:`REPL` autocompletion.