You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Enum's dir() does not contain inherited members #89698
>>> from enum import*
>>> classE(IntEnum):
... x =1
...
>>> dir(E)
['__class__', '__doc__', '__members__', '__module__', 'x']
>>> E.from_bytes
<built-in method from_bytes of EnumType object at 0x559d47415ce0>
>>> E.to_bytes
<method 'to_bytes' of 'int' objects>
>>> E.numerator
<attribute 'numerator' of 'int' objects>
>>> E.__add__
<slot wrapper '__add__' of 'int' objects>
There are methods and attributes inherited from int, but they are not shown in dir(). As result they are absent in help() and completion does not work for them.
I had a go at writing a patch for __dir__ that would include any methods an enum class had acquired through int/str/etc. mixins, while continuing to ignore enum dunders and sunders (as is currently the case). My patch also allows user-defined methods defined in enum subclasses to show up in the help() output, whereas they currently do not, since help(enum_member) looks up dir(enum_class) rather than dir(enum_member).
The patch is a fair way more complex than the the existing code, however.
Enums have had a custom dir() from the beginning, partly because they are not standard objects and do not follow standard rules.
The question posed by this issue is whether Enums with mixed-in data types should show the inherited methods, and if yes, should it also show inherited __dunders__.
I'm inclined to say yes for the normal inherited methods, I'm not sure about inherited __dunders__.
I would argue it's quite important for IntEnum to have the dunder methods inherited from int show up in help(). Dunder methods indicate that an object has certain behaviours, so it's important for a user to be able to verify that an IntEnum member has similar behaviours to an int instance. IntEnum is advertised in the documentation as something that can be used everywhere where an integer is expected; it's surprising when the output from help() is hugely abbreviated for IntEnum relative to int.
But, I agree that my first draft of this PR is more complex than I'd like it to be.
Pure enums have a few more dir() entries now; mixed enums now show all inherited methods/attributes -- members still do not show up in member dirs (this is a good thing).
@ethanfurman: test_enum.test_dir_with_custom_dunders() is skipped since 2022, since commit 7c0914d:
commit 7c0914d35eaaab2f323260ba5fe8884732533888
Author: Ethan Furman <ethan@stoneleaf.us>
Date: Tue Jan 18 15:13:13 2022 -0800
bpo-45535: [Enum] include special dunders in dir() (GH-30677)
Include the `__dunders__` in `dir()` that make `Enum` special:
- `__contains__`
- `__getitem__`
- `__iter__`
- `__len__`
- `__members__`
What's the status of this test? Should it be removed?
Activity
serhiy-storchaka commentedon Oct 20, 2021
For example:
There are methods and attributes inherited from int, but they are not shown in dir(). As result they are absent in help() and completion does not work for them.
AlexWaygood commentedon Oct 21, 2021
I had a go at writing a patch for
__dir__that would include any methods an enum class had acquired throughint/str/etc. mixins, while continuing to ignore enum dunders and sunders (as is currently the case). My patch also allows user-defined methods defined in enum subclasses to show up in thehelp()output, whereas they currently do not, sincehelp(enum_member)looks updir(enum_class)rather thandir(enum_member).The patch is a fair way more complex than the the existing code, however.
ethanfurman commentedon Oct 21, 2021
Looks interesting, thank you for the patch.
serhiy-storchaka commentedon Oct 21, 2021
There may be a simple error (superfluous .__class__), but I am not sure.
BTW, why use mro() instead of __mro__? Most code use __mro__.
AlexWaygood commentedon Oct 22, 2021
Would there be interest in me submitting a PR along these lines?
----
Er, no reason, really. To be honest, I've never really understood why Python has both.
serhiy-storchaka commentedon Oct 29, 2021
PR 29316 looks complicated.
First of all, why do Enum needs a custom __dir__? What is wrong with the default implementation?
ethanfurman commentedon Oct 29, 2021
Enums have had a custom dir() from the beginning, partly because they are not standard objects and do not follow standard rules.
The question posed by this issue is whether Enums with mixed-in data types should show the inherited methods, and if yes, should it also show inherited
__dunders__.I'm inclined to say yes for the normal inherited methods, I'm not sure about inherited
__dunders__.AlexWaygood commentedon Oct 29, 2021
I would argue it's quite important for
IntEnumto have the dunder methods inherited fromintshow up inhelp(). Dunder methods indicate that an object has certain behaviours, so it's important for a user to be able to verify that anIntEnummember has similar behaviours to anintinstance.IntEnumis advertised in the documentation as something that can be used everywhere where an integer is expected; it's surprising when the output fromhelp()is hugely abbreviated forIntEnumrelative toint.But, I agree that my first draft of this PR is more complex than I'd like it to be.
ethanfurman commentedon Dec 2, 2021
New changeset b2afdc9 by Alex Waygood in branch 'main':
bpo-45535: Improve output of Enum
dir()(GH-29316)b2afdc9
ethanfurman commentedon Jan 17, 2022
Fixed in 3.11.
Pure enums have a few more dir() entries now; mixed enums now show all inherited methods/attributes -- members still do not show up in member dirs (this is a good thing).
ethanfurman commentedon Jan 18, 2022
New changeset 7c0914d by Ethan Furman in branch 'main':
bpo-45535: [Enum] include special dunders in dir() (GH-30677)
7c0914d
vstinner commentedon Oct 2, 2025
@ethanfurman: test_enum.test_dir_with_custom_dunders() is skipped since 2022, since commit 7c0914d:
What's the status of this test? Should it be removed?