bpo-43224: Implement pickling of TypeVarTuples (#32119)

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
Matthew Rahtz 2022-04-22 05:22:53 +01:00 committed by GitHub
parent 2551a6c92f
commit 5e130a8da4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 7 deletions

View file

@ -1,7 +1,7 @@
import contextlib
import collections
from collections import defaultdict
from functools import lru_cache
from functools import lru_cache, wraps
import inspect
import pickle
import re
@ -70,6 +70,18 @@ class BaseTestCase(TestCase):
f()
def all_pickle_protocols(test_func):
"""Runs `test_func` with various values for `proto` argument."""
@wraps(test_func)
def wrapper(self):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.subTest(pickle_proto=proto):
test_func(self, proto=proto)
return wrapper
class Employee:
pass
@ -911,6 +923,48 @@ class TypeVarTupleTests(BaseTestCase):
self.assertNotEqual(C[Unpack[Ts1]], C[Unpack[Ts2]])
class TypeVarTuplePicklingTests(BaseTestCase):
# These are slightly awkward tests to run, because TypeVarTuples are only
# picklable if defined in the global scope. We therefore need to push
# various things defined in these tests into the global scope with `global`
# statements at the start of each test.
@all_pickle_protocols
def test_pickling_then_unpickling_results_in_same_identity(self, proto):
global Ts1 # See explanation at start of class.
Ts1 = TypeVarTuple('Ts1')
Ts2 = pickle.loads(pickle.dumps(Ts1, proto))
self.assertIs(Ts1, Ts2)
@all_pickle_protocols
def test_pickling_then_unpickling_unpacked_results_in_same_identity(self, proto):
global Ts # See explanation at start of class.
Ts = TypeVarTuple('Ts')
unpacked1 = Unpack[Ts]
unpacked2 = pickle.loads(pickle.dumps(unpacked1, proto))
self.assertIs(unpacked1, unpacked2)
@all_pickle_protocols
def test_pickling_then_unpickling_tuple_with_typevartuple_equality(
self, proto
):
global T, Ts # See explanation at start of class.
T = TypeVar('T')
Ts = TypeVarTuple('Ts')
a1 = Tuple[Unpack[Ts]]
a2 = pickle.loads(pickle.dumps(a1, proto))
self.assertEqual(a1, a2)
a1 = Tuple[T, Unpack[Ts]]
a2 = pickle.loads(pickle.dumps(a1, proto))
self.assertEqual(a1, a2)
a1 = Tuple[int, Unpack[Ts]]
a2 = pickle.loads(pickle.dumps(a1, proto))
self.assertEqual(a1, a2)
class UnionTests(BaseTestCase):
def test_basics(self):