blob: d467d52badb9dae27c1964be10178dc98c3feca5 [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
Tim Peters47a6b132003-01-28 22:34:11 +00009
Serhiy Storchaka5bbd2312014-12-16 19:39:08 +020010import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000011from test import support
Jeremy Hylton66426532001-10-15 21:38:56 +000012
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030013from test.pickletester import AbstractUnpickleTests
Tim Peters47a6b132003-01-28 22:34:11 +000014from test.pickletester import AbstractPickleTests
Tim Peters47a6b132003-01-28 22:34:11 +000015from test.pickletester import AbstractPickleModuleTests
16from test.pickletester import AbstractPersistentPicklerTests
Serhiy Storchakadec25af2016-07-17 11:24:17 +030017from test.pickletester import AbstractIdentityPersistentPicklerTests
Collin Winter771d8342009-04-16 03:18:06 +000018from test.pickletester import AbstractPicklerUnpicklerObjectTests
Antoine Pitrou8d3c2902012-03-04 18:31:48 +010019from test.pickletester import AbstractDispatchTableTests
Antoine Pitrou82be19f2011-08-29 23:09:33 +020020from test.pickletester import BigmemPickleTests
Tim Peters47a6b132003-01-28 22:34:11 +000021
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000022try:
23 import _pickle
24 has_c_implementation = True
25except ImportError:
26 has_c_implementation = False
Jeremy Hylton66426532001-10-15 21:38:56 +000027
Guido van Rossum98297ee2007-11-06 21:34:58 +000028
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000029class PickleTests(AbstractPickleModuleTests):
30 pass
Guido van Rossum5d9113d2003-01-29 17:58:45 +000031
Tim Peterse0c446b2001-10-18 21:57:37 +000032
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030033class PyUnpicklerTests(AbstractUnpickleTests):
34
35 unpickler = pickle._Unpickler
Serhiy Storchakae9b30742015-11-23 15:17:43 +020036 bad_stack_errors = (IndexError,)
Serhiy Storchaka7279bef2015-11-29 13:12:10 +020037 bad_mark_errors = (IndexError, pickle.UnpicklingError,
38 TypeError, AttributeError, EOFError)
39 truncated_errors = (pickle.UnpicklingError, EOFError,
40 AttributeError, ValueError,
41 struct.error, IndexError, ImportError)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030042
43 def loads(self, buf, **kwds):
44 f = io.BytesIO(buf)
45 u = self.unpickler(f, **kwds)
46 return u.load()
47
48
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000049class PyPicklerTests(AbstractPickleTests):
Jeremy Hylton66426532001-10-15 21:38:56 +000050
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000051 pickler = pickle._Pickler
52 unpickler = pickle._Unpickler
Jeremy Hylton66426532001-10-15 21:38:56 +000053
Guido van Rossumf4169812008-03-17 22:56:06 +000054 def dumps(self, arg, proto=None):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000055 f = io.BytesIO()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000056 p = self.pickler(f, proto)
Jeremy Hylton66426532001-10-15 21:38:56 +000057 p.dump(arg)
58 f.seek(0)
Guido van Rossumcfe5f202007-05-08 21:26:54 +000059 return bytes(f.read())
Jeremy Hylton66426532001-10-15 21:38:56 +000060
Alexander Belopolskyec8f0df2011-02-24 20:34:38 +000061 def loads(self, buf, **kwds):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000062 f = io.BytesIO(buf)
Alexander Belopolskyec8f0df2011-02-24 20:34:38 +000063 u = self.unpickler(f, **kwds)
Jeremy Hylton66426532001-10-15 21:38:56 +000064 return u.load()
65
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000066
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030067class InMemoryPickleTests(AbstractPickleTests, AbstractUnpickleTests,
68 BigmemPickleTests):
Antoine Pitrouea99c5c2010-09-09 18:33:21 +000069
70 pickler = pickle._Pickler
71 unpickler = pickle._Unpickler
Serhiy Storchakae9b30742015-11-23 15:17:43 +020072 bad_stack_errors = (pickle.UnpicklingError, IndexError)
Serhiy Storchaka7279bef2015-11-29 13:12:10 +020073 bad_mark_errors = (pickle.UnpicklingError, IndexError,
74 TypeError, AttributeError, EOFError)
75 truncated_errors = (pickle.UnpicklingError, EOFError,
76 AttributeError, ValueError,
77 struct.error, IndexError, ImportError)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +000078
Antoine Pitrou82be19f2011-08-29 23:09:33 +020079 def dumps(self, arg, protocol=None):
80 return pickle.dumps(arg, protocol)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +000081
Alexander Belopolskyec8f0df2011-02-24 20:34:38 +000082 def loads(self, buf, **kwds):
83 return pickle.loads(buf, **kwds)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +000084
85
Serhiy Storchakadec25af2016-07-17 11:24:17 +030086class PersistentPicklerUnpicklerMixin(object):
Jeremy Hylton5e0f4e72002-11-13 22:01:27 +000087
Guido van Rossumf4169812008-03-17 22:56:06 +000088 def dumps(self, arg, proto=None):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000089 class PersPickler(self.pickler):
Jeremy Hylton5e0f4e72002-11-13 22:01:27 +000090 def persistent_id(subself, obj):
91 return self.persistent_id(obj)
Guido van Rossumcfe5f202007-05-08 21:26:54 +000092 f = io.BytesIO()
Guido van Rossum9d32bb12003-01-28 03:51:53 +000093 p = PersPickler(f, proto)
Jeremy Hylton5e0f4e72002-11-13 22:01:27 +000094 p.dump(arg)
Serhiy Storchakadec25af2016-07-17 11:24:17 +030095 return f.getvalue()
Jeremy Hylton5e0f4e72002-11-13 22:01:27 +000096
Alexander Belopolskyec8f0df2011-02-24 20:34:38 +000097 def loads(self, buf, **kwds):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +000098 class PersUnpickler(self.unpickler):
Jeremy Hylton5e0f4e72002-11-13 22:01:27 +000099 def persistent_load(subself, obj):
100 return self.persistent_load(obj)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000101 f = io.BytesIO(buf)
Alexander Belopolskyec8f0df2011-02-24 20:34:38 +0000102 u = PersUnpickler(f, **kwds)
Jeremy Hylton5e0f4e72002-11-13 22:01:27 +0000103 return u.load()
104
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000105
Serhiy Storchakadec25af2016-07-17 11:24:17 +0300106class PyPersPicklerTests(AbstractPersistentPicklerTests,
107 PersistentPicklerUnpicklerMixin):
108
109 pickler = pickle._Pickler
110 unpickler = pickle._Unpickler
111
112
113class PyIdPersPicklerTests(AbstractIdentityPersistentPicklerTests,
114 PersistentPicklerUnpicklerMixin):
115
116 pickler = pickle._Pickler
117 unpickler = pickle._Unpickler
118
119
Collin Winter771d8342009-04-16 03:18:06 +0000120class PyPicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests):
121
122 pickler_class = pickle._Pickler
123 unpickler_class = pickle._Unpickler
124
125
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100126class PyDispatchTableTests(AbstractDispatchTableTests):
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -0800127
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100128 pickler_class = pickle._Pickler
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -0800129
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100130 def get_dispatch_table(self):
131 return pickle.dispatch_table.copy()
132
133
134class PyChainDispatchTableTests(AbstractDispatchTableTests):
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -0800135
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100136 pickler_class = pickle._Pickler
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -0800137
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100138 def get_dispatch_table(self):
139 return collections.ChainMap({}, pickle.dispatch_table)
140
141
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000142if has_c_implementation:
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300143 class CUnpicklerTests(PyUnpicklerTests):
144 unpickler = _pickle.Unpickler
Serhiy Storchakae9b30742015-11-23 15:17:43 +0200145 bad_stack_errors = (pickle.UnpicklingError,)
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200146 bad_mark_errors = (EOFError,)
147 truncated_errors = (pickle.UnpicklingError, EOFError,
148 AttributeError, ValueError)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300149
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000150 class CPicklerTests(PyPicklerTests):
151 pickler = _pickle.Pickler
152 unpickler = _pickle.Unpickler
153
154 class CPersPicklerTests(PyPersPicklerTests):
155 pickler = _pickle.Pickler
156 unpickler = _pickle.Unpickler
157
Serhiy Storchakadec25af2016-07-17 11:24:17 +0300158 class CIdPersPicklerTests(PyIdPersPicklerTests):
159 pickler = _pickle.Pickler
160 unpickler = _pickle.Unpickler
161
Collin Winter771d8342009-04-16 03:18:06 +0000162 class CDumpPickle_LoadPickle(PyPicklerTests):
163 pickler = _pickle.Pickler
164 unpickler = pickle._Unpickler
165
166 class DumpPickle_CLoadPickle(PyPicklerTests):
167 pickler = pickle._Pickler
168 unpickler = _pickle.Unpickler
169
170 class CPicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests):
171 pickler_class = _pickle.Pickler
172 unpickler_class = _pickle.Unpickler
173
Christian Heimesa24b4d22013-07-01 15:17:45 +0200174 def test_issue18339(self):
175 unpickler = self.unpickler_class(io.BytesIO())
Christian Heimes21782482013-07-01 23:00:13 +0200176 with self.assertRaises(TypeError):
177 unpickler.memo = object
Christian Heimesa24b4d22013-07-01 15:17:45 +0200178 # used to cause a segfault
Christian Heimes21782482013-07-01 23:00:13 +0200179 with self.assertRaises(ValueError):
180 unpickler.memo = {-1: None}
Christian Heimesa24b4d22013-07-01 15:17:45 +0200181 unpickler.memo = {1: None}
182
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100183 class CDispatchTableTests(AbstractDispatchTableTests):
184 pickler_class = pickle.Pickler
185 def get_dispatch_table(self):
186 return pickle.dispatch_table.copy()
187
188 class CChainDispatchTableTests(AbstractDispatchTableTests):
189 pickler_class = pickle.Pickler
190 def get_dispatch_table(self):
191 return collections.ChainMap({}, pickle.dispatch_table)
192
Serhiy Storchaka5bbd2312014-12-16 19:39:08 +0200193 @support.cpython_only
194 class SizeofTests(unittest.TestCase):
195 check_sizeof = support.check_sizeof
196
197 def test_pickler(self):
198 basesize = support.calcobjsize('5P2n3i2n3iP')
199 p = _pickle.Pickler(io.BytesIO())
200 self.assertEqual(object.__sizeof__(p), basesize)
201 MT_size = struct.calcsize('3nP0n')
202 ME_size = struct.calcsize('Pn0P')
203 check = self.check_sizeof
204 check(p, basesize +
205 MT_size + 8 * ME_size + # Minimal memo table size.
206 sys.getsizeof(b'x'*4096)) # Minimal write buffer size.
207 for i in range(6):
208 p.dump(chr(i))
209 check(p, basesize +
210 MT_size + 32 * ME_size + # Size of memo table required to
211 # save references to 6 objects.
212 0) # Write buffer is cleared after every dump().
213
214 def test_unpickler(self):
215 basesize = support.calcobjsize('2Pn2P 2P2n2i5P 2P3n6P2n2i')
216 unpickler = _pickle.Unpickler
217 P = struct.calcsize('P') # Size of memo table entry.
218 n = struct.calcsize('n') # Size of mark table entry.
219 check = self.check_sizeof
220 for encoding in 'ASCII', 'UTF-16', 'latin-1':
221 for errors in 'strict', 'replace':
222 u = unpickler(io.BytesIO(),
223 encoding=encoding, errors=errors)
224 self.assertEqual(object.__sizeof__(u), basesize)
225 check(u, basesize +
226 32 * P + # Minimal memo table size.
227 len(encoding) + 1 + len(errors) + 1)
228
229 stdsize = basesize + len('ASCII') + 1 + len('strict') + 1
230 def check_unpickler(data, memo_size, marks_size):
231 dump = pickle.dumps(data)
232 u = unpickler(io.BytesIO(dump),
233 encoding='ASCII', errors='strict')
234 u.load()
235 check(u, stdsize + memo_size * P + marks_size * n)
236
237 check_unpickler(0, 32, 0)
238 # 20 is minimal non-empty mark stack size.
239 check_unpickler([0] * 100, 32, 20)
240 # 128 is memo table size required to save references to 100 objects.
241 check_unpickler([chr(i) for i in range(100)], 128, 20)
242 def recurse(deep):
243 data = 0
244 for i in range(deep):
245 data = [data, data]
246 return data
247 check_unpickler(recurse(0), 32, 0)
248 check_unpickler(recurse(1), 32, 20)
249 check_unpickler(recurse(20), 32, 58)
250 check_unpickler(recurse(50), 64, 58)
251 check_unpickler(recurse(100), 128, 134)
252
253 u = unpickler(io.BytesIO(pickle.dumps('a', 0)),
254 encoding='ASCII', errors='strict')
255 u.load()
256 check(u, stdsize + 32 * P + 2 + 1)
257
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000258
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300259ALT_IMPORT_MAPPING = {
260 ('_elementtree', 'xml.etree.ElementTree'),
261 ('cPickle', 'pickle'),
Serhiy Storchaka5c1d9d22016-01-18 22:33:44 +0200262 ('StringIO', 'io'),
263 ('cStringIO', 'io'),
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300264}
265
266ALT_NAME_MAPPING = {
267 ('__builtin__', 'basestring', 'builtins', 'str'),
268 ('exceptions', 'StandardError', 'builtins', 'Exception'),
269 ('UserDict', 'UserDict', 'collections', 'UserDict'),
270 ('socket', '_socketobject', 'socket', 'SocketType'),
271}
272
273def mapping(module, name):
274 if (module, name) in NAME_MAPPING:
275 module, name = NAME_MAPPING[(module, name)]
276 elif module in IMPORT_MAPPING:
277 module = IMPORT_MAPPING[module]
278 return module, name
279
280def reverse_mapping(module, name):
281 if (module, name) in REVERSE_NAME_MAPPING:
282 module, name = REVERSE_NAME_MAPPING[(module, name)]
283 elif module in REVERSE_IMPORT_MAPPING:
284 module = REVERSE_IMPORT_MAPPING[module]
285 return module, name
286
287def getmodule(module):
288 try:
289 return sys.modules[module]
290 except KeyError:
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300291 try:
292 __import__(module)
293 except AttributeError as exc:
294 if support.verbose:
295 print("Can't import module %r: %s" % (module, exc))
296 raise ImportError
297 except ImportError as exc:
298 if support.verbose:
299 print(exc)
300 raise
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300301 return sys.modules[module]
302
303def getattribute(module, name):
304 obj = getmodule(module)
305 for n in name.split('.'):
306 obj = getattr(obj, n)
307 return obj
308
309def get_exceptions(mod):
310 for name in dir(mod):
311 attr = getattr(mod, name)
312 if isinstance(attr, type) and issubclass(attr, BaseException):
313 yield name, attr
314
315class CompatPickleTests(unittest.TestCase):
316 def test_import(self):
317 modules = set(IMPORT_MAPPING.values())
318 modules |= set(REVERSE_IMPORT_MAPPING)
319 modules |= {module for module, name in REVERSE_NAME_MAPPING}
320 modules |= {module for module, name in NAME_MAPPING.values()}
321 for module in modules:
322 try:
323 getmodule(module)
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300324 except ImportError:
325 pass
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300326
327 def test_import_mapping(self):
328 for module3, module2 in REVERSE_IMPORT_MAPPING.items():
329 with self.subTest((module3, module2)):
330 try:
331 getmodule(module3)
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300332 except ImportError:
333 pass
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300334 if module3[:1] != '_':
335 self.assertIn(module2, IMPORT_MAPPING)
336 self.assertEqual(IMPORT_MAPPING[module2], module3)
337
338 def test_name_mapping(self):
339 for (module3, name3), (module2, name2) in REVERSE_NAME_MAPPING.items():
340 with self.subTest(((module3, name3), (module2, name2))):
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300341 if (module2, name2) == ('exceptions', 'OSError'):
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300342 attr = getattribute(module3, name3)
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300343 self.assertTrue(issubclass(attr, OSError))
344 else:
345 module, name = mapping(module2, name2)
346 if module3[:1] != '_':
347 self.assertEqual((module, name), (module3, name3))
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300348 try:
349 attr = getattribute(module3, name3)
350 except ImportError:
351 pass
352 else:
353 self.assertEqual(getattribute(module, name), attr)
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300354
355 def test_reverse_import_mapping(self):
356 for module2, module3 in IMPORT_MAPPING.items():
357 with self.subTest((module2, module3)):
358 try:
359 getmodule(module3)
360 except ImportError as exc:
361 if support.verbose:
362 print(exc)
363 if ((module2, module3) not in ALT_IMPORT_MAPPING and
364 REVERSE_IMPORT_MAPPING.get(module3, None) != module2):
365 for (m3, n3), (m2, n2) in REVERSE_NAME_MAPPING.items():
366 if (module3, module2) == (m3, m2):
367 break
368 else:
369 self.fail('No reverse mapping from %r to %r' %
370 (module3, module2))
371 module = REVERSE_IMPORT_MAPPING.get(module3, module3)
372 module = IMPORT_MAPPING.get(module, module)
373 self.assertEqual(module, module3)
374
375 def test_reverse_name_mapping(self):
376 for (module2, name2), (module3, name3) in NAME_MAPPING.items():
377 with self.subTest(((module2, name2), (module3, name3))):
Serhiy Storchakab9100e52015-03-31 16:49:26 +0300378 try:
379 attr = getattribute(module3, name3)
380 except ImportError:
381 pass
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300382 module, name = reverse_mapping(module3, name3)
383 if (module2, name2, module3, name3) not in ALT_NAME_MAPPING:
384 self.assertEqual((module, name), (module2, name2))
385 module, name = mapping(module, name)
386 self.assertEqual((module, name), (module3, name3))
387
388 def test_exceptions(self):
389 self.assertEqual(mapping('exceptions', 'StandardError'),
390 ('builtins', 'Exception'))
391 self.assertEqual(mapping('exceptions', 'Exception'),
392 ('builtins', 'Exception'))
393 self.assertEqual(reverse_mapping('builtins', 'Exception'),
394 ('exceptions', 'Exception'))
395 self.assertEqual(mapping('exceptions', 'OSError'),
396 ('builtins', 'OSError'))
397 self.assertEqual(reverse_mapping('builtins', 'OSError'),
398 ('exceptions', 'OSError'))
399
400 for name, exc in get_exceptions(builtins):
401 with self.subTest(name):
Yury Selivanov75445082015-05-11 22:57:16 -0400402 if exc in (BlockingIOError,
403 ResourceWarning,
Yury Selivanovf488fb42015-07-03 01:04:23 -0400404 StopAsyncIteration,
405 RecursionError):
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300406 continue
407 if exc is not OSError and issubclass(exc, OSError):
408 self.assertEqual(reverse_mapping('builtins', name),
409 ('exceptions', 'OSError'))
410 else:
411 self.assertEqual(reverse_mapping('builtins', name),
412 ('exceptions', name))
413 self.assertEqual(mapping('exceptions', name),
414 ('builtins', name))
415
Serhiy Storchaka7b2cfc42015-10-10 20:10:07 +0300416 def test_multiprocessing_exceptions(self):
417 module = support.import_module('multiprocessing.context')
418 for name, exc in get_exceptions(module):
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300419 with self.subTest(name):
420 self.assertEqual(reverse_mapping('multiprocessing.context', name),
421 ('multiprocessing', name))
422 self.assertEqual(mapping('multiprocessing', name),
423 ('multiprocessing.context', name))
424
425
Fred Drake694ed092001-12-19 16:42:15 +0000426def test_main():
Serhiy Storchakadec25af2016-07-17 11:24:17 +0300427 tests = [PickleTests, PyUnpicklerTests, PyPicklerTests,
428 PyPersPicklerTests, PyIdPersPicklerTests,
Serhiy Storchakabfe18242015-03-31 13:12:37 +0300429 PyDispatchTableTests, PyChainDispatchTableTests,
430 CompatPickleTests]
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000431 if has_c_implementation:
Serhiy Storchakadec25af2016-07-17 11:24:17 +0300432 tests.extend([CUnpicklerTests, CPicklerTests,
433 CPersPicklerTests, CIdPersPicklerTests,
Collin Winter771d8342009-04-16 03:18:06 +0000434 CDumpPickle_LoadPickle, DumpPickle_CLoadPickle,
435 PyPicklerUnpicklerObjectTests,
Antoine Pitrouea99c5c2010-09-09 18:33:21 +0000436 CPicklerUnpicklerObjectTests,
Antoine Pitrou8d3c2902012-03-04 18:31:48 +0100437 CDispatchTableTests, CChainDispatchTableTests,
Serhiy Storchaka5bbd2312014-12-16 19:39:08 +0200438 InMemoryPickleTests, SizeofTests])
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000439 support.run_unittest(*tests)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000440 support.run_doctest(pickle)
Fred Drake694ed092001-12-19 16:42:15 +0000441
Jeremy Hylton66426532001-10-15 21:38:56 +0000442if __name__ == "__main__":
Fred Drake694ed092001-12-19 16:42:15 +0000443 test_main()