Repository navigation
Enum's dir() does not contain inherited members #89698
Description
Activity
For example:
>>> from enum import * >>> class E(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.
- added3.9 (EOL)end of lifeend of life3.10 (EOL)end of lifeend of life3.11only security fixesonly security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Oct 20, 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.
Looks interesting, thank you for the patch.
There may be a simple error (superfluous .__class__), but I am not sure.
BTW, why use mro() instead of __mro__? Most code use __mro__.
Would there be interest in me submitting a PR along these lines?
----
why use mro() instead of __mro__?
Er, no reason, really. To be honest, I've never really understood why Python has both.
PR 29316 looks complicated.
First of all, why do Enum needs a custom __dir__? What is wrong with the default implementation?
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
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.
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: 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?
dir()#29316Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields: