From a52609440225389d279f538afe86ecff98ae39dd Mon Sep 17 00:00:00 2001 From: SimonGPrs <107691772+SimonGPrs@users.noreply.github.com> Date: Mon, 29 Sep 2025 16:16:27 +0200 Subject: [PATCH 1/4] Update enum.py [enum] Make dir(Enum) include public _sunder_ helpers for REPL completions (gh-139398) - I guess this enhances EnumType.__dir__ to include documented public _sunder_ helpers (_add_alias_, _add_value_alias_) if present on the Enum class - I think this could enabrle rlcompleter and the REPL show completions for these supported helpers and matching the intent of the enum API docs... - Normally I think no change to other (private or internal) _sunder_ names - Fixes: gh-139398 --- Lib/enum.py | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/Lib/enum.py b/Lib/enum.py index c00ae85d2f8efe..d88133a6a7aac3 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -773,22 +773,31 @@ def __delattr__(cls, attr): super().__delattr__(attr) def __dir__(cls): - interesting = set([ - '__class__', '__contains__', '__doc__', '__getitem__', - '__iter__', '__len__', '__members__', '__module__', - '__name__', '__qualname__', - ] - + cls._member_names_ - ) - if cls._new_member_ is not object.__new__: - interesting.add('__new__') - if cls.__init_subclass__ is not object.__init_subclass__: - interesting.add('__init_subclass__') - if cls._member_type_ is object: - return sorted(interesting) - else: - # return whatever mixed-in data type has - return sorted(set(dir(cls._member_type_)) | interesting) + interesting = set([ + '__class__', '__contains__', '__doc__', '__getitem__', + '__iter__', '__len__', '__members__', '__module__', + '__name__', '__qualname__', + ] + cls._member_names_) + + if cls._new_member_ is not object.__new__: + interesting.add('__new__') + if cls.__init_subclass__ is not object.__init_subclass__: + interesting.add('__init_subclass__') + + # SGP: Include documented public _sunder_ helpers defined on the Enum class. + # SGP: This makes them discoverable via dir(Enum) so rlcompleter can surface + # SGP: them in REPL completions. (rlcompleter drives dotted-name completion + # SGP: from dir(); _add_alias_/_add_value_alias_ are supported _sunder_ APIs.) + for _n in ("_add_alias_", "_add_value_alias_"): + if _n in cls.__dict__: + interesting.add(_n) + + if cls._member_type_ is object: + return sorted(interesting) + else: + # return whatever mixed-in data type has + # SGP: union the mixin's dir() with 'interesting' + return sorted(set(dir(cls._member_type_)) | interesting) def __getitem__(cls, name): """ From 7ab184a78d9099c15d2723266e1152b32ad4eaea Mon Sep 17 00:00:00 2001 From: SimonGPrs <107691772+SimonGPrs@users.noreply.github.com> Date: Mon, 29 Sep 2025 16:29:51 +0200 Subject: [PATCH 2/4] [enum] Make dir(Enum) include public _sunder_ helpers for REPL completions (gh-139398) Fix indentation in EnumType.__dir__ (gh-139398) Add NEWS entry for enum dir(Enum) completions (gh-139398) --- Lib/enum.py | 56 +++++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/Lib/enum.py b/Lib/enum.py index d88133a6a7aac3..843d98167cfb28 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -773,31 +773,37 @@ def __delattr__(cls, attr): super().__delattr__(attr) def __dir__(cls): - interesting = set([ - '__class__', '__contains__', '__doc__', '__getitem__', - '__iter__', '__len__', '__members__', '__module__', - '__name__', '__qualname__', - ] + cls._member_names_) - - if cls._new_member_ is not object.__new__: - interesting.add('__new__') - if cls.__init_subclass__ is not object.__init_subclass__: - interesting.add('__init_subclass__') - - # SGP: Include documented public _sunder_ helpers defined on the Enum class. - # SGP: This makes them discoverable via dir(Enum) so rlcompleter can surface - # SGP: them in REPL completions. (rlcompleter drives dotted-name completion - # SGP: from dir(); _add_alias_/_add_value_alias_ are supported _sunder_ APIs.) - for _n in ("_add_alias_", "_add_value_alias_"): - if _n in cls.__dict__: - interesting.add(_n) - - if cls._member_type_ is object: - return sorted(interesting) - else: - # return whatever mixed-in data type has - # SGP: union the mixin's dir() with 'interesting' - return sorted(set(dir(cls._member_type_)) | interesting) + interesting = set([ + '__class__', '__contains__', '__doc__', '__getitem__', + '__iter__', '__len__', '__members__', '__module__', + '__name__', '__qualname__', + ] + + cls._member_names_ + ) + + if cls._new_member_ is not object.__new__: + interesting.add('__new__') + if cls.__init_subclass__ is not object.__init_subclass__: + interesting.add('__init_subclass__') + + # SGP: Include documented public _sunder_ helpers defined on the Enum class. + # SGP: This makes them discoverable via dir(Enum) so rlcompleter can surface + # SGP: them in REPL completions. (rlcompleter drives dotted-name completion + # SGP: from dir(); _add_alias_/_add_value_alias_ are supported _sunder_ APIs.) + for _n in ("_add_alias_", "_add_value_alias_"): + if _n in cls.__dict__: + interesting.add(_n) + + if cls._member_type_ is object: + return sorted(interesting) + else: + # return whatever mixed-in data type has + # SGP: union the mixin's dir() with 'interesting' + return sorted(set(dir(cls._member_type_)) | interesting) + + + + def __getitem__(cls, name): """ From d7f1af98e8cff53fbc66896eacb127e7789e2295 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 14:39:36 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2025-09-29-14-39-34.gh-issue-139398.tbFBKV.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-09-29-14-39-34.gh-issue-139398.tbFBKV.rst diff --git a/Misc/NEWS.d/next/Library/2025-09-29-14-39-34.gh-issue-139398.tbFBKV.rst b/Misc/NEWS.d/next/Library/2025-09-29-14-39-34.gh-issue-139398.tbFBKV.rst new file mode 100644 index 00000000000000..476f765b1d9179 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-09-29-14-39-34.gh-issue-139398.tbFBKV.rst @@ -0,0 +1 @@ +dir(Enum) now includes public _sunder_ helpers (_add_alias_, _add_value_alias_) for better REPL completion. (gh-139398) From 01d3a59a347d87bdca4ad4b79c77f0dc5f2caa14 Mon Sep 17 00:00:00 2001 From: SimonGPrs <107691772+SimonGPrs@users.noreply.github.com> Date: Mon, 29 Sep 2025 16:54:57 +0200 Subject: [PATCH 4/4] Update enum.py Trim trailing whitespace and fix formatting in enum.py - Remove trailing spaces to satisfy lint/pre-commit checks - The code itself is not chnaged it is just the issue of the test --- Lib/enum.py | 56 ++++++++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/Lib/enum.py b/Lib/enum.py index 843d98167cfb28..d88133a6a7aac3 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -773,37 +773,31 @@ def __delattr__(cls, attr): super().__delattr__(attr) def __dir__(cls): - interesting = set([ - '__class__', '__contains__', '__doc__', '__getitem__', - '__iter__', '__len__', '__members__', '__module__', - '__name__', '__qualname__', - ] - + cls._member_names_ - ) - - if cls._new_member_ is not object.__new__: - interesting.add('__new__') - if cls.__init_subclass__ is not object.__init_subclass__: - interesting.add('__init_subclass__') - - # SGP: Include documented public _sunder_ helpers defined on the Enum class. - # SGP: This makes them discoverable via dir(Enum) so rlcompleter can surface - # SGP: them in REPL completions. (rlcompleter drives dotted-name completion - # SGP: from dir(); _add_alias_/_add_value_alias_ are supported _sunder_ APIs.) - for _n in ("_add_alias_", "_add_value_alias_"): - if _n in cls.__dict__: - interesting.add(_n) - - if cls._member_type_ is object: - return sorted(interesting) - else: - # return whatever mixed-in data type has - # SGP: union the mixin's dir() with 'interesting' - return sorted(set(dir(cls._member_type_)) | interesting) - - - - + interesting = set([ + '__class__', '__contains__', '__doc__', '__getitem__', + '__iter__', '__len__', '__members__', '__module__', + '__name__', '__qualname__', + ] + cls._member_names_) + + if cls._new_member_ is not object.__new__: + interesting.add('__new__') + if cls.__init_subclass__ is not object.__init_subclass__: + interesting.add('__init_subclass__') + + # SGP: Include documented public _sunder_ helpers defined on the Enum class. + # SGP: This makes them discoverable via dir(Enum) so rlcompleter can surface + # SGP: them in REPL completions. (rlcompleter drives dotted-name completion + # SGP: from dir(); _add_alias_/_add_value_alias_ are supported _sunder_ APIs.) + for _n in ("_add_alias_", "_add_value_alias_"): + if _n in cls.__dict__: + interesting.add(_n) + + if cls._member_type_ is object: + return sorted(interesting) + else: + # return whatever mixed-in data type has + # SGP: union the mixin's dir() with 'interesting' + return sorted(set(dir(cls._member_type_)) | interesting) def __getitem__(cls, name): """