Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
serhiy-storchaka opened this issue Oct 20, 2021 · 11 comments
Closed

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

serhiy-storchaka opened this issue Oct 20, 2021 · 11 comments
Assignees
Labels
3.10 only security fixes 3.11 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@serhiy-storchaka
Copy link
Member

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']

    @serhiy-storchaka
    Copy link
    Member Author

    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.

    @serhiy-storchaka serhiy-storchaka added 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Oct 20, 2021
    @AlexWaygood
    Copy link
    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.

    @ethanfurman
    Copy link
    Member

    Looks interesting, thank you for the patch.

    @ethanfurman ethanfurman removed the 3.9 only security fixes label Oct 21, 2021
    @ethanfurman ethanfurman self-assigned this Oct 21, 2021
    @ethanfurman ethanfurman removed the 3.9 only security fixes label Oct 21, 2021
    @ethanfurman ethanfurman self-assigned this Oct 21, 2021
    @serhiy-storchaka
    Copy link
    Member Author

    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
    Copy link
    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.

    @serhiy-storchaka
    Copy link
    Member Author

    PR 29316 looks complicated.

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

    @ethanfurman
    Copy link
    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__.

    @AlexWaygood
    Copy link
    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.

    @ethanfurman
    Copy link
    Member

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

    @ethanfurman
    Copy link
    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).

    @ethanfurman
    Copy link
    Member

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

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.10 only security fixes 3.11 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants