bpo-45577: test all pickle protocols in `test_zoneinfo` (GH-29167)

This commit is contained in:
Nikita Sobolev 2021-10-28 23:22:24 +03:00 committed by GitHub
parent 233841ab78
commit 66e6b3dcd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 44 deletions

View File

@ -1403,44 +1403,50 @@ def tzpath(self):
return [self.zoneinfo_data.tzpath]
def test_cache_hit(self):
zi_in = self.klass("Europe/Dublin")
pkl = pickle.dumps(zi_in)
zi_rt = pickle.loads(pkl)
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.subTest(proto=proto):
zi_in = self.klass("Europe/Dublin")
pkl = pickle.dumps(zi_in, protocol=proto)
zi_rt = pickle.loads(pkl)
with self.subTest(test="Is non-pickled ZoneInfo"):
self.assertIs(zi_in, zi_rt)
with self.subTest(test="Is non-pickled ZoneInfo"):
self.assertIs(zi_in, zi_rt)
zi_rt2 = pickle.loads(pkl)
with self.subTest(test="Is unpickled ZoneInfo"):
self.assertIs(zi_rt, zi_rt2)
zi_rt2 = pickle.loads(pkl)
with self.subTest(test="Is unpickled ZoneInfo"):
self.assertIs(zi_rt, zi_rt2)
def test_cache_miss(self):
zi_in = self.klass("Europe/Dublin")
pkl = pickle.dumps(zi_in)
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.subTest(proto=proto):
zi_in = self.klass("Europe/Dublin")
pkl = pickle.dumps(zi_in, protocol=proto)
del zi_in
self.klass.clear_cache() # Induce a cache miss
zi_rt = pickle.loads(pkl)
zi_rt2 = pickle.loads(pkl)
del zi_in
self.klass.clear_cache() # Induce a cache miss
zi_rt = pickle.loads(pkl)
zi_rt2 = pickle.loads(pkl)
self.assertIs(zi_rt, zi_rt2)
self.assertIs(zi_rt, zi_rt2)
def test_no_cache(self):
zi_no_cache = self.klass.no_cache("Europe/Dublin")
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.subTest(proto=proto):
zi_no_cache = self.klass.no_cache("Europe/Dublin")
pkl = pickle.dumps(zi_no_cache)
zi_rt = pickle.loads(pkl)
pkl = pickle.dumps(zi_no_cache, protocol=proto)
zi_rt = pickle.loads(pkl)
with self.subTest(test="Not the pickled object"):
self.assertIsNot(zi_rt, zi_no_cache)
with self.subTest(test="Not the pickled object"):
self.assertIsNot(zi_rt, zi_no_cache)
zi_rt2 = pickle.loads(pkl)
with self.subTest(test="Not a second unpickled object"):
self.assertIsNot(zi_rt, zi_rt2)
zi_rt2 = pickle.loads(pkl)
with self.subTest(test="Not a second unpickled object"):
self.assertIsNot(zi_rt, zi_rt2)
zi_cache = self.klass("Europe/Dublin")
with self.subTest(test="Not a cached object"):
self.assertIsNot(zi_rt, zi_cache)
zi_cache = self.klass("Europe/Dublin")
with self.subTest(test="Not a cached object"):
self.assertIsNot(zi_rt, zi_cache)
def test_from_file(self):
key = "Europe/Dublin"
@ -1456,35 +1462,38 @@ def test_from_file(self):
]
for zi, test_name in test_cases:
with self.subTest(test_name=test_name):
with self.assertRaises(pickle.PicklingError):
pickle.dumps(zi)
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.subTest(test_name=test_name, proto=proto):
with self.assertRaises(pickle.PicklingError):
pickle.dumps(zi, protocol=proto)
def test_pickle_after_from_file(self):
# This may be a bit of paranoia, but this test is to ensure that no
# global state is maintained in order to handle the pickle cache and
# from_file behavior, and that it is possible to interweave the
# constructors of each of these and pickling/unpickling without issues.
key = "Europe/Dublin"
zi = self.klass(key)
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.subTest(proto=proto):
key = "Europe/Dublin"
zi = self.klass(key)
pkl_0 = pickle.dumps(zi)
zi_rt_0 = pickle.loads(pkl_0)
self.assertIs(zi, zi_rt_0)
pkl_0 = pickle.dumps(zi, protocol=proto)
zi_rt_0 = pickle.loads(pkl_0)
self.assertIs(zi, zi_rt_0)
with open(self.zoneinfo_data.path_from_key(key), "rb") as f:
zi_ff = self.klass.from_file(f, key=key)
with open(self.zoneinfo_data.path_from_key(key), "rb") as f:
zi_ff = self.klass.from_file(f, key=key)
pkl_1 = pickle.dumps(zi)
zi_rt_1 = pickle.loads(pkl_1)
self.assertIs(zi, zi_rt_1)
pkl_1 = pickle.dumps(zi, protocol=proto)
zi_rt_1 = pickle.loads(pkl_1)
self.assertIs(zi, zi_rt_1)
with self.assertRaises(pickle.PicklingError):
pickle.dumps(zi_ff)
with self.assertRaises(pickle.PicklingError):
pickle.dumps(zi_ff, protocol=proto)
pkl_2 = pickle.dumps(zi)
zi_rt_2 = pickle.loads(pkl_2)
self.assertIs(zi, zi_rt_2)
pkl_2 = pickle.dumps(zi, protocol=proto)
zi_rt_2 = pickle.loads(pkl_2)
self.assertIs(zi, zi_rt_2)
class CZoneInfoPickleTest(ZoneInfoPickleTest):

View File

@ -0,0 +1 @@
Add subtests for all ``pickle`` protocols in ``test_zoneinfo``.