Skip to content

[Enum] Deprecate member.member access with removal in 3.14 #95077

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

Closed
ethanfurman opened this issue Jul 21, 2022 · 6 comments
Closed

[Enum] Deprecate member.member access with removal in 3.14 #95077

ethanfurman opened this issue Jul 21, 2022 · 6 comments
Labels
3.12 only security fixes stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@ethanfurman
Copy link
Member

Accessing one enum member from another was originally forbidden, but added later to improve performance (but still warned against in the docs). Those performance issues are no longer a problem, and it is now possible to have deprecation warnings in the code to aid in transitioning away from such usage.

@ethanfurman ethanfurman added type-feature A feature request or enhancement stdlib Python modules in the Lib dir 3.12 only security fixes labels Jul 21, 2022
@brandtbucher
Copy link
Member

Those performance issues are no longer a problem

As somebody who hasn't been following enum changes very closely: why is this?

@ethanfurman
Copy link
Member Author

Performance timings on my system:

The code
import time
import enum

class Color(enum.Enum):
    RED = "Red"
    BLUE = "Blue"
    GREEN = "Green"
RED, BLUE, GREEN = Color

class FastColor:
    RED = Color.RED
    BLUE = Color.BLUE
    GREEN = Color.GREEN

def f():
    for _ in range(10000000):
        Color.RED
        Color.BLUE
        Color.GREEN

def g():
    for _ in range(10000000):
        FastColor.RED
        FastColor.BLUE
        FastColor.GREEN

def h():
    for _ in range(10000000):
        RED
        BLUE
        GREEN

import timeit
print(round(timeit.timeit('f()', number=1, globals=globals()), 2), end='  ')
print(round(timeit.timeit('g()', number=1, globals=globals()), 2), end='  ')
print(round(timeit.timeit('h()', number=1, globals=globals()), 2), end=' \n\n')
version enum "fast" enum global enum
3.9 2.23 0.78 0.41
3.10 2.68 0.91 0.47
3.11 2.29 0.72 0.21
3.12 2.21 0.62 0.14

The 3.12 timings are with every enum member being accessed via the enum.property descriptor (i.e. no enum members being stored directly in the enum class __dict__).

Out of curiosity I ran the above code with member.member access, both with and without the deprecation warning:

warning no warning
20.41 4.16

So updating code to be correct will keep performance to 3.11 levels (or better).

@JelleZijlstra
Copy link
Member

How are the timings for accessing Color.RED.value affected?

@ethanfurman
Copy link
Member Author

Those performance issues are no longer a problem

As somebody who hasn't been following enum changes very closely: why is this?

I can only imagine it's due to the work you and others have done. I had already noticed this in the other issue when comparing 3.10/3.11/3.12, and I was able to get another slight boost by storing the member directly in the descriptor and avoiding a dict lookup.

@ethanfurman
Copy link
Member Author

ethanfurman commented Jul 21, 2022

How are the timings for accessing Color.RED.value affected?

Some improvement, but I don't think I can take any credit for that (and those timings are not affected by this issue).

version enum property simple python descriptor standard property
3.9 5.96 4.9 2.11
3.10 5.64 5.01 2.18
3.11 3.67 3.46 1.58
3.12 3.03 2.75 0.78

@ethanfurman
Copy link
Member Author

I can make .name and .value normal properties (when no member by the same name exists), but when I tried that they stopped being reported by inspect and so also stopped showing up in pydoc.

ethanfurman added a commit that referenced this issue Jul 25, 2022
…r access (GH-95083)

* issue deprecation warning for member.member access
* always store member property in current class
* remove __getattr__
@ethanfurman ethanfurman closed this as not planned Won't fix, can't repro, duplicate, stale Apr 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.12 only security fixes stdlib Python modules in the Lib dir type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants