]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-45167: Fix deepcopying of GenericAlias (GH-28324) (GH-28368)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Wed, 15 Sep 2021 19:31:14 +0000 (12:31 -0700)
committerGitHub <noreply@github.com>
Wed, 15 Sep 2021 19:31:14 +0000 (21:31 +0200)
(cherry picked from commit 5dce51a8875d9639786741e962b3cb208596b096)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/test/test_genericalias.py
Misc/NEWS.d/next/Core and Builtins/2021-09-14-09-23-59.bpo-45167.CPSSoV.rst [new file with mode: 0644]
Objects/genericaliasobject.c

index ccf40b13d3a94c00eaf4c87cf5cbcce94646d7a0..f7072a48c7263da070590c41c93c484268008c5b 100644 (file)
@@ -2,6 +2,7 @@
 
 import unittest
 import pickle
+import copy
 from collections import (
     defaultdict, deque, OrderedDict, Counter, UserDict, UserList
 )
@@ -270,11 +271,30 @@ class BaseTest(unittest.TestCase):
 
     def test_pickle(self):
         alias = GenericAlias(list, T)
-        s = pickle.dumps(alias)
-        loaded = pickle.loads(s)
-        self.assertEqual(alias.__origin__, loaded.__origin__)
-        self.assertEqual(alias.__args__, loaded.__args__)
-        self.assertEqual(alias.__parameters__, loaded.__parameters__)
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            s = pickle.dumps(alias, proto)
+            loaded = pickle.loads(s)
+            self.assertEqual(loaded.__origin__, alias.__origin__)
+            self.assertEqual(loaded.__args__, alias.__args__)
+            self.assertEqual(loaded.__parameters__, alias.__parameters__)
+
+    def test_copy(self):
+        class X(list):
+            def __copy__(self):
+                return self
+            def __deepcopy__(self, memo):
+                return self
+
+        for origin in list, deque, X:
+            alias = GenericAlias(origin, T)
+            copied = copy.copy(alias)
+            self.assertEqual(copied.__origin__, alias.__origin__)
+            self.assertEqual(copied.__args__, alias.__args__)
+            self.assertEqual(copied.__parameters__, alias.__parameters__)
+            copied = copy.deepcopy(alias)
+            self.assertEqual(copied.__origin__, alias.__origin__)
+            self.assertEqual(copied.__args__, alias.__args__)
+            self.assertEqual(copied.__parameters__, alias.__parameters__)
 
     def test_union(self):
         a = typing.Union[list[int], list[str]]
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-09-14-09-23-59.bpo-45167.CPSSoV.rst b/Misc/NEWS.d/next/Core and Builtins/2021-09-14-09-23-59.bpo-45167.CPSSoV.rst
new file mode 100644 (file)
index 0000000..47755ae
--- /dev/null
@@ -0,0 +1 @@
+Fix deepcopying of :class:`types.GenericAlias` objects.
index 69ad8a6d8353a78063960a11831f38b195e36394..4ab762c00e2a660d00079829508711aba55f88cd 100644 (file)
@@ -405,6 +405,8 @@ static const char* const attr_exceptions[] = {
     "__mro_entries__",
     "__reduce_ex__",  // needed so we don't look up object.__reduce_ex__
     "__reduce__",
+    "__copy__",
+    "__deepcopy__",
     NULL,
 };