1 from _compat_pickle import (IMPORT_MAPPING, REVERSE_IMPORT_MAPPING,
2 NAME_MAPPING, REVERSE_NAME_MAPPING)
3 import builtins
4 import pickle
5 import io
6 import collections
7 import struct
8 import sys
9 import warnings
10 import weakref
11
12 import doctest
13 import unittest
14 from test import support
15 from test.support import import_helper
16
17 from test.pickletester import AbstractHookTests
18 from test.pickletester import AbstractUnpickleTests
19 from test.pickletester import AbstractPickleTests
20 from test.pickletester import AbstractPickleModuleTests
21 from test.pickletester import AbstractPersistentPicklerTests
22 from test.pickletester import AbstractIdentityPersistentPicklerTests
23 from test.pickletester import AbstractPicklerUnpicklerObjectTests
24 from test.pickletester import AbstractDispatchTableTests
25 from test.pickletester import AbstractCustomPicklerClass
26 from test.pickletester import BigmemPickleTests
27
28 try:
29 import _pickle
30 has_c_implementation = True
31 except ImportError:
32 has_c_implementation = False
33
34
35 class ESC[4;38;5;81mPyPickleTests(ESC[4;38;5;149mAbstractPickleModuleTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
36 dump = staticmethod(pickle._dump)
37 dumps = staticmethod(pickle._dumps)
38 load = staticmethod(pickle._load)
39 loads = staticmethod(pickle._loads)
40 Pickler = pickle._Pickler
41 Unpickler = pickle._Unpickler
42
43
44 class ESC[4;38;5;81mPyUnpicklerTests(ESC[4;38;5;149mAbstractUnpickleTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
45
46 unpickler = pickle._Unpickler
47 bad_stack_errors = (IndexError,)
48 truncated_errors = (pickle.UnpicklingError, EOFError,
49 AttributeError, ValueError,
50 struct.error, IndexError, ImportError)
51
52 def loads(self, buf, **kwds):
53 f = io.BytesIO(buf)
54 u = self.unpickler(f, **kwds)
55 return u.load()
56
57
58 class ESC[4;38;5;81mPyPicklerTests(ESC[4;38;5;149mAbstractPickleTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
59
60 pickler = pickle._Pickler
61 unpickler = pickle._Unpickler
62
63 def dumps(self, arg, proto=None, **kwargs):
64 f = io.BytesIO()
65 p = self.pickler(f, proto, **kwargs)
66 p.dump(arg)
67 f.seek(0)
68 return bytes(f.read())
69
70 def loads(self, buf, **kwds):
71 f = io.BytesIO(buf)
72 u = self.unpickler(f, **kwds)
73 return u.load()
74
75
76 class ESC[4;38;5;81mInMemoryPickleTests(ESC[4;38;5;149mAbstractPickleTests, ESC[4;38;5;149mAbstractUnpickleTests,
77 ESC[4;38;5;149mBigmemPickleTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
78
79 bad_stack_errors = (pickle.UnpicklingError, IndexError)
80 truncated_errors = (pickle.UnpicklingError, EOFError,
81 AttributeError, ValueError,
82 struct.error, IndexError, ImportError)
83
84 def dumps(self, arg, protocol=None, **kwargs):
85 return pickle.dumps(arg, protocol, **kwargs)
86
87 def loads(self, buf, **kwds):
88 return pickle.loads(buf, **kwds)
89
90 test_framed_write_sizes_with_delayed_writer = None
91
92
93 class ESC[4;38;5;81mPersistentPicklerUnpicklerMixin(ESC[4;38;5;149mobject):
94
95 def dumps(self, arg, proto=None):
96 class ESC[4;38;5;81mPersPickler(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149mpickler):
97 def persistent_id(subself, obj):
98 return self.persistent_id(obj)
99 f = io.BytesIO()
100 p = PersPickler(f, proto)
101 p.dump(arg)
102 return f.getvalue()
103
104 def loads(self, buf, **kwds):
105 class ESC[4;38;5;81mPersUnpickler(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149munpickler):
106 def persistent_load(subself, obj):
107 return self.persistent_load(obj)
108 f = io.BytesIO(buf)
109 u = PersUnpickler(f, **kwds)
110 return u.load()
111
112
113 class ESC[4;38;5;81mPyPersPicklerTests(ESC[4;38;5;149mAbstractPersistentPicklerTests,
114 ESC[4;38;5;149mPersistentPicklerUnpicklerMixin, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
115
116 pickler = pickle._Pickler
117 unpickler = pickle._Unpickler
118
119
120 class ESC[4;38;5;81mPyIdPersPicklerTests(ESC[4;38;5;149mAbstractIdentityPersistentPicklerTests,
121 ESC[4;38;5;149mPersistentPicklerUnpicklerMixin, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
122
123 pickler = pickle._Pickler
124 unpickler = pickle._Unpickler
125
126 @support.cpython_only
127 def test_pickler_reference_cycle(self):
128 def check(Pickler):
129 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
130 f = io.BytesIO()
131 pickler = Pickler(f, proto)
132 pickler.dump('abc')
133 self.assertEqual(self.loads(f.getvalue()), 'abc')
134 pickler = Pickler(io.BytesIO())
135 self.assertEqual(pickler.persistent_id('def'), 'def')
136 r = weakref.ref(pickler)
137 del pickler
138 self.assertIsNone(r())
139
140 class ESC[4;38;5;81mPersPickler(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149mpickler):
141 def persistent_id(subself, obj):
142 return obj
143 check(PersPickler)
144
145 class ESC[4;38;5;81mPersPickler(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149mpickler):
146 @classmethod
147 def persistent_id(cls, obj):
148 return obj
149 check(PersPickler)
150
151 class ESC[4;38;5;81mPersPickler(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149mpickler):
152 @staticmethod
153 def persistent_id(obj):
154 return obj
155 check(PersPickler)
156
157 @support.cpython_only
158 def test_custom_pickler_dispatch_table_memleak(self):
159 # See https://github.com/python/cpython/issues/89988
160
161 class ESC[4;38;5;81mPickler(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149mpickler):
162 def __init__(self, *args, **kwargs):
163 self.dispatch_table = table
164 super().__init__(*args, **kwargs)
165
166 class ESC[4;38;5;81mDispatchTable:
167 pass
168
169 table = DispatchTable()
170 pickler = Pickler(io.BytesIO())
171 self.assertIs(pickler.dispatch_table, table)
172 table_ref = weakref.ref(table)
173 self.assertIsNotNone(table_ref())
174 del pickler
175 del table
176 support.gc_collect()
177 self.assertIsNone(table_ref())
178
179
180 @support.cpython_only
181 def test_unpickler_reference_cycle(self):
182 def check(Unpickler):
183 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
184 unpickler = Unpickler(io.BytesIO(self.dumps('abc', proto)))
185 self.assertEqual(unpickler.load(), 'abc')
186 unpickler = Unpickler(io.BytesIO())
187 self.assertEqual(unpickler.persistent_load('def'), 'def')
188 r = weakref.ref(unpickler)
189 del unpickler
190 self.assertIsNone(r())
191
192 class ESC[4;38;5;81mPersUnpickler(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149munpickler):
193 def persistent_load(subself, pid):
194 return pid
195 check(PersUnpickler)
196
197 class ESC[4;38;5;81mPersUnpickler(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149munpickler):
198 @classmethod
199 def persistent_load(cls, pid):
200 return pid
201 check(PersUnpickler)
202
203 class ESC[4;38;5;81mPersUnpickler(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149munpickler):
204 @staticmethod
205 def persistent_load(pid):
206 return pid
207 check(PersUnpickler)
208
209
210 class ESC[4;38;5;81mPyPicklerUnpicklerObjectTests(ESC[4;38;5;149mAbstractPicklerUnpicklerObjectTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
211
212 pickler_class = pickle._Pickler
213 unpickler_class = pickle._Unpickler
214
215
216 class ESC[4;38;5;81mPyDispatchTableTests(ESC[4;38;5;149mAbstractDispatchTableTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
217
218 pickler_class = pickle._Pickler
219
220 def get_dispatch_table(self):
221 return pickle.dispatch_table.copy()
222
223
224 class ESC[4;38;5;81mPyChainDispatchTableTests(ESC[4;38;5;149mAbstractDispatchTableTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
225
226 pickler_class = pickle._Pickler
227
228 def get_dispatch_table(self):
229 return collections.ChainMap({}, pickle.dispatch_table)
230
231
232 class ESC[4;38;5;81mPyPicklerHookTests(ESC[4;38;5;149mAbstractHookTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
233 class ESC[4;38;5;81mCustomPyPicklerClass(ESC[4;38;5;149mpickleESC[4;38;5;149m.ESC[4;38;5;149m_Pickler,
234 ESC[4;38;5;149mAbstractCustomPicklerClass):
235 pass
236 pickler_class = CustomPyPicklerClass
237
238
239 if has_c_implementation:
240 class ESC[4;38;5;81mCPickleTests(ESC[4;38;5;149mAbstractPickleModuleTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
241 from _pickle import dump, dumps, load, loads, Pickler, Unpickler
242
243 class ESC[4;38;5;81mCUnpicklerTests(ESC[4;38;5;149mPyUnpicklerTests):
244 unpickler = _pickle.Unpickler
245 bad_stack_errors = (pickle.UnpicklingError,)
246 truncated_errors = (pickle.UnpicklingError,)
247
248 class ESC[4;38;5;81mCPicklerTests(ESC[4;38;5;149mPyPicklerTests):
249 pickler = _pickle.Pickler
250 unpickler = _pickle.Unpickler
251
252 class ESC[4;38;5;81mCPersPicklerTests(ESC[4;38;5;149mPyPersPicklerTests):
253 pickler = _pickle.Pickler
254 unpickler = _pickle.Unpickler
255
256 class ESC[4;38;5;81mCIdPersPicklerTests(ESC[4;38;5;149mPyIdPersPicklerTests):
257 pickler = _pickle.Pickler
258 unpickler = _pickle.Unpickler
259
260 class ESC[4;38;5;81mCDumpPickle_LoadPickle(ESC[4;38;5;149mPyPicklerTests):
261 pickler = _pickle.Pickler
262 unpickler = pickle._Unpickler
263
264 class ESC[4;38;5;81mDumpPickle_CLoadPickle(ESC[4;38;5;149mPyPicklerTests):
265 pickler = pickle._Pickler
266 unpickler = _pickle.Unpickler
267
268 class ESC[4;38;5;81mCPicklerUnpicklerObjectTests(ESC[4;38;5;149mAbstractPicklerUnpicklerObjectTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
269 pickler_class = _pickle.Pickler
270 unpickler_class = _pickle.Unpickler
271
272 def test_issue18339(self):
273 unpickler = self.unpickler_class(io.BytesIO())
274 with self.assertRaises(TypeError):
275 unpickler.memo = object
276 # used to cause a segfault
277 with self.assertRaises(ValueError):
278 unpickler.memo = {-1: None}
279 unpickler.memo = {1: None}
280
281 class ESC[4;38;5;81mCDispatchTableTests(ESC[4;38;5;149mAbstractDispatchTableTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
282 pickler_class = pickle.Pickler
283 def get_dispatch_table(self):
284 return pickle.dispatch_table.copy()
285
286 class ESC[4;38;5;81mCChainDispatchTableTests(ESC[4;38;5;149mAbstractDispatchTableTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
287 pickler_class = pickle.Pickler
288 def get_dispatch_table(self):
289 return collections.ChainMap({}, pickle.dispatch_table)
290
291 class ESC[4;38;5;81mCPicklerHookTests(ESC[4;38;5;149mAbstractHookTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
292 class ESC[4;38;5;81mCustomCPicklerClass(ESC[4;38;5;149m_pickleESC[4;38;5;149m.ESC[4;38;5;149mPickler, ESC[4;38;5;149mAbstractCustomPicklerClass):
293 pass
294 pickler_class = CustomCPicklerClass
295
296 @support.cpython_only
297 class ESC[4;38;5;81mHeapTypesTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
298 def setUp(self):
299 pickler = _pickle.Pickler(io.BytesIO())
300 unpickler = _pickle.Unpickler(io.BytesIO())
301
302 self._types = (
303 _pickle.Pickler,
304 _pickle.Unpickler,
305 type(pickler.memo),
306 type(unpickler.memo),
307
308 # We cannot test the _pickle.Pdata;
309 # there's no way to get to it.
310 )
311
312 def test_have_gc(self):
313 import gc
314 for tp in self._types:
315 with self.subTest(tp=tp):
316 self.assertTrue(gc.is_tracked(tp))
317
318 def test_immutable(self):
319 for tp in self._types:
320 with self.subTest(tp=tp):
321 with self.assertRaisesRegex(TypeError, "immutable"):
322 tp.foo = "bar"
323
324 @support.cpython_only
325 class ESC[4;38;5;81mSizeofTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
326 check_sizeof = support.check_sizeof
327
328 def test_pickler(self):
329 basesize = support.calcobjsize('7P2n3i2n3i2P')
330 p = _pickle.Pickler(io.BytesIO())
331 self.assertEqual(object.__sizeof__(p), basesize)
332 MT_size = struct.calcsize('3nP0n')
333 ME_size = struct.calcsize('Pn0P')
334 check = self.check_sizeof
335 check(p, basesize +
336 MT_size + 8 * ME_size + # Minimal memo table size.
337 sys.getsizeof(b'x'*4096)) # Minimal write buffer size.
338 for i in range(6):
339 p.dump(chr(i))
340 check(p, basesize +
341 MT_size + 32 * ME_size + # Size of memo table required to
342 # save references to 6 objects.
343 0) # Write buffer is cleared after every dump().
344
345 def test_unpickler(self):
346 basesize = support.calcobjsize('2P2n2P 2P2n2i5P 2P3n8P2n2i')
347 unpickler = _pickle.Unpickler
348 P = struct.calcsize('P') # Size of memo table entry.
349 n = struct.calcsize('n') # Size of mark table entry.
350 check = self.check_sizeof
351 for encoding in 'ASCII', 'UTF-16', 'latin-1':
352 for errors in 'strict', 'replace':
353 u = unpickler(io.BytesIO(),
354 encoding=encoding, errors=errors)
355 self.assertEqual(object.__sizeof__(u), basesize)
356 check(u, basesize +
357 32 * P + # Minimal memo table size.
358 len(encoding) + 1 + len(errors) + 1)
359
360 stdsize = basesize + len('ASCII') + 1 + len('strict') + 1
361 def check_unpickler(data, memo_size, marks_size):
362 dump = pickle.dumps(data)
363 u = unpickler(io.BytesIO(dump),
364 encoding='ASCII', errors='strict')
365 u.load()
366 check(u, stdsize + memo_size * P + marks_size * n)
367
368 check_unpickler(0, 32, 0)
369 # 20 is minimal non-empty mark stack size.
370 check_unpickler([0] * 100, 32, 20)
371 # 128 is memo table size required to save references to 100 objects.
372 check_unpickler([chr(i) for i in range(100)], 128, 20)
373 def recurse(deep):
374 data = 0
375 for i in range(deep):
376 data = [data, data]
377 return data
378 check_unpickler(recurse(0), 32, 0)
379 check_unpickler(recurse(1), 32, 20)
380 check_unpickler(recurse(20), 32, 20)
381 check_unpickler(recurse(50), 64, 60)
382 check_unpickler(recurse(100), 128, 140)
383
384 u = unpickler(io.BytesIO(pickle.dumps('a', 0)),
385 encoding='ASCII', errors='strict')
386 u.load()
387 check(u, stdsize + 32 * P + 2 + 1)
388
389
390 ALT_IMPORT_MAPPING = {
391 ('_elementtree', 'xml.etree.ElementTree'),
392 ('cPickle', 'pickle'),
393 ('StringIO', 'io'),
394 ('cStringIO', 'io'),
395 }
396
397 ALT_NAME_MAPPING = {
398 ('__builtin__', 'basestring', 'builtins', 'str'),
399 ('exceptions', 'StandardError', 'builtins', 'Exception'),
400 ('UserDict', 'UserDict', 'collections', 'UserDict'),
401 ('socket', '_socketobject', 'socket', 'SocketType'),
402 }
403
404 def mapping(module, name):
405 if (module, name) in NAME_MAPPING:
406 module, name = NAME_MAPPING[(module, name)]
407 elif module in IMPORT_MAPPING:
408 module = IMPORT_MAPPING[module]
409 return module, name
410
411 def reverse_mapping(module, name):
412 if (module, name) in REVERSE_NAME_MAPPING:
413 module, name = REVERSE_NAME_MAPPING[(module, name)]
414 elif module in REVERSE_IMPORT_MAPPING:
415 module = REVERSE_IMPORT_MAPPING[module]
416 return module, name
417
418 def getmodule(module):
419 try:
420 return sys.modules[module]
421 except KeyError:
422 try:
423 with warnings.catch_warnings():
424 action = 'always' if support.verbose else 'ignore'
425 warnings.simplefilter(action, DeprecationWarning)
426 __import__(module)
427 except AttributeError as exc:
428 if support.verbose:
429 print("Can't import module %r: %s" % (module, exc))
430 raise ImportError
431 except ImportError as exc:
432 if support.verbose:
433 print(exc)
434 raise
435 return sys.modules[module]
436
437 def getattribute(module, name):
438 obj = getmodule(module)
439 for n in name.split('.'):
440 obj = getattr(obj, n)
441 return obj
442
443 def get_exceptions(mod):
444 for name in dir(mod):
445 attr = getattr(mod, name)
446 if isinstance(attr, type) and issubclass(attr, BaseException):
447 yield name, attr
448
449 class ESC[4;38;5;81mCompatPickleTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
450 def test_import(self):
451 modules = set(IMPORT_MAPPING.values())
452 modules |= set(REVERSE_IMPORT_MAPPING)
453 modules |= {module for module, name in REVERSE_NAME_MAPPING}
454 modules |= {module for module, name in NAME_MAPPING.values()}
455 for module in modules:
456 try:
457 getmodule(module)
458 except ImportError:
459 pass
460
461 def test_import_mapping(self):
462 for module3, module2 in REVERSE_IMPORT_MAPPING.items():
463 with self.subTest((module3, module2)):
464 try:
465 getmodule(module3)
466 except ImportError:
467 pass
468 if module3[:1] != '_':
469 self.assertIn(module2, IMPORT_MAPPING)
470 self.assertEqual(IMPORT_MAPPING[module2], module3)
471
472 def test_name_mapping(self):
473 for (module3, name3), (module2, name2) in REVERSE_NAME_MAPPING.items():
474 with self.subTest(((module3, name3), (module2, name2))):
475 if (module2, name2) == ('exceptions', 'OSError'):
476 attr = getattribute(module3, name3)
477 self.assertTrue(issubclass(attr, OSError))
478 elif (module2, name2) == ('exceptions', 'ImportError'):
479 attr = getattribute(module3, name3)
480 self.assertTrue(issubclass(attr, ImportError))
481 else:
482 module, name = mapping(module2, name2)
483 if module3[:1] != '_':
484 self.assertEqual((module, name), (module3, name3))
485 try:
486 attr = getattribute(module3, name3)
487 except ImportError:
488 pass
489 else:
490 self.assertEqual(getattribute(module, name), attr)
491
492 def test_reverse_import_mapping(self):
493 for module2, module3 in IMPORT_MAPPING.items():
494 with self.subTest((module2, module3)):
495 try:
496 getmodule(module3)
497 except ImportError as exc:
498 if support.verbose:
499 print(exc)
500 if ((module2, module3) not in ALT_IMPORT_MAPPING and
501 REVERSE_IMPORT_MAPPING.get(module3, None) != module2):
502 for (m3, n3), (m2, n2) in REVERSE_NAME_MAPPING.items():
503 if (module3, module2) == (m3, m2):
504 break
505 else:
506 self.fail('No reverse mapping from %r to %r' %
507 (module3, module2))
508 module = REVERSE_IMPORT_MAPPING.get(module3, module3)
509 module = IMPORT_MAPPING.get(module, module)
510 self.assertEqual(module, module3)
511
512 def test_reverse_name_mapping(self):
513 for (module2, name2), (module3, name3) in NAME_MAPPING.items():
514 with self.subTest(((module2, name2), (module3, name3))):
515 try:
516 attr = getattribute(module3, name3)
517 except ImportError:
518 pass
519 module, name = reverse_mapping(module3, name3)
520 if (module2, name2, module3, name3) not in ALT_NAME_MAPPING:
521 self.assertEqual((module, name), (module2, name2))
522 module, name = mapping(module, name)
523 self.assertEqual((module, name), (module3, name3))
524
525 def test_exceptions(self):
526 self.assertEqual(mapping('exceptions', 'StandardError'),
527 ('builtins', 'Exception'))
528 self.assertEqual(mapping('exceptions', 'Exception'),
529 ('builtins', 'Exception'))
530 self.assertEqual(reverse_mapping('builtins', 'Exception'),
531 ('exceptions', 'Exception'))
532 self.assertEqual(mapping('exceptions', 'OSError'),
533 ('builtins', 'OSError'))
534 self.assertEqual(reverse_mapping('builtins', 'OSError'),
535 ('exceptions', 'OSError'))
536
537 for name, exc in get_exceptions(builtins):
538 with self.subTest(name):
539 if exc in (BlockingIOError,
540 ResourceWarning,
541 StopAsyncIteration,
542 RecursionError,
543 EncodingWarning,
544 BaseExceptionGroup,
545 ExceptionGroup):
546 continue
547 if exc is not OSError and issubclass(exc, OSError):
548 self.assertEqual(reverse_mapping('builtins', name),
549 ('exceptions', 'OSError'))
550 elif exc is not ImportError and issubclass(exc, ImportError):
551 self.assertEqual(reverse_mapping('builtins', name),
552 ('exceptions', 'ImportError'))
553 self.assertEqual(mapping('exceptions', name),
554 ('exceptions', name))
555 else:
556 self.assertEqual(reverse_mapping('builtins', name),
557 ('exceptions', name))
558 self.assertEqual(mapping('exceptions', name),
559 ('builtins', name))
560
561 def test_multiprocessing_exceptions(self):
562 module = import_helper.import_module('multiprocessing.context')
563 for name, exc in get_exceptions(module):
564 if issubclass(exc, Warning):
565 continue
566 with self.subTest(name):
567 self.assertEqual(reverse_mapping('multiprocessing.context', name),
568 ('multiprocessing', name))
569 self.assertEqual(mapping('multiprocessing', name),
570 ('multiprocessing.context', name))
571
572
573 def load_tests(loader, tests, pattern):
574 tests.addTest(doctest.DocTestSuite())
575 return tests
576
577
578 if __name__ == "__main__":
579 unittest.main()