blob: 635c5af0317af7cec2ea1a69b908189ccf06f8c8 [file] [log] [blame]
Serhiy Storchaka22afc502015-09-29 15:51:40 +03001# -*- coding: utf-8 -*-
Jeremy Hylton66426532001-10-15 21:38:56 +00002import unittest
Tim Peters4190fb82003-02-02 16:09:05 +00003import pickle
Tim Peters8587b3c2003-02-13 15:44:41 +00004import cPickle
Amaury Forgeot d'Arc74b30162009-07-23 19:26:02 +00005import StringIO
Collin Winterf8089c72009-04-09 16:46:46 +00006import cStringIO
Tim Peters31f119e2003-02-03 16:20:13 +00007import pickletools
Georg Brandldffbf5f2008-05-20 07:49:57 +00008import copy_reg
Serhiy Storchakabf19ce22015-11-29 13:12:40 +02009import sys
Tim Peters4190fb82003-02-02 16:09:05 +000010
Serhiy Storchakabf19ce22015-11-29 13:12:40 +020011from test import test_support as support
Zachary Ware916c7c72015-11-27 01:21:51 -060012from test.test_support import TestFailed, verbose, have_unicode, TESTFN
Benjamin Petersond627e122013-03-30 10:36:31 -040013try:
14 from test.test_support import _2G, _1M, precisionbigmemtest
15except ImportError:
16 # this import might fail when run on older Python versions by test_xpickle
Benjamin Petersonf3ad0302013-03-30 15:30:28 -040017 _2G = _1M = 0
Benjamin Petersond627e122013-03-30 10:36:31 -040018 def precisionbigmemtest(*args, **kwargs):
19 return lambda self: None
Tim Peterse089c682001-04-10 03:41:41 +000020
Tim Petersee1a53c2003-02-02 02:57:53 +000021# Tests that try a number of pickle protocols should have a
22# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000023# kind of outer loop.
24assert pickle.HIGHEST_PROTOCOL == cPickle.HIGHEST_PROTOCOL == 2
25protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000026
Collin Winterf8089c72009-04-09 16:46:46 +000027# Copy of test.test_support.run_with_locale. This is needed to support Python
28# 2.4, which didn't include it. This is all to support test_xpickle, which
29# bounces pickled objects through older Python versions to test backwards
30# compatibility.
31def run_with_locale(catstr, *locales):
32 def decorator(func):
33 def inner(*args, **kwds):
34 try:
35 import locale
36 category = getattr(locale, catstr)
37 orig_locale = locale.setlocale(category)
38 except AttributeError:
39 # if the test author gives us an invalid category string
40 raise
41 except:
42 # cannot retrieve original locale, so do nothing
43 locale = orig_locale = None
44 else:
45 for loc in locales:
46 try:
47 locale.setlocale(category, loc)
48 break
49 except:
50 pass
51
52 # now run the function, resetting the locale on exceptions
53 try:
54 return func(*args, **kwds)
55 finally:
56 if locale and orig_locale:
57 locale.setlocale(category, orig_locale)
58 inner.func_name = func.func_name
59 inner.__doc__ = func.__doc__
60 return inner
61 return decorator
62
Tim Peters22e71712003-02-03 22:27:38 +000063
64# Return True if opcode code appears in the pickle, else False.
65def opcode_in_pickle(code, pickle):
66 for op, dummy, dummy in pickletools.genops(pickle):
67 if op.code == code:
68 return True
69 return False
70
Tim Peters8d2613a2003-02-11 16:40:16 +000071# Return the number of times opcode code appears in pickle.
72def count_opcode(code, pickle):
73 n = 0
74 for op, dummy, dummy in pickletools.genops(pickle):
75 if op.code == code:
76 n += 1
77 return n
78
Tim Peters3e667d52003-02-04 21:47:44 +000079# We can't very well test the extension registry without putting known stuff
80# in it, but we have to be careful to restore its original state. Code
81# should do this:
82#
83# e = ExtensionSaver(extension_code)
84# try:
85# fiddle w/ the extension registry's stuff for extension_code
86# finally:
87# e.restore()
88
89class ExtensionSaver:
90 # Remember current registration for code (if any), and remove it (if
91 # there is one).
92 def __init__(self, code):
93 self.code = code
Georg Brandldffbf5f2008-05-20 07:49:57 +000094 if code in copy_reg._inverted_registry:
95 self.pair = copy_reg._inverted_registry[code]
96 copy_reg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000097 else:
98 self.pair = None
99
100 # Restore previous registration for code.
101 def restore(self):
102 code = self.code
Georg Brandldffbf5f2008-05-20 07:49:57 +0000103 curpair = copy_reg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +0000104 if curpair is not None:
Georg Brandldffbf5f2008-05-20 07:49:57 +0000105 copy_reg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000106 pair = self.pair
107 if pair is not None:
Georg Brandldffbf5f2008-05-20 07:49:57 +0000108 copy_reg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000109
Jeremy Hylton66426532001-10-15 21:38:56 +0000110class C:
111 def __cmp__(self, other):
112 return cmp(self.__dict__, other.__dict__)
113
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300114class D(C):
115 def __init__(self, arg):
116 pass
117
118class E(C):
119 def __getinitargs__(self):
120 return ()
121
Serhiy Storchakada87e452015-11-07 11:15:32 +0200122class H(object):
123 pass
124
125# Hashable mutable key
126class K(object):
127 def __init__(self, value):
128 self.value = value
129
130 def __reduce__(self):
131 # Shouldn't support the recursion itself
132 return K, (self.value,)
133
Jeremy Hylton66426532001-10-15 21:38:56 +0000134import __main__
135__main__.C = C
136C.__module__ = "__main__"
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300137__main__.D = D
138D.__module__ = "__main__"
139__main__.E = E
140E.__module__ = "__main__"
Serhiy Storchakada87e452015-11-07 11:15:32 +0200141__main__.H = H
142H.__module__ = "__main__"
143__main__.K = K
144K.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000145
146class myint(int):
147 def __init__(self, x):
148 self.str = str(x)
149
150class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000151
Jeremy Hylton66426532001-10-15 21:38:56 +0000152 def __init__(self, a, b):
153 self.a = a
154 self.b = b
155
156 def __getinitargs__(self):
157 return self.a, self.b
158
Guido van Rossum04a86612001-12-19 16:58:54 +0000159class metaclass(type):
160 pass
161
162class use_metaclass(object):
163 __metaclass__ = metaclass
164
Antoine Pitrou561a8212011-10-04 09:34:48 +0200165class pickling_metaclass(type):
166 def __eq__(self, other):
167 return (type(self) == type(other) and
168 self.reduce_args == other.reduce_args)
169
170 def __reduce__(self):
171 return (create_dynamic_class, self.reduce_args)
172
Ezio Melotti030aa352011-11-06 18:50:32 +0200173 __hash__ = None
174
Antoine Pitrou561a8212011-10-04 09:34:48 +0200175def create_dynamic_class(name, bases):
176 result = pickling_metaclass(name, bases, dict())
177 result.reduce_args = (name, bases)
178 return result
179
Tim Peters70b02d72003-02-02 17:26:40 +0000180# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
181# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000182
Jeremy Hylton66426532001-10-15 21:38:56 +0000183# break into multiple strings to avoid confusing font-lock-mode
Tim Peters70b02d72003-02-02 17:26:40 +0000184DATA0 = """(lp1
Tim Peterse9358162001-01-22 22:05:20 +0000185I0
186aL1L
Tim Peters461922a2001-04-09 20:07:05 +0000187aF2
Tim Peterse9358162001-01-22 22:05:20 +0000188ac__builtin__
189complex
Tim Peters461922a2001-04-09 20:07:05 +0000190p2
191""" + \
192"""(F3
193F0
194tRp3
195aI1
196aI-1
197aI255
198aI-255
199aI-256
200aI65535
201aI-65535
202aI-65536
203aI2147483647
204aI-2147483647
205aI-2147483648
206a""" + \
207"""(S'abc'
Tim Peterse9358162001-01-22 22:05:20 +0000208p4
209g4
Tim Peters461922a2001-04-09 20:07:05 +0000210""" + \
Guido van Rossum42f92da2001-04-16 00:28:21 +0000211"""(i__main__
Tim Peterse9358162001-01-22 22:05:20 +0000212C
213p5
Tim Peters461922a2001-04-09 20:07:05 +0000214""" + \
Tim Peterse9358162001-01-22 22:05:20 +0000215"""(dp6
216S'foo'
217p7
218I1
219sS'bar'
220p8
221I2
222sbg5
223tp9
224ag9
225aI5
226a.
227"""
228
Tim Peters70b02d72003-02-02 17:26:40 +0000229# Disassembly of DATA0.
230DATA0_DIS = """\
231 0: ( MARK
232 1: l LIST (MARK at 0)
233 2: p PUT 1
234 5: I INT 0
235 8: a APPEND
236 9: L LONG 1L
237 13: a APPEND
238 14: F FLOAT 2.0
239 17: a APPEND
240 18: c GLOBAL '__builtin__ complex'
241 39: p PUT 2
242 42: ( MARK
243 43: F FLOAT 3.0
244 46: F FLOAT 0.0
245 49: t TUPLE (MARK at 42)
246 50: R REDUCE
247 51: p PUT 3
248 54: a APPEND
249 55: I INT 1
250 58: a APPEND
251 59: I INT -1
252 63: a APPEND
253 64: I INT 255
254 69: a APPEND
255 70: I INT -255
256 76: a APPEND
257 77: I INT -256
258 83: a APPEND
259 84: I INT 65535
260 91: a APPEND
261 92: I INT -65535
262 100: a APPEND
263 101: I INT -65536
264 109: a APPEND
265 110: I INT 2147483647
266 122: a APPEND
267 123: I INT -2147483647
268 136: a APPEND
269 137: I INT -2147483648
270 150: a APPEND
271 151: ( MARK
272 152: S STRING 'abc'
273 159: p PUT 4
274 162: g GET 4
275 165: ( MARK
276 166: i INST '__main__ C' (MARK at 165)
277 178: p PUT 5
278 181: ( MARK
279 182: d DICT (MARK at 181)
280 183: p PUT 6
281 186: S STRING 'foo'
282 193: p PUT 7
283 196: I INT 1
284 199: s SETITEM
285 200: S STRING 'bar'
286 207: p PUT 8
287 210: I INT 2
288 213: s SETITEM
289 214: b BUILD
290 215: g GET 5
291 218: t TUPLE (MARK at 151)
292 219: p PUT 9
293 222: a APPEND
294 223: g GET 9
295 226: a APPEND
296 227: I INT 5
297 230: a APPEND
298 231: . STOP
299highest protocol among opcodes = 0
300"""
301
302DATA1 = (']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00'
303 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00'
304 '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff'
305 '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff'
306 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00'
307 '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n'
308 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh'
309 '\x06tq\nh\nK\x05e.'
310 )
311
312# Disassembly of DATA1.
313DATA1_DIS = """\
314 0: ] EMPTY_LIST
315 1: q BINPUT 1
316 3: ( MARK
317 4: K BININT1 0
318 6: L LONG 1L
319 10: G BINFLOAT 2.0
320 19: c GLOBAL '__builtin__ complex'
321 40: q BINPUT 2
322 42: ( MARK
323 43: G BINFLOAT 3.0
324 52: G BINFLOAT 0.0
325 61: t TUPLE (MARK at 42)
326 62: R REDUCE
327 63: q BINPUT 3
328 65: K BININT1 1
329 67: J BININT -1
330 72: K BININT1 255
331 74: J BININT -255
332 79: J BININT -256
333 84: M BININT2 65535
334 87: J BININT -65535
335 92: J BININT -65536
336 97: J BININT 2147483647
337 102: J BININT -2147483647
338 107: J BININT -2147483648
339 112: ( MARK
340 113: U SHORT_BINSTRING 'abc'
341 118: q BINPUT 4
342 120: h BINGET 4
343 122: ( MARK
344 123: c GLOBAL '__main__ C'
345 135: q BINPUT 5
346 137: o OBJ (MARK at 122)
347 138: q BINPUT 6
348 140: } EMPTY_DICT
349 141: q BINPUT 7
350 143: ( MARK
351 144: U SHORT_BINSTRING 'foo'
352 149: q BINPUT 8
353 151: K BININT1 1
354 153: U SHORT_BINSTRING 'bar'
355 158: q BINPUT 9
356 160: K BININT1 2
357 162: u SETITEMS (MARK at 143)
358 163: b BUILD
359 164: h BINGET 6
360 166: t TUPLE (MARK at 112)
361 167: q BINPUT 10
362 169: h BINGET 10
363 171: K BININT1 5
364 173: e APPENDS (MARK at 3)
365 174: . STOP
366highest protocol among opcodes = 1
367"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000368
Tim Petersfc273752003-03-02 04:54:24 +0000369DATA2 = ('\x80\x02]q\x01(K\x00\x8a\x01\x01G@\x00\x00\x00\x00\x00\x00\x00'
370 'c__builtin__\ncomplex\nq\x02G@\x08\x00\x00\x00\x00\x00\x00G\x00'
371 '\x00\x00\x00\x00\x00\x00\x00\x86Rq\x03K\x01J\xff\xff\xff\xffK'
372 '\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xff'
373 'J\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00'
374 '\x80(U\x03abcq\x04h\x04(c__main__\nC\nq\x05oq\x06}q\x07(U\x03foo'
375 'q\x08K\x01U\x03barq\tK\x02ubh\x06tq\nh\nK\x05e.')
376
377# Disassembly of DATA2.
378DATA2_DIS = """\
379 0: \x80 PROTO 2
380 2: ] EMPTY_LIST
381 3: q BINPUT 1
382 5: ( MARK
383 6: K BININT1 0
384 8: \x8a LONG1 1L
385 11: G BINFLOAT 2.0
386 20: c GLOBAL '__builtin__ complex'
387 41: q BINPUT 2
388 43: G BINFLOAT 3.0
389 52: G BINFLOAT 0.0
390 61: \x86 TUPLE2
391 62: R REDUCE
392 63: q BINPUT 3
393 65: K BININT1 1
394 67: J BININT -1
395 72: K BININT1 255
396 74: J BININT -255
397 79: J BININT -256
398 84: M BININT2 65535
399 87: J BININT -65535
400 92: J BININT -65536
401 97: J BININT 2147483647
402 102: J BININT -2147483647
403 107: J BININT -2147483648
404 112: ( MARK
405 113: U SHORT_BINSTRING 'abc'
406 118: q BINPUT 4
407 120: h BINGET 4
408 122: ( MARK
409 123: c GLOBAL '__main__ C'
410 135: q BINPUT 5
411 137: o OBJ (MARK at 122)
412 138: q BINPUT 6
413 140: } EMPTY_DICT
414 141: q BINPUT 7
415 143: ( MARK
416 144: U SHORT_BINSTRING 'foo'
417 149: q BINPUT 8
418 151: K BININT1 1
419 153: U SHORT_BINSTRING 'bar'
420 158: q BINPUT 9
421 160: K BININT1 2
422 162: u SETITEMS (MARK at 143)
423 163: b BUILD
424 164: h BINGET 6
425 166: t TUPLE (MARK at 112)
426 167: q BINPUT 10
427 169: h BINGET 10
428 171: K BININT1 5
429 173: e APPENDS (MARK at 5)
430 174: . STOP
431highest protocol among opcodes = 2
432"""
433
Jeremy Hylton66426532001-10-15 21:38:56 +0000434def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000435 c = C()
436 c.foo = 1
437 c.bar = 2
438 x = [0, 1L, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000439 # Append some integer test cases at cPickle.c's internal size
440 # cutoffs.
441 uint1max = 0xff
442 uint2max = 0xffff
443 int4max = 0x7fffffff
444 x.extend([1, -1,
445 uint1max, -uint1max, -uint1max-1,
446 uint2max, -uint2max, -uint2max-1,
447 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000448 y = ('abc', 'abc', c, c)
449 x.append(y)
450 x.append(y)
451 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000452 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000453
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300454
455class AbstractUnpickleTests(unittest.TestCase):
456 # Subclass must define self.loads, self.error.
Tim Petersc58440f2001-04-09 17:16:31 +0000457
Jeremy Hylton66426532001-10-15 21:38:56 +0000458 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000459
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300460 def assert_is_copy(self, obj, objcopy, msg=None):
461 """Utility method to verify if two objects are copies of each others.
462 """
463 if msg is None:
464 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
465 self.assertEqual(obj, objcopy, msg=msg)
466 self.assertIs(type(obj), type(objcopy), msg=msg)
467 if hasattr(obj, '__dict__'):
468 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
469 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
470 if hasattr(obj, '__slots__'):
471 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
472 for slot in obj.__slots__:
473 self.assertEqual(
474 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
475 self.assertEqual(getattr(obj, slot, None),
476 getattr(objcopy, slot, None), msg=msg)
477
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200478 def check_unpickling_error(self, errors, data):
Serhiy Storchakad26b6632015-11-29 16:13:51 +0200479 try:
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200480 try:
481 self.loads(data)
482 except:
483 if support.verbose > 1:
Serhiy Storchakad26b6632015-11-29 16:13:51 +0200484 exc_type, exc, tb = sys.exc_info()
485 print '%-32r - %s: %s' % (data, exc_type.__name__, exc)
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200486 raise
Serhiy Storchakad26b6632015-11-29 16:13:51 +0200487 except errors:
488 pass
489 else:
490 try:
491 exc_name = errors.__name__
492 except AttributeError:
493 exc_name = str(errors)
494 raise self.failureException('%s not raised' % exc_name)
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200495
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300496 def test_load_from_canned_string(self):
497 expected = self._testdata
498 for canned in DATA0, DATA1, DATA2:
499 got = self.loads(canned)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300500 self.assert_is_copy(expected, got)
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300501
502 def test_garyp(self):
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200503 self.check_unpickling_error(self.error, 'garyp')
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300504
505 def test_maxint64(self):
506 maxint64 = (1L << 63) - 1
507 data = 'I' + str(maxint64) + '\n.'
508 got = self.loads(data)
509 self.assertEqual(got, maxint64)
510
511 # Try too with a bogus literal.
512 data = 'I' + str(maxint64) + 'JUNK\n.'
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200513 self.check_unpickling_error(ValueError, data)
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300514
515 def test_insecure_strings(self):
516 insecure = ["abc", "2 + 2", # not quoted
517 #"'abc' + 'def'", # not a single quoted string
518 "'abc", # quote is not closed
519 "'abc\"", # open quote and close quote don't match
520 "'abc' ?", # junk after close quote
521 "'\\'", # trailing backslash
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300522 # issue #17710
523 "'", '"',
524 "' ", '" ',
525 '\'"', '"\'',
526 " ''", ' ""',
527 ' ',
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300528 # some tests of the quoting rules
529 #"'abc\"\''",
530 #"'\\\\a\'\'\'\\\'\\\\\''",
531 ]
532 for s in insecure:
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300533 buf = "S" + s + "\n."
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200534 self.check_unpickling_error(ValueError, buf)
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300535
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300536 def test_correctly_quoted_string(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300537 goodpickles = [("S''\n.", ''),
538 ('S""\n.', ''),
539 ('S"\\n"\n.', '\n'),
540 ("S'\\n'\n.", '\n')]
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300541 for p, expected in goodpickles:
542 self.assertEqual(self.loads(p), expected)
543
544 def test_load_classic_instance(self):
545 # See issue5180. Test loading 2.x pickles that
546 # contain an instance of old style class.
547 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
548 xname = X.__name__.encode('ascii')
549 # Protocol 0 (text mode pickle):
550 """
551 0: ( MARK
552 1: i INST '__main__ X' (MARK at 0)
553 13: p PUT 0
554 16: ( MARK
555 17: d DICT (MARK at 16)
556 18: p PUT 1
557 21: b BUILD
558 22: . STOP
559 """
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300560 pickle0 = ("(i__main__\n"
561 "X\n"
562 "p0\n"
563 "(dp1\nb.").replace('X', xname)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300564 self.assert_is_copy(X(*args), self.loads(pickle0))
565
566 # Protocol 1 (binary mode pickle)
567 """
568 0: ( MARK
569 1: c GLOBAL '__main__ X'
570 13: q BINPUT 0
571 15: o OBJ (MARK at 0)
572 16: q BINPUT 1
573 18: } EMPTY_DICT
574 19: q BINPUT 2
575 21: b BUILD
576 22: . STOP
577 """
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300578 pickle1 = ('(c__main__\n'
579 'X\n'
580 'q\x00oq\x01}q\x02b.').replace('X', xname)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300581 self.assert_is_copy(X(*args), self.loads(pickle1))
582
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300583 # Protocol 2 (pickle2 = '\x80\x02' + pickle1)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300584 """
585 0: \x80 PROTO 2
586 2: ( MARK
587 3: c GLOBAL '__main__ X'
588 15: q BINPUT 0
589 17: o OBJ (MARK at 2)
590 18: q BINPUT 1
591 20: } EMPTY_DICT
592 21: q BINPUT 2
593 23: b BUILD
594 24: . STOP
595 """
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300596 pickle2 = ('\x80\x02(c__main__\n'
597 'X\n'
598 'q\x00oq\x01}q\x02b.').replace('X', xname)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300599 self.assert_is_copy(X(*args), self.loads(pickle2))
600
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300601 def test_load_str(self):
602 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300603 self.assertEqual(self.loads("S'a\\x00\\xa0'\n."), 'a\x00\xa0')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300604 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300605 self.assertEqual(self.loads('U\x03a\x00\xa0.'), 'a\x00\xa0')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300606 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300607 self.assertEqual(self.loads('\x80\x02U\x03a\x00\xa0.'), 'a\x00\xa0')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300608
609 def test_load_unicode(self):
610 # From Python 2: pickle.dumps(u'Ï€', protocol=0)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300611 self.assertEqual(self.loads('V\\u03c0\n.'), u'Ï€')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300612 # From Python 2: pickle.dumps(u'Ï€', protocol=1)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300613 self.assertEqual(self.loads('X\x02\x00\x00\x00\xcf\x80.'), u'Ï€')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300614 # From Python 2: pickle.dumps(u'Ï€', protocol=2)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300615 self.assertEqual(self.loads('\x80\x02X\x02\x00\x00\x00\xcf\x80.'), u'Ï€')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300616
617 def test_constants(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300618 self.assertIsNone(self.loads('N.'))
619 self.assertIs(self.loads('\x88.'), True)
620 self.assertIs(self.loads('\x89.'), False)
621 self.assertIs(self.loads('I01\n.'), True)
622 self.assertIs(self.loads('I00\n.'), False)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300623
624 def test_misc_get(self):
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200625 self.check_unpickling_error(self.error, 'g0\np0\n')
626 self.check_unpickling_error(self.error, 'h\x00q\x00')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300627
628 def test_get(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300629 pickled = '((lp100000\ng100000\nt.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300630 unpickled = self.loads(pickled)
631 self.assertEqual(unpickled, ([],)*2)
632 self.assertIs(unpickled[0], unpickled[1])
633
634 def test_binget(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300635 pickled = '(]q\xffh\xfft.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300636 unpickled = self.loads(pickled)
637 self.assertEqual(unpickled, ([],)*2)
638 self.assertIs(unpickled[0], unpickled[1])
639
640 def test_long_binget(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300641 pickled = '(]r\x00\x00\x01\x00j\x00\x00\x01\x00t.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300642 unpickled = self.loads(pickled)
643 self.assertEqual(unpickled, ([],)*2)
644 self.assertIs(unpickled[0], unpickled[1])
645
646 def test_dup(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300647 pickled = '((l2t.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300648 unpickled = self.loads(pickled)
649 self.assertEqual(unpickled, ([],)*2)
650 self.assertIs(unpickled[0], unpickled[1])
651
Serhiy Storchaka5c137662015-11-23 15:20:43 +0200652 def test_bad_stack(self):
653 badpickles = [
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200654 '.', # STOP
655 '0', # POP
656 '1', # POP_MARK
657 '2', # DUP
658 # '(2', # PyUnpickler doesn't raise
659 'R', # REDUCE
660 ')R',
661 'a', # APPEND
662 'Na',
663 'b', # BUILD
664 'Nb',
665 'd', # DICT
666 'e', # APPENDS
667 # '(e', # PyUnpickler raises AttributeError
668 'i__builtin__\nlist\n', # INST
669 'l', # LIST
670 'o', # OBJ
671 '(o',
672 'p1\n', # PUT
673 'q\x00', # BINPUT
674 'r\x00\x00\x00\x00', # LONG_BINPUT
675 's', # SETITEM
676 'Ns',
677 'NNs',
678 't', # TUPLE
679 'u', # SETITEMS
680 # '(u', # PyUnpickler doesn't raise
681 '}(Nu',
682 '\x81', # NEWOBJ
683 ')\x81',
684 '\x85', # TUPLE1
685 '\x86', # TUPLE2
686 'N\x86',
687 '\x87', # TUPLE3
688 'N\x87',
689 'NN\x87',
Serhiy Storchaka5c137662015-11-23 15:20:43 +0200690 ]
691 for p in badpickles:
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200692 self.check_unpickling_error(self.bad_stack_errors, p)
Serhiy Storchaka5c137662015-11-23 15:20:43 +0200693
694 def test_bad_mark(self):
695 badpickles = [
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200696 # 'N(.', # STOP
697 'N(2', # DUP
698 'c__builtin__\nlist\n)(R', # REDUCE
699 'c__builtin__\nlist\n()R',
700 ']N(a', # APPEND
701 # BUILD
702 'c__builtin__\nValueError\n)R}(b',
703 'c__builtin__\nValueError\n)R(}b',
704 '(Nd', # DICT
705 'N(p1\n', # PUT
706 'N(q\x00', # BINPUT
707 'N(r\x00\x00\x00\x00', # LONG_BINPUT
708 '}NN(s', # SETITEM
709 '}N(Ns',
710 '}(NNs',
711 '}((u', # SETITEMS
712 # NEWOBJ
713 'c__builtin__\nlist\n)(\x81',
714 'c__builtin__\nlist\n()\x81',
715 'N(\x85', # TUPLE1
716 'NN(\x86', # TUPLE2
717 'N(N\x86',
718 'NNN(\x87', # TUPLE3
719 'NN(N\x87',
720 'N(NN\x87',
Serhiy Storchaka5c137662015-11-23 15:20:43 +0200721 ]
722 for p in badpickles:
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200723 self.check_unpickling_error(self.bad_mark_errors, p)
724
725 def test_truncated_data(self):
Serhiy Storchaka81772f12015-11-29 19:20:11 +0200726 self.check_unpickling_error(EOFError, '')
727 self.check_unpickling_error(EOFError, 'N')
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200728 badpickles = [
729 'F', # FLOAT
730 'F0.0',
731 'F0.00',
732 'G', # BINFLOAT
733 'G\x00\x00\x00\x00\x00\x00\x00',
734 'I', # INT
735 'I0',
736 'J', # BININT
737 'J\x00\x00\x00',
738 'K', # BININT1
739 'L', # LONG
740 'L0',
741 'L10',
742 'L0L',
743 'L10L',
744 'M', # BININT2
745 'M\x00',
746 # 'P', # PERSID
747 # 'Pabc',
748 'S', # STRING
Serhiy Storchaka03f3c2f2015-11-29 20:18:27 +0200749 "S'abc'",
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200750 'T', # BINSTRING
751 'T\x03\x00\x00',
752 'T\x03\x00\x00\x00',
753 'T\x03\x00\x00\x00ab',
754 'U', # SHORT_BINSTRING
755 'U\x03',
756 'U\x03ab',
757 'V', # UNICODE
758 'Vabc',
759 'X', # BINUNICODE
760 'X\x03\x00\x00',
761 'X\x03\x00\x00\x00',
762 'X\x03\x00\x00\x00ab',
763 '(c', # GLOBAL
764 '(c__builtin__',
765 '(c__builtin__\n',
766 '(c__builtin__\nlist',
767 'Ng', # GET
768 'Ng0',
769 '(i', # INST
770 '(i__builtin__',
771 '(i__builtin__\n',
772 '(i__builtin__\nlist',
773 'Nh', # BINGET
774 'Nj', # LONG_BINGET
775 'Nj\x00\x00\x00',
776 'Np', # PUT
777 'Np0',
778 'Nq', # BINPUT
779 'Nr', # LONG_BINPUT
780 'Nr\x00\x00\x00',
781 '\x80', # PROTO
782 '\x82', # EXT1
783 '\x83', # EXT2
784 '\x84\x01',
785 '\x84', # EXT4
786 '\x84\x01\x00\x00',
787 '\x8a', # LONG1
788 '\x8b', # LONG4
789 '\x8b\x00\x00\x00',
790 ]
791 for p in badpickles:
792 self.check_unpickling_error(self.truncated_errors, p)
Serhiy Storchaka5c137662015-11-23 15:20:43 +0200793
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300794
795class AbstractPickleTests(unittest.TestCase):
796 # Subclass must define self.dumps, self.loads.
797
798 _testdata = AbstractUnpickleTests._testdata
799
Jeremy Hylton66426532001-10-15 21:38:56 +0000800 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000801 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000802
Jeremy Hylton66426532001-10-15 21:38:56 +0000803 def test_misc(self):
804 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000805 for proto in protocols:
806 x = myint(4)
807 s = self.dumps(x, proto)
808 y = self.loads(s)
809 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000810
Tim Peters70b02d72003-02-02 17:26:40 +0000811 x = (1, ())
812 s = self.dumps(x, proto)
813 y = self.loads(s)
814 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000815
Tim Peters70b02d72003-02-02 17:26:40 +0000816 x = initarg(1, x)
817 s = self.dumps(x, proto)
818 y = self.loads(s)
819 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000820
Jeremy Hylton66426532001-10-15 21:38:56 +0000821 # XXX test __reduce__ protocol?
822
Tim Peters70b02d72003-02-02 17:26:40 +0000823 def test_roundtrip_equality(self):
824 expected = self._testdata
825 for proto in protocols:
826 s = self.dumps(expected, proto)
827 got = self.loads(s)
828 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000829
Tim Peters70b02d72003-02-02 17:26:40 +0000830 # There are gratuitous differences between pickles produced by
831 # pickle and cPickle, largely because cPickle starts PUT indices at
832 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
833 # there's a comment with an exclamation point there whose meaning
834 # is a mystery. cPickle also suppresses PUT for objects with a refcount
835 # of 1.
836 def dont_test_disassembly(self):
Tim Peters70b02d72003-02-02 17:26:40 +0000837 from pickletools import dis
838
839 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
840 s = self.dumps(self._testdata, proto)
Collin Winterf8089c72009-04-09 16:46:46 +0000841 filelike = cStringIO.StringIO()
Tim Peters70b02d72003-02-02 17:26:40 +0000842 dis(s, out=filelike)
843 got = filelike.getvalue()
844 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000845
846 def test_recursive_list(self):
847 l = []
848 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000849 for proto in protocols:
850 s = self.dumps(l, proto)
851 x = self.loads(s)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200852 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000853 self.assertEqual(len(x), 1)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200854 self.assertIs(x[0], x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000855
Serhiy Storchakada87e452015-11-07 11:15:32 +0200856 def test_recursive_tuple_and_list(self):
Collin Winter57bef682009-05-26 04:12:39 +0000857 t = ([],)
858 t[0].append(t)
859 for proto in protocols:
860 s = self.dumps(t, proto)
861 x = self.loads(s)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200862 self.assertIsInstance(x, tuple)
Collin Winter57bef682009-05-26 04:12:39 +0000863 self.assertEqual(len(x), 1)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200864 self.assertIsInstance(x[0], list)
Collin Winter57bef682009-05-26 04:12:39 +0000865 self.assertEqual(len(x[0]), 1)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200866 self.assertIs(x[0][0], x)
Collin Winter57bef682009-05-26 04:12:39 +0000867
Jeremy Hylton66426532001-10-15 21:38:56 +0000868 def test_recursive_dict(self):
869 d = {}
870 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000871 for proto in protocols:
872 s = self.dumps(d, proto)
873 x = self.loads(s)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200874 self.assertIsInstance(x, dict)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000875 self.assertEqual(x.keys(), [1])
Serhiy Storchakada87e452015-11-07 11:15:32 +0200876 self.assertIs(x[1], x)
877
878 def test_recursive_dict_key(self):
879 d = {}
880 k = K(d)
881 d[k] = 1
882 for proto in protocols:
883 s = self.dumps(d, proto)
884 x = self.loads(s)
885 self.assertIsInstance(x, dict)
886 self.assertEqual(len(x.keys()), 1)
887 self.assertIsInstance(x.keys()[0], K)
888 self.assertIs(x.keys()[0].value, x)
889
890 def test_recursive_list_subclass(self):
891 y = MyList()
892 y.append(y)
893 s = self.dumps(y, 2)
894 x = self.loads(s)
895 self.assertIsInstance(x, MyList)
896 self.assertEqual(len(x), 1)
897 self.assertIs(x[0], x)
898
899 def test_recursive_dict_subclass(self):
900 d = MyDict()
901 d[1] = d
902 s = self.dumps(d, 2)
903 x = self.loads(s)
904 self.assertIsInstance(x, MyDict)
905 self.assertEqual(x.keys(), [1])
906 self.assertIs(x[1], x)
907
908 def test_recursive_dict_subclass_key(self):
909 d = MyDict()
910 k = K(d)
911 d[k] = 1
912 s = self.dumps(d, 2)
913 x = self.loads(s)
914 self.assertIsInstance(x, MyDict)
915 self.assertEqual(len(x.keys()), 1)
916 self.assertIsInstance(x.keys()[0], K)
917 self.assertIs(x.keys()[0].value, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000918
919 def test_recursive_inst(self):
920 i = C()
921 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000922 for proto in protocols:
Ezio Melottia84ecc62013-03-04 15:23:12 +0200923 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +0000924 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000925 self.assertEqual(dir(x), dir(i))
Ezio Melottia84ecc62013-03-04 15:23:12 +0200926 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000927
928 def test_recursive_multi(self):
929 l = []
930 d = {1:l}
931 i = C()
932 i.attr = d
933 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000934 for proto in protocols:
935 s = self.dumps(l, proto)
936 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000937 self.assertEqual(len(x), 1)
938 self.assertEqual(dir(x[0]), dir(i))
939 self.assertEqual(x[0].attr.keys(), [1])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000940 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000941
Serhiy Storchakada87e452015-11-07 11:15:32 +0200942 def check_recursive_collection_and_inst(self, factory):
943 h = H()
944 y = factory([h])
945 h.attr = y
946 for proto in protocols:
947 s = self.dumps(y, proto)
948 x = self.loads(s)
949 self.assertIsInstance(x, type(y))
950 self.assertEqual(len(x), 1)
951 self.assertIsInstance(list(x)[0], H)
952 self.assertIs(list(x)[0].attr, x)
953
954 def test_recursive_list_and_inst(self):
955 self.check_recursive_collection_and_inst(list)
956
957 def test_recursive_tuple_and_inst(self):
958 self.check_recursive_collection_and_inst(tuple)
959
960 def test_recursive_dict_and_inst(self):
961 self.check_recursive_collection_and_inst(dict.fromkeys)
962
963 def test_recursive_set_and_inst(self):
964 self.check_recursive_collection_and_inst(set)
965
966 def test_recursive_frozenset_and_inst(self):
967 self.check_recursive_collection_and_inst(frozenset)
968
969 def test_recursive_list_subclass_and_inst(self):
970 self.check_recursive_collection_and_inst(MyList)
971
972 def test_recursive_tuple_subclass_and_inst(self):
973 self.check_recursive_collection_and_inst(MyTuple)
974
975 def test_recursive_dict_subclass_and_inst(self):
976 self.check_recursive_collection_and_inst(MyDict.fromkeys)
977
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000978 if have_unicode:
Jeremy Hylton66426532001-10-15 21:38:56 +0000979 def test_unicode(self):
Alexandre Vassalottie57e9992008-12-27 10:02:59 +0000980 endcases = [u'', u'<\\u>', u'<\\\u1234>', u'<\n>',
981 u'<\\>', u'<\\\U00012345>']
Tim Petersee1a53c2003-02-02 02:57:53 +0000982 for proto in protocols:
983 for u in endcases:
984 p = self.dumps(u, proto)
985 u2 = self.loads(p)
986 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000987
Alexandre Vassalottif852bf92008-12-27 07:08:47 +0000988 def test_unicode_high_plane(self):
989 t = u'\U00012345'
990 for proto in protocols:
991 p = self.dumps(t, proto)
992 t2 = self.loads(p)
993 self.assertEqual(t2, t)
994
Jeremy Hylton66426532001-10-15 21:38:56 +0000995 def test_ints(self):
996 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000997 for proto in protocols:
998 n = sys.maxint
999 while n:
1000 for expected in (-n, n):
1001 s = self.dumps(expected, proto)
1002 n2 = self.loads(s)
1003 self.assertEqual(expected, n2)
1004 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +00001005
Tim Petersee1a53c2003-02-02 02:57:53 +00001006 def test_long(self):
1007 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +00001008 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +00001009 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
1010 nbase = 1L << nbits
1011 for npos in nbase-1, nbase, nbase+1:
1012 for n in npos, -npos:
1013 pickle = self.dumps(n, proto)
1014 got = self.loads(pickle)
1015 self.assertEqual(n, got)
1016 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
1017 # bother with those.
Tim Petersee1a53c2003-02-02 02:57:53 +00001018 nbase = long("deadbeeffeedface", 16)
1019 nbase += nbase << 1000000
1020 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +00001021 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +00001022 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +00001023 self.assertEqual(n, got)
1024
Mark Dickinsona3ecd2c2009-01-24 16:40:29 +00001025 def test_float(self):
1026 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
1027 3.14, 263.44582062374053, 6.022e23, 1e30]
1028 test_values = test_values + [-x for x in test_values]
1029 for proto in protocols:
1030 for value in test_values:
1031 pickle = self.dumps(value, proto)
1032 got = self.loads(pickle)
1033 self.assertEqual(value, got)
1034
Georg Brandlde9b6242006-04-30 11:13:56 +00001035 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
1036 def test_float_format(self):
1037 # make sure that floats are formatted locale independent
1038 self.assertEqual(self.dumps(1.2)[0:3], 'F1.')
1039
Jeremy Hylton66426532001-10-15 21:38:56 +00001040 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +00001041 pass
Jeremy Hylton66426532001-10-15 21:38:56 +00001042
1043 def test_getinitargs(self):
1044 pass
1045
Guido van Rossum04a86612001-12-19 16:58:54 +00001046 def test_metaclass(self):
1047 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +00001048 for proto in protocols:
1049 s = self.dumps(a, proto)
1050 b = self.loads(s)
1051 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +00001052
Antoine Pitrou561a8212011-10-04 09:34:48 +02001053 def test_dynamic_class(self):
1054 a = create_dynamic_class("my_dynamic_class", (object,))
1055 copy_reg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
1056 for proto in protocols:
1057 s = self.dumps(a, proto)
1058 b = self.loads(s)
1059 self.assertEqual(a, b)
1060
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001061 def test_structseq(self):
1062 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +00001063 import os
Tim Peters70b02d72003-02-02 17:26:40 +00001064
1065 t = time.localtime()
1066 for proto in protocols:
1067 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +00001068 u = self.loads(s)
1069 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +00001070 if hasattr(os, "stat"):
1071 t = os.stat(os.curdir)
1072 s = self.dumps(t, proto)
1073 u = self.loads(s)
1074 self.assertEqual(t, u)
1075 if hasattr(os, "statvfs"):
1076 t = os.statvfs(os.curdir)
1077 s = self.dumps(t, proto)
1078 u = self.loads(s)
1079 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001080
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001081 # Tests for protocol 2
1082
Tim Peters4190fb82003-02-02 16:09:05 +00001083 def test_proto(self):
1084 build_none = pickle.NONE + pickle.STOP
1085 for proto in protocols:
1086 expected = build_none
1087 if proto >= 2:
1088 expected = pickle.PROTO + chr(proto) + expected
1089 p = self.dumps(None, proto)
1090 self.assertEqual(p, expected)
1091
1092 oob = protocols[-1] + 1 # a future protocol
1093 badpickle = pickle.PROTO + chr(oob) + build_none
1094 try:
1095 self.loads(badpickle)
1096 except ValueError, detail:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001097 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +00001098 "unsupported pickle protocol"))
1099 else:
1100 self.fail("expected bad protocol number to raise ValueError")
1101
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001102 def test_long1(self):
1103 x = 12345678910111213141516178920L
Tim Peters61bf2572003-02-03 21:31:22 +00001104 for proto in protocols:
1105 s = self.dumps(x, proto)
1106 y = self.loads(s)
1107 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001108 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001109
1110 def test_long4(self):
1111 x = 12345678910111213141516178920L << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +00001112 for proto in protocols:
1113 s = self.dumps(x, proto)
1114 y = self.loads(s)
1115 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001116 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001117
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001118 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +00001119 # Map (proto, len(tuple)) to expected opcode.
1120 expected_opcode = {(0, 0): pickle.TUPLE,
1121 (0, 1): pickle.TUPLE,
1122 (0, 2): pickle.TUPLE,
1123 (0, 3): pickle.TUPLE,
1124 (0, 4): pickle.TUPLE,
1125
1126 (1, 0): pickle.EMPTY_TUPLE,
1127 (1, 1): pickle.TUPLE,
1128 (1, 2): pickle.TUPLE,
1129 (1, 3): pickle.TUPLE,
1130 (1, 4): pickle.TUPLE,
1131
1132 (2, 0): pickle.EMPTY_TUPLE,
1133 (2, 1): pickle.TUPLE1,
1134 (2, 2): pickle.TUPLE2,
1135 (2, 3): pickle.TUPLE3,
1136 (2, 4): pickle.TUPLE,
1137 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001138 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +00001139 b = (1,)
1140 c = (1, 2)
1141 d = (1, 2, 3)
1142 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +00001143 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001144 for x in a, b, c, d, e:
1145 s = self.dumps(x, proto)
1146 y = self.loads(s)
1147 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +00001148 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +00001149 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +00001150
Guido van Rossum7d97d312003-01-28 04:25:27 +00001151 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +00001152 # Map (proto, singleton) to expected opcode.
1153 expected_opcode = {(0, None): pickle.NONE,
1154 (1, None): pickle.NONE,
1155 (2, None): pickle.NONE,
1156
1157 (0, True): pickle.INT,
1158 (1, True): pickle.INT,
1159 (2, True): pickle.NEWTRUE,
1160
1161 (0, False): pickle.INT,
1162 (1, False): pickle.INT,
1163 (2, False): pickle.NEWFALSE,
1164 }
Tim Peters4190fb82003-02-02 16:09:05 +00001165 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +00001166 for x in None, False, True:
1167 s = self.dumps(x, proto)
1168 y = self.loads(s)
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001169 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +00001170 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +00001171 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +00001172
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001173 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001174 x = MyTuple([1, 2, 3])
1175 x.foo = 42
1176 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001177 for proto in protocols:
1178 s = self.dumps(x, proto)
1179 y = self.loads(s)
1180 self.assertEqual(tuple(x), tuple(y))
1181 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001182
1183 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001184 x = MyList([1, 2, 3])
1185 x.foo = 42
1186 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001187 for proto in protocols:
1188 s = self.dumps(x, proto)
1189 y = self.loads(s)
1190 self.assertEqual(list(x), list(y))
1191 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001192
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001193 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001194 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001195 for C in myclasses:
1196 B = C.__base__
1197 x = C(C.sample)
1198 x.foo = 42
1199 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001200 y = self.loads(s)
1201 detail = (proto, C, B, x, y, type(y))
1202 self.assertEqual(B(x), B(y), detail)
1203 self.assertEqual(x.__dict__, y.__dict__, detail)
1204
Georg Brandldffbf5f2008-05-20 07:49:57 +00001205 # Register a type with copy_reg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001206 # an object of that type. Check that the resulting pickle uses opcode
1207 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001208
Tim Peters22e71712003-02-03 22:27:38 +00001209 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001210 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001211 try:
Georg Brandldffbf5f2008-05-20 07:49:57 +00001212 copy_reg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001213 x = MyList([1, 2, 3])
1214 x.foo = 42
1215 x.bar = "hello"
1216
Tim Peters22e71712003-02-03 22:27:38 +00001217 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001218 s1 = self.dumps(x, 1)
Ezio Melottiaa980582010-01-23 23:04:36 +00001219 self.assertIn(__name__, s1)
1220 self.assertIn("MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +00001221 self.assertEqual(opcode_in_pickle(opcode, s1), False)
1222
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001223 y = self.loads(s1)
1224 self.assertEqual(list(x), list(y))
1225 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001226
Tim Peters22e71712003-02-03 22:27:38 +00001227 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001228 s2 = self.dumps(x, 2)
Ezio Melottiaa980582010-01-23 23:04:36 +00001229 self.assertNotIn(__name__, s2)
1230 self.assertNotIn("MyList", s2)
Tim Peters3e667d52003-02-04 21:47:44 +00001231 self.assertEqual(opcode_in_pickle(opcode, s2), True)
1232
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001233 y = self.loads(s2)
1234 self.assertEqual(list(x), list(y))
1235 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001236
1237 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001238 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001239
1240 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001241 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1242 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001243
1244 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001245 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1246 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1247 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001248
1249 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001250 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1251 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1252 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1253
Tim Peters8d2613a2003-02-11 16:40:16 +00001254 def test_list_chunking(self):
1255 n = 10 # too small to chunk
1256 x = range(n)
1257 for proto in protocols:
1258 s = self.dumps(x, proto)
1259 y = self.loads(s)
1260 self.assertEqual(x, y)
1261 num_appends = count_opcode(pickle.APPENDS, s)
1262 self.assertEqual(num_appends, proto > 0)
1263
1264 n = 2500 # expect at least two chunks when proto > 0
1265 x = range(n)
1266 for proto in protocols:
1267 s = self.dumps(x, proto)
1268 y = self.loads(s)
1269 self.assertEqual(x, y)
1270 num_appends = count_opcode(pickle.APPENDS, s)
1271 if proto == 0:
1272 self.assertEqual(num_appends, 0)
1273 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001274 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001275
1276 def test_dict_chunking(self):
1277 n = 10 # too small to chunk
1278 x = dict.fromkeys(range(n))
1279 for proto in protocols:
1280 s = self.dumps(x, proto)
1281 y = self.loads(s)
1282 self.assertEqual(x, y)
1283 num_setitems = count_opcode(pickle.SETITEMS, s)
1284 self.assertEqual(num_setitems, proto > 0)
1285
1286 n = 2500 # expect at least two chunks when proto > 0
1287 x = dict.fromkeys(range(n))
1288 for proto in protocols:
1289 s = self.dumps(x, proto)
1290 y = self.loads(s)
1291 self.assertEqual(x, y)
1292 num_setitems = count_opcode(pickle.SETITEMS, s)
1293 if proto == 0:
1294 self.assertEqual(num_setitems, 0)
1295 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001296 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001297
Tim Peterse9ef2032003-02-13 18:42:00 +00001298 def test_simple_newobj(self):
1299 x = object.__new__(SimpleNewObj) # avoid __init__
1300 x.abc = 666
1301 for proto in protocols:
1302 s = self.dumps(x, proto)
1303 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
1304 y = self.loads(s) # will raise TypeError if __init__ called
1305 self.assertEqual(y.abc, 666)
1306 self.assertEqual(x.__dict__, y.__dict__)
1307
Tim Peters42f08ac2003-02-11 22:43:24 +00001308 def test_newobj_list_slots(self):
1309 x = SlotList([1, 2, 3])
1310 x.foo = 42
1311 x.bar = "hello"
1312 s = self.dumps(x, 2)
1313 y = self.loads(s)
1314 self.assertEqual(list(x), list(y))
1315 self.assertEqual(x.__dict__, y.__dict__)
1316 self.assertEqual(x.foo, y.foo)
1317 self.assertEqual(x.bar, y.bar)
1318
Guido van Rossum2a30b212003-02-18 22:41:24 +00001319 def test_reduce_overrides_default_reduce_ex(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001320 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001321 x = REX_one()
1322 self.assertEqual(x._reduce_called, 0)
1323 s = self.dumps(x, proto)
1324 self.assertEqual(x._reduce_called, 1)
1325 y = self.loads(s)
1326 self.assertEqual(y._reduce_called, 0)
1327
1328 def test_reduce_ex_called(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001329 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001330 x = REX_two()
1331 self.assertEqual(x._proto, None)
1332 s = self.dumps(x, proto)
1333 self.assertEqual(x._proto, proto)
1334 y = self.loads(s)
1335 self.assertEqual(y._proto, None)
1336
1337 def test_reduce_ex_overrides_reduce(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001338 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001339 x = REX_three()
1340 self.assertEqual(x._proto, None)
1341 s = self.dumps(x, proto)
1342 self.assertEqual(x._proto, proto)
1343 y = self.loads(s)
1344 self.assertEqual(y._proto, None)
1345
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001346 def test_reduce_ex_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001347 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001348 x = REX_four()
1349 self.assertEqual(x._proto, None)
1350 s = self.dumps(x, proto)
1351 self.assertEqual(x._proto, proto)
1352 y = self.loads(s)
1353 self.assertEqual(y._proto, proto)
1354
1355 def test_reduce_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001356 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001357 x = REX_five()
1358 self.assertEqual(x._reduce_called, 0)
1359 s = self.dumps(x, proto)
1360 self.assertEqual(x._reduce_called, 1)
1361 y = self.loads(s)
1362 self.assertEqual(y._reduce_called, 1)
1363
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001364 def test_reduce_bad_iterator(self):
1365 # Issue4176: crash when 4th and 5th items of __reduce__()
1366 # are not iterators
1367 class C(object):
1368 def __reduce__(self):
1369 # 4th item is not an iterator
1370 return list, (), None, [], None
1371 class D(object):
1372 def __reduce__(self):
1373 # 5th item is not an iterator
1374 return dict, (), None, None, []
1375
Serhiy Storchakaff41d452015-12-30 20:59:32 +02001376 # Protocol 0 in Python implementation is less strict and also accepts
1377 # iterables.
Collin Winterf8089c72009-04-09 16:46:46 +00001378 for proto in protocols:
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001379 try:
1380 self.dumps(C(), proto)
Serhiy Storchakaff41d452015-12-30 20:59:32 +02001381 except (AttributeError, pickle.PicklingError, cPickle.PicklingError):
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001382 pass
1383 try:
1384 self.dumps(D(), proto)
Serhiy Storchakaff41d452015-12-30 20:59:32 +02001385 except (AttributeError, pickle.PicklingError, cPickle.PicklingError):
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001386 pass
1387
Collin Winterf8089c72009-04-09 16:46:46 +00001388 def test_many_puts_and_gets(self):
1389 # Test that internal data structures correctly deal with lots of
1390 # puts/gets.
1391 keys = ("aaa" + str(i) for i in xrange(100))
1392 large_dict = dict((k, [4, 5, 6]) for k in keys)
1393 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1394
1395 for proto in protocols:
1396 dumped = self.dumps(obj, proto)
1397 loaded = self.loads(dumped)
1398 self.assertEqual(loaded, obj,
1399 "Failed protocol %d: %r != %r"
1400 % (proto, obj, loaded))
1401
Antoine Pitrou74309892009-05-02 21:13:23 +00001402 def test_attribute_name_interning(self):
1403 # Test that attribute names of pickled objects are interned when
1404 # unpickling.
1405 for proto in protocols:
1406 x = C()
1407 x.foo = 42
1408 x.bar = "hello"
1409 s = self.dumps(x, proto)
1410 y = self.loads(s)
1411 x_keys = sorted(x.__dict__)
1412 y_keys = sorted(y.__dict__)
1413 for x_key, y_key in zip(x_keys, y_keys):
1414 self.assertIs(x_key, y_key)
1415
Collin Winterf8089c72009-04-09 16:46:46 +00001416
Guido van Rossum2a30b212003-02-18 22:41:24 +00001417# Test classes for reduce_ex
1418
1419class REX_one(object):
1420 _reduce_called = 0
1421 def __reduce__(self):
1422 self._reduce_called = 1
1423 return REX_one, ()
1424 # No __reduce_ex__ here, but inheriting it from object
1425
1426class REX_two(object):
1427 _proto = None
1428 def __reduce_ex__(self, proto):
1429 self._proto = proto
1430 return REX_two, ()
1431 # No __reduce__ here, but inheriting it from object
1432
1433class REX_three(object):
1434 _proto = None
1435 def __reduce_ex__(self, proto):
1436 self._proto = proto
1437 return REX_two, ()
1438 def __reduce__(self):
1439 raise TestFailed, "This __reduce__ shouldn't be called"
1440
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001441class REX_four(object):
1442 _proto = None
1443 def __reduce_ex__(self, proto):
1444 self._proto = proto
1445 return object.__reduce_ex__(self, proto)
1446 # Calling base class method should succeed
1447
1448class REX_five(object):
1449 _reduce_called = 0
1450 def __reduce__(self):
1451 self._reduce_called = 1
1452 return object.__reduce__(self)
1453 # This one used to fail with infinite recursion
1454
Guido van Rossum2a30b212003-02-18 22:41:24 +00001455# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001456
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001457class MyInt(int):
1458 sample = 1
1459
1460class MyLong(long):
1461 sample = 1L
1462
1463class MyFloat(float):
1464 sample = 1.0
1465
1466class MyComplex(complex):
1467 sample = 1.0 + 0.0j
1468
1469class MyStr(str):
1470 sample = "hello"
1471
1472class MyUnicode(unicode):
1473 sample = u"hello \u1234"
1474
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001475class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001476 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001477
1478class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001479 sample = [1, 2, 3]
1480
1481class MyDict(dict):
1482 sample = {"a": 1, "b": 2}
1483
1484myclasses = [MyInt, MyLong, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001485 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001486 MyStr, MyUnicode,
1487 MyTuple, MyList, MyDict]
1488
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001489
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001490class SlotList(MyList):
1491 __slots__ = ["foo"]
1492
Tim Peterse9ef2032003-02-13 18:42:00 +00001493class SimpleNewObj(object):
1494 def __init__(self, a, b, c):
1495 # raise an error, to make sure this isn't called
1496 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1497
Jeremy Hylton66426532001-10-15 21:38:56 +00001498class AbstractPickleModuleTests(unittest.TestCase):
1499
1500 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001501 import os
1502 f = open(TESTFN, "w")
1503 try:
1504 f.close()
1505 self.assertRaises(ValueError, self.module.dump, 123, f)
1506 finally:
1507 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001508
1509 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001510 import os
1511 f = open(TESTFN, "w")
1512 try:
1513 f.close()
1514 self.assertRaises(ValueError, self.module.dump, 123, f)
1515 finally:
1516 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001517
Collin Winterf8089c72009-04-09 16:46:46 +00001518 def test_load_from_and_dump_to_file(self):
1519 stream = cStringIO.StringIO()
1520 data = [123, {}, 124]
1521 self.module.dump(data, stream)
1522 stream.seek(0)
1523 unpickled = self.module.load(stream)
1524 self.assertEqual(unpickled, data)
1525
Tim Petersc0c93702003-02-13 19:30:57 +00001526 def test_highest_protocol(self):
1527 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
1528 self.assertEqual(self.module.HIGHEST_PROTOCOL, 2)
1529
Martin v. Löwis544f1192004-07-27 05:22:33 +00001530 def test_callapi(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001531 f = cStringIO.StringIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001532 # With and without keyword arguments
1533 self.module.dump(123, f, -1)
1534 self.module.dump(123, file=f, protocol=-1)
1535 self.module.dumps(123, -1)
1536 self.module.dumps(123, protocol=-1)
1537 self.module.Pickler(f, -1)
1538 self.module.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001539
Amaury Forgeot d'Arc74b30162009-07-23 19:26:02 +00001540 def test_incomplete_input(self):
1541 s = StringIO.StringIO("X''.")
1542 self.assertRaises(EOFError, self.module.load, s)
1543
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001544 def test_restricted(self):
1545 # issue7128: cPickle failed in restricted mode
1546 builtins = {self.module.__name__: self.module,
1547 '__import__': __import__}
1548 d = {}
1549 teststr = "def f(): {0}.dumps(0)".format(self.module.__name__)
1550 exec teststr in {'__builtins__': builtins}, d
1551 d['f']()
1552
Antoine Pitrou0d423b82010-01-07 17:46:49 +00001553 def test_bad_input(self):
1554 # Test issue4298
1555 s = '\x58\0\0\0\x54'
1556 self.assertRaises(EOFError, self.module.loads, s)
Serhiy Storchakabf19ce22015-11-29 13:12:40 +02001557
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001558
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001559class AbstractPersistentPicklerTests(unittest.TestCase):
1560
1561 # This class defines persistent_id() and persistent_load()
1562 # functions that should be used by the pickler. All even integers
1563 # are pickled using persistent ids.
1564
1565 def persistent_id(self, object):
1566 if isinstance(object, int) and object % 2 == 0:
1567 self.id_count += 1
1568 return str(object)
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001569 elif object == "test_false_value":
1570 self.false_count += 1
1571 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001572 else:
1573 return None
1574
1575 def persistent_load(self, oid):
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001576 if not oid:
1577 self.load_false_count += 1
1578 return "test_false_value"
1579 else:
1580 self.load_count += 1
1581 object = int(oid)
1582 assert object % 2 == 0
1583 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001584
1585 def test_persistence(self):
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001586 L = range(10) + ["test_false_value"]
1587 for proto in protocols:
1588 self.id_count = 0
1589 self.false_count = 0
1590 self.load_false_count = 0
1591 self.load_count = 0
1592 self.assertEqual(self.loads(self.dumps(L, proto)), L)
1593 self.assertEqual(self.id_count, 5)
1594 self.assertEqual(self.false_count, 1)
1595 self.assertEqual(self.load_count, 5)
1596 self.assertEqual(self.load_false_count, 1)
Collin Winterf8089c72009-04-09 16:46:46 +00001597
1598class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1599
1600 pickler_class = None
1601 unpickler_class = None
1602
1603 def setUp(self):
1604 assert self.pickler_class
1605 assert self.unpickler_class
1606
1607 def test_clear_pickler_memo(self):
1608 # To test whether clear_memo() has any effect, we pickle an object,
1609 # then pickle it again without clearing the memo; the two serialized
1610 # forms should be different. If we clear_memo() and then pickle the
1611 # object again, the third serialized form should be identical to the
1612 # first one we obtained.
1613 data = ["abcdefg", "abcdefg", 44]
1614 f = cStringIO.StringIO()
1615 pickler = self.pickler_class(f)
1616
1617 pickler.dump(data)
1618 first_pickled = f.getvalue()
1619
1620 # Reset StringIO object.
1621 f.seek(0)
1622 f.truncate()
1623
1624 pickler.dump(data)
1625 second_pickled = f.getvalue()
1626
1627 # Reset the Pickler and StringIO objects.
1628 pickler.clear_memo()
1629 f.seek(0)
1630 f.truncate()
1631
1632 pickler.dump(data)
1633 third_pickled = f.getvalue()
1634
1635 self.assertNotEqual(first_pickled, second_pickled)
1636 self.assertEqual(first_pickled, third_pickled)
1637
1638 def test_priming_pickler_memo(self):
1639 # Verify that we can set the Pickler's memo attribute.
1640 data = ["abcdefg", "abcdefg", 44]
1641 f = cStringIO.StringIO()
1642 pickler = self.pickler_class(f)
1643
1644 pickler.dump(data)
1645 first_pickled = f.getvalue()
1646
1647 f = cStringIO.StringIO()
1648 primed = self.pickler_class(f)
1649 primed.memo = pickler.memo
1650
1651 primed.dump(data)
1652 primed_pickled = f.getvalue()
1653
1654 self.assertNotEqual(first_pickled, primed_pickled)
1655
1656 def test_priming_unpickler_memo(self):
1657 # Verify that we can set the Unpickler's memo attribute.
1658 data = ["abcdefg", "abcdefg", 44]
1659 f = cStringIO.StringIO()
1660 pickler = self.pickler_class(f)
1661
1662 pickler.dump(data)
1663 first_pickled = f.getvalue()
1664
1665 f = cStringIO.StringIO()
1666 primed = self.pickler_class(f)
1667 primed.memo = pickler.memo
1668
1669 primed.dump(data)
1670 primed_pickled = f.getvalue()
1671
1672 unpickler = self.unpickler_class(cStringIO.StringIO(first_pickled))
1673 unpickled_data1 = unpickler.load()
1674
1675 self.assertEqual(unpickled_data1, data)
1676
1677 primed = self.unpickler_class(cStringIO.StringIO(primed_pickled))
1678 primed.memo = unpickler.memo
1679 unpickled_data2 = primed.load()
1680
1681 primed.memo.clear()
1682
1683 self.assertEqual(unpickled_data2, data)
1684 self.assertTrue(unpickled_data2 is unpickled_data1)
1685
1686 def test_reusing_unpickler_objects(self):
1687 data1 = ["abcdefg", "abcdefg", 44]
1688 f = cStringIO.StringIO()
1689 pickler = self.pickler_class(f)
1690 pickler.dump(data1)
1691 pickled1 = f.getvalue()
1692
1693 data2 = ["abcdefg", 44, 44]
1694 f = cStringIO.StringIO()
1695 pickler = self.pickler_class(f)
1696 pickler.dump(data2)
1697 pickled2 = f.getvalue()
1698
1699 f = cStringIO.StringIO()
1700 f.write(pickled1)
1701 f.seek(0)
1702 unpickler = self.unpickler_class(f)
1703 self.assertEqual(unpickler.load(), data1)
1704
1705 f.seek(0)
1706 f.truncate()
1707 f.write(pickled2)
1708 f.seek(0)
1709 self.assertEqual(unpickler.load(), data2)
Serhiy Storchakacdc7a912013-02-12 21:36:47 +02001710
1711class BigmemPickleTests(unittest.TestCase):
1712
1713 # Memory requirements: 1 byte per character for input strings, 1 byte
1714 # for pickled data, 1 byte for unpickled strings, 1 byte for internal
1715 # buffer and 1 byte of free space for resizing of internal buffer.
1716
1717 @precisionbigmemtest(size=_2G + 100*_1M, memuse=5)
1718 def test_huge_strlist(self, size):
1719 chunksize = 2**20
1720 data = []
1721 while size > chunksize:
1722 data.append('x' * chunksize)
1723 size -= chunksize
1724 chunksize += 1
1725 data.append('y' * size)
1726
1727 try:
1728 for proto in protocols:
1729 try:
1730 pickled = self.dumps(data, proto)
1731 res = self.loads(pickled)
1732 self.assertEqual(res, data)
1733 finally:
1734 res = None
1735 pickled = None
1736 finally:
1737 data = None