|
1 | 1 | import contextlib |
2 | 2 | import collections |
3 | 3 | from collections import defaultdict |
4 | | -from functools import lru_cache |
| 4 | +from functools import lru_cache, wraps |
5 | 5 | import inspect |
6 | 6 | import pickle |
7 | 7 | import re |
@@ -70,6 +70,18 @@ def clear_caches(self): |
70 | 70 | f() |
71 | 71 |
|
72 | 72 |
|
| 73 | +def all_pickle_protocols(test_func): |
| 74 | + """Runs `test_func` with various values for `proto` argument.""" |
| 75 | + |
| 76 | + @wraps(test_func) |
| 77 | + def wrapper(self): |
| 78 | + for proto in range(pickle.HIGHEST_PROTOCOL + 1): |
| 79 | + with self.subTest(pickle_proto=proto): |
| 80 | + test_func(self, proto=proto) |
| 81 | + |
| 82 | + return wrapper |
| 83 | + |
| 84 | + |
73 | 85 | class Employee: |
74 | 86 | pass |
75 | 87 |
|
@@ -911,6 +923,48 @@ class C(Generic[Unpack[Ts]]): pass |
911 | 923 | self.assertNotEqual(C[Unpack[Ts1]], C[Unpack[Ts2]]) |
912 | 924 |
|
913 | 925 |
|
| 926 | +class TypeVarTuplePicklingTests(BaseTestCase): |
| 927 | + # These are slightly awkward tests to run, because TypeVarTuples are only |
| 928 | + # picklable if defined in the global scope. We therefore need to push |
| 929 | + # various things defined in these tests into the global scope with `global` |
| 930 | + # statements at the start of each test. |
| 931 | + |
| 932 | + @all_pickle_protocols |
| 933 | + def test_pickling_then_unpickling_results_in_same_identity(self, proto): |
| 934 | + global Ts1 # See explanation at start of class. |
| 935 | + Ts1 = TypeVarTuple('Ts1') |
| 936 | + Ts2 = pickle.loads(pickle.dumps(Ts1, proto)) |
| 937 | + self.assertIs(Ts1, Ts2) |
| 938 | + |
| 939 | + @all_pickle_protocols |
| 940 | + def test_pickling_then_unpickling_unpacked_results_in_same_identity(self, proto): |
| 941 | + global Ts # See explanation at start of class. |
| 942 | + Ts = TypeVarTuple('Ts') |
| 943 | + unpacked1 = Unpack[Ts] |
| 944 | + unpacked2 = pickle.loads(pickle.dumps(unpacked1, proto)) |
| 945 | + self.assertIs(unpacked1, unpacked2) |
| 946 | + |
| 947 | + @all_pickle_protocols |
| 948 | + def test_pickling_then_unpickling_tuple_with_typevartuple_equality( |
| 949 | + self, proto |
| 950 | + ): |
| 951 | + global T, Ts # See explanation at start of class. |
| 952 | + T = TypeVar('T') |
| 953 | + Ts = TypeVarTuple('Ts') |
| 954 | + |
| 955 | + a1 = Tuple[Unpack[Ts]] |
| 956 | + a2 = pickle.loads(pickle.dumps(a1, proto)) |
| 957 | + self.assertEqual(a1, a2) |
| 958 | + |
| 959 | + a1 = Tuple[T, Unpack[Ts]] |
| 960 | + a2 = pickle.loads(pickle.dumps(a1, proto)) |
| 961 | + self.assertEqual(a1, a2) |
| 962 | + |
| 963 | + a1 = Tuple[int, Unpack[Ts]] |
| 964 | + a2 = pickle.loads(pickle.dumps(a1, proto)) |
| 965 | + self.assertEqual(a1, a2) |
| 966 | + |
| 967 | + |
914 | 968 | class UnionTests(BaseTestCase): |
915 | 969 |
|
916 | 970 | def test_basics(self): |
|
0 commit comments