blob: f7b9225cb298c555b4af9e9cd584bf79b93ff31a [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
Tim Peters4190fb82003-02-02 16:09:05 +00009
Benjamin Petersond627e122013-03-30 10:36:31 -040010from test.test_support import TestFailed, verbose, have_unicode, TESTFN
11try:
12 from test.test_support import _2G, _1M, precisionbigmemtest
13except ImportError:
14 # this import might fail when run on older Python versions by test_xpickle
Benjamin Petersonf3ad0302013-03-30 15:30:28 -040015 _2G = _1M = 0
Benjamin Petersond627e122013-03-30 10:36:31 -040016 def precisionbigmemtest(*args, **kwargs):
17 return lambda self: None
Tim Peterse089c682001-04-10 03:41:41 +000018
Tim Petersee1a53c2003-02-02 02:57:53 +000019# Tests that try a number of pickle protocols should have a
20# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000021# kind of outer loop.
22assert pickle.HIGHEST_PROTOCOL == cPickle.HIGHEST_PROTOCOL == 2
23protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000024
Collin Winterf8089c72009-04-09 16:46:46 +000025# Copy of test.test_support.run_with_locale. This is needed to support Python
26# 2.4, which didn't include it. This is all to support test_xpickle, which
27# bounces pickled objects through older Python versions to test backwards
28# compatibility.
29def run_with_locale(catstr, *locales):
30 def decorator(func):
31 def inner(*args, **kwds):
32 try:
33 import locale
34 category = getattr(locale, catstr)
35 orig_locale = locale.setlocale(category)
36 except AttributeError:
37 # if the test author gives us an invalid category string
38 raise
39 except:
40 # cannot retrieve original locale, so do nothing
41 locale = orig_locale = None
42 else:
43 for loc in locales:
44 try:
45 locale.setlocale(category, loc)
46 break
47 except:
48 pass
49
50 # now run the function, resetting the locale on exceptions
51 try:
52 return func(*args, **kwds)
53 finally:
54 if locale and orig_locale:
55 locale.setlocale(category, orig_locale)
56 inner.func_name = func.func_name
57 inner.__doc__ = func.__doc__
58 return inner
59 return decorator
60
Tim Peters22e71712003-02-03 22:27:38 +000061
62# Return True if opcode code appears in the pickle, else False.
63def opcode_in_pickle(code, pickle):
64 for op, dummy, dummy in pickletools.genops(pickle):
65 if op.code == code:
66 return True
67 return False
68
Tim Peters8d2613a2003-02-11 16:40:16 +000069# Return the number of times opcode code appears in pickle.
70def count_opcode(code, pickle):
71 n = 0
72 for op, dummy, dummy in pickletools.genops(pickle):
73 if op.code == code:
74 n += 1
75 return n
76
Tim Peters3e667d52003-02-04 21:47:44 +000077# We can't very well test the extension registry without putting known stuff
78# in it, but we have to be careful to restore its original state. Code
79# should do this:
80#
81# e = ExtensionSaver(extension_code)
82# try:
83# fiddle w/ the extension registry's stuff for extension_code
84# finally:
85# e.restore()
86
87class ExtensionSaver:
88 # Remember current registration for code (if any), and remove it (if
89 # there is one).
90 def __init__(self, code):
91 self.code = code
Georg Brandldffbf5f2008-05-20 07:49:57 +000092 if code in copy_reg._inverted_registry:
93 self.pair = copy_reg._inverted_registry[code]
94 copy_reg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000095 else:
96 self.pair = None
97
98 # Restore previous registration for code.
99 def restore(self):
100 code = self.code
Georg Brandldffbf5f2008-05-20 07:49:57 +0000101 curpair = copy_reg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +0000102 if curpair is not None:
Georg Brandldffbf5f2008-05-20 07:49:57 +0000103 copy_reg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000104 pair = self.pair
105 if pair is not None:
Georg Brandldffbf5f2008-05-20 07:49:57 +0000106 copy_reg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000107
Jeremy Hylton66426532001-10-15 21:38:56 +0000108class C:
109 def __cmp__(self, other):
110 return cmp(self.__dict__, other.__dict__)
111
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300112class D(C):
113 def __init__(self, arg):
114 pass
115
116class E(C):
117 def __getinitargs__(self):
118 return ()
119
Jeremy Hylton66426532001-10-15 21:38:56 +0000120import __main__
121__main__.C = C
122C.__module__ = "__main__"
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300123__main__.D = D
124D.__module__ = "__main__"
125__main__.E = E
126E.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000127
128class myint(int):
129 def __init__(self, x):
130 self.str = str(x)
131
132class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000133
Jeremy Hylton66426532001-10-15 21:38:56 +0000134 def __init__(self, a, b):
135 self.a = a
136 self.b = b
137
138 def __getinitargs__(self):
139 return self.a, self.b
140
Guido van Rossum04a86612001-12-19 16:58:54 +0000141class metaclass(type):
142 pass
143
144class use_metaclass(object):
145 __metaclass__ = metaclass
146
Antoine Pitrou561a8212011-10-04 09:34:48 +0200147class pickling_metaclass(type):
148 def __eq__(self, other):
149 return (type(self) == type(other) and
150 self.reduce_args == other.reduce_args)
151
152 def __reduce__(self):
153 return (create_dynamic_class, self.reduce_args)
154
Ezio Melotti030aa352011-11-06 18:50:32 +0200155 __hash__ = None
156
Antoine Pitrou561a8212011-10-04 09:34:48 +0200157def create_dynamic_class(name, bases):
158 result = pickling_metaclass(name, bases, dict())
159 result.reduce_args = (name, bases)
160 return result
161
Tim Peters70b02d72003-02-02 17:26:40 +0000162# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
163# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000164
Jeremy Hylton66426532001-10-15 21:38:56 +0000165# break into multiple strings to avoid confusing font-lock-mode
Tim Peters70b02d72003-02-02 17:26:40 +0000166DATA0 = """(lp1
Tim Peterse9358162001-01-22 22:05:20 +0000167I0
168aL1L
Tim Peters461922a2001-04-09 20:07:05 +0000169aF2
Tim Peterse9358162001-01-22 22:05:20 +0000170ac__builtin__
171complex
Tim Peters461922a2001-04-09 20:07:05 +0000172p2
173""" + \
174"""(F3
175F0
176tRp3
177aI1
178aI-1
179aI255
180aI-255
181aI-256
182aI65535
183aI-65535
184aI-65536
185aI2147483647
186aI-2147483647
187aI-2147483648
188a""" + \
189"""(S'abc'
Tim Peterse9358162001-01-22 22:05:20 +0000190p4
191g4
Tim Peters461922a2001-04-09 20:07:05 +0000192""" + \
Guido van Rossum42f92da2001-04-16 00:28:21 +0000193"""(i__main__
Tim Peterse9358162001-01-22 22:05:20 +0000194C
195p5
Tim Peters461922a2001-04-09 20:07:05 +0000196""" + \
Tim Peterse9358162001-01-22 22:05:20 +0000197"""(dp6
198S'foo'
199p7
200I1
201sS'bar'
202p8
203I2
204sbg5
205tp9
206ag9
207aI5
208a.
209"""
210
Tim Peters70b02d72003-02-02 17:26:40 +0000211# Disassembly of DATA0.
212DATA0_DIS = """\
213 0: ( MARK
214 1: l LIST (MARK at 0)
215 2: p PUT 1
216 5: I INT 0
217 8: a APPEND
218 9: L LONG 1L
219 13: a APPEND
220 14: F FLOAT 2.0
221 17: a APPEND
222 18: c GLOBAL '__builtin__ complex'
223 39: p PUT 2
224 42: ( MARK
225 43: F FLOAT 3.0
226 46: F FLOAT 0.0
227 49: t TUPLE (MARK at 42)
228 50: R REDUCE
229 51: p PUT 3
230 54: a APPEND
231 55: I INT 1
232 58: a APPEND
233 59: I INT -1
234 63: a APPEND
235 64: I INT 255
236 69: a APPEND
237 70: I INT -255
238 76: a APPEND
239 77: I INT -256
240 83: a APPEND
241 84: I INT 65535
242 91: a APPEND
243 92: I INT -65535
244 100: a APPEND
245 101: I INT -65536
246 109: a APPEND
247 110: I INT 2147483647
248 122: a APPEND
249 123: I INT -2147483647
250 136: a APPEND
251 137: I INT -2147483648
252 150: a APPEND
253 151: ( MARK
254 152: S STRING 'abc'
255 159: p PUT 4
256 162: g GET 4
257 165: ( MARK
258 166: i INST '__main__ C' (MARK at 165)
259 178: p PUT 5
260 181: ( MARK
261 182: d DICT (MARK at 181)
262 183: p PUT 6
263 186: S STRING 'foo'
264 193: p PUT 7
265 196: I INT 1
266 199: s SETITEM
267 200: S STRING 'bar'
268 207: p PUT 8
269 210: I INT 2
270 213: s SETITEM
271 214: b BUILD
272 215: g GET 5
273 218: t TUPLE (MARK at 151)
274 219: p PUT 9
275 222: a APPEND
276 223: g GET 9
277 226: a APPEND
278 227: I INT 5
279 230: a APPEND
280 231: . STOP
281highest protocol among opcodes = 0
282"""
283
284DATA1 = (']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00'
285 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00'
286 '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff'
287 '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff'
288 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00'
289 '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n'
290 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh'
291 '\x06tq\nh\nK\x05e.'
292 )
293
294# Disassembly of DATA1.
295DATA1_DIS = """\
296 0: ] EMPTY_LIST
297 1: q BINPUT 1
298 3: ( MARK
299 4: K BININT1 0
300 6: L LONG 1L
301 10: G BINFLOAT 2.0
302 19: c GLOBAL '__builtin__ complex'
303 40: q BINPUT 2
304 42: ( MARK
305 43: G BINFLOAT 3.0
306 52: G BINFLOAT 0.0
307 61: t TUPLE (MARK at 42)
308 62: R REDUCE
309 63: q BINPUT 3
310 65: K BININT1 1
311 67: J BININT -1
312 72: K BININT1 255
313 74: J BININT -255
314 79: J BININT -256
315 84: M BININT2 65535
316 87: J BININT -65535
317 92: J BININT -65536
318 97: J BININT 2147483647
319 102: J BININT -2147483647
320 107: J BININT -2147483648
321 112: ( MARK
322 113: U SHORT_BINSTRING 'abc'
323 118: q BINPUT 4
324 120: h BINGET 4
325 122: ( MARK
326 123: c GLOBAL '__main__ C'
327 135: q BINPUT 5
328 137: o OBJ (MARK at 122)
329 138: q BINPUT 6
330 140: } EMPTY_DICT
331 141: q BINPUT 7
332 143: ( MARK
333 144: U SHORT_BINSTRING 'foo'
334 149: q BINPUT 8
335 151: K BININT1 1
336 153: U SHORT_BINSTRING 'bar'
337 158: q BINPUT 9
338 160: K BININT1 2
339 162: u SETITEMS (MARK at 143)
340 163: b BUILD
341 164: h BINGET 6
342 166: t TUPLE (MARK at 112)
343 167: q BINPUT 10
344 169: h BINGET 10
345 171: K BININT1 5
346 173: e APPENDS (MARK at 3)
347 174: . STOP
348highest protocol among opcodes = 1
349"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000350
Tim Petersfc273752003-03-02 04:54:24 +0000351DATA2 = ('\x80\x02]q\x01(K\x00\x8a\x01\x01G@\x00\x00\x00\x00\x00\x00\x00'
352 'c__builtin__\ncomplex\nq\x02G@\x08\x00\x00\x00\x00\x00\x00G\x00'
353 '\x00\x00\x00\x00\x00\x00\x00\x86Rq\x03K\x01J\xff\xff\xff\xffK'
354 '\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xff'
355 'J\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00'
356 '\x80(U\x03abcq\x04h\x04(c__main__\nC\nq\x05oq\x06}q\x07(U\x03foo'
357 'q\x08K\x01U\x03barq\tK\x02ubh\x06tq\nh\nK\x05e.')
358
359# Disassembly of DATA2.
360DATA2_DIS = """\
361 0: \x80 PROTO 2
362 2: ] EMPTY_LIST
363 3: q BINPUT 1
364 5: ( MARK
365 6: K BININT1 0
366 8: \x8a LONG1 1L
367 11: G BINFLOAT 2.0
368 20: c GLOBAL '__builtin__ complex'
369 41: q BINPUT 2
370 43: G BINFLOAT 3.0
371 52: G BINFLOAT 0.0
372 61: \x86 TUPLE2
373 62: R REDUCE
374 63: q BINPUT 3
375 65: K BININT1 1
376 67: J BININT -1
377 72: K BININT1 255
378 74: J BININT -255
379 79: J BININT -256
380 84: M BININT2 65535
381 87: J BININT -65535
382 92: J BININT -65536
383 97: J BININT 2147483647
384 102: J BININT -2147483647
385 107: J BININT -2147483648
386 112: ( MARK
387 113: U SHORT_BINSTRING 'abc'
388 118: q BINPUT 4
389 120: h BINGET 4
390 122: ( MARK
391 123: c GLOBAL '__main__ C'
392 135: q BINPUT 5
393 137: o OBJ (MARK at 122)
394 138: q BINPUT 6
395 140: } EMPTY_DICT
396 141: q BINPUT 7
397 143: ( MARK
398 144: U SHORT_BINSTRING 'foo'
399 149: q BINPUT 8
400 151: K BININT1 1
401 153: U SHORT_BINSTRING 'bar'
402 158: q BINPUT 9
403 160: K BININT1 2
404 162: u SETITEMS (MARK at 143)
405 163: b BUILD
406 164: h BINGET 6
407 166: t TUPLE (MARK at 112)
408 167: q BINPUT 10
409 169: h BINGET 10
410 171: K BININT1 5
411 173: e APPENDS (MARK at 5)
412 174: . STOP
413highest protocol among opcodes = 2
414"""
415
Jeremy Hylton66426532001-10-15 21:38:56 +0000416def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000417 c = C()
418 c.foo = 1
419 c.bar = 2
420 x = [0, 1L, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000421 # Append some integer test cases at cPickle.c's internal size
422 # cutoffs.
423 uint1max = 0xff
424 uint2max = 0xffff
425 int4max = 0x7fffffff
426 x.extend([1, -1,
427 uint1max, -uint1max, -uint1max-1,
428 uint2max, -uint2max, -uint2max-1,
429 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000430 y = ('abc', 'abc', c, c)
431 x.append(y)
432 x.append(y)
433 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000434 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000435
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300436
437class AbstractUnpickleTests(unittest.TestCase):
438 # Subclass must define self.loads, self.error.
Tim Petersc58440f2001-04-09 17:16:31 +0000439
Jeremy Hylton66426532001-10-15 21:38:56 +0000440 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000441
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300442 def assert_is_copy(self, obj, objcopy, msg=None):
443 """Utility method to verify if two objects are copies of each others.
444 """
445 if msg is None:
446 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
447 self.assertEqual(obj, objcopy, msg=msg)
448 self.assertIs(type(obj), type(objcopy), msg=msg)
449 if hasattr(obj, '__dict__'):
450 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
451 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
452 if hasattr(obj, '__slots__'):
453 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
454 for slot in obj.__slots__:
455 self.assertEqual(
456 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
457 self.assertEqual(getattr(obj, slot, None),
458 getattr(objcopy, slot, None), msg=msg)
459
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300460 def test_load_from_canned_string(self):
461 expected = self._testdata
462 for canned in DATA0, DATA1, DATA2:
463 got = self.loads(canned)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300464 self.assert_is_copy(expected, got)
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300465
466 def test_garyp(self):
467 self.assertRaises(self.error, self.loads, 'garyp')
468
469 def test_maxint64(self):
470 maxint64 = (1L << 63) - 1
471 data = 'I' + str(maxint64) + '\n.'
472 got = self.loads(data)
473 self.assertEqual(got, maxint64)
474
475 # Try too with a bogus literal.
476 data = 'I' + str(maxint64) + 'JUNK\n.'
477 self.assertRaises(ValueError, self.loads, data)
478
479 def test_insecure_strings(self):
480 insecure = ["abc", "2 + 2", # not quoted
481 #"'abc' + 'def'", # not a single quoted string
482 "'abc", # quote is not closed
483 "'abc\"", # open quote and close quote don't match
484 "'abc' ?", # junk after close quote
485 "'\\'", # trailing backslash
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300486 # issue #17710
487 "'", '"',
488 "' ", '" ',
489 '\'"', '"\'',
490 " ''", ' ""',
491 ' ',
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300492 # some tests of the quoting rules
493 #"'abc\"\''",
494 #"'\\\\a\'\'\'\\\'\\\\\''",
495 ]
496 for s in insecure:
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300497 buf = "S" + s + "\n."
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300498 self.assertRaises(ValueError, self.loads, buf)
499
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300500 def test_correctly_quoted_string(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300501 goodpickles = [("S''\n.", ''),
502 ('S""\n.', ''),
503 ('S"\\n"\n.', '\n'),
504 ("S'\\n'\n.", '\n')]
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300505 for p, expected in goodpickles:
506 self.assertEqual(self.loads(p), expected)
507
508 def test_load_classic_instance(self):
509 # See issue5180. Test loading 2.x pickles that
510 # contain an instance of old style class.
511 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
512 xname = X.__name__.encode('ascii')
513 # Protocol 0 (text mode pickle):
514 """
515 0: ( MARK
516 1: i INST '__main__ X' (MARK at 0)
517 13: p PUT 0
518 16: ( MARK
519 17: d DICT (MARK at 16)
520 18: p PUT 1
521 21: b BUILD
522 22: . STOP
523 """
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300524 pickle0 = ("(i__main__\n"
525 "X\n"
526 "p0\n"
527 "(dp1\nb.").replace('X', xname)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300528 self.assert_is_copy(X(*args), self.loads(pickle0))
529
530 # Protocol 1 (binary mode pickle)
531 """
532 0: ( MARK
533 1: c GLOBAL '__main__ X'
534 13: q BINPUT 0
535 15: o OBJ (MARK at 0)
536 16: q BINPUT 1
537 18: } EMPTY_DICT
538 19: q BINPUT 2
539 21: b BUILD
540 22: . STOP
541 """
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300542 pickle1 = ('(c__main__\n'
543 'X\n'
544 'q\x00oq\x01}q\x02b.').replace('X', xname)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300545 self.assert_is_copy(X(*args), self.loads(pickle1))
546
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300547 # Protocol 2 (pickle2 = '\x80\x02' + pickle1)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300548 """
549 0: \x80 PROTO 2
550 2: ( MARK
551 3: c GLOBAL '__main__ X'
552 15: q BINPUT 0
553 17: o OBJ (MARK at 2)
554 18: q BINPUT 1
555 20: } EMPTY_DICT
556 21: q BINPUT 2
557 23: b BUILD
558 24: . STOP
559 """
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300560 pickle2 = ('\x80\x02(c__main__\n'
561 'X\n'
562 'q\x00oq\x01}q\x02b.').replace('X', xname)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300563 self.assert_is_copy(X(*args), self.loads(pickle2))
564
565 def test_pop_empty_stack(self):
566 # Test issue7455
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300567 s = '0'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300568 self.assertRaises((cPickle.UnpicklingError, IndexError), self.loads, s)
569
570 def test_load_str(self):
571 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300572 self.assertEqual(self.loads("S'a\\x00\\xa0'\n."), 'a\x00\xa0')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300573 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300574 self.assertEqual(self.loads('U\x03a\x00\xa0.'), 'a\x00\xa0')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300575 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300576 self.assertEqual(self.loads('\x80\x02U\x03a\x00\xa0.'), 'a\x00\xa0')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300577
578 def test_load_unicode(self):
579 # From Python 2: pickle.dumps(u'Ï€', protocol=0)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300580 self.assertEqual(self.loads('V\\u03c0\n.'), u'Ï€')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300581 # From Python 2: pickle.dumps(u'Ï€', protocol=1)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300582 self.assertEqual(self.loads('X\x02\x00\x00\x00\xcf\x80.'), u'Ï€')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300583 # From Python 2: pickle.dumps(u'Ï€', protocol=2)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300584 self.assertEqual(self.loads('\x80\x02X\x02\x00\x00\x00\xcf\x80.'), u'Ï€')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300585
586 def test_constants(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300587 self.assertIsNone(self.loads('N.'))
588 self.assertIs(self.loads('\x88.'), True)
589 self.assertIs(self.loads('\x89.'), False)
590 self.assertIs(self.loads('I01\n.'), True)
591 self.assertIs(self.loads('I00\n.'), False)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300592
593 def test_misc_get(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300594 self.assertRaises(self.error, self.loads, 'g0\np0\n')
595 self.assertRaises(self.error, self.loads, 'h\x00q\x00')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300596
597 def test_get(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300598 pickled = '((lp100000\ng100000\nt.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300599 unpickled = self.loads(pickled)
600 self.assertEqual(unpickled, ([],)*2)
601 self.assertIs(unpickled[0], unpickled[1])
602
603 def test_binget(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300604 pickled = '(]q\xffh\xfft.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300605 unpickled = self.loads(pickled)
606 self.assertEqual(unpickled, ([],)*2)
607 self.assertIs(unpickled[0], unpickled[1])
608
609 def test_long_binget(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300610 pickled = '(]r\x00\x00\x01\x00j\x00\x00\x01\x00t.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300611 unpickled = self.loads(pickled)
612 self.assertEqual(unpickled, ([],)*2)
613 self.assertIs(unpickled[0], unpickled[1])
614
615 def test_dup(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300616 pickled = '((l2t.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300617 unpickled = self.loads(pickled)
618 self.assertEqual(unpickled, ([],)*2)
619 self.assertIs(unpickled[0], unpickled[1])
620
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300621
622class AbstractPickleTests(unittest.TestCase):
623 # Subclass must define self.dumps, self.loads.
624
625 _testdata = AbstractUnpickleTests._testdata
626
Jeremy Hylton66426532001-10-15 21:38:56 +0000627 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000628 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000629
Jeremy Hylton66426532001-10-15 21:38:56 +0000630 def test_misc(self):
631 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000632 for proto in protocols:
633 x = myint(4)
634 s = self.dumps(x, proto)
635 y = self.loads(s)
636 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000637
Tim Peters70b02d72003-02-02 17:26:40 +0000638 x = (1, ())
639 s = self.dumps(x, proto)
640 y = self.loads(s)
641 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000642
Tim Peters70b02d72003-02-02 17:26:40 +0000643 x = initarg(1, x)
644 s = self.dumps(x, proto)
645 y = self.loads(s)
646 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000647
Jeremy Hylton66426532001-10-15 21:38:56 +0000648 # XXX test __reduce__ protocol?
649
Tim Peters70b02d72003-02-02 17:26:40 +0000650 def test_roundtrip_equality(self):
651 expected = self._testdata
652 for proto in protocols:
653 s = self.dumps(expected, proto)
654 got = self.loads(s)
655 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000656
Tim Peters70b02d72003-02-02 17:26:40 +0000657 # There are gratuitous differences between pickles produced by
658 # pickle and cPickle, largely because cPickle starts PUT indices at
659 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
660 # there's a comment with an exclamation point there whose meaning
661 # is a mystery. cPickle also suppresses PUT for objects with a refcount
662 # of 1.
663 def dont_test_disassembly(self):
Tim Peters70b02d72003-02-02 17:26:40 +0000664 from pickletools import dis
665
666 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
667 s = self.dumps(self._testdata, proto)
Collin Winterf8089c72009-04-09 16:46:46 +0000668 filelike = cStringIO.StringIO()
Tim Peters70b02d72003-02-02 17:26:40 +0000669 dis(s, out=filelike)
670 got = filelike.getvalue()
671 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000672
673 def test_recursive_list(self):
674 l = []
675 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000676 for proto in protocols:
677 s = self.dumps(l, proto)
678 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000679 self.assertEqual(len(x), 1)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000680 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000681
Collin Winter57bef682009-05-26 04:12:39 +0000682 def test_recursive_tuple(self):
683 t = ([],)
684 t[0].append(t)
685 for proto in protocols:
686 s = self.dumps(t, proto)
687 x = self.loads(s)
688 self.assertEqual(len(x), 1)
689 self.assertEqual(len(x[0]), 1)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000690 self.assertTrue(x is x[0][0])
Collin Winter57bef682009-05-26 04:12:39 +0000691
Jeremy Hylton66426532001-10-15 21:38:56 +0000692 def test_recursive_dict(self):
693 d = {}
694 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000695 for proto in protocols:
696 s = self.dumps(d, proto)
697 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000698 self.assertEqual(x.keys(), [1])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000699 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000700
701 def test_recursive_inst(self):
702 i = C()
703 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000704 for proto in protocols:
Ezio Melottia84ecc62013-03-04 15:23:12 +0200705 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +0000706 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000707 self.assertEqual(dir(x), dir(i))
Ezio Melottia84ecc62013-03-04 15:23:12 +0200708 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000709
710 def test_recursive_multi(self):
711 l = []
712 d = {1:l}
713 i = C()
714 i.attr = d
715 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000716 for proto in protocols:
717 s = self.dumps(l, proto)
718 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000719 self.assertEqual(len(x), 1)
720 self.assertEqual(dir(x[0]), dir(i))
721 self.assertEqual(x[0].attr.keys(), [1])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000722 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000723
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000724 if have_unicode:
Jeremy Hylton66426532001-10-15 21:38:56 +0000725 def test_unicode(self):
Alexandre Vassalottie57e9992008-12-27 10:02:59 +0000726 endcases = [u'', u'<\\u>', u'<\\\u1234>', u'<\n>',
727 u'<\\>', u'<\\\U00012345>']
Tim Petersee1a53c2003-02-02 02:57:53 +0000728 for proto in protocols:
729 for u in endcases:
730 p = self.dumps(u, proto)
731 u2 = self.loads(p)
732 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000733
Alexandre Vassalottif852bf92008-12-27 07:08:47 +0000734 def test_unicode_high_plane(self):
735 t = u'\U00012345'
736 for proto in protocols:
737 p = self.dumps(t, proto)
738 t2 = self.loads(p)
739 self.assertEqual(t2, t)
740
Jeremy Hylton66426532001-10-15 21:38:56 +0000741 def test_ints(self):
742 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000743 for proto in protocols:
744 n = sys.maxint
745 while n:
746 for expected in (-n, n):
747 s = self.dumps(expected, proto)
748 n2 = self.loads(s)
749 self.assertEqual(expected, n2)
750 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000751
Tim Petersee1a53c2003-02-02 02:57:53 +0000752 def test_long(self):
753 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000754 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000755 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
756 nbase = 1L << nbits
757 for npos in nbase-1, nbase, nbase+1:
758 for n in npos, -npos:
759 pickle = self.dumps(n, proto)
760 got = self.loads(pickle)
761 self.assertEqual(n, got)
762 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
763 # bother with those.
Tim Petersee1a53c2003-02-02 02:57:53 +0000764 nbase = long("deadbeeffeedface", 16)
765 nbase += nbase << 1000000
766 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000767 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000768 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000769 self.assertEqual(n, got)
770
Mark Dickinsona3ecd2c2009-01-24 16:40:29 +0000771 def test_float(self):
772 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
773 3.14, 263.44582062374053, 6.022e23, 1e30]
774 test_values = test_values + [-x for x in test_values]
775 for proto in protocols:
776 for value in test_values:
777 pickle = self.dumps(value, proto)
778 got = self.loads(pickle)
779 self.assertEqual(value, got)
780
Georg Brandlde9b6242006-04-30 11:13:56 +0000781 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
782 def test_float_format(self):
783 # make sure that floats are formatted locale independent
784 self.assertEqual(self.dumps(1.2)[0:3], 'F1.')
785
Jeremy Hylton66426532001-10-15 21:38:56 +0000786 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000787 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000788
789 def test_getinitargs(self):
790 pass
791
Guido van Rossum04a86612001-12-19 16:58:54 +0000792 def test_metaclass(self):
793 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000794 for proto in protocols:
795 s = self.dumps(a, proto)
796 b = self.loads(s)
797 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000798
Antoine Pitrou561a8212011-10-04 09:34:48 +0200799 def test_dynamic_class(self):
800 a = create_dynamic_class("my_dynamic_class", (object,))
801 copy_reg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
802 for proto in protocols:
803 s = self.dumps(a, proto)
804 b = self.loads(s)
805 self.assertEqual(a, b)
806
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000807 def test_structseq(self):
808 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000809 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000810
811 t = time.localtime()
812 for proto in protocols:
813 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000814 u = self.loads(s)
815 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000816 if hasattr(os, "stat"):
817 t = os.stat(os.curdir)
818 s = self.dumps(t, proto)
819 u = self.loads(s)
820 self.assertEqual(t, u)
821 if hasattr(os, "statvfs"):
822 t = os.statvfs(os.curdir)
823 s = self.dumps(t, proto)
824 u = self.loads(s)
825 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000826
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000827 # Tests for protocol 2
828
Tim Peters4190fb82003-02-02 16:09:05 +0000829 def test_proto(self):
830 build_none = pickle.NONE + pickle.STOP
831 for proto in protocols:
832 expected = build_none
833 if proto >= 2:
834 expected = pickle.PROTO + chr(proto) + expected
835 p = self.dumps(None, proto)
836 self.assertEqual(p, expected)
837
838 oob = protocols[-1] + 1 # a future protocol
839 badpickle = pickle.PROTO + chr(oob) + build_none
840 try:
841 self.loads(badpickle)
842 except ValueError, detail:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000843 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +0000844 "unsupported pickle protocol"))
845 else:
846 self.fail("expected bad protocol number to raise ValueError")
847
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000848 def test_long1(self):
849 x = 12345678910111213141516178920L
Tim Peters61bf2572003-02-03 21:31:22 +0000850 for proto in protocols:
851 s = self.dumps(x, proto)
852 y = self.loads(s)
853 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000854 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000855
856 def test_long4(self):
857 x = 12345678910111213141516178920L << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000858 for proto in protocols:
859 s = self.dumps(x, proto)
860 y = self.loads(s)
861 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000862 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000863
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000864 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000865 # Map (proto, len(tuple)) to expected opcode.
866 expected_opcode = {(0, 0): pickle.TUPLE,
867 (0, 1): pickle.TUPLE,
868 (0, 2): pickle.TUPLE,
869 (0, 3): pickle.TUPLE,
870 (0, 4): pickle.TUPLE,
871
872 (1, 0): pickle.EMPTY_TUPLE,
873 (1, 1): pickle.TUPLE,
874 (1, 2): pickle.TUPLE,
875 (1, 3): pickle.TUPLE,
876 (1, 4): pickle.TUPLE,
877
878 (2, 0): pickle.EMPTY_TUPLE,
879 (2, 1): pickle.TUPLE1,
880 (2, 2): pickle.TUPLE2,
881 (2, 3): pickle.TUPLE3,
882 (2, 4): pickle.TUPLE,
883 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000884 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000885 b = (1,)
886 c = (1, 2)
887 d = (1, 2, 3)
888 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000889 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000890 for x in a, b, c, d, e:
891 s = self.dumps(x, proto)
892 y = self.loads(s)
893 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000894 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +0000895 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +0000896
Guido van Rossum7d97d312003-01-28 04:25:27 +0000897 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000898 # Map (proto, singleton) to expected opcode.
899 expected_opcode = {(0, None): pickle.NONE,
900 (1, None): pickle.NONE,
901 (2, None): pickle.NONE,
902
903 (0, True): pickle.INT,
904 (1, True): pickle.INT,
905 (2, True): pickle.NEWTRUE,
906
907 (0, False): pickle.INT,
908 (1, False): pickle.INT,
909 (2, False): pickle.NEWFALSE,
910 }
Tim Peters4190fb82003-02-02 16:09:05 +0000911 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000912 for x in None, False, True:
913 s = self.dumps(x, proto)
914 y = self.loads(s)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000915 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +0000916 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +0000917 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +0000918
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000919 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000920 x = MyTuple([1, 2, 3])
921 x.foo = 42
922 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000923 for proto in protocols:
924 s = self.dumps(x, proto)
925 y = self.loads(s)
926 self.assertEqual(tuple(x), tuple(y))
927 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000928
929 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000930 x = MyList([1, 2, 3])
931 x.foo = 42
932 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000933 for proto in protocols:
934 s = self.dumps(x, proto)
935 y = self.loads(s)
936 self.assertEqual(list(x), list(y))
937 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000938
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000939 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +0000940 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000941 for C in myclasses:
942 B = C.__base__
943 x = C(C.sample)
944 x.foo = 42
945 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000946 y = self.loads(s)
947 detail = (proto, C, B, x, y, type(y))
948 self.assertEqual(B(x), B(y), detail)
949 self.assertEqual(x.__dict__, y.__dict__, detail)
950
Georg Brandldffbf5f2008-05-20 07:49:57 +0000951 # Register a type with copy_reg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +0000952 # an object of that type. Check that the resulting pickle uses opcode
953 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +0000954
Tim Peters22e71712003-02-03 22:27:38 +0000955 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +0000956 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000957 try:
Georg Brandldffbf5f2008-05-20 07:49:57 +0000958 copy_reg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000959 x = MyList([1, 2, 3])
960 x.foo = 42
961 x.bar = "hello"
962
Tim Peters22e71712003-02-03 22:27:38 +0000963 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000964 s1 = self.dumps(x, 1)
Ezio Melottiaa980582010-01-23 23:04:36 +0000965 self.assertIn(__name__, s1)
966 self.assertIn("MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +0000967 self.assertEqual(opcode_in_pickle(opcode, s1), False)
968
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000969 y = self.loads(s1)
970 self.assertEqual(list(x), list(y))
971 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000972
Tim Peters22e71712003-02-03 22:27:38 +0000973 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000974 s2 = self.dumps(x, 2)
Ezio Melottiaa980582010-01-23 23:04:36 +0000975 self.assertNotIn(__name__, s2)
976 self.assertNotIn("MyList", s2)
Tim Peters3e667d52003-02-04 21:47:44 +0000977 self.assertEqual(opcode_in_pickle(opcode, s2), True)
978
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000979 y = self.loads(s2)
980 self.assertEqual(list(x), list(y))
981 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000982
983 finally:
Tim Peters3e667d52003-02-04 21:47:44 +0000984 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +0000985
986 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000987 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
988 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000989
990 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000991 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
992 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
993 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000994
995 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000996 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
997 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
998 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
999
Tim Peters8d2613a2003-02-11 16:40:16 +00001000 def test_list_chunking(self):
1001 n = 10 # too small to chunk
1002 x = range(n)
1003 for proto in protocols:
1004 s = self.dumps(x, proto)
1005 y = self.loads(s)
1006 self.assertEqual(x, y)
1007 num_appends = count_opcode(pickle.APPENDS, s)
1008 self.assertEqual(num_appends, proto > 0)
1009
1010 n = 2500 # expect at least two chunks when proto > 0
1011 x = range(n)
1012 for proto in protocols:
1013 s = self.dumps(x, proto)
1014 y = self.loads(s)
1015 self.assertEqual(x, y)
1016 num_appends = count_opcode(pickle.APPENDS, s)
1017 if proto == 0:
1018 self.assertEqual(num_appends, 0)
1019 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001020 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001021
1022 def test_dict_chunking(self):
1023 n = 10 # too small to chunk
1024 x = dict.fromkeys(range(n))
1025 for proto in protocols:
1026 s = self.dumps(x, proto)
1027 y = self.loads(s)
1028 self.assertEqual(x, y)
1029 num_setitems = count_opcode(pickle.SETITEMS, s)
1030 self.assertEqual(num_setitems, proto > 0)
1031
1032 n = 2500 # expect at least two chunks when proto > 0
1033 x = dict.fromkeys(range(n))
1034 for proto in protocols:
1035 s = self.dumps(x, proto)
1036 y = self.loads(s)
1037 self.assertEqual(x, y)
1038 num_setitems = count_opcode(pickle.SETITEMS, s)
1039 if proto == 0:
1040 self.assertEqual(num_setitems, 0)
1041 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001042 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001043
Tim Peterse9ef2032003-02-13 18:42:00 +00001044 def test_simple_newobj(self):
1045 x = object.__new__(SimpleNewObj) # avoid __init__
1046 x.abc = 666
1047 for proto in protocols:
1048 s = self.dumps(x, proto)
1049 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
1050 y = self.loads(s) # will raise TypeError if __init__ called
1051 self.assertEqual(y.abc, 666)
1052 self.assertEqual(x.__dict__, y.__dict__)
1053
Tim Peters42f08ac2003-02-11 22:43:24 +00001054 def test_newobj_list_slots(self):
1055 x = SlotList([1, 2, 3])
1056 x.foo = 42
1057 x.bar = "hello"
1058 s = self.dumps(x, 2)
1059 y = self.loads(s)
1060 self.assertEqual(list(x), list(y))
1061 self.assertEqual(x.__dict__, y.__dict__)
1062 self.assertEqual(x.foo, y.foo)
1063 self.assertEqual(x.bar, y.bar)
1064
Guido van Rossum2a30b212003-02-18 22:41:24 +00001065 def test_reduce_overrides_default_reduce_ex(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001066 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001067 x = REX_one()
1068 self.assertEqual(x._reduce_called, 0)
1069 s = self.dumps(x, proto)
1070 self.assertEqual(x._reduce_called, 1)
1071 y = self.loads(s)
1072 self.assertEqual(y._reduce_called, 0)
1073
1074 def test_reduce_ex_called(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001075 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001076 x = REX_two()
1077 self.assertEqual(x._proto, None)
1078 s = self.dumps(x, proto)
1079 self.assertEqual(x._proto, proto)
1080 y = self.loads(s)
1081 self.assertEqual(y._proto, None)
1082
1083 def test_reduce_ex_overrides_reduce(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001084 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001085 x = REX_three()
1086 self.assertEqual(x._proto, None)
1087 s = self.dumps(x, proto)
1088 self.assertEqual(x._proto, proto)
1089 y = self.loads(s)
1090 self.assertEqual(y._proto, None)
1091
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001092 def test_reduce_ex_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001093 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001094 x = REX_four()
1095 self.assertEqual(x._proto, None)
1096 s = self.dumps(x, proto)
1097 self.assertEqual(x._proto, proto)
1098 y = self.loads(s)
1099 self.assertEqual(y._proto, proto)
1100
1101 def test_reduce_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001102 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001103 x = REX_five()
1104 self.assertEqual(x._reduce_called, 0)
1105 s = self.dumps(x, proto)
1106 self.assertEqual(x._reduce_called, 1)
1107 y = self.loads(s)
1108 self.assertEqual(y._reduce_called, 1)
1109
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001110 def test_reduce_bad_iterator(self):
1111 # Issue4176: crash when 4th and 5th items of __reduce__()
1112 # are not iterators
1113 class C(object):
1114 def __reduce__(self):
1115 # 4th item is not an iterator
1116 return list, (), None, [], None
1117 class D(object):
1118 def __reduce__(self):
1119 # 5th item is not an iterator
1120 return dict, (), None, None, []
1121
1122 # Protocol 0 is less strict and also accept iterables.
Collin Winterf8089c72009-04-09 16:46:46 +00001123 for proto in protocols:
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001124 try:
1125 self.dumps(C(), proto)
1126 except (AttributeError, pickle.PickleError, cPickle.PickleError):
1127 pass
1128 try:
1129 self.dumps(D(), proto)
1130 except (AttributeError, pickle.PickleError, cPickle.PickleError):
1131 pass
1132
Collin Winterf8089c72009-04-09 16:46:46 +00001133 def test_many_puts_and_gets(self):
1134 # Test that internal data structures correctly deal with lots of
1135 # puts/gets.
1136 keys = ("aaa" + str(i) for i in xrange(100))
1137 large_dict = dict((k, [4, 5, 6]) for k in keys)
1138 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1139
1140 for proto in protocols:
1141 dumped = self.dumps(obj, proto)
1142 loaded = self.loads(dumped)
1143 self.assertEqual(loaded, obj,
1144 "Failed protocol %d: %r != %r"
1145 % (proto, obj, loaded))
1146
Antoine Pitrou74309892009-05-02 21:13:23 +00001147 def test_attribute_name_interning(self):
1148 # Test that attribute names of pickled objects are interned when
1149 # unpickling.
1150 for proto in protocols:
1151 x = C()
1152 x.foo = 42
1153 x.bar = "hello"
1154 s = self.dumps(x, proto)
1155 y = self.loads(s)
1156 x_keys = sorted(x.__dict__)
1157 y_keys = sorted(y.__dict__)
1158 for x_key, y_key in zip(x_keys, y_keys):
1159 self.assertIs(x_key, y_key)
1160
Collin Winterf8089c72009-04-09 16:46:46 +00001161
Guido van Rossum2a30b212003-02-18 22:41:24 +00001162# Test classes for reduce_ex
1163
1164class REX_one(object):
1165 _reduce_called = 0
1166 def __reduce__(self):
1167 self._reduce_called = 1
1168 return REX_one, ()
1169 # No __reduce_ex__ here, but inheriting it from object
1170
1171class REX_two(object):
1172 _proto = None
1173 def __reduce_ex__(self, proto):
1174 self._proto = proto
1175 return REX_two, ()
1176 # No __reduce__ here, but inheriting it from object
1177
1178class REX_three(object):
1179 _proto = None
1180 def __reduce_ex__(self, proto):
1181 self._proto = proto
1182 return REX_two, ()
1183 def __reduce__(self):
1184 raise TestFailed, "This __reduce__ shouldn't be called"
1185
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001186class REX_four(object):
1187 _proto = None
1188 def __reduce_ex__(self, proto):
1189 self._proto = proto
1190 return object.__reduce_ex__(self, proto)
1191 # Calling base class method should succeed
1192
1193class REX_five(object):
1194 _reduce_called = 0
1195 def __reduce__(self):
1196 self._reduce_called = 1
1197 return object.__reduce__(self)
1198 # This one used to fail with infinite recursion
1199
Guido van Rossum2a30b212003-02-18 22:41:24 +00001200# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001201
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001202class MyInt(int):
1203 sample = 1
1204
1205class MyLong(long):
1206 sample = 1L
1207
1208class MyFloat(float):
1209 sample = 1.0
1210
1211class MyComplex(complex):
1212 sample = 1.0 + 0.0j
1213
1214class MyStr(str):
1215 sample = "hello"
1216
1217class MyUnicode(unicode):
1218 sample = u"hello \u1234"
1219
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001220class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001221 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001222
1223class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001224 sample = [1, 2, 3]
1225
1226class MyDict(dict):
1227 sample = {"a": 1, "b": 2}
1228
1229myclasses = [MyInt, MyLong, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001230 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001231 MyStr, MyUnicode,
1232 MyTuple, MyList, MyDict]
1233
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001234
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001235class SlotList(MyList):
1236 __slots__ = ["foo"]
1237
Tim Peterse9ef2032003-02-13 18:42:00 +00001238class SimpleNewObj(object):
1239 def __init__(self, a, b, c):
1240 # raise an error, to make sure this isn't called
1241 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1242
Jeremy Hylton66426532001-10-15 21:38:56 +00001243class AbstractPickleModuleTests(unittest.TestCase):
1244
1245 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001246 import os
1247 f = open(TESTFN, "w")
1248 try:
1249 f.close()
1250 self.assertRaises(ValueError, self.module.dump, 123, f)
1251 finally:
1252 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001253
1254 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001255 import os
1256 f = open(TESTFN, "w")
1257 try:
1258 f.close()
1259 self.assertRaises(ValueError, self.module.dump, 123, f)
1260 finally:
1261 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001262
Collin Winterf8089c72009-04-09 16:46:46 +00001263 def test_load_from_and_dump_to_file(self):
1264 stream = cStringIO.StringIO()
1265 data = [123, {}, 124]
1266 self.module.dump(data, stream)
1267 stream.seek(0)
1268 unpickled = self.module.load(stream)
1269 self.assertEqual(unpickled, data)
1270
Tim Petersc0c93702003-02-13 19:30:57 +00001271 def test_highest_protocol(self):
1272 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
1273 self.assertEqual(self.module.HIGHEST_PROTOCOL, 2)
1274
Martin v. Löwis544f1192004-07-27 05:22:33 +00001275 def test_callapi(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001276 f = cStringIO.StringIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001277 # With and without keyword arguments
1278 self.module.dump(123, f, -1)
1279 self.module.dump(123, file=f, protocol=-1)
1280 self.module.dumps(123, -1)
1281 self.module.dumps(123, protocol=-1)
1282 self.module.Pickler(f, -1)
1283 self.module.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001284
Amaury Forgeot d'Arc74b30162009-07-23 19:26:02 +00001285 def test_incomplete_input(self):
1286 s = StringIO.StringIO("X''.")
1287 self.assertRaises(EOFError, self.module.load, s)
1288
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001289 def test_restricted(self):
1290 # issue7128: cPickle failed in restricted mode
1291 builtins = {self.module.__name__: self.module,
1292 '__import__': __import__}
1293 d = {}
1294 teststr = "def f(): {0}.dumps(0)".format(self.module.__name__)
1295 exec teststr in {'__builtins__': builtins}, d
1296 d['f']()
1297
Antoine Pitrou0d423b82010-01-07 17:46:49 +00001298 def test_bad_input(self):
1299 # Test issue4298
1300 s = '\x58\0\0\0\x54'
1301 self.assertRaises(EOFError, self.module.loads, s)
1302 # Test issue7455
1303 s = '0'
1304 # XXX Why doesn't pickle raise UnpicklingError?
1305 self.assertRaises((IndexError, cPickle.UnpicklingError),
1306 self.module.loads, s)
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001307
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001308class AbstractPersistentPicklerTests(unittest.TestCase):
1309
1310 # This class defines persistent_id() and persistent_load()
1311 # functions that should be used by the pickler. All even integers
1312 # are pickled using persistent ids.
1313
1314 def persistent_id(self, object):
1315 if isinstance(object, int) and object % 2 == 0:
1316 self.id_count += 1
1317 return str(object)
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001318 elif object == "test_false_value":
1319 self.false_count += 1
1320 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001321 else:
1322 return None
1323
1324 def persistent_load(self, oid):
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001325 if not oid:
1326 self.load_false_count += 1
1327 return "test_false_value"
1328 else:
1329 self.load_count += 1
1330 object = int(oid)
1331 assert object % 2 == 0
1332 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001333
1334 def test_persistence(self):
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001335 L = range(10) + ["test_false_value"]
1336 for proto in protocols:
1337 self.id_count = 0
1338 self.false_count = 0
1339 self.load_false_count = 0
1340 self.load_count = 0
1341 self.assertEqual(self.loads(self.dumps(L, proto)), L)
1342 self.assertEqual(self.id_count, 5)
1343 self.assertEqual(self.false_count, 1)
1344 self.assertEqual(self.load_count, 5)
1345 self.assertEqual(self.load_false_count, 1)
Collin Winterf8089c72009-04-09 16:46:46 +00001346
1347class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1348
1349 pickler_class = None
1350 unpickler_class = None
1351
1352 def setUp(self):
1353 assert self.pickler_class
1354 assert self.unpickler_class
1355
1356 def test_clear_pickler_memo(self):
1357 # To test whether clear_memo() has any effect, we pickle an object,
1358 # then pickle it again without clearing the memo; the two serialized
1359 # forms should be different. If we clear_memo() and then pickle the
1360 # object again, the third serialized form should be identical to the
1361 # first one we obtained.
1362 data = ["abcdefg", "abcdefg", 44]
1363 f = cStringIO.StringIO()
1364 pickler = self.pickler_class(f)
1365
1366 pickler.dump(data)
1367 first_pickled = f.getvalue()
1368
1369 # Reset StringIO object.
1370 f.seek(0)
1371 f.truncate()
1372
1373 pickler.dump(data)
1374 second_pickled = f.getvalue()
1375
1376 # Reset the Pickler and StringIO objects.
1377 pickler.clear_memo()
1378 f.seek(0)
1379 f.truncate()
1380
1381 pickler.dump(data)
1382 third_pickled = f.getvalue()
1383
1384 self.assertNotEqual(first_pickled, second_pickled)
1385 self.assertEqual(first_pickled, third_pickled)
1386
1387 def test_priming_pickler_memo(self):
1388 # Verify that we can set the Pickler's memo attribute.
1389 data = ["abcdefg", "abcdefg", 44]
1390 f = cStringIO.StringIO()
1391 pickler = self.pickler_class(f)
1392
1393 pickler.dump(data)
1394 first_pickled = f.getvalue()
1395
1396 f = cStringIO.StringIO()
1397 primed = self.pickler_class(f)
1398 primed.memo = pickler.memo
1399
1400 primed.dump(data)
1401 primed_pickled = f.getvalue()
1402
1403 self.assertNotEqual(first_pickled, primed_pickled)
1404
1405 def test_priming_unpickler_memo(self):
1406 # Verify that we can set the Unpickler's memo attribute.
1407 data = ["abcdefg", "abcdefg", 44]
1408 f = cStringIO.StringIO()
1409 pickler = self.pickler_class(f)
1410
1411 pickler.dump(data)
1412 first_pickled = f.getvalue()
1413
1414 f = cStringIO.StringIO()
1415 primed = self.pickler_class(f)
1416 primed.memo = pickler.memo
1417
1418 primed.dump(data)
1419 primed_pickled = f.getvalue()
1420
1421 unpickler = self.unpickler_class(cStringIO.StringIO(first_pickled))
1422 unpickled_data1 = unpickler.load()
1423
1424 self.assertEqual(unpickled_data1, data)
1425
1426 primed = self.unpickler_class(cStringIO.StringIO(primed_pickled))
1427 primed.memo = unpickler.memo
1428 unpickled_data2 = primed.load()
1429
1430 primed.memo.clear()
1431
1432 self.assertEqual(unpickled_data2, data)
1433 self.assertTrue(unpickled_data2 is unpickled_data1)
1434
1435 def test_reusing_unpickler_objects(self):
1436 data1 = ["abcdefg", "abcdefg", 44]
1437 f = cStringIO.StringIO()
1438 pickler = self.pickler_class(f)
1439 pickler.dump(data1)
1440 pickled1 = f.getvalue()
1441
1442 data2 = ["abcdefg", 44, 44]
1443 f = cStringIO.StringIO()
1444 pickler = self.pickler_class(f)
1445 pickler.dump(data2)
1446 pickled2 = f.getvalue()
1447
1448 f = cStringIO.StringIO()
1449 f.write(pickled1)
1450 f.seek(0)
1451 unpickler = self.unpickler_class(f)
1452 self.assertEqual(unpickler.load(), data1)
1453
1454 f.seek(0)
1455 f.truncate()
1456 f.write(pickled2)
1457 f.seek(0)
1458 self.assertEqual(unpickler.load(), data2)
Serhiy Storchakacdc7a912013-02-12 21:36:47 +02001459
1460class BigmemPickleTests(unittest.TestCase):
1461
1462 # Memory requirements: 1 byte per character for input strings, 1 byte
1463 # for pickled data, 1 byte for unpickled strings, 1 byte for internal
1464 # buffer and 1 byte of free space for resizing of internal buffer.
1465
1466 @precisionbigmemtest(size=_2G + 100*_1M, memuse=5)
1467 def test_huge_strlist(self, size):
1468 chunksize = 2**20
1469 data = []
1470 while size > chunksize:
1471 data.append('x' * chunksize)
1472 size -= chunksize
1473 chunksize += 1
1474 data.append('y' * size)
1475
1476 try:
1477 for proto in protocols:
1478 try:
1479 pickled = self.dumps(data, proto)
1480 res = self.loads(pickled)
1481 self.assertEqual(res, data)
1482 finally:
1483 res = None
1484 pickled = None
1485 finally:
1486 data = None