diff options
author | Michael Droettboom <mdboom@gmail.com> | 2022-07-07 11:26:56 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-07 11:26:56 (GMT) |
commit | ed136b96737fdbeff864079d12904cb962c6cce5 (patch) | |
tree | f8ec5bc48b2fdf0362d95c8d3f62b7a956d9b2c5 /Lib/enum.py | |
parent | 277f55cb04409ccdf651d43df5eb9dcb3ee3128c (diff) | |
download | cpython-ed136b96737fdbeff864079d12904cb962c6cce5.zip cpython-ed136b96737fdbeff864079d12904cb962c6cce5.tar.gz cpython-ed136b96737fdbeff864079d12904cb962c6cce5.tar.bz2 |
gh-93910: Fix enum performance regression (GH-94614)
This removes the performance regression in 3.11, **at the expense of not fixing
the "bug" that allows accessing values from values** (e.g. `Color.RED.BLUE`).
Using the benchmark @markshannon [presented](https://github.com/python/cpython/issues/93910#issuecomment-1165503032), the results are:
| Version | Enum | Fast enum | Normal class |
| --- | --- | --- | --- |
| 3.10 | 2.04 | 0.59 | 0.56 |
| 3.11 | 2.78 | 0.31 | 0.15 |
| This PR | 1.30 | 0.32 | 0.16 |
I share this mostly as information about the source of the regression, as this may be useful. It may be that the lower-risk approach for the beta is just to revert to a previously-known working state.
Diffstat (limited to 'Lib/enum.py')
-rw-r--r-- | Lib/enum.py | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/Lib/enum.py b/Lib/enum.py index 69216c9..652878c 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -309,16 +309,17 @@ class _proto_member: if descriptor and not need_override: # previous enum.property found, no further action needed pass - else: + elif descriptor and need_override: redirect = property() redirect.__set_name__(enum_class, member_name) - if descriptor and need_override: - # previous enum.property found, but some other inherited attribute - # is in the way; copy fget, fset, fdel to this one - redirect.fget = descriptor.fget - redirect.fset = descriptor.fset - redirect.fdel = descriptor.fdel + # Previous enum.property found, but some other inherited attribute + # is in the way; copy fget, fset, fdel to this one. + redirect.fget = descriptor.fget + redirect.fset = descriptor.fset + redirect.fdel = descriptor.fdel setattr(enum_class, member_name, redirect) + else: + setattr(enum_class, member_name, enum_member) # now add to _member_map_ (even aliases) enum_class._member_map_[member_name] = enum_member try: @@ -647,7 +648,7 @@ class EnumType(type): 'member order does not match _order_:\n %r\n %r' % (enum_class._member_names_, _order_) ) - # + return enum_class def __bool__(cls): |