]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-150817: Speed up Flag bitwise operations (GH-150824)
authorBernát Gábor <gaborjbernat@gmail.com>
Thu, 4 Jun 2026 19:58:20 +0000 (12:58 -0700)
committerGitHub <noreply@github.com>
Thu, 4 Jun 2026 19:58:20 +0000 (12:58 -0700)
Flag.__or__, __and__ and __xor__ walked both operands on every call to reject
None values. Run that scan only when one of the operand values is actually
None, so valid combinations skip it. The TypeError and its message are
unchanged for the invalid cases.

Lib/enum.py
Misc/NEWS.d/next/Library/2026-06-02-15-44-57.gh-issue-150817.lpFCh0.rst [new file with mode: 0644]

index f97a5193492e602f928d1037408df02afce5d4e7..7aff36c94ce1dcf1be2e6bad774fc5371e2b8d64 100644 (file)
@@ -1620,10 +1620,14 @@ class Flag(Enum, boundary=STRICT):
         if other_value is NotImplemented:
             return NotImplemented
 
-        for flag in self, other:
-            if self._get_value(flag) is None:
-                raise TypeError(f"'{flag}' cannot be combined with other flags with |")
         value = self._value_
+        # _get_value(self) is self._value_ and _get_value(other) is
+        # other_value, so only walk the operands (to raise on the offending
+        # flag) when one of those values is actually None.
+        if value is None or other_value is None:
+            for flag in self, other:
+                if self._get_value(flag) is None:
+                    raise TypeError(f"'{flag}' cannot be combined with other flags with |")
         return self.__class__(value | other_value)
 
     def __and__(self, other):
@@ -1631,10 +1635,11 @@ class Flag(Enum, boundary=STRICT):
         if other_value is NotImplemented:
             return NotImplemented
 
-        for flag in self, other:
-            if self._get_value(flag) is None:
-                raise TypeError(f"'{flag}' cannot be combined with other flags with &")
         value = self._value_
+        if value is None or other_value is None:
+            for flag in self, other:
+                if self._get_value(flag) is None:
+                    raise TypeError(f"'{flag}' cannot be combined with other flags with &")
         return self.__class__(value & other_value)
 
     def __xor__(self, other):
@@ -1642,10 +1647,11 @@ class Flag(Enum, boundary=STRICT):
         if other_value is NotImplemented:
             return NotImplemented
 
-        for flag in self, other:
-            if self._get_value(flag) is None:
-                raise TypeError(f"'{flag}' cannot be combined with other flags with ^")
         value = self._value_
+        if value is None or other_value is None:
+            for flag in self, other:
+                if self._get_value(flag) is None:
+                    raise TypeError(f"'{flag}' cannot be combined with other flags with ^")
         return self.__class__(value ^ other_value)
 
     def __invert__(self):
diff --git a/Misc/NEWS.d/next/Library/2026-06-02-15-44-57.gh-issue-150817.lpFCh0.rst b/Misc/NEWS.d/next/Library/2026-06-02-15-44-57.gh-issue-150817.lpFCh0.rst
new file mode 100644 (file)
index 0000000..42532bb
--- /dev/null
@@ -0,0 +1,2 @@
+Speed up the ``|``, ``&`` and ``^`` operations on :class:`enum.Flag` members.
+Patch by Bernát Gábor.