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

Lines changed: 3 additions & 0 deletions
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

Lines changed: 28 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy