From d4a8066c82a9b71c26d98c285db233fe2ef07517 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Thu, 4 Jun 2026 12:58:20 -0700 Subject: [PATCH] gh-150817: Speed up Flag bitwise operations (GH-150824) 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 | 24 ++++++++++++------- ...-06-02-15-44-57.gh-issue-150817.lpFCh0.rst | 2 ++ 2 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-06-02-15-44-57.gh-issue-150817.lpFCh0.rst diff --git a/Lib/enum.py b/Lib/enum.py index f97a5193492e..7aff36c94ce1 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -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 index 000000000000..42532bb0222c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-02-15-44-57.gh-issue-150817.lpFCh0.rst @@ -0,0 +1,2 @@ +Speed up the ``|``, ``&`` and ``^`` operations on :class:`enum.Flag` members. +Patch by Bernát Gábor. -- 2.47.3