[Python-checkins] [3.11] gh-93820: Pickle enum.Flag by name (GH-93891). (GH-94288)
serhiy-storchaka
webhook-mailer at python.org
Sun Jun 26 07:24:20 EDT 2022
https://github.com/python/cpython/commit/1b27ec5ac62606b6b5da34dfb794d5975949f864
commit: 1b27ec5ac62606b6b5da34dfb794d5975949f864
branch: 3.11
author: Serhiy Storchaka <storchaka at gmail.com>
committer: serhiy-storchaka <storchaka at gmail.com>
date: 2022-06-26T14:24:04+03:00
summary:
[3.11] gh-93820: Pickle enum.Flag by name (GH-93891). (GH-94288)
(cherry picked from commit 536985814a7116f14c9bc90aa1b3e3d36d5b2367)
Co-authored-by: Serhiy Storchaka <storchaka at gmail.com>
files:
A Misc/NEWS.d/next/Library/2022-06-16-11-16-53.gh-issue-93820.00X0Y5.rst
M Lib/enum.py
M Lib/test/test_enum.py
diff --git a/Lib/enum.py b/Lib/enum.py
index 5bd4da918d718..e11093c6cf468 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -1286,7 +1286,21 @@ class Flag(Enum, boundary=STRICT):
"""
def __reduce_ex__(self, proto):
- return self.__class__, (self._value_, )
+ cls = self.__class__
+ unknown = self._value_ & ~cls._flag_mask_
+ member_value = self._value_ & cls._flag_mask_
+ if unknown and member_value:
+ return _or_, (cls(member_value), unknown)
+ for val in _iter_bits_lsb(member_value):
+ rest = member_value & ~val
+ if rest:
+ return _or_, (cls(rest), cls._value2member_map_.get(val))
+ else:
+ break
+ if self._name_ is None:
+ return cls, (self._value_,)
+ else:
+ return getattr, (cls, self._name_)
_numeric_repr_ = repr
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index c510f1b1cf714..ac5c52b2b303b 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -66,10 +66,27 @@ class FloatStooges(float, Enum):
class FlagStooges(Flag):
LARRY = 1
CURLY = 2
- MOE = 3
+ MOE = 4
except Exception as exc:
FlagStooges = exc
+class FlagStoogesWithZero(Flag):
+ NOFLAG = 0
+ LARRY = 1
+ CURLY = 2
+ MOE = 4
+
+class IntFlagStooges(IntFlag):
+ LARRY = 1
+ CURLY = 2
+ MOE = 4
+
+class IntFlagStoogesWithZero(IntFlag):
+ NOFLAG = 0
+ LARRY = 1
+ CURLY = 2
+ MOE = 4
+
# for pickle test and subclass tests
class Name(StrEnum):
BDFL = 'Guido van Rossum'
@@ -2964,9 +2981,32 @@ def test_programatic_function_from_dict(self):
def test_pickle(self):
if isinstance(FlagStooges, Exception):
raise FlagStooges
- test_pickle_dump_load(self.assertIs, FlagStooges.CURLY|FlagStooges.MOE)
+ test_pickle_dump_load(self.assertIs, FlagStooges.CURLY)
+ test_pickle_dump_load(self.assertEqual,
+ FlagStooges.CURLY|FlagStooges.MOE)
+ test_pickle_dump_load(self.assertEqual,
+ FlagStooges.CURLY&~FlagStooges.CURLY)
test_pickle_dump_load(self.assertIs, FlagStooges)
+ test_pickle_dump_load(self.assertIs, FlagStoogesWithZero.CURLY)
+ test_pickle_dump_load(self.assertEqual,
+ FlagStoogesWithZero.CURLY|FlagStoogesWithZero.MOE)
+ test_pickle_dump_load(self.assertIs, FlagStoogesWithZero.NOFLAG)
+
+ test_pickle_dump_load(self.assertIs, IntFlagStooges.CURLY)
+ test_pickle_dump_load(self.assertEqual,
+ IntFlagStooges.CURLY|IntFlagStooges.MOE)
+ test_pickle_dump_load(self.assertEqual,
+ IntFlagStooges.CURLY|IntFlagStooges.MOE|0x30)
+ test_pickle_dump_load(self.assertEqual, IntFlagStooges(0))
+ test_pickle_dump_load(self.assertEqual, IntFlagStooges(0x30))
+ test_pickle_dump_load(self.assertIs, IntFlagStooges)
+
+ test_pickle_dump_load(self.assertIs, IntFlagStoogesWithZero.CURLY)
+ test_pickle_dump_load(self.assertEqual,
+ IntFlagStoogesWithZero.CURLY|IntFlagStoogesWithZero.MOE)
+ test_pickle_dump_load(self.assertIs, IntFlagStoogesWithZero.NOFLAG)
+
@unittest.skipIf(
python_version >= (3, 12),
'__contains__ now returns True/False for all inputs',
diff --git a/Misc/NEWS.d/next/Library/2022-06-16-11-16-53.gh-issue-93820.00X0Y5.rst b/Misc/NEWS.d/next/Library/2022-06-16-11-16-53.gh-issue-93820.00X0Y5.rst
new file mode 100644
index 0000000000000..70bb1e6c0cd76
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-06-16-11-16-53.gh-issue-93820.00X0Y5.rst
@@ -0,0 +1 @@
+Pickle :class:`enum.Flag` by name.
More information about the Python-checkins
mailing list