mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
277f55cb04
commit
ed136b9673
17
Lib/enum.py
17
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):
|
||||
|
|
|
@ -2646,6 +2646,7 @@ class TestSpecial(unittest.TestCase):
|
|||
self.assertEqual(Private._Private__corporal, 'Radar')
|
||||
self.assertEqual(Private._Private__major_, 'Hoolihan')
|
||||
|
||||
@unittest.skip("Accessing all values retained for performance reasons, see GH-93910")
|
||||
def test_exception_for_member_from_member_access(self):
|
||||
with self.assertRaisesRegex(AttributeError, "<enum .Di.> member has no attribute .NO."):
|
||||
class Di(Enum):
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
The ability to access the other values of an enum on an enum (e.g.
|
||||
``Color.RED.BLUE``) has been restored in order to fix a performance
|
||||
regression.
|
Loading…
Reference in New Issue