Skip to content

[3.12] EnumMeta.__getattr__ removed without deprecation #106762

Description

@jacobtylerwalls

Bug report

>>> from enum import Enum
>>> class Color(Enum):
...     RED = "red"
... 

3.11

>>> Color.__getattr__("RED")
<Color.RED: 'red'>

3.12b4

>>> Color.__getattr__("RED")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Color' has no attribute '__getattr__'. Did you mean: '__getitem__'?

I see that __getattr__ is documented, so I would have expected either a deprecation notice or an entry in What's New for Python 3.12.

Linked PRs

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    3.12only security fixes
    3.13only security fixes
    on Jul 15, 2023
  2. ethanfurman commented on Jul 15, 2023

    @ethanfurman
    Member

    It's actually EnumMeta.__getattr__, but yes, it needs to be removed from the documentation as well as having a news entry.

  3. changed the title [-][3.12] `Enum.__getattr__` removed without deprecation[/-] [+][3.12] `EnumMeta.__getattr__` removed without deprecation[/+] on Jul 15, 2023
  4. jacobtylerwalls commented on Jul 15, 2023

    @jacobtylerwalls
    ContributorAuthor

    Do you remember what the rationale was for removing __getattr__ in 4e704d7? Most of that commit was reverted in #103236 but not the removal of __getattr__.

    The docs reference to __getattr__ was already removed in 6a980de.

  5. ethanfurman commented on Jul 17, 2023

    @ethanfurman
    Member

    It was the original method of looking up enum members, but it was quite slow; a more performant method is being used now.

    Do you have a situation where __getattr__ was being directly called?

  6. jacobtylerwalls commented on Jul 17, 2023

    @jacobtylerwalls
    ContributorAuthor

    Yes, I found it when trying to pass the pylint test suite against Python 3.12. Apparently the presence of a __getattr__ attribute is used as a heuristic for whether dot-access syntax is permitted, so pylint's linting of enums will have false negatives without a patch.

    Do you have a situation where getattr was being directly called?

    So, not called directly, but more like if getattr(EnumClass, "__getattr__"):

    A deprecation period would give just a little more runway to deal with that, but the patch probably isn't particularly involved.

  7. jacobtylerwalls commented on Jul 17, 2023

    @jacobtylerwalls
    ContributorAuthor

    What about just keeping __getattr__ as a shim for __getitem__?

  8. ethanfurman commented on Jul 17, 2023

    @ethanfurman
    Member

    Where is has_dynamic_getattr defined? Is it just looking for presence, or something more?

  9. jacobtylerwalls commented on Jul 17, 2023

    @jacobtylerwalls
    ContributorAuthor

    It's in an upstream dependency astroid. Here's has_dynamic_getattr: I'm fairly certain it just checks for presence. (When it calls self.getattr, it's checking for the presence of an entry in self.locals, where self is astroid's version of the ast node for the class, and locals is the set of names defined on the class, like this):

    # python 3.11
    (Pdb) self
    <ClassDef.Color l.2 at 0x106fb0910>
    (Pdb) self.metaclass()
    <ClassDef.EnumType l.468 at 0x1072c9450>
    (Pdb) '__getattr__' in self.metaclass().locals
    True
  10. jacobtylerwalls commented on Jul 22, 2023

    @jacobtylerwalls
    ContributorAuthor

    cc/ @Yhg1s to put on your radar for rc1.

  11. added a commit that references this issue on Jul 30, 2023
  12. added a commit that references this issue on Jul 31, 2023
  13. added a commit that references this issue on Jul 31, 2023
  14. added a commit that references this issue on Jul 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

3.12only security fixes3.13only security fixesstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions