]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-93820: Pickle enum.Flag by name (GH-93891). (GH-94288)
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 26 Jun 2022 11:24:04 +0000 (14:24 +0300)
committerGitHub <noreply@github.com>
Sun, 26 Jun 2022 11:24:04 +0000 (14:24 +0300)
(cherry picked from commit 536985814a7116f14c9bc90aa1b3e3d36d5b2367)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/enum.py
Lib/test/test_enum.py
Misc/NEWS.d/next/Library/2022-06-16-11-16-53.gh-issue-93820.00X0Y5.rst [new file with mode: 0644]

index 5bd4da918d718d42363a7aae81273228b04128c0..e11093c6cf46834027d3d4ab72d15e56ef547ceb 100644 (file)
@@ -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
 
index c510f1b1cf714fc305df7c2498e22f20b683aebe..ac5c52b2b303b3fc6d576f3f3d36e99e0243d1c0 100644 (file)
@@ -66,10 +66,27 @@ try:
     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 @@ class OldTestFlag(unittest.TestCase):
     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 (file)
index 0000000..70bb1e6
--- /dev/null
@@ -0,0 +1 @@
+Pickle :class:`enum.Flag` by name.