summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2022-07-07 12:01:09 (GMT)
committerGitHub <noreply@github.com>2022-07-07 12:01:09 (GMT)
commit65c431685b40583b877da573e41514d63217815d (patch)
tree60d6cf81492f08025e5d6ff2e481153a3a8824c3
parent421c4b025583df9396dbd6b1e0e90d4a8b6d083f (diff)
downloadcpython-65c431685b40583b877da573e41514d63217815d.zip
cpython-65c431685b40583b877da573e41514d63217815d.tar.gz
cpython-65c431685b40583b877da573e41514d63217815d.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/93910GH-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. (cherry picked from commit ed136b96737fdbeff864079d12904cb962c6cce5) Co-authored-by: Michael Droettboom <mdboom@gmail.com>
-rw-r--r--Lib/enum.py17
-rw-r--r--Lib/test/test_enum.py1
-rw-r--r--Misc/NEWS.d/next/Library/2022-07-06-14-45-12.gh-issue-93910.iZcp67.rst3
3 files changed, 13 insertions, 8 deletions
diff --git a/Lib/enum.py b/Lib/enum.py
index e11093c..e597191 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):
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index ac5c52b..f9a6627 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -2611,6 +2611,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):
diff --git a/Misc/NEWS.d/next/Library/2022-07-06-14-45-12.gh-issue-93910.iZcp67.rst b/Misc/NEWS.d/next/Library/2022-07-06-14-45-12.gh-issue-93910.iZcp67.rst
new file mode 100644
index 0000000..2e58911
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-07-06-14-45-12.gh-issue-93910.iZcp67.rst
@@ -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.