From bad1257c96943dcb39584a41e1a178542479df97 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 15 Dec 2014 14:03:42 +0200 Subject: Issue #22777: Test pickling with all protocols. --- Lib/ctypes/test/test_pickling.py | 20 ++-- Lib/test/audiotests.py | 5 +- Lib/test/datetimetester.py | 11 +- Lib/test/seq_tests.py | 7 +- Lib/test/test_array.py | 21 ++-- Lib/test/test_bool.py | 7 +- Lib/test/test_builtin.py | 25 +++-- Lib/test/test_bytes.py | 33 +++--- Lib/test/test_bz2.py | 10 +- Lib/test/test_collections.py | 81 ++++++-------- Lib/test/test_configparser.py | 182 ++++++++++++++++--------------- Lib/test/test_decimal.py | 194 +++++++++++++++++---------------- Lib/test/test_deque.py | 43 ++++---- Lib/test/test_dict.py | 97 +++++++++-------- Lib/test/test_email/test_pickleable.py | 14 ++- Lib/test/test_enumerate.py | 29 ++--- Lib/test/test_functools.py | 5 +- Lib/test/test_iter.py | 33 +++--- Lib/test/test_itertools.py | 170 +++++++++++++++++------------ Lib/test/test_list.py | 42 +++---- Lib/test/test_lzma.py | 9 +- Lib/test/test_memoryio.py | 3 +- Lib/test/test_minidom.py | 75 ++++++------- Lib/test/test_os.py | 22 ++-- Lib/test/test_random.py | 14 ++- Lib/test/test_range.py | 46 ++++---- Lib/test/test_set.py | 48 ++++---- Lib/test/test_tuple.py | 42 +++---- Lib/test/test_xml_dom_minicompat.py | 25 +++-- Lib/test/test_xml_etree.py | 57 +++++----- 30 files changed, 725 insertions(+), 645 deletions(-) diff --git a/Lib/ctypes/test/test_pickling.py b/Lib/ctypes/test/test_pickling.py index 8c91222..c4a79b9 100644 --- a/Lib/ctypes/test/test_pickling.py +++ b/Lib/ctypes/test/test_pickling.py @@ -14,9 +14,9 @@ class X(Structure): class Y(X): _fields_ = [("str", c_char_p)] -class PickleTest(unittest.TestCase): +class PickleTest: def dumps(self, item): - return pickle.dumps(item) + return pickle.dumps(item, self.proto) def loads(self, item): return pickle.loads(item) @@ -67,17 +67,15 @@ class PickleTest(unittest.TestCase): self.assertRaises(ValueError, lambda: self.dumps(item)) def test_wchar(self): - pickle.dumps(c_char(b"x")) + self.dumps(c_char(b"x")) # Issue 5049 - pickle.dumps(c_wchar("x")) + self.dumps(c_wchar("x")) -class PickleTest_1(PickleTest): - def dumps(self, item): - return pickle.dumps(item, 1) - -class PickleTest_2(PickleTest): - def dumps(self, item): - return pickle.dumps(item, 2) +for proto in range(pickle.HIGHEST_PROTOCOL + 1): + name = 'PickleTest_%s' % proto + globals()[name] = type(name, + (PickleTest, unittest.TestCase), + {'proto': proto}) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/audiotests.py b/Lib/test/audiotests.py index b7497ce..0ae2242 100644 --- a/Lib/test/audiotests.py +++ b/Lib/test/audiotests.py @@ -45,8 +45,9 @@ class AudioTests: self.assertEqual(params.comptype, comptype) self.assertEqual(params.compname, compname) - dump = pickle.dumps(params) - self.assertEqual(pickle.loads(dump), params) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + dump = pickle.dumps(params, proto) + self.assertEqual(pickle.loads(dump), params) class AudioWriteTests(AudioTests): diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index cf496b4..f42b0f9 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1682,11 +1682,12 @@ class TestDateTime(TestDate): def test_more_pickling(self): a = self.theclass(2003, 2, 7, 16, 48, 37, 444116) - s = pickle.dumps(a) - b = pickle.loads(s) - self.assertEqual(b.year, 2003) - self.assertEqual(b.month, 2) - self.assertEqual(b.day, 7) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(a, proto) + b = pickle.loads(s) + self.assertEqual(b.year, 2003) + self.assertEqual(b.month, 2) + self.assertEqual(b.day, 7) def test_pickling_subclass_datetime(self): args = 6, 7, 23, 20, 59, 1, 64**2 diff --git a/Lib/test/seq_tests.py b/Lib/test/seq_tests.py index f185a82..9834af1 100644 --- a/Lib/test/seq_tests.py +++ b/Lib/test/seq_tests.py @@ -392,6 +392,7 @@ class CommonTest(unittest.TestCase): def test_pickle(self): lst = self.type2test([4, 5, 6, 7]) - lst2 = pickle.loads(pickle.dumps(lst)) - self.assertEqual(lst2, lst) - self.assertNotEqual(id(lst2), id(lst)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + lst2 = pickle.loads(pickle.dumps(lst, proto)) + self.assertEqual(lst2, lst) + self.assertNotEqual(id(lst2), id(lst)) diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index f8dbf06..07c9bf9 100644 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -285,17 +285,18 @@ class BaseTest: def test_iterator_pickle(self): data = array.array(self.typecode, self.example) - orgit = iter(data) - d = pickle.dumps(orgit) - it = pickle.loads(d) - self.assertEqual(type(orgit), type(it)) - self.assertEqual(list(it), list(data)) - - if len(data): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + orgit = iter(data) + d = pickle.dumps(orgit, proto) it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(list(it), list(data)[1:]) + self.assertEqual(type(orgit), type(it)) + self.assertEqual(list(it), list(data)) + + if len(data): + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(list(it), list(data)[1:]) def test_insert(self): a = array.array(self.typecode, self.example) diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py index 4bab28b..2507439 100644 --- a/Lib/test/test_bool.py +++ b/Lib/test/test_bool.py @@ -269,10 +269,9 @@ class BoolTest(unittest.TestCase): def test_pickle(self): import pickle - self.assertIs(pickle.loads(pickle.dumps(True)), True) - self.assertIs(pickle.loads(pickle.dumps(False)), False) - self.assertIs(pickle.loads(pickle.dumps(True, True)), True) - self.assertIs(pickle.loads(pickle.dumps(False, True)), False) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertIs(pickle.loads(pickle.dumps(True, proto)), True) + self.assertIs(pickle.loads(pickle.dumps(False, proto)), False) def test_picklevalues(self): # Test for specific backwards-compatible pickle values diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index b561a6f..14366c6 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -121,9 +121,9 @@ def map_char(arg): class BuiltinTest(unittest.TestCase): # Helper to check picklability - def check_iter_pickle(self, it, seq): + def check_iter_pickle(self, it, seq, proto): itorg = it - d = pickle.dumps(it) + d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(type(itorg), type(it)) self.assertEqual(list(it), seq) @@ -134,7 +134,7 @@ class BuiltinTest(unittest.TestCase): next(it) except StopIteration: return - d = pickle.dumps(it) + d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(list(it), seq[1:]) @@ -636,9 +636,10 @@ class BuiltinTest(unittest.TestCase): self.assertRaises(TypeError, list, filter(42, (1, 2))) def test_filter_pickle(self): - f1 = filter(filter_char, "abcdeabcde") - f2 = filter(filter_char, "abcdeabcde") - self.check_iter_pickle(f1, list(f2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + f1 = filter(filter_char, "abcdeabcde") + f2 = filter(filter_char, "abcdeabcde") + self.check_iter_pickle(f1, list(f2), proto) def test_getattr(self): self.assertTrue(getattr(sys, 'stdout') is sys.stdout) @@ -834,9 +835,10 @@ class BuiltinTest(unittest.TestCase): self.assertRaises(RuntimeError, list, map(badfunc, range(5))) def test_map_pickle(self): - m1 = map(map_char, "Is this the real life?") - m2 = map(map_char, "Is this the real life?") - self.check_iter_pickle(m1, list(m2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + m1 = map(map_char, "Is this the real life?") + m2 = map(map_char, "Is this the real life?") + self.check_iter_pickle(m1, list(m2), proto) def test_max(self): self.assertEqual(max('123123'), '3') @@ -1433,8 +1435,9 @@ class BuiltinTest(unittest.TestCase): a = (1, 2, 3) b = (4, 5, 6) t = [(1, 4), (2, 5), (3, 6)] - z1 = zip(a, b) - self.check_iter_pickle(z1, t) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z1 = zip(a, b) + self.check_iter_pickle(z1, t, proto) def test_format(self): # Test the basic machinery of the format() builtin. Don't test diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 7b66a5e..e15807e 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -555,22 +555,23 @@ class BaseBytesTest: self.assertEqual(b, q) def test_iterator_pickling(self): - for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0": - it = itorg = iter(self.type2test(b)) - data = list(self.type2test(b)) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(list(it), data) - - it = pickle.loads(d) - try: - next(it) - except StopIteration: - continue - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(list(it), data[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0": + it = itorg = iter(self.type2test(b)) + data = list(self.type2test(b)) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(list(it), data) + + it = pickle.loads(d) + try: + next(it) + except StopIteration: + continue + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(list(it), data[1:]) def test_strip(self): b = self.type2test(b'mississippi') diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py index 40d8425..ce012d6 100644 --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -646,8 +646,9 @@ class BZ2CompressorTest(BaseTest): data = None def testPickle(self): - with self.assertRaises(TypeError): - pickle.dumps(BZ2Compressor()) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises(TypeError): + pickle.dumps(BZ2Compressor(), proto) class BZ2DecompressorTest(BaseTest): @@ -702,8 +703,9 @@ class BZ2DecompressorTest(BaseTest): decompressed = None def testPickle(self): - with self.assertRaises(TypeError): - pickle.dumps(BZ2Decompressor()) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises(TypeError): + pickle.dumps(BZ2Decompressor(), proto) class CompressDecompressTest(BaseTest): diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 3724b22..df1c63c 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -63,10 +63,17 @@ class TestChainMap(unittest.TestCase): for m1, m2 in zip(d.maps[1:], e.maps[1:]): self.assertIs(m1, m2) - for e in [pickle.loads(pickle.dumps(d)), - copy.deepcopy(d), + # check deep copies + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + e = pickle.loads(pickle.dumps(d, proto)) + self.assertEqual(d, e) + self.assertEqual(d.maps, e.maps) + self.assertIsNot(d, e) + for m1, m2 in zip(d.maps, e.maps): + self.assertIsNot(m1, m2, e) + for e in [copy.deepcopy(d), eval(repr(d)) - ]: # check deep copies + ]: self.assertEqual(d, e) self.assertEqual(d.maps, e.maps) self.assertIsNot(d, e) @@ -1110,28 +1117,21 @@ class TestCounter(unittest.TestCase): # Check that counters are copyable, deepcopyable, picklable, and #have a repr/eval round-trip words = Counter('which witch had which witches wrist watch'.split()) + def check(dup): + msg = "\ncopy: %s\nwords: %s" % (dup, words) + self.assertIsNot(dup, words, msg) + self.assertEqual(dup, words) + check(words.copy()) + check(copy.copy(words)) + check(copy.deepcopy(words)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + check(pickle.loads(pickle.dumps(words, proto))) + check(eval(repr(words))) update_test = Counter() update_test.update(words) - for label, dup in [ - ('words.copy()', words.copy()), - ('copy.copy(words)', copy.copy(words)), - ('copy.deepcopy(words)', copy.deepcopy(words)), - ('pickle.loads(pickle.dumps(words, 0))', - pickle.loads(pickle.dumps(words, 0))), - ('pickle.loads(pickle.dumps(words, 1))', - pickle.loads(pickle.dumps(words, 1))), - ('pickle.loads(pickle.dumps(words, 2))', - pickle.loads(pickle.dumps(words, 2))), - ('pickle.loads(pickle.dumps(words, -1))', - pickle.loads(pickle.dumps(words, -1))), - ('eval(repr(words))', eval(repr(words))), - ('update_test', update_test), - ('Counter(words)', Counter(words)), - ]: - with self.subTest(label=label): - msg = "\ncopy: %s\nwords: %s" % (dup, words) - self.assertIsNot(dup, words, msg) - self.assertEqual(dup, words) + check(update_test) + check(Counter(words)) def test_copy_subclass(self): class MyCounter(Counter): @@ -1433,30 +1433,21 @@ class TestOrderedDict(unittest.TestCase): # and have a repr/eval round-trip pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] od = OrderedDict(pairs) + def check(dup): + msg = "\ncopy: %s\nod: %s" % (dup, od) + self.assertIsNot(dup, od, msg) + self.assertEqual(dup, od) + check(od.copy()) + check(copy.copy(od)) + check(copy.deepcopy(od)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + check(pickle.loads(pickle.dumps(od, proto))) + check(eval(repr(od))) update_test = OrderedDict() update_test.update(od) - for label, dup in [ - ('od.copy()', od.copy()), - ('copy.copy(od)', copy.copy(od)), - ('copy.deepcopy(od)', copy.deepcopy(od)), - ('pickle.loads(pickle.dumps(od, 0))', - pickle.loads(pickle.dumps(od, 0))), - ('pickle.loads(pickle.dumps(od, 1))', - pickle.loads(pickle.dumps(od, 1))), - ('pickle.loads(pickle.dumps(od, 2))', - pickle.loads(pickle.dumps(od, 2))), - ('pickle.loads(pickle.dumps(od, 3))', - pickle.loads(pickle.dumps(od, 3))), - ('pickle.loads(pickle.dumps(od, -1))', - pickle.loads(pickle.dumps(od, -1))), - ('eval(repr(od))', eval(repr(od))), - ('update_test', update_test), - ('OrderedDict(od)', OrderedDict(od)), - ]: - with self.subTest(label=label): - msg = "\ncopy: %s\nod: %s" % (dup, od) - self.assertIsNot(dup, od, msg) - self.assertEqual(dup, od) + check(update_test) + check(OrderedDict(od)) def test_yaml_linkage(self): # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature. diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 78bd315..09c229a 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -1591,104 +1591,113 @@ class ExceptionPicklingTestCase(unittest.TestCase): def test_error(self): import pickle e1 = configparser.Error('value') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(repr(e1), repr(e2)) def test_nosectionerror(self): import pickle e1 = configparser.NoSectionError('section') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(repr(e1), repr(e2)) def test_nooptionerror(self): import pickle e1 = configparser.NoOptionError('option', 'section') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(repr(e1), repr(e2)) def test_duplicatesectionerror(self): import pickle e1 = configparser.DuplicateSectionError('section', 'source', 123) - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.lineno, e2.lineno) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.lineno, e2.lineno) + self.assertEqual(repr(e1), repr(e2)) def test_duplicateoptionerror(self): import pickle e1 = configparser.DuplicateOptionError('section', 'option', 'source', 123) - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.lineno, e2.lineno) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.lineno, e2.lineno) + self.assertEqual(repr(e1), repr(e2)) def test_interpolationerror(self): import pickle e1 = configparser.InterpolationError('option', 'section', 'msg') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(repr(e1), repr(e2)) def test_interpolationmissingoptionerror(self): import pickle e1 = configparser.InterpolationMissingOptionError('option', 'section', 'rawval', 'reference') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(e1.reference, e2.reference) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(e1.reference, e2.reference) + self.assertEqual(repr(e1), repr(e2)) def test_interpolationsyntaxerror(self): import pickle e1 = configparser.InterpolationSyntaxError('option', 'section', 'msg') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(repr(e1), repr(e2)) def test_interpolationdeptherror(self): import pickle e1 = configparser.InterpolationDepthError('option', 'section', 'rawval') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(repr(e1), repr(e2)) def test_parsingerror(self): import pickle @@ -1696,36 +1705,39 @@ class ExceptionPicklingTestCase(unittest.TestCase): e1.append(1, 'line1') e1.append(2, 'line2') e1.append(3, 'line3') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.errors, e2.errors) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.errors, e2.errors) + self.assertEqual(repr(e1), repr(e2)) e1 = configparser.ParsingError(filename='filename') e1.append(1, 'line1') e1.append(2, 'line2') e1.append(3, 'line3') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.errors, e2.errors) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.errors, e2.errors) + self.assertEqual(repr(e1), repr(e2)) def test_missingsectionheadererror(self): import pickle e1 = configparser.MissingSectionHeaderError('filename', 123, 'line') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.line, e2.line) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.lineno, e2.lineno) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.line, e2.line) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.lineno, e2.lineno) + self.assertEqual(repr(e1), repr(e2)) class InlineCommentStrippingTestCase(unittest.TestCase): diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index b4c8c34..a178f6f 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -2406,54 +2406,55 @@ class PythonAPItests(unittest.TestCase): self.assertNotIsInstance(Decimal(0), numbers.Real) def test_pickle(self): - Decimal = self.decimal.Decimal - - savedecimal = sys.modules['decimal'] - - # Round trip - sys.modules['decimal'] = self.decimal - d = Decimal('-3.141590000') - p = pickle.dumps(d) - e = pickle.loads(p) - self.assertEqual(d, e) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + Decimal = self.decimal.Decimal - if C: - # Test interchangeability - x = C.Decimal('-3.123e81723') - y = P.Decimal('-3.123e81723') + savedecimal = sys.modules['decimal'] - sys.modules['decimal'] = C - sx = pickle.dumps(x) - sys.modules['decimal'] = P - r = pickle.loads(sx) - self.assertIsInstance(r, P.Decimal) - self.assertEqual(r, y) + # Round trip + sys.modules['decimal'] = self.decimal + d = Decimal('-3.141590000') + p = pickle.dumps(d, proto) + e = pickle.loads(p) + self.assertEqual(d, e) - sys.modules['decimal'] = P - sy = pickle.dumps(y) - sys.modules['decimal'] = C - r = pickle.loads(sy) - self.assertIsInstance(r, C.Decimal) - self.assertEqual(r, x) + if C: + # Test interchangeability + x = C.Decimal('-3.123e81723') + y = P.Decimal('-3.123e81723') - x = C.Decimal('-3.123e81723').as_tuple() - y = P.Decimal('-3.123e81723').as_tuple() + sys.modules['decimal'] = C + sx = pickle.dumps(x, proto) + sys.modules['decimal'] = P + r = pickle.loads(sx) + self.assertIsInstance(r, P.Decimal) + self.assertEqual(r, y) + + sys.modules['decimal'] = P + sy = pickle.dumps(y, proto) + sys.modules['decimal'] = C + r = pickle.loads(sy) + self.assertIsInstance(r, C.Decimal) + self.assertEqual(r, x) - sys.modules['decimal'] = C - sx = pickle.dumps(x) - sys.modules['decimal'] = P - r = pickle.loads(sx) - self.assertIsInstance(r, P.DecimalTuple) - self.assertEqual(r, y) + x = C.Decimal('-3.123e81723').as_tuple() + y = P.Decimal('-3.123e81723').as_tuple() - sys.modules['decimal'] = P - sy = pickle.dumps(y) - sys.modules['decimal'] = C - r = pickle.loads(sy) - self.assertIsInstance(r, C.DecimalTuple) - self.assertEqual(r, x) + sys.modules['decimal'] = C + sx = pickle.dumps(x, proto) + sys.modules['decimal'] = P + r = pickle.loads(sx) + self.assertIsInstance(r, P.DecimalTuple) + self.assertEqual(r, y) + + sys.modules['decimal'] = P + sy = pickle.dumps(y, proto) + sys.modules['decimal'] = C + r = pickle.loads(sy) + self.assertIsInstance(r, C.DecimalTuple) + self.assertEqual(r, x) - sys.modules['decimal'] = savedecimal + sys.modules['decimal'] = savedecimal def test_int(self): Decimal = self.decimal.Decimal @@ -2777,63 +2778,64 @@ class ContextAPItests(unittest.TestCase): def test_pickle(self): - Context = self.decimal.Context + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + Context = self.decimal.Context - savedecimal = sys.modules['decimal'] + savedecimal = sys.modules['decimal'] - # Round trip - sys.modules['decimal'] = self.decimal - c = Context() - e = pickle.loads(pickle.dumps(c)) - - self.assertEqual(c.prec, e.prec) - self.assertEqual(c.Emin, e.Emin) - self.assertEqual(c.Emax, e.Emax) - self.assertEqual(c.rounding, e.rounding) - self.assertEqual(c.capitals, e.capitals) - self.assertEqual(c.clamp, e.clamp) - self.assertEqual(c.flags, e.flags) - self.assertEqual(c.traps, e.traps) - - # Test interchangeability - combinations = [(C, P), (P, C)] if C else [(P, P)] - for dumper, loader in combinations: - for ri, _ in enumerate(RoundingModes): - for fi, _ in enumerate(OrderedSignals[dumper]): - for ti, _ in enumerate(OrderedSignals[dumper]): - - prec = random.randrange(1, 100) - emin = random.randrange(-100, 0) - emax = random.randrange(1, 100) - caps = random.randrange(2) - clamp = random.randrange(2) - - # One module dumps - sys.modules['decimal'] = dumper - c = dumper.Context( - prec=prec, Emin=emin, Emax=emax, - rounding=RoundingModes[ri], - capitals=caps, clamp=clamp, - flags=OrderedSignals[dumper][:fi], - traps=OrderedSignals[dumper][:ti] - ) - s = pickle.dumps(c) - - # The other module loads - sys.modules['decimal'] = loader - d = pickle.loads(s) - self.assertIsInstance(d, loader.Context) - - self.assertEqual(d.prec, prec) - self.assertEqual(d.Emin, emin) - self.assertEqual(d.Emax, emax) - self.assertEqual(d.rounding, RoundingModes[ri]) - self.assertEqual(d.capitals, caps) - self.assertEqual(d.clamp, clamp) - assert_signals(self, d, 'flags', OrderedSignals[loader][:fi]) - assert_signals(self, d, 'traps', OrderedSignals[loader][:ti]) - - sys.modules['decimal'] = savedecimal + # Round trip + sys.modules['decimal'] = self.decimal + c = Context() + e = pickle.loads(pickle.dumps(c, proto)) + + self.assertEqual(c.prec, e.prec) + self.assertEqual(c.Emin, e.Emin) + self.assertEqual(c.Emax, e.Emax) + self.assertEqual(c.rounding, e.rounding) + self.assertEqual(c.capitals, e.capitals) + self.assertEqual(c.clamp, e.clamp) + self.assertEqual(c.flags, e.flags) + self.assertEqual(c.traps, e.traps) + + # Test interchangeability + combinations = [(C, P), (P, C)] if C else [(P, P)] + for dumper, loader in combinations: + for ri, _ in enumerate(RoundingModes): + for fi, _ in enumerate(OrderedSignals[dumper]): + for ti, _ in enumerate(OrderedSignals[dumper]): + + prec = random.randrange(1, 100) + emin = random.randrange(-100, 0) + emax = random.randrange(1, 100) + caps = random.randrange(2) + clamp = random.randrange(2) + + # One module dumps + sys.modules['decimal'] = dumper + c = dumper.Context( + prec=prec, Emin=emin, Emax=emax, + rounding=RoundingModes[ri], + capitals=caps, clamp=clamp, + flags=OrderedSignals[dumper][:fi], + traps=OrderedSignals[dumper][:ti] + ) + s = pickle.dumps(c, proto) + + # The other module loads + sys.modules['decimal'] = loader + d = pickle.loads(s) + self.assertIsInstance(d, loader.Context) + + self.assertEqual(d.prec, prec) + self.assertEqual(d.Emin, emin) + self.assertEqual(d.Emax, emax) + self.assertEqual(d.rounding, RoundingModes[ri]) + self.assertEqual(d.capitals, caps) + self.assertEqual(d.clamp, clamp) + assert_signals(self, d, 'flags', OrderedSignals[loader][:fi]) + assert_signals(self, d, 'traps', OrderedSignals[loader][:ti]) + + sys.modules['decimal'] = savedecimal def test_equality_with_other_types(self): Decimal = self.decimal.Decimal diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py index 7bff1d2..5ecbc73 100644 --- a/Lib/test/test_deque.py +++ b/Lib/test/test_deque.py @@ -474,16 +474,17 @@ class TestBasic(unittest.TestCase): def test_iterator_pickle(self): data = deque(range(200)) - it = itorg = iter(data) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(list(it), list(data)) - - it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(list(it), list(data)[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + it = itorg = iter(data) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(list(it), list(data)) + + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(list(it), list(data)[1:]) def test_deepcopy(self): mut = [10] @@ -614,11 +615,12 @@ class TestSubclass(unittest.TestCase): self.assertEqual(type(d), type(e)) self.assertEqual(list(d), list(e)) - s = pickle.dumps(d) - e = pickle.loads(s) - self.assertNotEqual(id(d), id(e)) - self.assertEqual(type(d), type(e)) - self.assertEqual(list(d), list(e)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(d, proto) + e = pickle.loads(s) + self.assertNotEqual(id(d), id(e)) + self.assertEqual(type(d), type(e)) + self.assertEqual(list(d), list(e)) d = Deque('abcde', maxlen=4) @@ -630,11 +632,12 @@ class TestSubclass(unittest.TestCase): self.assertEqual(type(d), type(e)) self.assertEqual(list(d), list(e)) - s = pickle.dumps(d) - e = pickle.loads(s) - self.assertNotEqual(id(d), id(e)) - self.assertEqual(type(d), type(e)) - self.assertEqual(list(d), list(e)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(d, proto) + e = pickle.loads(s) + self.assertNotEqual(id(d), id(e)) + self.assertEqual(type(d), type(e)) + self.assertEqual(list(d), list(e)) ## def test_pickle(self): ## d = Deque('abc') diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 98d8a3b..c96d000 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -837,57 +837,60 @@ class DictTest(unittest.TestCase): self._tracked(MyDict()) def test_iterator_pickling(self): - data = {1:"a", 2:"b", 3:"c"} - it = iter(data) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(sorted(it), sorted(data)) - - it = pickle.loads(d) - try: - drop = next(it) - except StopIteration: - return - d = pickle.dumps(it) - it = pickle.loads(d) - del data[drop] - self.assertEqual(sorted(it), sorted(data)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + data = {1:"a", 2:"b", 3:"c"} + it = iter(data) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(sorted(it), sorted(data)) + + it = pickle.loads(d) + try: + drop = next(it) + except StopIteration: + continue + d = pickle.dumps(it, proto) + it = pickle.loads(d) + del data[drop] + self.assertEqual(sorted(it), sorted(data)) def test_itemiterator_pickling(self): - data = {1:"a", 2:"b", 3:"c"} - # dictviews aren't picklable, only their iterators - itorg = iter(data.items()) - d = pickle.dumps(itorg) - it = pickle.loads(d) - # note that the type of type of the unpickled iterator - # is not necessarily the same as the original. It is - # merely an object supporting the iterator protocol, yielding - # the same objects as the original one. - # self.assertEqual(type(itorg), type(it)) - self.assertTrue(isinstance(it, collections.abc.Iterator)) - self.assertEqual(dict(it), data) - - it = pickle.loads(d) - drop = next(it) - d = pickle.dumps(it) - it = pickle.loads(d) - del data[drop[0]] - self.assertEqual(dict(it), data) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + data = {1:"a", 2:"b", 3:"c"} + # dictviews aren't picklable, only their iterators + itorg = iter(data.items()) + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + # note that the type of type of the unpickled iterator + # is not necessarily the same as the original. It is + # merely an object supporting the iterator protocol, yielding + # the same objects as the original one. + # self.assertEqual(type(itorg), type(it)) + self.assertIsInstance(it, collections.abc.Iterator) + self.assertEqual(dict(it), data) + + it = pickle.loads(d) + drop = next(it) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + del data[drop[0]] + self.assertEqual(dict(it), data) def test_valuesiterator_pickling(self): - data = {1:"a", 2:"b", 3:"c"} - # data.values() isn't picklable, only its iterator - it = iter(data.values()) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(sorted(list(it)), sorted(list(data.values()))) - - it = pickle.loads(d) - drop = next(it) - d = pickle.dumps(it) - it = pickle.loads(d) - values = list(it) + [drop] - self.assertEqual(sorted(values), sorted(list(data.values()))) + for proto in range(pickle.HIGHEST_PROTOCOL): + data = {1:"a", 2:"b", 3:"c"} + # data.values() isn't picklable, only its iterator + it = iter(data.values()) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(sorted(list(it)), sorted(list(data.values()))) + + it = pickle.loads(d) + drop = next(it) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + values = list(it) + [drop] + self.assertEqual(sorted(values), sorted(list(data.values()))) def test_instance_dict_getattr_str_subclass(self): class Foo: diff --git a/Lib/test/test_email/test_pickleable.py b/Lib/test/test_email/test_pickleable.py index daa8d25..16b4467 100644 --- a/Lib/test/test_email/test_pickleable.py +++ b/Lib/test/test_email/test_pickleable.py @@ -30,9 +30,10 @@ class TestPickleCopyHeader(TestEmailBase): def header_as_pickle(self, name, value): header = self.header_factory(name, value) - p = pickle.dumps(header) - h = pickle.loads(p) - self.assertEqual(str(h), str(header)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(header, proto) + h = pickle.loads(p) + self.assertEqual(str(h), str(header)) @parameterize @@ -65,9 +66,10 @@ class TestPickleCopyMessage(TestEmailBase): self.assertEqual(msg2.as_string(), msg.as_string()) def msg_as_pickle(self, msg): - p = pickle.dumps(msg) - msg2 = pickle.loads(p) - self.assertEqual(msg2.as_string(), msg.as_string()) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(msg, proto) + msg2 = pickle.loads(p) + self.assertEqual(msg2.as_string(), msg.as_string()) if __name__ == '__main__': diff --git a/Lib/test/test_enumerate.py b/Lib/test/test_enumerate.py index 8742afc..e85254c 100644 --- a/Lib/test/test_enumerate.py +++ b/Lib/test/test_enumerate.py @@ -66,20 +66,21 @@ class N: class PickleTest: # Helper to check picklability def check_pickle(self, itorg, seq): - d = pickle.dumps(itorg) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(list(it), seq) - - it = pickle.loads(d) - try: - next(it) - except StopIteration: - self.assertFalse(seq[1:]) - return - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(list(it), seq[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(list(it), seq) + + it = pickle.loads(d) + try: + next(it) + except StopIteration: + self.assertFalse(seq[1:]) + continue + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(list(it), seq[1:]) class EnumerateTestCase(unittest.TestCase, PickleTest): diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index a7e5c7e..1012053 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -182,8 +182,9 @@ class TestPartialC(TestPartial, unittest.TestCase): def test_pickle(self): f = self.partial(signature, 'asdf', bar=True) f.add_something_to__dict__ = True - f_copy = pickle.loads(pickle.dumps(f)) - self.assertEqual(signature(f), signature(f_copy)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + f_copy = pickle.loads(pickle.dumps(f, proto)) + self.assertEqual(signature(f), signature(f_copy)) # Issue 6083: Reference counting bug def test_setstate_refcount(self): diff --git a/Lib/test/test_iter.py b/Lib/test/test_iter.py index 43f8e15..e06f239 100644 --- a/Lib/test/test_iter.py +++ b/Lib/test/test_iter.py @@ -76,22 +76,23 @@ class TestCase(unittest.TestCase): # Helper to check picklability def check_pickle(self, itorg, seq): - d = pickle.dumps(itorg) - it = pickle.loads(d) - # Cannot assert type equality because dict iterators unpickle as list - # iterators. - # self.assertEqual(type(itorg), type(it)) - self.assertTrue(isinstance(it, collections.abc.Iterator)) - self.assertEqual(list(it), seq) - - it = pickle.loads(d) - try: - next(it) - except StopIteration: - return - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(list(it), seq[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + # Cannot assert type equality because dict iterators unpickle as list + # iterators. + # self.assertEqual(type(itorg), type(it)) + self.assertTrue(isinstance(it, collections.abc.Iterator)) + self.assertEqual(list(it), seq) + + it = pickle.loads(d) + try: + next(it) + except StopIteration: + continue + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(list(it), seq[1:]) # Test basic use of iter() function def test_iter_basic(self): diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index 5f33d39..511094e 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -74,9 +74,12 @@ def testR2(r): def underten(x): return x<10 +picklecopiers = [lambda s, proto=proto: pickle.loads(pickle.dumps(s, proto)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1)] + class TestBasicOps(unittest.TestCase): - def pickletest(self, it, stop=4, take=1, compare=None): + def pickletest(self, protocol, it, stop=4, take=1, compare=None): """Test that an iterator is the same after pickling, also when part-consumed""" def expand(it, i=0): # Recursively expand iterables, within sensible bounds @@ -91,7 +94,7 @@ class TestBasicOps(unittest.TestCase): return [expand(e, i+1) for e in l] # Test the initial copy against the original - dump = pickle.dumps(it) + dump = pickle.dumps(it, protocol) i2 = pickle.loads(dump) self.assertEqual(type(it), type(i2)) a, b = expand(it), expand(i2) @@ -109,7 +112,7 @@ class TestBasicOps(unittest.TestCase): took += 1 except StopIteration: pass #in case there is less data than 'take' - dump = pickle.dumps(i3) + dump = pickle.dumps(i3, protocol) i4 = pickle.loads(dump) a, b = expand(i3), expand(i4) self.assertEqual(a, b) @@ -143,7 +146,8 @@ class TestBasicOps(unittest.TestCase): [2, 16, 144, 720, 5040, 0, 0, 0, 0, 0]) with self.assertRaises(TypeError): list(accumulate(s, chr)) # unary-operation - self.pickletest(accumulate(range(10))) # test pickling + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, accumulate(range(10))) # test pickling def test_chain(self): @@ -168,9 +172,7 @@ class TestBasicOps(unittest.TestCase): self.assertRaises(TypeError, list, chain.from_iterable([2, 3])) def test_chain_reducible(self): - operators = [copy.deepcopy, - lambda s: pickle.loads(pickle.dumps(s))] - for oper in operators: + for oper in [copy.deepcopy] + picklecopiers: it = chain('abc', 'def') self.assertEqual(list(oper(it)), list('abcdef')) self.assertEqual(next(it), 'a') @@ -179,7 +181,8 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(list(oper(chain(''))), []) self.assertEqual(take(4, oper(chain('abc', 'def'))), list('abcd')) self.assertRaises(TypeError, list, oper(chain(2, 3))) - self.pickletest(chain('abc', 'def'), compare=list('abcdef')) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, chain('abc', 'def'), compare=list('abcdef')) def test_combinations(self): self.assertRaises(TypeError, combinations, 'abc') # missing r argument @@ -187,7 +190,7 @@ class TestBasicOps(unittest.TestCase): self.assertRaises(TypeError, combinations, None) # pool is not iterable self.assertRaises(ValueError, combinations, 'abc', -2) # r is negative - for op in (lambda a:a, lambda a:pickle.loads(pickle.dumps(a))): + for op in [lambda a:a] + picklecopiers: self.assertEqual(list(op(combinations('abc', 32))), []) # r > n self.assertEqual(list(op(combinations('ABCD', 2))), @@ -258,7 +261,8 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(result, list(combinations2(values, r))) # matches second pure python version self.assertEqual(result, list(combinations3(values, r))) # matches second pure python version - self.pickletest(combinations(values, r)) # test pickling + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, combinations(values, r)) # test pickling # Test implementation detail: tuple re-use @support.impl_detail("tuple reuse is specific to CPython") @@ -273,7 +277,7 @@ class TestBasicOps(unittest.TestCase): self.assertRaises(TypeError, cwr, None) # pool is not iterable self.assertRaises(ValueError, cwr, 'abc', -2) # r is negative - for op in (lambda a:a, lambda a:pickle.loads(pickle.dumps(a))): + for op in [lambda a:a] + picklecopiers: self.assertEqual(list(op(cwr('ABC', 2))), [('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C')]) testIntermediate = cwr('ABC', 2) @@ -339,7 +343,8 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(result, list(cwr1(values, r))) # matches first pure python version self.assertEqual(result, list(cwr2(values, r))) # matches second pure python version - self.pickletest(cwr(values,r)) # test pickling + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, cwr(values,r)) # test pickling # Test implementation detail: tuple re-use @@ -409,7 +414,8 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(result, list(permutations(values, None))) # test r as None self.assertEqual(result, list(permutations(values))) # test default r - self.pickletest(permutations(values, r)) # test pickling + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, permutations(values, r)) # test pickling @support.impl_detail("tuple reuse is specific to CPython") def test_permutations_tuple_reuse(self): @@ -466,7 +472,7 @@ class TestBasicOps(unittest.TestCase): self.assertRaises(TypeError, compress, range(6), None) # too many args # check copy, deepcopy, pickle - for op in (lambda a:copy.copy(a), lambda a:copy.deepcopy(a), lambda a:pickle.loads(pickle.dumps(a))): + for op in [lambda a:copy.copy(a), lambda a:copy.deepcopy(a)] + picklecopiers: for data, selectors, result1, result2 in [ ('ABCDEF', [1,0,1,0,1,1], 'ACEF', 'CEF'), ('ABCDEF', [0,0,0,0,0,0], '', ''), @@ -517,7 +523,8 @@ class TestBasicOps(unittest.TestCase): c = count(value) self.assertEqual(next(copy.copy(c)), value) self.assertEqual(next(copy.deepcopy(c)), value) - self.pickletest(count(value)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, count(value)) #check proper internal error handling for large "step' sizes count(1, maxsize+5); sys.exc_info() @@ -564,7 +571,8 @@ class TestBasicOps(unittest.TestCase): else: r2 = ('count(%r, %r)' % (i, j)) self.assertEqual(r1, r2) - self.pickletest(count(i, j)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, count(i, j)) def test_cycle(self): self.assertEqual(take(10, cycle('abc')), list('abcabcabca')) @@ -580,10 +588,16 @@ class TestBasicOps(unittest.TestCase): #an internal iterator #self.assertEqual(take(10, copy.copy(c)), list('bcabcabcab')) self.assertEqual(take(10, copy.deepcopy(c)), list('bcabcabcab')) - self.assertEqual(take(10, pickle.loads(pickle.dumps(c))), list('bcabcabcab')) - next(c) - self.assertEqual(take(10, pickle.loads(pickle.dumps(c))), list('cabcabcabc')) - self.pickletest(cycle('abc')) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertEqual(take(10, pickle.loads(pickle.dumps(c, proto))), + list('bcabcabcab')) + next(c) + self.assertEqual(take(10, pickle.loads(pickle.dumps(c, proto))), + list('cabcabcabc')) + next(c) + next(c) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, cycle('abc')) def test_groupby(self): # Check whether it accepts arguments correctly @@ -604,12 +618,13 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(s, dup) # Check normal pickled - dup = [] - for k, g in pickle.loads(pickle.dumps(groupby(s, testR))): - for elem in g: - self.assertEqual(k, elem[0]) - dup.append(elem) - self.assertEqual(s, dup) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + dup = [] + for k, g in pickle.loads(pickle.dumps(groupby(s, testR), proto)): + for elem in g: + self.assertEqual(k, elem[0]) + dup.append(elem) + self.assertEqual(s, dup) # Check nested case dup = [] @@ -622,14 +637,15 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(s, dup) # Check nested and pickled - dup = [] - for k, g in pickle.loads(pickle.dumps(groupby(s, testR))): - for ik, ig in pickle.loads(pickle.dumps(groupby(g, testR2))): - for elem in ig: - self.assertEqual(k, elem[0]) - self.assertEqual(ik, elem[2]) - dup.append(elem) - self.assertEqual(s, dup) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + dup = [] + for k, g in pickle.loads(pickle.dumps(groupby(s, testR), proto)): + for ik, ig in pickle.loads(pickle.dumps(groupby(g, testR2), proto)): + for elem in ig: + self.assertEqual(k, elem[0]) + self.assertEqual(ik, elem[2]) + dup.append(elem) + self.assertEqual(s, dup) # Check case where inner iterator is not used @@ -711,12 +727,14 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(list(copy.copy(c)), ans) c = filter(isEven, range(6)) self.assertEqual(list(copy.deepcopy(c)), ans) - c = filter(isEven, range(6)) - self.assertEqual(list(pickle.loads(pickle.dumps(c))), ans) - next(c) - self.assertEqual(list(pickle.loads(pickle.dumps(c))), ans[1:]) - c = filter(isEven, range(6)) - self.pickletest(c) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + c = filter(isEven, range(6)) + self.assertEqual(list(pickle.loads(pickle.dumps(c, proto))), ans) + next(c) + self.assertEqual(list(pickle.loads(pickle.dumps(c, proto))), ans[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + c = filter(isEven, range(6)) + self.pickletest(proto, c) def test_filterfalse(self): self.assertEqual(list(filterfalse(isEven, range(6))), [1,3,5]) @@ -728,7 +746,8 @@ class TestBasicOps(unittest.TestCase): self.assertRaises(TypeError, filterfalse, lambda x:x, range(6), 7) self.assertRaises(TypeError, filterfalse, isEven, 3) self.assertRaises(TypeError, next, filterfalse(range(6), range(6))) - self.pickletest(filterfalse(isEven, range(6))) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, filterfalse(isEven, range(6))) def test_zip(self): # XXX This is rather silly now that builtin zip() calls zip()... @@ -760,15 +779,18 @@ class TestBasicOps(unittest.TestCase): ans = [(x,y) for x, y in copy.deepcopy(zip('abc',count()))] self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) - ans = [(x,y) for x, y in pickle.loads(pickle.dumps(zip('abc',count())))] - self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + ans = [(x,y) for x, y in pickle.loads(pickle.dumps(zip('abc',count()), proto))] + self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) - testIntermediate = zip('abc',count()) - next(testIntermediate) - ans = [(x,y) for x, y in pickle.loads(pickle.dumps(testIntermediate))] - self.assertEqual(ans, [('b', 1), ('c', 2)]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + testIntermediate = zip('abc',count()) + next(testIntermediate) + ans = [(x,y) for x, y in pickle.loads(pickle.dumps(testIntermediate, proto))] + self.assertEqual(ans, [('b', 1), ('c', 2)]) - self.pickletest(zip('abc', count())) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, zip('abc', count())) def test_ziplongest(self): for args in [ @@ -820,10 +842,11 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(len(dict.fromkeys(ids)), len(ids)) def test_zip_longest_pickling(self): - self.pickletest(zip_longest("abc", "def")) - self.pickletest(zip_longest("abc", "defgh")) - self.pickletest(zip_longest("abc", "defgh", fillvalue=1)) - self.pickletest(zip_longest("", "defgh")) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, zip_longest("abc", "def")) + self.pickletest(proto, zip_longest("abc", "defgh")) + self.pickletest(proto, zip_longest("abc", "defgh", fillvalue=1)) + self.pickletest(proto, zip_longest("", "defgh")) def test_bug_7244(self): @@ -940,7 +963,8 @@ class TestBasicOps(unittest.TestCase): ]: self.assertEqual(list(copy.copy(product(*args))), result) self.assertEqual(list(copy.deepcopy(product(*args))), result) - self.pickletest(product(*args)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, product(*args)) def test_repeat(self): self.assertEqual(list(repeat(object='a', times=3)), ['a', 'a', 'a']) @@ -965,7 +989,8 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(next(c), 'a') self.assertEqual(take(2, copy.copy(c)), list('a' * 2)) self.assertEqual(take(2, copy.deepcopy(c)), list('a' * 2)) - self.pickletest(repeat(object='a', times=10)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, repeat(object='a', times=10)) def test_repeat_with_negative_times(self): self.assertEqual(repr(repeat('a', -1)), "repeat('a', 0)") @@ -999,8 +1024,9 @@ class TestBasicOps(unittest.TestCase): c = map(tupleize, 'abc', count()) self.assertEqual(list(copy.deepcopy(c)), ans) - c = map(tupleize, 'abc', count()) - self.pickletest(c) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + c = map(tupleize, 'abc', count()) + self.pickletest(proto, c) def test_starmap(self): self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))), @@ -1025,8 +1051,9 @@ class TestBasicOps(unittest.TestCase): c = starmap(operator.pow, zip(range(3), range(1,7))) self.assertEqual(list(copy.deepcopy(c)), ans) - c = starmap(operator.pow, zip(range(3), range(1,7))) - self.pickletest(c) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + c = starmap(operator.pow, zip(range(3), range(1,7))) + self.pickletest(proto, c) def test_islice(self): for args in [ # islice(args) should agree with range(args) @@ -1091,7 +1118,8 @@ class TestBasicOps(unittest.TestCase): list(range(*args))) self.assertEqual(list(copy.deepcopy(islice(range(100), *args))), list(range(*args))) - self.pickletest(islice(range(100), *args)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, islice(range(100), *args)) # Issue #21321: check source iterator is not referenced # from islice() after the latter has been exhausted @@ -1120,7 +1148,8 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(list(copy.copy(takewhile(underten, data))), [1, 3, 5]) self.assertEqual(list(copy.deepcopy(takewhile(underten, data))), [1, 3, 5]) - self.pickletest(takewhile(underten, data)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, takewhile(underten, data)) def test_dropwhile(self): data = [1, 3, 5, 20, 2, 4, 6, 8] @@ -1136,7 +1165,8 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(list(copy.copy(dropwhile(underten, data))), [20, 2, 4, 6, 8]) self.assertEqual(list(copy.deepcopy(dropwhile(underten, data))), [20, 2, 4, 6, 8]) - self.pickletest(dropwhile(underten, data)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, dropwhile(underten, data)) def test_tee(self): n = 200 @@ -1280,10 +1310,11 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(list(b), long_ans[60:]) # check pickle - self.pickletest(iter(tee('abc'))) - a, b = tee('abc') - self.pickletest(a, compare=ans) - self.pickletest(b, compare=ans) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, iter(tee('abc'))) + a, b = tee('abc') + self.pickletest(proto, a, compare=ans) + self.pickletest(proto, b, compare=ans) # Issue 13454: Crash when deleting backward iterator from tee() def test_tee_del_backward(self): @@ -1323,11 +1354,14 @@ class TestExamples(unittest.TestCase): # check copy, deepcopy, pickle data = [1, 2, 3, 4, 5] accumulated = [1, 3, 6, 10, 15] - it = accumulate(data) - self.assertEqual(list(pickle.loads(pickle.dumps(it))), accumulated[:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + it = accumulate(data) + self.assertEqual(list(pickle.loads(pickle.dumps(it, proto))), accumulated[:]) + self.assertEqual(next(it), 1) + self.assertEqual(list(pickle.loads(pickle.dumps(it, proto))), accumulated[1:]) + it = accumulate(data) self.assertEqual(next(it), 1) - self.assertEqual(list(pickle.loads(pickle.dumps(it))), accumulated[1:]) self.assertEqual(list(copy.deepcopy(it)), accumulated[1:]) self.assertEqual(list(copy.copy(it)), accumulated[1:]) diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py index 5df27d3..3b94700 100644 --- a/Lib/test/test_list.py +++ b/Lib/test/test_list.py @@ -74,29 +74,31 @@ class ListTest(list_tests.CommonTest): # Userlist iterators don't support pickling yet since # they are based on generators. data = self.type2test([4, 5, 6, 7]) - it = itorg = iter(data) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(self.type2test(it), self.type2test(data)) - - it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(self.type2test(it), self.type2test(data)[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + it = itorg = iter(data) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(self.type2test(it), self.type2test(data)) + + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(self.type2test(it), self.type2test(data)[1:]) def test_reversed_pickle(self): data = self.type2test([4, 5, 6, 7]) - it = itorg = reversed(data) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(self.type2test(it), self.type2test(reversed(data))) - - it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(self.type2test(it), self.type2test(reversed(data))[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + it = itorg = reversed(data) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(self.type2test(it), self.type2test(reversed(data))) + + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(self.type2test(it), self.type2test(reversed(data))[1:]) def test_no_comdat_folding(self): # Issue 8847: In the PGO build, the MSVC linker's COMDAT folding diff --git a/Lib/test/test_lzma.py b/Lib/test/test_lzma.py index 3e73d7f..07fadbd 100644 --- a/Lib/test/test_lzma.py +++ b/Lib/test/test_lzma.py @@ -220,10 +220,11 @@ class CompressorDecompressorTestCase(unittest.TestCase): # Pickling raises an exception; there's no way to serialize an lzma_stream. def test_pickle(self): - with self.assertRaises(TypeError): - pickle.dumps(LZMACompressor()) - with self.assertRaises(TypeError): - pickle.dumps(LZMADecompressor()) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises(TypeError): + pickle.dumps(LZMACompressor(), proto) + with self.assertRaises(TypeError): + pickle.dumps(LZMADecompressor(), proto) class CompressDecompressFunctionTestCase(unittest.TestCase): diff --git a/Lib/test/test_memoryio.py b/Lib/test/test_memoryio.py index 9ef293e..7cae8b2 100644 --- a/Lib/test/test_memoryio.py +++ b/Lib/test/test_memoryio.py @@ -366,13 +366,14 @@ class MemoryTestMixin: # the module-level. import __main__ PickleTestMemIO.__module__ = '__main__' + PickleTestMemIO.__qualname__ = PickleTestMemIO.__name__ __main__.PickleTestMemIO = PickleTestMemIO submemio = PickleTestMemIO(buf, 80) submemio.seek(2) # We only support pickle protocol 2 and onward since we use extended # __reduce__ API of PEP 307 to provide pickling support. - for proto in range(2, pickle.HIGHEST_PROTOCOL): + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): for obj in (memio, submemio): obj2 = pickle.loads(pickle.dumps(obj, protocol=proto)) self.assertEqual(obj.getvalue(), obj2.getvalue()) diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index 2489ff7..d06a83d 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -1468,43 +1468,44 @@ class MinidomTest(unittest.TestCase): " \n" "]> text\n" " ") - s = pickle.dumps(doc) - doc2 = pickle.loads(s) - stack = [(doc, doc2)] - while stack: - n1, n2 = stack.pop() - self.confirm(n1.nodeType == n2.nodeType - and len(n1.childNodes) == len(n2.childNodes) - and n1.nodeName == n2.nodeName - and not n1.isSameNode(n2) - and not n2.isSameNode(n1)) - if n1.nodeType == Node.DOCUMENT_TYPE_NODE: - len(n1.entities) - len(n2.entities) - len(n1.notations) - len(n2.notations) - self.confirm(len(n1.entities) == len(n2.entities) - and len(n1.notations) == len(n2.notations)) - for i in range(len(n1.notations)): - # XXX this loop body doesn't seem to be executed? - no1 = n1.notations.item(i) - no2 = n1.notations.item(i) - self.confirm(no1.name == no2.name - and no1.publicId == no2.publicId - and no1.systemId == no2.systemId) - stack.append((no1, no2)) - for i in range(len(n1.entities)): - e1 = n1.entities.item(i) - e2 = n2.entities.item(i) - self.confirm(e1.notationName == e2.notationName - and e1.publicId == e2.publicId - and e1.systemId == e2.systemId) - stack.append((e1, e2)) - if n1.nodeType != Node.DOCUMENT_NODE: - self.confirm(n1.ownerDocument.isSameNode(doc) - and n2.ownerDocument.isSameNode(doc2)) - for i in range(len(n1.childNodes)): - stack.append((n1.childNodes[i], n2.childNodes[i])) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(doc, proto) + doc2 = pickle.loads(s) + stack = [(doc, doc2)] + while stack: + n1, n2 = stack.pop() + self.confirm(n1.nodeType == n2.nodeType + and len(n1.childNodes) == len(n2.childNodes) + and n1.nodeName == n2.nodeName + and not n1.isSameNode(n2) + and not n2.isSameNode(n1)) + if n1.nodeType == Node.DOCUMENT_TYPE_NODE: + len(n1.entities) + len(n2.entities) + len(n1.notations) + len(n2.notations) + self.confirm(len(n1.entities) == len(n2.entities) + and len(n1.notations) == len(n2.notations)) + for i in range(len(n1.notations)): + # XXX this loop body doesn't seem to be executed? + no1 = n1.notations.item(i) + no2 = n1.notations.item(i) + self.confirm(no1.name == no2.name + and no1.publicId == no2.publicId + and no1.systemId == no2.systemId) + stack.append((no1, no2)) + for i in range(len(n1.entities)): + e1 = n1.entities.item(i) + e2 = n2.entities.item(i) + self.confirm(e1.notationName == e2.notationName + and e1.publicId == e2.publicId + and e1.systemId == e2.systemId) + stack.append((e1, e2)) + if n1.nodeType != Node.DOCUMENT_NODE: + self.confirm(n1.ownerDocument.isSameNode(doc) + and n2.ownerDocument.isSameNode(doc2)) + for i in range(len(n1.childNodes)): + stack.append((n1.childNodes[i], n2.childNodes[i])) def testSerializeCommentNodeWithDoubleHyphen(self): doc = create_doc_without_doctype() diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index e129bef..ce6bd91 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -265,10 +265,13 @@ class StatAttributeTests(unittest.TestCase): def test_stat_result_pickle(self): result = os.stat(self.fname) - p = pickle.dumps(result) - self.assertIn(b'\x03cos\nstat_result\n', p) - unpickled = pickle.loads(p) - self.assertEqual(result, unpickled) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(result, proto) + self.assertIn(b'stat_result', p) + if proto < 4: + self.assertIn(b'cos\nstat_result\n', p) + unpickled = pickle.loads(p) + self.assertEqual(result, unpickled) @unittest.skipUnless(hasattr(os, 'statvfs'), 'test needs os.statvfs()') def test_statvfs_attributes(self): @@ -324,10 +327,13 @@ class StatAttributeTests(unittest.TestCase): if e.errno == errno.ENOSYS: self.skipTest('os.statvfs() failed with ENOSYS') - p = pickle.dumps(result) - self.assertIn(b'\x03cos\nstatvfs_result\n', p) - unpickled = pickle.loads(p) - self.assertEqual(result, unpickled) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(result, proto) + self.assertIn(b'statvfs_result', p) + if proto < 4: + self.assertIn(b'cos\nstatvfs_result\n', p) + unpickled = pickle.loads(p) + self.assertEqual(result, unpickled) def test_utime_dir(self): delta = 1000000 diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index 103d462..e648045 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -159,11 +159,12 @@ class TestBasicOps: self.assertEqual(y1, y2) def test_pickling(self): - state = pickle.dumps(self.gen) - origseq = [self.gen.random() for i in range(10)] - newgen = pickle.loads(state) - restoredseq = [newgen.random() for i in range(10)] - self.assertEqual(origseq, restoredseq) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + state = pickle.dumps(self.gen, proto) + origseq = [self.gen.random() for i in range(10)] + newgen = pickle.loads(state) + restoredseq = [newgen.random() for i in range(10)] + self.assertEqual(origseq, restoredseq) def test_bug_1727780(self): # verify that version-2-pickles can be loaded @@ -215,7 +216,8 @@ class SystemRandom_TestBasicOps(TestBasicOps, unittest.TestCase): self.assertEqual(self.gen.gauss_next, None) def test_pickling(self): - self.assertRaises(NotImplementedError, pickle.dumps, self.gen) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertRaises(NotImplementedError, pickle.dumps, self.gen, proto) def test_53_bits_per_float(self): # This should pass whenever a C double has 53 bit precision. diff --git a/Lib/test/test_range.py b/Lib/test/test_range.py index fecda1b..2dbcebc 100644 --- a/Lib/test/test_range.py +++ b/Lib/test/test_range.py @@ -366,7 +366,7 @@ class RangeTest(unittest.TestCase): it = itorg = iter(range(*t)) data = list(range(*t)) - d = pickle.dumps(it) + d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(type(itorg), type(it)) self.assertEqual(list(it), data) @@ -376,33 +376,35 @@ class RangeTest(unittest.TestCase): next(it) except StopIteration: continue - d = pickle.dumps(it) + d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(list(it), data[1:]) def test_exhausted_iterator_pickling(self): - r = range(2**65, 2**65+2) - i = iter(r) - while True: - r = next(i) - if r == 2**65+1: - break - d = pickle.dumps(i) - i2 = pickle.loads(d) - self.assertEqual(list(i), []) - self.assertEqual(list(i2), []) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + r = range(2**65, 2**65+2) + i = iter(r) + while True: + r = next(i) + if r == 2**65+1: + break + d = pickle.dumps(i, proto) + i2 = pickle.loads(d) + self.assertEqual(list(i), []) + self.assertEqual(list(i2), []) def test_large_exhausted_iterator_pickling(self): - r = range(20) - i = iter(r) - while True: - r = next(i) - if r == 19: - break - d = pickle.dumps(i) - i2 = pickle.loads(d) - self.assertEqual(list(i), []) - self.assertEqual(list(i2), []) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + r = range(20) + i = iter(r) + while True: + r = next(i) + if r == 19: + break + d = pickle.dumps(i, proto) + i2 = pickle.loads(d) + self.assertEqual(list(i), []) + self.assertEqual(list(i2), []) def test_odd_bug(self): # This used to raise a "SystemError: NULL result without error" diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index bfef621..65e4243 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -231,29 +231,30 @@ class TestJointOps: self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup)) if type(self.s) not in (set, frozenset): self.s.x = 10 - p = pickle.dumps(self.s) + p = pickle.dumps(self.s, i) dup = pickle.loads(p) self.assertEqual(self.s.x, dup.x) def test_iterator_pickling(self): - itorg = iter(self.s) - data = self.thetype(self.s) - d = pickle.dumps(itorg) - it = pickle.loads(d) - # Set iterators unpickle as list iterators due to the - # undefined order of set items. - # self.assertEqual(type(itorg), type(it)) - self.assertTrue(isinstance(it, collections.abc.Iterator)) - self.assertEqual(self.thetype(it), data) - - it = pickle.loads(d) - try: - drop = next(it) - except StopIteration: - return - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(self.thetype(it), data - self.thetype((drop,))) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + itorg = iter(self.s) + data = self.thetype(self.s) + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + # Set iterators unpickle as list iterators due to the + # undefined order of set items. + # self.assertEqual(type(itorg), type(it)) + self.assertIsInstance(it, collections.abc.Iterator) + self.assertEqual(self.thetype(it), data) + + it = pickle.loads(d) + try: + drop = next(it) + except StopIteration: + continue + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(self.thetype(it), data - self.thetype((drop,))) def test_deepcopy(self): class Tracer: @@ -851,10 +852,11 @@ class TestBasicOps: self.assertEqual(setiter.__length_hint__(), len(self.set)) def test_pickling(self): - p = pickle.dumps(self.set) - copy = pickle.loads(p) - self.assertEqual(self.set, copy, - "%s != %s" % (self.set, copy)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(self.set, proto) + copy = pickle.loads(p) + self.assertEqual(self.set, copy, + "%s != %s" % (self.set, copy)) #------------------------------------------------------------------------------ diff --git a/Lib/test/test_tuple.py b/Lib/test/test_tuple.py index e41711c..51875a1 100644 --- a/Lib/test/test_tuple.py +++ b/Lib/test/test_tuple.py @@ -169,29 +169,31 @@ class TupleTest(seq_tests.CommonTest): # Userlist iterators don't support pickling yet since # they are based on generators. data = self.type2test([4, 5, 6, 7]) - itorg = iter(data) - d = pickle.dumps(itorg) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(self.type2test(it), self.type2test(data)) - - it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(self.type2test(it), self.type2test(data)[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + itorg = iter(data) + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(self.type2test(it), self.type2test(data)) + + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(self.type2test(it), self.type2test(data)[1:]) def test_reversed_pickle(self): data = self.type2test([4, 5, 6, 7]) - itorg = reversed(data) - d = pickle.dumps(itorg) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(self.type2test(it), self.type2test(reversed(data))) - - it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(self.type2test(it), self.type2test(reversed(data))[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + itorg = reversed(data) + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(self.type2test(it), self.type2test(reversed(data))) + + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(self.type2test(it), self.type2test(reversed(data))[1:]) def test_no_comdat_folding(self): # Issue 8847: In the PGO build, the MSVC linker's COMDAT folding diff --git a/Lib/test/test_xml_dom_minicompat.py b/Lib/test/test_xml_dom_minicompat.py index 085e52a..47c4de6 100644 --- a/Lib/test/test_xml_dom_minicompat.py +++ b/Lib/test/test_xml_dom_minicompat.py @@ -84,18 +84,19 @@ class NodeListTestCase(unittest.TestCase): def test_nodelist_pickle_roundtrip(self): # Test pickling and unpickling of a NodeList. - # Empty NodeList. - node_list = NodeList() - pickled = pickle.dumps(node_list) - unpickled = pickle.loads(pickled) - self.assertEqual(unpickled, node_list) - - # Non-empty NodeList. - node_list.append(1) - node_list.append(2) - pickled = pickle.dumps(node_list) - unpickled = pickle.loads(pickled) - self.assertEqual(unpickled, node_list) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + # Empty NodeList. + node_list = NodeList() + pickled = pickle.dumps(node_list, proto) + unpickled = pickle.loads(pickled) + self.assertEqual(unpickled, node_list) + + # Non-empty NodeList. + node_list.append(1) + node_list.append(2) + pickled = pickle.dumps(node_list, proto) + unpickled = pickle.loads(pickled) + self.assertEqual(unpickled, node_list) if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 89971f1..d3c0da0 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -121,11 +121,11 @@ class ElementTestCase: def setUpClass(cls): cls.modules = {pyET, ET} - def pickleRoundTrip(self, obj, name, dumper, loader): + def pickleRoundTrip(self, obj, name, dumper, loader, proto): save_m = sys.modules[name] try: sys.modules[name] = dumper - temp = pickle.dumps(obj) + temp = pickle.dumps(obj, proto) sys.modules[name] = loader result = pickle.loads(temp) except pickle.PicklingError as pe: @@ -1677,33 +1677,36 @@ class BasicElementTest(ElementTestCase, unittest.TestCase): def test_pickle(self): # issue #16076: the C implementation wasn't pickleable. - for dumper, loader in product(self.modules, repeat=2): - e = dumper.Element('foo', bar=42) - e.text = "text goes here" - e.tail = "opposite of head" - dumper.SubElement(e, 'child').append(dumper.Element('grandchild')) - e.append(dumper.Element('child')) - e.findall('.//grandchild')[0].set('attr', 'other value') - - e2 = self.pickleRoundTrip(e, 'xml.etree.ElementTree', - dumper, loader) - - self.assertEqual(e2.tag, 'foo') - self.assertEqual(e2.attrib['bar'], 42) - self.assertEqual(len(e2), 2) - self.assertEqualElements(e, e2) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + for dumper, loader in product(self.modules, repeat=2): + e = dumper.Element('foo', bar=42) + e.text = "text goes here" + e.tail = "opposite of head" + dumper.SubElement(e, 'child').append(dumper.Element('grandchild')) + e.append(dumper.Element('child')) + e.findall('.//grandchild')[0].set('attr', 'other value') + + e2 = self.pickleRoundTrip(e, 'xml.etree.ElementTree', + dumper, loader, proto) + + self.assertEqual(e2.tag, 'foo') + self.assertEqual(e2.attrib['bar'], 42) + self.assertEqual(len(e2), 2) + self.assertEqualElements(e, e2) def test_pickle_issue18997(self): - for dumper, loader in product(self.modules, repeat=2): - XMLTEXT = """ - 4 - """ - e1 = dumper.fromstring(XMLTEXT) - if hasattr(e1, '__getstate__'): - self.assertEqual(e1.__getstate__()['tag'], 'group') - e2 = self.pickleRoundTrip(e1, 'xml.etree.ElementTree', dumper, loader) - self.assertEqual(e2.tag, 'group') - self.assertEqual(e2[0].tag, 'dogs') + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + for dumper, loader in product(self.modules, repeat=2): + XMLTEXT = """ + 4 + """ + e1 = dumper.fromstring(XMLTEXT) + if hasattr(e1, '__getstate__'): + self.assertEqual(e1.__getstate__()['tag'], 'group') + e2 = self.pickleRoundTrip(e1, 'xml.etree.ElementTree', + dumper, loader, proto) + self.assertEqual(e2.tag, 'group') + self.assertEqual(e2[0].tag, 'dogs') class ElementTreeTypeTest(unittest.TestCase): -- cgit v0.12