Skip to content

Commit 3fbf5c6

Browse files
gh-93820: Fix copy() regression in enum.Flag (GH-93876) (#93886)
GH-26658 introduced a regression in copy / pickle protocol for combined `enum.Flag`s. `copy.copy(re.A | re.I)` would fail with `AttributeError: ASCII|IGNORECASE`. `enum.Flag` now has a `__reduce_ex__()` method that reduces flags by combined value, not by combined name. (cherry picked from commit 05b32c1) Co-authored-by: Christian Heimes <christian@python.org> Co-authored-by: Christian Heimes <christian@python.org>
1 parent 7456109 commit 3fbf5c6

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

Lib/enum.py

+3
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,9 @@ class Flag(Enum, boundary=STRICT):
13721372
Support for flags
13731373
"""
13741374

1375+
def __reduce_ex__(self, proto):
1376+
return self.__class__, (self._value_, )
1377+
13751378
_numeric_repr_ = repr
13761379

13771380
def _generate_next_value_(name, start, count, last_values):

Lib/test/test_enum.py

+28
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import copy
12
import enum
23
import doctest
34
import inspect
@@ -732,6 +733,13 @@ def test_format_specs(self):
732733
self.assertFormatIsValue('{:5.2}', TE.third)
733734
self.assertFormatIsValue('{:f}', TE.third)
734735

736+
def test_copy(self):
737+
TE = self.MainEnum
738+
copied = copy.copy(TE)
739+
self.assertEqual(copied, TE)
740+
deep = copy.deepcopy(TE)
741+
self.assertEqual(deep, TE)
742+
735743

736744
class _FlagTests:
737745

@@ -2652,6 +2660,26 @@ class MyIntFlag(int, Flag):
26522660
self.assertTrue(isinstance(MyIntFlag.ONE | MyIntFlag.TWO, MyIntFlag), MyIntFlag.ONE | MyIntFlag.TWO)
26532661
self.assertTrue(isinstance(MyIntFlag.ONE | 2, MyIntFlag))
26542662

2663+
def test_int_flags_copy(self):
2664+
class MyIntFlag(IntFlag):
2665+
ONE = 1
2666+
TWO = 2
2667+
FOUR = 4
2668+
2669+
flags = MyIntFlag.ONE | MyIntFlag.TWO
2670+
copied = copy.copy(flags)
2671+
deep = copy.deepcopy(flags)
2672+
self.assertEqual(copied, flags)
2673+
self.assertEqual(deep, flags)
2674+
2675+
flags = MyIntFlag.ONE | MyIntFlag.TWO | 8
2676+
copied = copy.copy(flags)
2677+
deep = copy.deepcopy(flags)
2678+
self.assertEqual(copied, flags)
2679+
self.assertEqual(deep, flags)
2680+
self.assertEqual(copied.value, 1 | 2 | 8)
2681+
2682+
26552683
class TestOrder(unittest.TestCase):
26562684
"test usage of the `_order_` attribute"
26572685

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed a regression when :func:`copy.copy`-ing :class:`enum.Flag` with
2+
multiple flag members.

0 commit comments

Comments
 (0)