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

'__new__' is never shown in dir(SomeEnum) #90427

Closed
sobolevn opened this issue Jan 5, 2022 · 3 comments
Closed

'__new__' is never shown in dir(SomeEnum) #90427

sobolevn opened this issue Jan 5, 2022 · 3 comments
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@sobolevn
Copy link
Member

sobolevn commented Jan 5, 2022

BPO 46269
Nosy @ethanfurman, @sobolevn, @AlexWaygood
PRs
  • bpo-46269: remove special-casing of __new__ in Enum.__dir__ #30421
  • 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 = None
    closed_at = <Date 2022-01-14.12:09:05.490>
    created_at = <Date 2022-01-05.15:15:11.571>
    labels = ['type-bug', 'library']
    title = "'__new__' is never shown in `dir(SomeEnum)`"
    updated_at = <Date 2022-01-14.12:09:05.490>
    user = 'https://github.com/sobolevn'

    bugs.python.org fields:

    activity = <Date 2022-01-14.12:09:05.490>
    actor = 'sobolevn'
    assignee = 'none'
    closed = True
    closed_date = <Date 2022-01-14.12:09:05.490>
    closer = 'sobolevn'
    components = ['Library (Lib)']
    creation = <Date 2022-01-05.15:15:11.571>
    creator = 'sobolevn'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 46269
    keywords = ['patch']
    message_count = 3.0
    messages = ['409771', '409785', '409790']
    nosy_count = 3.0
    nosy_names = ['ethan.furman', 'sobolevn', 'AlexWaygood']
    pr_nums = ['30421']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue46269'
    versions = []

    @sobolevn
    Copy link
    Member Author

    sobolevn commented Jan 5, 2022

    Right now __new__ is marked to be special-cased in Enum.__dir__.
    It is generally ignored:
    But, (I think that was the original idea), when __new__ is overridden, it should be added to the output.

    But, this line is problematic: https://github.com/python/cpython/blame/46e4c257e7c26c813620232135781e6c53fe8d4d/Lib/enum.py#L656

    Why? Because self.__new__ is always EnumMeta.__new__. Original __new__ is renamed to _new_member_.

    This behavior is also not tested.

    So, my proposal is: let's always remove this method from __dir__. Why?

    • If we modify the check above to compare _new_member_, we will show __new__ as the output. It is kinda misleading
    • __new__ is not supposed to be overloaded in EnumMeta, it is very special
    • __new__ is a very basic thing. It would be kinda strange not to see it for some cases, but to see it for others. For example, all (?) other data types always show __new__, even if it is not explicitly defined:
    >>> class A:
    ...    def __new__(*args, **kwargs): ...
    ... 
    >>> assert '__new__' in dir(A)
    
    >>> class B: ...
    ... 
    >>> assert '__new__' in dir(B)
    

    I guess being consistent here (we don't show __new__ at all times) is better.

    I will send a PR that removes these two lines in a moment! Any other ideas are much appreciated!

    Related:

    @sobolevn sobolevn added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Jan 5, 2022
    @AlexWaygood
    Copy link
    Member

    Thanks, Nikita! My bad for not adding tests for __new__ in PR 29316.

    To confirm: yes, my idea in PR 29316 was that "__new__" (along with most enum dunders) should not show up in the output of dir(Enum), but should show up in dir(EnumSubclass) if and only if __new__ has been overridden outside of enum.py. That's because, unlike with most Python classes, the fact that enum.Enum has a __new__ method or a __format__ method doesn't really tell you very much about enum.Enum's behaviour, due to how magical enums are. But if it's been overridden in a custom Enum subclass, that does tell you that the enum class has special behaviour in some way — the HTTPStatus enum at Lib/http/init.py:6 is a really good example of that.

    But you're right: the existing code doesn't work as expected, at all:

    >>> from http import HTTPStatus
    >>> '__new__' in dir(HTTPStatus)
    False
    

    @ethanfurman
    Copy link
    Member

    New changeset 817a6bc by Nikita Sobolev in branch 'main':
    bpo-46269: [Enum] remove special-casing of __new__ in EnumType.__dir__ (GH-30421)
    817a6bc

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