From 3fbf5c6427c260eab41c37f6eb7f66b79ab4ea88 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 16 Jun 2022 20:56:20 -0700 Subject: 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 05b32c1c796d6c80479756ae898f488eac5f4f71) Co-authored-by: Christian Heimes Co-authored-by: Christian Heimes --- Lib/enum.py | 3 +++ Lib/test/test_enum.py | 28 ++++++++++++++++++++++ .../2022-06-15-21-20-02.gh-issue-93820.FAMLY8.rst | 2 ++ 3 files changed, 33 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-06-15-21-20-02.gh-issue-93820.FAMLY8.rst diff --git a/Lib/enum.py b/Lib/enum.py index fe521b1..091acb3 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -1372,6 +1372,9 @@ class Flag(Enum, boundary=STRICT): Support for flags """ + def __reduce_ex__(self, proto): + return self.__class__, (self._value_, ) + _numeric_repr_ = repr def _generate_next_value_(name, start, count, last_values): diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 56cebfe..b44c566 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -1,3 +1,4 @@ +import copy import enum import doctest import inspect @@ -732,6 +733,13 @@ class _MinimalOutputTests: self.assertFormatIsValue('{:5.2}', TE.third) self.assertFormatIsValue('{:f}', TE.third) + def test_copy(self): + TE = self.MainEnum + copied = copy.copy(TE) + self.assertEqual(copied, TE) + deep = copy.deepcopy(TE) + self.assertEqual(deep, TE) + class _FlagTests: @@ -2652,6 +2660,26 @@ class TestSpecial(unittest.TestCase): self.assertTrue(isinstance(MyIntFlag.ONE | MyIntFlag.TWO, MyIntFlag), MyIntFlag.ONE | MyIntFlag.TWO) self.assertTrue(isinstance(MyIntFlag.ONE | 2, MyIntFlag)) + def test_int_flags_copy(self): + class MyIntFlag(IntFlag): + ONE = 1 + TWO = 2 + FOUR = 4 + + flags = MyIntFlag.ONE | MyIntFlag.TWO + copied = copy.copy(flags) + deep = copy.deepcopy(flags) + self.assertEqual(copied, flags) + self.assertEqual(deep, flags) + + flags = MyIntFlag.ONE | MyIntFlag.TWO | 8 + copied = copy.copy(flags) + deep = copy.deepcopy(flags) + self.assertEqual(copied, flags) + self.assertEqual(deep, flags) + self.assertEqual(copied.value, 1 | 2 | 8) + + class TestOrder(unittest.TestCase): "test usage of the `_order_` attribute" diff --git a/Misc/NEWS.d/next/Library/2022-06-15-21-20-02.gh-issue-93820.FAMLY8.rst b/Misc/NEWS.d/next/Library/2022-06-15-21-20-02.gh-issue-93820.FAMLY8.rst new file mode 100644 index 0000000..e06d897 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-06-15-21-20-02.gh-issue-93820.FAMLY8.rst @@ -0,0 +1,2 @@ +Fixed a regression when :func:`copy.copy`-ing :class:`enum.Flag` with +multiple flag members. -- cgit v0.12