From b7dedc89f1ec476352f3678d0c55252159da27df Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 29 Oct 2016 12:44:29 -0700 Subject: [PATCH] Issue #28556: updates to typing.py (fix copy, deepcopy, pickle) --- Lib/test/test_typing.py | 19 +++++++++++++++++++ Lib/typing.py | 8 ++++++++ 2 files changed, 27 insertions(+) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 8e0a8c522fc..b50f36679d3 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4,6 +4,7 @@ import pickle import re import sys from unittest import TestCase, main, skipUnless, SkipTest +from copy import copy, deepcopy from typing import Any from typing import TypeVar, AnyStr @@ -845,6 +846,24 @@ class GenericTests(BaseTestCase): self.assertEqual(x.foo, 42) self.assertEqual(x.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): with self.assertRaises(TypeError): diff --git a/Lib/typing.py b/Lib/typing.py index bda4ea59c2a..572708b5ed6 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -190,6 +190,9 @@ class _FinalTypingBase(_TypingBase, _root=True): return self raise TypeError("Cannot instantiate %r" % cls) + def __reduce__(self): + return _trim_name(type(self).__name__) + class _ForwardRef(_TypingBase, _root=True): """Wrapper to hold a forward reference.""" @@ -1051,6 +1054,11 @@ class GenericMeta(TypingMeta, abc.ABCMeta): # classes are supposed to be rare anyways. 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. Generic = None