bpo-45167: Fix deepcopying of GenericAlias (GH-28324)

This commit is contained in:
Serhiy Storchaka 2021-09-15 21:25:41 +03:00 committed by GitHub
parent 84a6061e29
commit 5dce51a887
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 5 deletions

View File

@ -2,6 +2,7 @@
import unittest import unittest
import pickle import pickle
import copy
from collections import ( from collections import (
defaultdict, deque, OrderedDict, Counter, UserDict, UserList defaultdict, deque, OrderedDict, Counter, UserDict, UserList
) )
@ -270,11 +271,30 @@ class BaseTest(unittest.TestCase):
def test_pickle(self): def test_pickle(self):
alias = GenericAlias(list, T) alias = GenericAlias(list, T)
s = pickle.dumps(alias) for proto in range(pickle.HIGHEST_PROTOCOL + 1):
loaded = pickle.loads(s) s = pickle.dumps(alias, proto)
self.assertEqual(alias.__origin__, loaded.__origin__) loaded = pickle.loads(s)
self.assertEqual(alias.__args__, loaded.__args__) self.assertEqual(loaded.__origin__, alias.__origin__)
self.assertEqual(alias.__parameters__, loaded.__parameters__) 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): def test_union(self):
a = typing.Union[list[int], list[str]] a = typing.Union[list[int], list[str]]

View File

@ -0,0 +1 @@
Fix deepcopying of :class:`types.GenericAlias` objects.

View File

@ -418,6 +418,8 @@ static const char* const attr_exceptions[] = {
"__mro_entries__", "__mro_entries__",
"__reduce_ex__", // needed so we don't look up object.__reduce_ex__ "__reduce_ex__", // needed so we don't look up object.__reduce_ex__
"__reduce__", "__reduce__",
"__copy__",
"__deepcopy__",
NULL, NULL,
}; };