diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index be7f59b0fce2a5..04b41ad6eadf38 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -222,7 +222,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) @@ -355,7 +355,7 @@ Data types ... print(f'today is {cls(dt.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 f536a3eae2b6e3..f97a5193492e60 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -784,6 +784,8 @@ def __dir__(cls): '__class__', '__contains__', '__doc__', '__getitem__', '__iter__', '__len__', '__members__', '__module__', '__name__', '__qualname__', + # Supported sunder names of Enum class + '_generate_next_value_', '_missing_', ] + members ) @@ -1297,7 +1299,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 e0dcc6b8a519e7..b05eab43bd9eff 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=Enum.__dict__['_missing_']), + Attribute(name='_generate_next_value_', kind='static method', + defining_class=self.Color, object=self.Color.__dict__['_generate_next_value_']), Attribute(name='YELLOW', kind='data', defining_class=self.Color, object=self.Color.YELLOW), Attribute(name='MAGENTA', kind='data', @@ -5178,11 +5184,13 @@ 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 + # breakpoint() 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 + # breakpoint() if failed: self.fail("result does not equal expected, see print above") @@ -5537,6 +5545,7 @@ def enum_dir(cls): '__class__', '__contains__', '__doc__', '__getitem__', '__iter__', '__len__', '__members__', '__module__', '__name__', '__qualname__', + '_generate_next_value_', '_missing_', ] + members ) @@ -5552,7 +5561,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..201b682d177c01 --- /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.