From: Serhiy Storchaka Date: Tue, 31 Mar 2015 10:17:10 +0000 (+0300) Subject: Issue #18473: Fixed 2to3 and 3to2 compatible pickle mappings. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d5d818d40b9378488dc82150926e20e925acf7fe;p=python Issue #18473: Fixed 2to3 and 3to2 compatible pickle mappings. Fixed ambigious reverse mappings. Added many new mappings. Import mapping is no longer applied to modules already mapped with full name mapping. Added tests for compatible pickling and unpickling and for consistency of _compat_pickle mappings. --- d5d818d40b9378488dc82150926e20e925acf7fe diff --cc Lib/test/pickletester.py index f8372e32e6,2c496d0959..c95fb22ee3 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@@ -1691,27 -1647,51 +1693,72 @@@ class AbstractPickleTests(unittest.Test unpickled = self.loads(self.dumps(method, proto)) self.assertEqual(method(*args), unpickled(*args)) + def test_compat_pickle(self): + tests = [ + (range(1, 7), '__builtin__', 'xrange'), + (map(int, '123'), 'itertools', 'imap'), + (functools.reduce, '__builtin__', 'reduce'), + (dbm.whichdb, 'whichdb', 'whichdb'), + (Exception(), 'exceptions', 'Exception'), + (collections.UserDict(), 'UserDict', 'IterableUserDict'), + (collections.UserList(), 'UserList', 'UserList'), + (collections.defaultdict(), 'collections', 'defaultdict'), + ] + for val, mod, name in tests: + for proto in range(3): + with self.subTest(type=type(val), proto=proto): + pickled = self.dumps(val, proto) + self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled) + self.assertIs(type(self.loads(pickled)), type(val)) + + def test_compat_unpickle(self): + # xrange(1, 7) + pickled = b'\x80\x02c__builtin__\nxrange\nK\x01K\x07K\x01\x87R.' + unpickled = self.loads(pickled) + self.assertIs(type(unpickled), range) + self.assertEqual(unpickled, range(1, 7)) + self.assertEqual(list(unpickled), [1, 2, 3, 4, 5, 6]) + # reduce + pickled = b'\x80\x02c__builtin__\nreduce\n.' + self.assertIs(self.loads(pickled), functools.reduce) + # whichdb.whichdb + pickled = b'\x80\x02cwhichdb\nwhichdb\n.' + self.assertIs(self.loads(pickled), dbm.whichdb) + # Exception(), StandardError() + for name in (b'Exception', b'StandardError'): + pickled = (b'\x80\x02cexceptions\n' + name + b'\nU\x03ugh\x85R.') + unpickled = self.loads(pickled) + self.assertIs(type(unpickled), Exception) + self.assertEqual(str(unpickled), 'ugh') + # UserDict.UserDict({1: 2}), UserDict.IterableUserDict({1: 2}) + for name in (b'UserDict', b'IterableUserDict'): + pickled = (b'\x80\x02(cUserDict\n' + name + + b'\no}U\x04data}K\x01K\x02ssb.') + unpickled = self.loads(pickled) + self.assertIs(type(unpickled), collections.UserDict) + self.assertEqual(unpickled, collections.UserDict({1: 2})) + + def test_local_lookup_error(self): + # Test that whichmodule() errors out cleanly when looking up + # an assumed globally-reachable object fails. + def f(): + pass + # Since the function is local, lookup will fail + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((AttributeError, pickle.PicklingError)): + pickletools.dis(self.dumps(f, proto)) + # Same without a __module__ attribute (exercises a different path + # in _pickle.c). + del f.__module__ + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((AttributeError, pickle.PicklingError)): + pickletools.dis(self.dumps(f, proto)) + # Yet a different path. + f.__name__ = f.__qualname__ + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((AttributeError, pickle.PicklingError)): + pickletools.dis(self.dumps(f, proto)) + class BigmemPickleTests(unittest.TestCase): diff --cc Misc/NEWS index b24ffb5120,cd72813dad..5fb96f7141 --- a/Misc/NEWS +++ b/Misc/NEWS @@@ -2,40 -2,10 +2,44 @@@ Python News +++++++++++ -What's New in Python 3.4.4rc1? -============================== +What's New in Python 3.5.0 alpha 4? +=================================== + +Release date: XXX + +Core and Builtins +----------------- + +Library +------- + ++- Issue #18473: Fixed 2to3 and 3to2 compatible pickle mappings. Fixed ++ ambigious reverse mappings. Added many new mappings. Import mapping is no ++ longer applied to modules already mapped with full name mapping. ++ +- Issue #23485: select.select() is now retried automatically with the + recomputed timeout when interrupted by a signal, except if the signal handler + raises an exception. This change is part of the PEP 475. + +- Issue #23752: When built from an existing file descriptor, io.FileIO() now + only calls fstat() once. Before fstat() was called twice, which was not + necessary. + +Build +----- + +Tests +----- + +Tools/Demos +----------- + -Release date: tba + +What's New in Python 3.5.0 alpha 3? +=================================== + +Release date: 2015-03-28 Core and Builtins -----------------