blob: f8b43a1eb666fbd5d02a6bea1350b4b143a69dd0 [file] [log] [blame]
Serhiy Storchakabfe18242015-03-31 13:12:37 +03001from _compat_pickle import (IMPORT_MAPPING, REVERSE_IMPORT_MAPPING,
2 NAME_MAPPING, REVERSE_NAME_MAPPING)
3import builtins
Jeremy Hyltonbe467e52000-09-15 15:14:51 +00004import pickle
Guido van Rossumcfe5f202007-05-08 21:26:54 +00005import io
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01006import collections
Serhiy Storchaka5bbd2312014-12-16 19:39:08 +02007import struct
8import sys
Miss Islington (bot)aa726682021-08-02 10:09:05 -07009import warnings
Serhiy Storchaka986375e2017-11-30 22:48:31 +020010import weakref
Tim Peters47a6b132003-01-28 22:34:11 +000011
Serhiy Storchaka5bbd2312014-12-16 19:39:08 +020012import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000013from test import support
Hai Shi883bc632020-07-06 17:12:49 +080014from test.support import import_helper
Jeremy Hylton66426532001-10-15 21:38:56 +000015
Pierre Glaser289f1f82019-05-08 23:08:25 +020016from test.pickletester import AbstractHookTests
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030017from test.pickletester import AbstractUnpickleTests
Tim Peters47a6b132003-01-28 22:34:11 +000018from test.pickletester import AbstractPickleTests
Tim Peters47a6b132003-01-28 22:34:11 +000019from test.pickletester import AbstractPickleModuleTests
20from test.pickletester import AbstractPersistentPicklerTests
Serhiy Storchakadec25af2016-07-17 11:24:17 +030021from test.pickletester import AbstractIdentityPersistentPicklerTests
Collin Winter771d8342009-04-16 03:18:06 +000022from test.pickletester import AbstractPicklerUnpicklerObjectTests
Antoine Pitrou8d3c2902012-03-04 18:31:48 +010023from test.pickletester import AbstractDispatchTableTests
Pierre Glaser289f1f82019-05-08 23:08:25 +020024from test.pickletester import AbstractCustomPicklerClass
Antoine Pitrou82be19f2011-08-29 23:09:33 +020025from test.pickletester import BigmemPickleTests
Tim Peters47a6b132003-01-28 22:34:11 +000026
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000027try:
28 import _pickle
29 has_c_implementation = True
30except ImportError:
31 has_c_implementation = False
Jeremy Hylton66426532001-10-15 21:38:56 +000032
Guido van Rossum98297ee2007-11-06 21:34:58 +000033
Serhiy Storchaka65452562017-11-15 14:01:08 +020034class PyPickleTests(AbstractPickleModuleTests):
35 dump = staticmethod(pickle._dump)
36 dumps = staticmethod(pickle._dumps)
37 load = staticmethod(pickle._load)
38 loads = staticmethod(pickle._loads)
39 Pickler = pickle._Pickler
40 Unpickler = pickle._Unpickler
Guido van Rossum5d9113d2003-01-29 17:58:45 +000041
Tim Peterse0c446b2001-10-18 21:57:37 +000042
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030043class PyUnpicklerTests(AbstractUnpickleTests):
44
45 unpickler = pickle._Unpickler
Serhiy Storchakae9b30742015-11-23 15:17:43 +020046 bad_stack_errors = (IndexError,)
Serhiy Storchaka7279bef2015-11-29 13:12:10 +020047 truncated_errors = (pickle.UnpicklingError, EOFError,
48 AttributeError, ValueError,
49 struct.error, IndexError, ImportError)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030050
51 def loads(self, buf, **kwds):
52 f = io.BytesIO(buf)
53 u = self.unpickler(f, **kwds)
54 return u.load()
55
56
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000057class PyPicklerTests(AbstractPickleTests):
Jeremy Hylton66426532001-10-15 21:38:56 +000058
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000059 pickler = pickle._Pickler
60 unpickler = pickle._Unpickler
Jeremy Hylton66426532001-10-15 21:38:56 +000061
Antoine Pitrou91f43802019-05-26 17:10:09 +020062 def dumps(self, arg, proto=None, **kwargs):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000063 f = io.BytesIO()
Antoine Pitrou91f43802019-05-26 17:10:09 +020064 p = self.pickler(f, proto, **kwargs)
Jeremy Hylton66426532001-10-15 21:38:56 +000065 p.dump(arg)
66 f.seek(0)
Guido van Rossumcfe5f202007-05-08 21:26:54 +000067 return bytes(f.read())
Jeremy Hylton66426532001-10-15 21:38:56 +000068
Alexander Belopolskyec8f0df2011-02-24 20:34:38 +000069 def loads(self, buf, **kwds):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000070 f = io.BytesIO(buf)
Alexander Belopolskyec8f0df2011-02-24 20:34:38 +000071 u = self.unpickler(f, **kwds)
Jeremy Hylton66426532001-10-15 21:38:56 +000072 return u.load()
73
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000074
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030075class InMemoryPickleTests(AbstractPickleTests, AbstractUnpickleTests,
76 BigmemPickleTests):
Antoine Pitrouea99c5c2010-09-09 18:33:21 +000077
Serhiy Storchakae9b30742015-11-23 15:17:43 +020078 bad_stack_errors = (pickle.UnpicklingError, IndexError)
Serhiy Storchaka7279bef2015-11-29 13:12:10 +020079 truncated_errors = (pickle.UnpicklingError, EOFError,
80 AttributeError, ValueError,
81 struct.error, IndexError, ImportError)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +000082
Antoine Pitrou91f43802019-05-26 17:10:09 +020083 def dumps(self, arg, protocol=None, **kwargs):
84 return pickle.dumps(arg, protocol, **kwargs)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +000085
Alexander Belopolskyec8f0df2011-02-24 20:34:38 +000086 def loads(self, buf, **kwds):
87 return pickle.loads(buf, **kwds)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +000088
Serhiy Storchaka0a2da502018-01-11 13:03:20 +020089 test_framed_write_sizes_with_delayed_writer = None
90
Antoine Pitrouea99c5c2010-09-09 18:33:21 +000091
Serhiy Storchakadec25af2016-07-17 11:24:17 +030092class PersistentPicklerUnpicklerMixin(object):
Jeremy Hylton5e0f4e72002-11-13 22:01:27 +000093
Guido van Rossumf4169812008-03-17 22:56:06 +000094 def dumps(self, arg, proto=None):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000095 class PersPickler(self.pickler):
Jeremy Hylton5e0f4e72002-11-13 22:01:27 +000096 def persistent_id(subself, obj):
97 return self.persistent_id(obj)
Guido van Rossumcfe5f202007-05-08 21:26:54 +000098 f = io.BytesIO()
Guido van Rossum9d32bb12003-01-28 03:51:53 +000099 p = PersPickler(f, proto)
Jeremy Hylton5e0f4e72002-11-13 22:01:27 +0000100 p.dump(arg)
Serhiy Storchakadec25af2016-07-17 11:24:17 +0300101 return f.getvalue()
Jeremy Hylton5e0f4e72002-11-13 22:01:27 +0000102
Alexander Belopolskyec8f0df2011-02-24 20:34:38 +0000103 def loads(self, buf, **kwds):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000104 class PersUnpickler(self.unpickler):
Jeremy Hylton5e0f4e72002-11-13 22:01:27 +0000105 def persistent_load(subself, obj):
106 return self.persistent_load(obj)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000107 f = io.BytesIO(buf)
Alexander Belopolskyec8f0df2011-02-24 20:34:38 +0000108 u = PersUnpickler(f, **kwds)
Jeremy Hylton5e0f4e72002-11-13 22:01:27 +0000109 return u.load()
110
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000111
Serhiy Storchakadec25af2016-07-17 11:24:17 +0300112class PyPersPicklerTests(AbstractPersistentPicklerTests,
113 PersistentPicklerUnpicklerMixin):
114
115 pickler = pickle._Pickler
116 unpickler = pickle._Unpickler
117
118
119class PyIdPersPicklerTests(AbstractIdentityPersistentPicklerTests,
120 PersistentPicklerUnpicklerMixin):
121
122 pickler = pickle._Pickler
123 unpickler = pickle._Unpickler
124
Serhiy Storchaka986375e2017-11-30 22:48:31 +0200125 @support.cpython_only
126 def test_pickler_reference_cycle(self):
127 def check(Pickler):
128 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
129 f = io.BytesIO()
130 pickler = Pickler(f, proto)
131 pickler.dump('abc')
132 self.assertEqual(self.loads(f.getvalue()), 'abc')
133 pickler = Pickler(io.BytesIO())
134 self.assertEqual(pickler.persistent_id('def'), 'def')
135 r = weakref.ref(pickler)
136 del pickler
137 self.assertIsNone(r())
138
139 class PersPickler(self.pickler):
140 def persistent_id(subself, obj):
141 return obj
142 check(PersPickler)
143
144 class PersPickler(self.pickler):
145 @classmethod
146 def persistent_id(cls, obj):
147 return obj
148 check(PersPickler)
149
150 class PersPickler(self.pickler):
151 @staticmethod
152 def persistent_id(obj):
153 return obj
154 check(PersPickler)
155
156 @support.cpython_only
157 def test_unpickler_reference_cycle(self):
158 def check(Unpickler):
159 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
160 unpickler = Unpickler(io.BytesIO(self.dumps('abc', proto)))
161 self.assertEqual(unpickler.load(), 'abc')
162 unpickler = Unpickler(io.BytesIO())
163 self.assertEqual(unpickler.persistent_load('def'), 'def')
164 r = weakref.ref(unpickler)
165 del unpickler
166 self.assertIsNone(r())
167
168 class PersUnpickler(self.unpickler):
169 def persistent_load(subself, pid):
170 return pid
171 check(PersUnpickler)
172
173 class PersUnpickler(self.unpickler):
174 @classmethod
175 def persistent_load(cls, pid):
176 return pid
177 check(PersUnpickler)
178
179 class PersUnpickler(self.unpickler):
180 @staticmethod
181 def persistent_load(pid):
182 return pid
183 check(PersUnpickler)
184
Serhiy Storchakadec25af2016-07-17 11:24:17 +0300185
Collin Winter771d8342009-04-16 03:18:06 +0000186class PyPicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests):
187
188 pickler_class = pickle._Pickler
189 unpickler_class = pickle._Unpickler
190
191
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100192class PyDispatchTableTests(AbstractDispatchTableTests):
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -0800193
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100194 pickler_class = pickle._Pickler
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -0800195
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100196 def get_dispatch_table(self):
197 return pickle.dispatch_table.copy()
198
199
200class PyChainDispatchTableTests(AbstractDispatchTableTests):
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -0800201
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100202 pickler_class = pickle._Pickler
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -0800203
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100204 def get_dispatch_table(self):
205 return collections.ChainMap({}, pickle.dispatch_table)
206
207
Victor Stinner63ab4ba2019-06-13 13:58:51 +0200208class PyPicklerHookTests(AbstractHookTests):
209 class CustomPyPicklerClass(pickle._Pickler,
210 AbstractCustomPicklerClass):
211 pass
212 pickler_class = CustomPyPicklerClass
213
214
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000215if has_c_implementation:
Serhiy Storchaka65452562017-11-15 14:01:08 +0200216 class CPickleTests(AbstractPickleModuleTests):
217 from _pickle import dump, dumps, load, loads, Pickler, Unpickler
218
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300219 class CUnpicklerTests(PyUnpicklerTests):
220 unpickler = _pickle.Unpickler
Serhiy Storchakae9b30742015-11-23 15:17:43 +0200221 bad_stack_errors = (pickle.UnpicklingError,)
Serhiy Storchaka90493ab2016-09-06 23:55:11 +0300222 truncated_errors = (pickle.UnpicklingError,)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300223
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000224 class CPicklerTests(PyPicklerTests):
225 pickler = _pickle.Pickler
226 unpickler = _pickle.Unpickler
227
228 class CPersPicklerTests(PyPersPicklerTests):
229 pickler = _pickle.Pickler
230 unpickler = _pickle.Unpickler
231
Serhiy Storchakadec25af2016-07-17 11:24:17 +0300232 class CIdPersPicklerTests(PyIdPersPicklerTests):
233 pickler = _pickle.Pickler
234 unpickler = _pickle.Unpickler
235
Collin Winter771d8342009-04-16 03:18:06 +0000236 class CDumpPickle_LoadPickle(PyPicklerTests):
237 pickler = _pickle.Pickler
238 unpickler = pickle._Unpickler
239
240 class DumpPickle_CLoadPickle(PyPicklerTests):
241 pickler = pickle._Pickler
242 unpickler = _pickle.Unpickler
243
244 class CPicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests):
245 pickler_class = _pickle.Pickler
246 unpickler_class = _pickle.Unpickler
247
Christian Heimesa24b4d22013-07-01 15:17:45 +0200248 def test_issue18339(self):
249 unpickler = self.unpickler_class(io.BytesIO())
Christian Heimes21782482013-07-01 23:00:13 +0200250 with self.assertRaises(TypeError):
251 unpickler.memo = object
Christian Heimesa24b4d22013-07-01 15:17:45 +0200252 # used to cause a segfault
Christian Heimes21782482013-07-01 23:00:13 +0200253 with self.assertRaises(ValueError):
254 unpickler.memo = {-1: None}
Christian Heimesa24b4d22013-07-01 15:17:45 +0200255 unpickler.memo = {1: None}
256
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100257 class CDispatchTableTests(AbstractDispatchTableTests):
258 pickler_class = pickle.Pickler
259 def get_dispatch_table(self):
260 return pickle.dispatch_table.copy()
261
262 class CChainDispatchTableTests(AbstractDispatchTableTests):
263 pickler_class = pickle.Pickler
264 def get_dispatch_table(self):
265 return collections.ChainMap({}, pickle.dispatch_table)
266
Pierre Glaser289f1f82019-05-08 23:08:25 +0200267 class CPicklerHookTests(AbstractHookTests):
268 class CustomCPicklerClass(_pickle.Pickler, AbstractCustomPicklerClass):
269 pass
270 pickler_class = CustomCPicklerClass
271
Serhiy Storchaka5bbd2312014-12-16 19:39:08 +0200272 @support.cpython_only
273 class SizeofTests(unittest.TestCase):
274 check_sizeof = support.check_sizeof
275
276 def test_pickler(self):
Antoine Pitrou91f43802019-05-26 17:10:09 +0200277 basesize = support.calcobjsize('7P2n3i2n3i2P')
Serhiy Storchaka5bbd2312014-12-16 19:39:08 +0200278 p = _pickle.Pickler(io.BytesIO())
279 self.assertEqual(object.__sizeof__(p), basesize)
280 MT_size = struct.calcsize('3nP0n')
281 ME_size = struct.calcsize('Pn0P')
282 check = self.check_sizeof
283 check(p, basesize +
284 MT_size + 8 * ME_size + # Minimal memo table size.
285 sys.getsizeof(b'x'*4096)) # Minimal write buffer size.
286 for i in range(6):
287 p.dump(chr(i))
288 check(p, basesize +
289 MT_size + 32 * ME_size + # Size of memo table required to
290 # save references to 6 objects.
291 0) # Write buffer is cleared after every dump().
292
293 def test_unpickler(self):
Antoine Pitrou91f43802019-05-26 17:10:09 +0200294 basesize = support.calcobjsize('2P2n2P 2P2n2i5P 2P3n8P2n2i')
Serhiy Storchaka5bbd2312014-12-16 19:39:08 +0200295 unpickler = _pickle.Unpickler
296 P = struct.calcsize('P') # Size of memo table entry.
297 n = struct.calcsize('n') # Size of mark table entry.
298 check = self.check_sizeof
299 for encoding in 'ASCII', 'UTF-16', 'latin-1':
300 for errors in 'strict', 'replace':
301 u = unpickler(io.BytesIO(),
302 encoding=encoding, errors=errors)
303 self.assertEqual(object.__sizeof__(u), basesize)
304 check(u, basesize +
305 32 * P + # Minimal memo table size.
306 len(encoding) + 1 + len(errors) + 1)
307
308 stdsize = basesize + len('ASCII') + 1 + len('strict') + 1
309 def check_unpickler(data, memo_size, marks_size):
310 dump = pickle.dumps(data)
311 u = unpickler(io.BytesIO(dump),
312 encoding='ASCII', errors='strict')
313 u.load()
314 check(u, stdsize + memo_size * P + marks_size * n)
315
316 check_unpickler(0, 32, 0)
317 # 20 is minimal non-empty mark stack size.
318 check_unpickler([0] * 100, 32, 20)
319 # 128 is memo table size required to save references to 100 objects.
320 check_unpickler([chr(i) for i in range(100)], 128, 20)
321 def recurse(deep):
322 data = 0
323 for i in range(deep):
324 data = [data, data]
325 return data
326 check_unpickler(recurse(0), 32, 0)
327 check_unpickler(recurse(1), 32, 20)
Sergey Fedoseev86b89912018-08-25 12:54:40 +0500328 check_unpickler(recurse(20), 32, 20)
329 check_unpickler(recurse(50), 64, 60)
330 check_unpickler(recurse(100), 128, 140)
Serhiy Storchaka5bbd2312014-12-16 19:39:08 +0200331
332 u = unpickler(io.BytesIO(pickle.dumps('a', 0)),
333 encoding='ASCII', errors='strict')
334 u.load()
335 check(u, stdsize + 32 * P + 2 + 1)
336
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000337
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300338ALT_IMPORT_MAPPING = {
339 ('_elementtree', 'xml.etree.ElementTree'),
340 ('cPickle', 'pickle'),
Serhiy Storchaka5c1d9d22016-01-18 22:33:44 +0200341 ('StringIO', 'io'),
342 ('cStringIO', 'io'),
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300343}
344
345ALT_NAME_MAPPING = {
346 ('__builtin__', 'basestring', 'builtins', 'str'),
347 ('exceptions', 'StandardError', 'builtins', 'Exception'),
348 ('UserDict', 'UserDict', 'collections', 'UserDict'),
349 ('socket', '_socketobject', 'socket', 'SocketType'),
350}
351
352def mapping(module, name):
353 if (module, name) in NAME_MAPPING:
354 module, name = NAME_MAPPING[(module, name)]
355 elif module in IMPORT_MAPPING:
356 module = IMPORT_MAPPING[module]
357 return module, name
358
359def reverse_mapping(module, name):
360 if (module, name) in REVERSE_NAME_MAPPING:
361 module, name = REVERSE_NAME_MAPPING[(module, name)]
362 elif module in REVERSE_IMPORT_MAPPING:
363 module = REVERSE_IMPORT_MAPPING[module]
364 return module, name
365
366def getmodule(module):
367 try:
368 return sys.modules[module]
369 except KeyError:
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300370 try:
Miss Islington (bot)aa726682021-08-02 10:09:05 -0700371 with warnings.catch_warnings():
372 action = 'always' if support.verbose else 'ignore'
373 warnings.simplefilter(action, DeprecationWarning)
374 __import__(module)
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300375 except AttributeError as exc:
376 if support.verbose:
377 print("Can't import module %r: %s" % (module, exc))
378 raise ImportError
379 except ImportError as exc:
380 if support.verbose:
381 print(exc)
382 raise
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300383 return sys.modules[module]
384
385def getattribute(module, name):
386 obj = getmodule(module)
387 for n in name.split('.'):
388 obj = getattr(obj, n)
389 return obj
390
391def get_exceptions(mod):
392 for name in dir(mod):
393 attr = getattr(mod, name)
394 if isinstance(attr, type) and issubclass(attr, BaseException):
395 yield name, attr
396
397class CompatPickleTests(unittest.TestCase):
398 def test_import(self):
399 modules = set(IMPORT_MAPPING.values())
400 modules |= set(REVERSE_IMPORT_MAPPING)
401 modules |= {module for module, name in REVERSE_NAME_MAPPING}
402 modules |= {module for module, name in NAME_MAPPING.values()}
403 for module in modules:
404 try:
405 getmodule(module)
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300406 except ImportError:
407 pass
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300408
409 def test_import_mapping(self):
410 for module3, module2 in REVERSE_IMPORT_MAPPING.items():
411 with self.subTest((module3, module2)):
412 try:
413 getmodule(module3)
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300414 except ImportError:
415 pass
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300416 if module3[:1] != '_':
417 self.assertIn(module2, IMPORT_MAPPING)
418 self.assertEqual(IMPORT_MAPPING[module2], module3)
419
420 def test_name_mapping(self):
421 for (module3, name3), (module2, name2) in REVERSE_NAME_MAPPING.items():
422 with self.subTest(((module3, name3), (module2, name2))):
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300423 if (module2, name2) == ('exceptions', 'OSError'):
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300424 attr = getattribute(module3, name3)
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300425 self.assertTrue(issubclass(attr, OSError))
Eric Snowc9432652016-09-07 15:42:32 -0700426 elif (module2, name2) == ('exceptions', 'ImportError'):
427 attr = getattribute(module3, name3)
428 self.assertTrue(issubclass(attr, ImportError))
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300429 else:
430 module, name = mapping(module2, name2)
431 if module3[:1] != '_':
432 self.assertEqual((module, name), (module3, name3))
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300433 try:
434 attr = getattribute(module3, name3)
435 except ImportError:
436 pass
437 else:
438 self.assertEqual(getattribute(module, name), attr)
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300439
440 def test_reverse_import_mapping(self):
441 for module2, module3 in IMPORT_MAPPING.items():
442 with self.subTest((module2, module3)):
443 try:
444 getmodule(module3)
445 except ImportError as exc:
446 if support.verbose:
447 print(exc)
448 if ((module2, module3) not in ALT_IMPORT_MAPPING and
449 REVERSE_IMPORT_MAPPING.get(module3, None) != module2):
450 for (m3, n3), (m2, n2) in REVERSE_NAME_MAPPING.items():
451 if (module3, module2) == (m3, m2):
452 break
453 else:
454 self.fail('No reverse mapping from %r to %r' %
455 (module3, module2))
456 module = REVERSE_IMPORT_MAPPING.get(module3, module3)
457 module = IMPORT_MAPPING.get(module, module)
458 self.assertEqual(module, module3)
459
460 def test_reverse_name_mapping(self):
461 for (module2, name2), (module3, name3) in NAME_MAPPING.items():
462 with self.subTest(((module2, name2), (module3, name3))):
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300463 try:
464 attr = getattribute(module3, name3)
465 except ImportError:
466 pass
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300467 module, name = reverse_mapping(module3, name3)
468 if (module2, name2, module3, name3) not in ALT_NAME_MAPPING:
469 self.assertEqual((module, name), (module2, name2))
470 module, name = mapping(module, name)
471 self.assertEqual((module, name), (module3, name3))
472
473 def test_exceptions(self):
474 self.assertEqual(mapping('exceptions', 'StandardError'),
475 ('builtins', 'Exception'))
476 self.assertEqual(mapping('exceptions', 'Exception'),
477 ('builtins', 'Exception'))
478 self.assertEqual(reverse_mapping('builtins', 'Exception'),
479 ('exceptions', 'Exception'))
480 self.assertEqual(mapping('exceptions', 'OSError'),
481 ('builtins', 'OSError'))
482 self.assertEqual(reverse_mapping('builtins', 'OSError'),
483 ('exceptions', 'OSError'))
484
485 for name, exc in get_exceptions(builtins):
486 with self.subTest(name):
Yury Selivanov75445082015-05-11 22:57:16 -0400487 if exc in (BlockingIOError,
488 ResourceWarning,
Yury Selivanovf488fb42015-07-03 01:04:23 -0400489 StopAsyncIteration,
Inada Naoki48274832021-03-29 12:28:14 +0900490 RecursionError,
491 EncodingWarning):
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300492 continue
493 if exc is not OSError and issubclass(exc, OSError):
494 self.assertEqual(reverse_mapping('builtins', name),
495 ('exceptions', 'OSError'))
Eric Snowc9432652016-09-07 15:42:32 -0700496 elif exc is not ImportError and issubclass(exc, ImportError):
497 self.assertEqual(reverse_mapping('builtins', name),
498 ('exceptions', 'ImportError'))
499 self.assertEqual(mapping('exceptions', name),
500 ('exceptions', name))
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300501 else:
502 self.assertEqual(reverse_mapping('builtins', name),
503 ('exceptions', name))
504 self.assertEqual(mapping('exceptions', name),
505 ('builtins', name))
506
Serhiy Storchaka7b2cfc42015-10-10 20:10:07 +0300507 def test_multiprocessing_exceptions(self):
Hai Shi883bc632020-07-06 17:12:49 +0800508 module = import_helper.import_module('multiprocessing.context')
Serhiy Storchaka7b2cfc42015-10-10 20:10:07 +0300509 for name, exc in get_exceptions(module):
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300510 with self.subTest(name):
511 self.assertEqual(reverse_mapping('multiprocessing.context', name),
512 ('multiprocessing', name))
513 self.assertEqual(mapping('multiprocessing', name),
514 ('multiprocessing.context', name))
515
516
Fred Drake694ed092001-12-19 16:42:15 +0000517def test_main():
Serhiy Storchaka65452562017-11-15 14:01:08 +0200518 tests = [PyPickleTests, PyUnpicklerTests, PyPicklerTests,
Serhiy Storchakadec25af2016-07-17 11:24:17 +0300519 PyPersPicklerTests, PyIdPersPicklerTests,
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300520 PyDispatchTableTests, PyChainDispatchTableTests,
Pierre Glaser289f1f82019-05-08 23:08:25 +0200521 CompatPickleTests, PyPicklerHookTests]
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000522 if has_c_implementation:
Serhiy Storchaka65452562017-11-15 14:01:08 +0200523 tests.extend([CPickleTests, CUnpicklerTests, CPicklerTests,
Serhiy Storchakadec25af2016-07-17 11:24:17 +0300524 CPersPicklerTests, CIdPersPicklerTests,
Collin Winter771d8342009-04-16 03:18:06 +0000525 CDumpPickle_LoadPickle, DumpPickle_CLoadPickle,
526 PyPicklerUnpicklerObjectTests,
Antoine Pitrouea99c5c2010-09-09 18:33:21 +0000527 CPicklerUnpicklerObjectTests,
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100528 CDispatchTableTests, CChainDispatchTableTests,
Pierre Glaser289f1f82019-05-08 23:08:25 +0200529 CPicklerHookTests,
Serhiy Storchaka5bbd2312014-12-16 19:39:08 +0200530 InMemoryPickleTests, SizeofTests])
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000531 support.run_unittest(*tests)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000532 support.run_doctest(pickle)
Fred Drake694ed092001-12-19 16:42:15 +0000533
Jeremy Hylton66426532001-10-15 21:38:56 +0000534if __name__ == "__main__":
Fred Drake694ed092001-12-19 16:42:15 +0000535 test_main()