Issue #28556: updates to typing.py (fix copy, deepcopy, pickle)

This commit is contained in:
Guido van Rossum 2016-10-29 12:44:29 -07:00
parent 5fc25a873c
commit b7dedc89f1
2 changed files with 27 additions and 0 deletions

View file

@ -4,6 +4,7 @@ import pickle
import re import re
import sys import sys
from unittest import TestCase, main, skipUnless, SkipTest from unittest import TestCase, main, skipUnless, SkipTest
from copy import copy, deepcopy
from typing import Any from typing import Any
from typing import TypeVar, AnyStr from typing import TypeVar, AnyStr
@ -845,6 +846,24 @@ class GenericTests(BaseTestCase):
self.assertEqual(x.foo, 42) self.assertEqual(x.foo, 42)
self.assertEqual(x.bar, 'abc') self.assertEqual(x.bar, 'abc')
self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'})
simples = [Any, Union, Tuple, Callable, ClassVar, List, typing.Iterable]
for s in simples:
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
z = pickle.dumps(s, proto)
x = pickle.loads(z)
self.assertEqual(s, x)
def test_copy_and_deepcopy(self):
T = TypeVar('T')
class Node(Generic[T]): ...
things = [Union[T, int], Tuple[T, int], Callable[..., T], Callable[[int], int],
Tuple[Any, Any], Node[T], Node[int], Node[Any], typing.Iterable[T],
typing.Iterable[Any], typing.Iterable[int], typing.Dict[int, str],
typing.Dict[T, Any], ClassVar[int], ClassVar[List[T]], Tuple['T', 'T'],
Union['T', int], List['T'], typing.Mapping['T', int]]
for t in things + [Any]:
self.assertEqual(t, copy(t))
self.assertEqual(t, deepcopy(t))
def test_errors(self): def test_errors(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):

View file

@ -190,6 +190,9 @@ class _FinalTypingBase(_TypingBase, _root=True):
return self return self
raise TypeError("Cannot instantiate %r" % cls) raise TypeError("Cannot instantiate %r" % cls)
def __reduce__(self):
return _trim_name(type(self).__name__)
class _ForwardRef(_TypingBase, _root=True): class _ForwardRef(_TypingBase, _root=True):
"""Wrapper to hold a forward reference.""" """Wrapper to hold a forward reference."""
@ -1051,6 +1054,11 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
# classes are supposed to be rare anyways. # classes are supposed to be rare anyways.
return issubclass(instance.__class__, self) return issubclass(instance.__class__, self)
def __copy__(self):
return self.__class__(self.__name__, self.__bases__, dict(self.__dict__),
self.__parameters__, self.__args__, self.__origin__,
self.__extra__, self.__orig_bases__)
# Prevent checks for Generic to crash when defining Generic. # Prevent checks for Generic to crash when defining Generic.
Generic = None Generic = None