Skip to content

Enum's dir() does not contain inherited members #89698

Description

@serhiy-storchaka
BPO 45535
Nosy @warsaw, @ethanfurman, @serhiy-storchaka, @AlexWaygood
PRs
  • bpo-45535: Improve output of Enum dir() #29316
  • bpo-45535: [Enum] include special dunders in dir() #30677
  • Superseder
  • bpo-40066: Enum: modify repr, str; update docs
  • Files
  • Enum_dir_patch.txt
  • enum_dir_output_with_patch.txt
  • Note: 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:

    assignee = 'https://github.com/ethanfurman'
    closed_at = <Date 2022-01-17.17:02:11.779>
    created_at = <Date 2021-10-20.10:35:06.095>
    labels = ['type-bug', 'library', '3.10', '3.11']
    title = "Enum's dir() does not contain inherited members"
    updated_at = <Date 2022-01-18.23:13:23.710>
    user = 'https://github.com/serhiy-storchaka'

    bugs.python.org fields:

    activity = <Date 2022-01-18.23:13:23.710>
    actor = 'ethan.furman'
    assignee = 'ethan.furman'
    closed = True
    closed_date = <Date 2022-01-17.17:02:11.779>
    closer = 'ethan.furman'
    components = ['Library (Lib)']
    creation = <Date 2021-10-20.10:35:06.095>
    creator = 'serhiy.storchaka'
    dependencies = []
    files = ['50382', '50383']
    hgrepos = []
    issue_num = 45535
    keywords = ['patch']
    message_count = 11.0
    messages = ['404420', '404621', '404634', '404635', '404721', '405313', '405320', '405323', '407539', '410807', '410912']
    nosy_count = 5.0
    nosy_names = ['barry', 'eli.bendersky', 'ethan.furman', 'serhiy.storchaka', 'AlexWaygood']
    pr_nums = ['29316', '30677']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = '40066'
    type = 'behavior'
    url = 'https://bugs.python.org/issue45535'
    versions = ['Python 3.10', 'Python 3.11']

    Activity

    1. serhiy-storchaka commented on Oct 20, 2021

      @serhiy-storchaka
      MemberAuthor

      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.

    2. added
      3.11only security fixes
      stdlibStandard Library Python modules in the Lib/ directory
      type-bugAn unexpected behavior, bug, or error
      on Oct 20, 2021
    3. AlexWaygood commented on Oct 21, 2021

      @AlexWaygood
      Member

      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.

    4. ethanfurman commented on Oct 21, 2021

      @ethanfurman
      Member

      Looks interesting, thank you for the patch.

    5. self-assigned this
      on Oct 21, 2021
    6. self-assigned this
      on Oct 21, 2021
    7. serhiy-storchaka commented on Oct 21, 2021

      @serhiy-storchaka
      MemberAuthor

      There may be a simple error (superfluous .__class__), but I am not sure.

      BTW, why use mro() instead of __mro__? Most code use __mro__.

    8. AlexWaygood commented on Oct 22, 2021

      @AlexWaygood
      Member

      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.

    9. serhiy-storchaka commented on Oct 29, 2021

      @serhiy-storchaka
      MemberAuthor

      PR 29316 looks complicated.

      First of all, why do Enum needs a custom __dir__? What is wrong with the default implementation?

    10. ethanfurman commented on Oct 29, 2021

      @ethanfurman
      Member

      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__.

    11. AlexWaygood commented on Oct 29, 2021

      @AlexWaygood
      Member

      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.

    12. ethanfurman commented on Dec 2, 2021

      @ethanfurman
      Member

      New changeset b2afdc9 by Alex Waygood in branch 'main':
      bpo-45535: Improve output of Enum dir() (GH-29316)
      b2afdc9

    13. ethanfurman commented on Jan 17, 2022

      @ethanfurman
      Member

      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).

    14. ethanfurman commented on Jan 18, 2022

      @ethanfurman
      Member

      New changeset 7c0914d by Ethan Furman in branch 'main':
      bpo-45535: [Enum] include special dunders in dir() (GH-30677)
      7c0914d

    15. transferred this issue fromon Apr 10, 2022
    16. vstinner commented on Oct 2, 2025

      @vstinner
      Member

      @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?

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    Labels

    3.10 (EOL)end of life3.11only security fixesstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions