blob: b0a3b041e391ce335db2ac4d99cfbcce3b3cdbe4 [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
Serhiy Storchaka5c137662015-11-23 15:20:43 +020010from test.test_support import TestFailed, verbose, have_unicode, TESTFN, captured_stdout
Benjamin Petersond627e122013-03-30 10:36:31 -040011try:
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
Serhiy Storchakada87e452015-11-07 11:15:32 +0200120class H(object):
121 pass
122
123# Hashable mutable key
124class K(object):
125 def __init__(self, value):
126 self.value = value
127
128 def __reduce__(self):
129 # Shouldn't support the recursion itself
130 return K, (self.value,)
131
Jeremy Hylton66426532001-10-15 21:38:56 +0000132import __main__
133__main__.C = C
134C.__module__ = "__main__"
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300135__main__.D = D
136D.__module__ = "__main__"
137__main__.E = E
138E.__module__ = "__main__"
Serhiy Storchakada87e452015-11-07 11:15:32 +0200139__main__.H = H
140H.__module__ = "__main__"
141__main__.K = K
142K.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000143
144class myint(int):
145 def __init__(self, x):
146 self.str = str(x)
147
148class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000149
Jeremy Hylton66426532001-10-15 21:38:56 +0000150 def __init__(self, a, b):
151 self.a = a
152 self.b = b
153
154 def __getinitargs__(self):
155 return self.a, self.b
156
Guido van Rossum04a86612001-12-19 16:58:54 +0000157class metaclass(type):
158 pass
159
160class use_metaclass(object):
161 __metaclass__ = metaclass
162
Antoine Pitrou561a8212011-10-04 09:34:48 +0200163class pickling_metaclass(type):
164 def __eq__(self, other):
165 return (type(self) == type(other) and
166 self.reduce_args == other.reduce_args)
167
168 def __reduce__(self):
169 return (create_dynamic_class, self.reduce_args)
170
Ezio Melotti030aa352011-11-06 18:50:32 +0200171 __hash__ = None
172
Antoine Pitrou561a8212011-10-04 09:34:48 +0200173def create_dynamic_class(name, bases):
174 result = pickling_metaclass(name, bases, dict())
175 result.reduce_args = (name, bases)
176 return result
177
Tim Peters70b02d72003-02-02 17:26:40 +0000178# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
179# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000180
Jeremy Hylton66426532001-10-15 21:38:56 +0000181# break into multiple strings to avoid confusing font-lock-mode
Tim Peters70b02d72003-02-02 17:26:40 +0000182DATA0 = """(lp1
Tim Peterse9358162001-01-22 22:05:20 +0000183I0
184aL1L
Tim Peters461922a2001-04-09 20:07:05 +0000185aF2
Tim Peterse9358162001-01-22 22:05:20 +0000186ac__builtin__
187complex
Tim Peters461922a2001-04-09 20:07:05 +0000188p2
189""" + \
190"""(F3
191F0
192tRp3
193aI1
194aI-1
195aI255
196aI-255
197aI-256
198aI65535
199aI-65535
200aI-65536
201aI2147483647
202aI-2147483647
203aI-2147483648
204a""" + \
205"""(S'abc'
Tim Peterse9358162001-01-22 22:05:20 +0000206p4
207g4
Tim Peters461922a2001-04-09 20:07:05 +0000208""" + \
Guido van Rossum42f92da2001-04-16 00:28:21 +0000209"""(i__main__
Tim Peterse9358162001-01-22 22:05:20 +0000210C
211p5
Tim Peters461922a2001-04-09 20:07:05 +0000212""" + \
Tim Peterse9358162001-01-22 22:05:20 +0000213"""(dp6
214S'foo'
215p7
216I1
217sS'bar'
218p8
219I2
220sbg5
221tp9
222ag9
223aI5
224a.
225"""
226
Tim Peters70b02d72003-02-02 17:26:40 +0000227# Disassembly of DATA0.
228DATA0_DIS = """\
229 0: ( MARK
230 1: l LIST (MARK at 0)
231 2: p PUT 1
232 5: I INT 0
233 8: a APPEND
234 9: L LONG 1L
235 13: a APPEND
236 14: F FLOAT 2.0
237 17: a APPEND
238 18: c GLOBAL '__builtin__ complex'
239 39: p PUT 2
240 42: ( MARK
241 43: F FLOAT 3.0
242 46: F FLOAT 0.0
243 49: t TUPLE (MARK at 42)
244 50: R REDUCE
245 51: p PUT 3
246 54: a APPEND
247 55: I INT 1
248 58: a APPEND
249 59: I INT -1
250 63: a APPEND
251 64: I INT 255
252 69: a APPEND
253 70: I INT -255
254 76: a APPEND
255 77: I INT -256
256 83: a APPEND
257 84: I INT 65535
258 91: a APPEND
259 92: I INT -65535
260 100: a APPEND
261 101: I INT -65536
262 109: a APPEND
263 110: I INT 2147483647
264 122: a APPEND
265 123: I INT -2147483647
266 136: a APPEND
267 137: I INT -2147483648
268 150: a APPEND
269 151: ( MARK
270 152: S STRING 'abc'
271 159: p PUT 4
272 162: g GET 4
273 165: ( MARK
274 166: i INST '__main__ C' (MARK at 165)
275 178: p PUT 5
276 181: ( MARK
277 182: d DICT (MARK at 181)
278 183: p PUT 6
279 186: S STRING 'foo'
280 193: p PUT 7
281 196: I INT 1
282 199: s SETITEM
283 200: S STRING 'bar'
284 207: p PUT 8
285 210: I INT 2
286 213: s SETITEM
287 214: b BUILD
288 215: g GET 5
289 218: t TUPLE (MARK at 151)
290 219: p PUT 9
291 222: a APPEND
292 223: g GET 9
293 226: a APPEND
294 227: I INT 5
295 230: a APPEND
296 231: . STOP
297highest protocol among opcodes = 0
298"""
299
300DATA1 = (']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00'
301 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00'
302 '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff'
303 '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff'
304 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00'
305 '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n'
306 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh'
307 '\x06tq\nh\nK\x05e.'
308 )
309
310# Disassembly of DATA1.
311DATA1_DIS = """\
312 0: ] EMPTY_LIST
313 1: q BINPUT 1
314 3: ( MARK
315 4: K BININT1 0
316 6: L LONG 1L
317 10: G BINFLOAT 2.0
318 19: c GLOBAL '__builtin__ complex'
319 40: q BINPUT 2
320 42: ( MARK
321 43: G BINFLOAT 3.0
322 52: G BINFLOAT 0.0
323 61: t TUPLE (MARK at 42)
324 62: R REDUCE
325 63: q BINPUT 3
326 65: K BININT1 1
327 67: J BININT -1
328 72: K BININT1 255
329 74: J BININT -255
330 79: J BININT -256
331 84: M BININT2 65535
332 87: J BININT -65535
333 92: J BININT -65536
334 97: J BININT 2147483647
335 102: J BININT -2147483647
336 107: J BININT -2147483648
337 112: ( MARK
338 113: U SHORT_BINSTRING 'abc'
339 118: q BINPUT 4
340 120: h BINGET 4
341 122: ( MARK
342 123: c GLOBAL '__main__ C'
343 135: q BINPUT 5
344 137: o OBJ (MARK at 122)
345 138: q BINPUT 6
346 140: } EMPTY_DICT
347 141: q BINPUT 7
348 143: ( MARK
349 144: U SHORT_BINSTRING 'foo'
350 149: q BINPUT 8
351 151: K BININT1 1
352 153: U SHORT_BINSTRING 'bar'
353 158: q BINPUT 9
354 160: K BININT1 2
355 162: u SETITEMS (MARK at 143)
356 163: b BUILD
357 164: h BINGET 6
358 166: t TUPLE (MARK at 112)
359 167: q BINPUT 10
360 169: h BINGET 10
361 171: K BININT1 5
362 173: e APPENDS (MARK at 3)
363 174: . STOP
364highest protocol among opcodes = 1
365"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000366
Tim Petersfc273752003-03-02 04:54:24 +0000367DATA2 = ('\x80\x02]q\x01(K\x00\x8a\x01\x01G@\x00\x00\x00\x00\x00\x00\x00'
368 'c__builtin__\ncomplex\nq\x02G@\x08\x00\x00\x00\x00\x00\x00G\x00'
369 '\x00\x00\x00\x00\x00\x00\x00\x86Rq\x03K\x01J\xff\xff\xff\xffK'
370 '\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xff'
371 'J\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00'
372 '\x80(U\x03abcq\x04h\x04(c__main__\nC\nq\x05oq\x06}q\x07(U\x03foo'
373 'q\x08K\x01U\x03barq\tK\x02ubh\x06tq\nh\nK\x05e.')
374
375# Disassembly of DATA2.
376DATA2_DIS = """\
377 0: \x80 PROTO 2
378 2: ] EMPTY_LIST
379 3: q BINPUT 1
380 5: ( MARK
381 6: K BININT1 0
382 8: \x8a LONG1 1L
383 11: G BINFLOAT 2.0
384 20: c GLOBAL '__builtin__ complex'
385 41: q BINPUT 2
386 43: G BINFLOAT 3.0
387 52: G BINFLOAT 0.0
388 61: \x86 TUPLE2
389 62: R REDUCE
390 63: q BINPUT 3
391 65: K BININT1 1
392 67: J BININT -1
393 72: K BININT1 255
394 74: J BININT -255
395 79: J BININT -256
396 84: M BININT2 65535
397 87: J BININT -65535
398 92: J BININT -65536
399 97: J BININT 2147483647
400 102: J BININT -2147483647
401 107: J BININT -2147483648
402 112: ( MARK
403 113: U SHORT_BINSTRING 'abc'
404 118: q BINPUT 4
405 120: h BINGET 4
406 122: ( MARK
407 123: c GLOBAL '__main__ C'
408 135: q BINPUT 5
409 137: o OBJ (MARK at 122)
410 138: q BINPUT 6
411 140: } EMPTY_DICT
412 141: q BINPUT 7
413 143: ( MARK
414 144: U SHORT_BINSTRING 'foo'
415 149: q BINPUT 8
416 151: K BININT1 1
417 153: U SHORT_BINSTRING 'bar'
418 158: q BINPUT 9
419 160: K BININT1 2
420 162: u SETITEMS (MARK at 143)
421 163: b BUILD
422 164: h BINGET 6
423 166: t TUPLE (MARK at 112)
424 167: q BINPUT 10
425 169: h BINGET 10
426 171: K BININT1 5
427 173: e APPENDS (MARK at 5)
428 174: . STOP
429highest protocol among opcodes = 2
430"""
431
Jeremy Hylton66426532001-10-15 21:38:56 +0000432def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000433 c = C()
434 c.foo = 1
435 c.bar = 2
436 x = [0, 1L, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000437 # Append some integer test cases at cPickle.c's internal size
438 # cutoffs.
439 uint1max = 0xff
440 uint2max = 0xffff
441 int4max = 0x7fffffff
442 x.extend([1, -1,
443 uint1max, -uint1max, -uint1max-1,
444 uint2max, -uint2max, -uint2max-1,
445 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000446 y = ('abc', 'abc', c, c)
447 x.append(y)
448 x.append(y)
449 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000450 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000451
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300452
453class AbstractUnpickleTests(unittest.TestCase):
454 # Subclass must define self.loads, self.error.
Tim Petersc58440f2001-04-09 17:16:31 +0000455
Jeremy Hylton66426532001-10-15 21:38:56 +0000456 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000457
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300458 def assert_is_copy(self, obj, objcopy, msg=None):
459 """Utility method to verify if two objects are copies of each others.
460 """
461 if msg is None:
462 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
463 self.assertEqual(obj, objcopy, msg=msg)
464 self.assertIs(type(obj), type(objcopy), msg=msg)
465 if hasattr(obj, '__dict__'):
466 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
467 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
468 if hasattr(obj, '__slots__'):
469 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
470 for slot in obj.__slots__:
471 self.assertEqual(
472 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
473 self.assertEqual(getattr(obj, slot, None),
474 getattr(objcopy, slot, None), msg=msg)
475
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300476 def test_load_from_canned_string(self):
477 expected = self._testdata
478 for canned in DATA0, DATA1, DATA2:
479 got = self.loads(canned)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300480 self.assert_is_copy(expected, got)
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300481
482 def test_garyp(self):
483 self.assertRaises(self.error, self.loads, 'garyp')
484
485 def test_maxint64(self):
486 maxint64 = (1L << 63) - 1
487 data = 'I' + str(maxint64) + '\n.'
488 got = self.loads(data)
489 self.assertEqual(got, maxint64)
490
491 # Try too with a bogus literal.
492 data = 'I' + str(maxint64) + 'JUNK\n.'
493 self.assertRaises(ValueError, self.loads, data)
494
495 def test_insecure_strings(self):
496 insecure = ["abc", "2 + 2", # not quoted
497 #"'abc' + 'def'", # not a single quoted string
498 "'abc", # quote is not closed
499 "'abc\"", # open quote and close quote don't match
500 "'abc' ?", # junk after close quote
501 "'\\'", # trailing backslash
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300502 # issue #17710
503 "'", '"',
504 "' ", '" ',
505 '\'"', '"\'',
506 " ''", ' ""',
507 ' ',
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300508 # some tests of the quoting rules
509 #"'abc\"\''",
510 #"'\\\\a\'\'\'\\\'\\\\\''",
511 ]
512 for s in insecure:
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300513 buf = "S" + s + "\n."
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300514 self.assertRaises(ValueError, self.loads, buf)
515
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300516 def test_correctly_quoted_string(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300517 goodpickles = [("S''\n.", ''),
518 ('S""\n.', ''),
519 ('S"\\n"\n.', '\n'),
520 ("S'\\n'\n.", '\n')]
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300521 for p, expected in goodpickles:
522 self.assertEqual(self.loads(p), expected)
523
524 def test_load_classic_instance(self):
525 # See issue5180. Test loading 2.x pickles that
526 # contain an instance of old style class.
527 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
528 xname = X.__name__.encode('ascii')
529 # Protocol 0 (text mode pickle):
530 """
531 0: ( MARK
532 1: i INST '__main__ X' (MARK at 0)
533 13: p PUT 0
534 16: ( MARK
535 17: d DICT (MARK at 16)
536 18: p PUT 1
537 21: b BUILD
538 22: . STOP
539 """
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300540 pickle0 = ("(i__main__\n"
541 "X\n"
542 "p0\n"
543 "(dp1\nb.").replace('X', xname)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300544 self.assert_is_copy(X(*args), self.loads(pickle0))
545
546 # Protocol 1 (binary mode pickle)
547 """
548 0: ( MARK
549 1: c GLOBAL '__main__ X'
550 13: q BINPUT 0
551 15: o OBJ (MARK at 0)
552 16: q BINPUT 1
553 18: } EMPTY_DICT
554 19: q BINPUT 2
555 21: b BUILD
556 22: . STOP
557 """
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300558 pickle1 = ('(c__main__\n'
559 'X\n'
560 'q\x00oq\x01}q\x02b.').replace('X', xname)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300561 self.assert_is_copy(X(*args), self.loads(pickle1))
562
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300563 # Protocol 2 (pickle2 = '\x80\x02' + pickle1)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300564 """
565 0: \x80 PROTO 2
566 2: ( MARK
567 3: c GLOBAL '__main__ X'
568 15: q BINPUT 0
569 17: o OBJ (MARK at 2)
570 18: q BINPUT 1
571 20: } EMPTY_DICT
572 21: q BINPUT 2
573 23: b BUILD
574 24: . STOP
575 """
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300576 pickle2 = ('\x80\x02(c__main__\n'
577 'X\n'
578 'q\x00oq\x01}q\x02b.').replace('X', xname)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300579 self.assert_is_copy(X(*args), self.loads(pickle2))
580
581 def test_pop_empty_stack(self):
582 # Test issue7455
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300583 s = '0'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300584 self.assertRaises((cPickle.UnpicklingError, IndexError), self.loads, s)
585
586 def test_load_str(self):
587 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300588 self.assertEqual(self.loads("S'a\\x00\\xa0'\n."), 'a\x00\xa0')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300589 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300590 self.assertEqual(self.loads('U\x03a\x00\xa0.'), 'a\x00\xa0')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300591 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300592 self.assertEqual(self.loads('\x80\x02U\x03a\x00\xa0.'), 'a\x00\xa0')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300593
594 def test_load_unicode(self):
595 # From Python 2: pickle.dumps(u'Ï€', protocol=0)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300596 self.assertEqual(self.loads('V\\u03c0\n.'), u'Ï€')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300597 # From Python 2: pickle.dumps(u'Ï€', protocol=1)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300598 self.assertEqual(self.loads('X\x02\x00\x00\x00\xcf\x80.'), u'Ï€')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300599 # From Python 2: pickle.dumps(u'Ï€', protocol=2)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300600 self.assertEqual(self.loads('\x80\x02X\x02\x00\x00\x00\xcf\x80.'), u'Ï€')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300601
602 def test_constants(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300603 self.assertIsNone(self.loads('N.'))
604 self.assertIs(self.loads('\x88.'), True)
605 self.assertIs(self.loads('\x89.'), False)
606 self.assertIs(self.loads('I01\n.'), True)
607 self.assertIs(self.loads('I00\n.'), False)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300608
609 def test_misc_get(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300610 self.assertRaises(self.error, self.loads, 'g0\np0\n')
611 self.assertRaises(self.error, self.loads, 'h\x00q\x00')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300612
613 def test_get(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300614 pickled = '((lp100000\ng100000\nt.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300615 unpickled = self.loads(pickled)
616 self.assertEqual(unpickled, ([],)*2)
617 self.assertIs(unpickled[0], unpickled[1])
618
619 def test_binget(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300620 pickled = '(]q\xffh\xfft.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300621 unpickled = self.loads(pickled)
622 self.assertEqual(unpickled, ([],)*2)
623 self.assertIs(unpickled[0], unpickled[1])
624
625 def test_long_binget(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300626 pickled = '(]r\x00\x00\x01\x00j\x00\x00\x01\x00t.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300627 unpickled = self.loads(pickled)
628 self.assertEqual(unpickled, ([],)*2)
629 self.assertIs(unpickled[0], unpickled[1])
630
631 def test_dup(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300632 pickled = '((l2t.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300633 unpickled = self.loads(pickled)
634 self.assertEqual(unpickled, ([],)*2)
635 self.assertIs(unpickled[0], unpickled[1])
636
Serhiy Storchaka5c137662015-11-23 15:20:43 +0200637 def test_bad_stack(self):
638 badpickles = [
639 b'0.', # POP
640 b'1.', # POP_MARK
641 b'2.', # DUP
642 # b'(2.', # PyUnpickler doesn't raise
643 b'R.', # REDUCE
644 b')R.',
645 b'a.', # APPEND
646 b'Na.',
647 b'b.', # BUILD
648 b'Nb.',
649 b'd.', # DICT
650 b'e.', # APPENDS
651 # b'(e.', # PyUnpickler raises AttributeError
652 b'i__builtin__\nlist\n.', # INST
653 b'l.', # LIST
654 b'o.', # OBJ
655 b'(o.',
656 b'p1\n.', # PUT
657 b'q\x00.', # BINPUT
658 b'r\x00\x00\x00\x00.', # LONG_BINPUT
659 b's.', # SETITEM
660 b'Ns.',
661 b'NNs.',
662 b't.', # TUPLE
663 b'u.', # SETITEMS
664 b'(u.',
665 b'}(Nu.',
666 b'\x81.', # NEWOBJ
667 b')\x81.',
668 b'\x85.', # TUPLE1
669 b'\x86.', # TUPLE2
670 b'N\x86.',
671 b'\x87.', # TUPLE3
672 b'N\x87.',
673 b'NN\x87.',
674 ]
675 for p in badpickles:
676 try:
677 self.assertRaises(self.bad_stack_errors, self.loads, p)
678 except:
679 print '***', repr(p)
680 raise
681
682 def test_bad_mark(self):
683 badpickles = [
684 b'c__builtin__\nlist\n)(R.', # REDUCE
685 b'c__builtin__\nlist\n()R.',
686 b']N(a.', # APPEND
687 b'cexceptions\nValueError\n)R}(b.', # BUILD
688 b'cexceptions\nValueError\n)R(}b.',
689 b'(Nd.', # DICT
690 b'}NN(s.', # SETITEM
691 b'}N(Ns.',
692 b'c__builtin__\nlist\n)(\x81.', # NEWOBJ
693 b'c__builtin__\nlist\n()\x81.',
694 b'N(\x85.', # TUPLE1
695 b'NN(\x86.', # TUPLE2
696 b'N(N\x86.',
697 b'NNN(\x87.', # TUPLE3
698 b'NN(N\x87.',
699 b'N(NN\x87.',
700 ]
701 for p in badpickles:
702 # PyUnpickler prints reduce errors to stdout
703 try:
704 self.loads(p)
705 except (IndexError, AttributeError, TypeError,
706 pickle.UnpicklingError):
707 pass
708
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300709
710class AbstractPickleTests(unittest.TestCase):
711 # Subclass must define self.dumps, self.loads.
712
713 _testdata = AbstractUnpickleTests._testdata
714
Jeremy Hylton66426532001-10-15 21:38:56 +0000715 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000716 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000717
Jeremy Hylton66426532001-10-15 21:38:56 +0000718 def test_misc(self):
719 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000720 for proto in protocols:
721 x = myint(4)
722 s = self.dumps(x, proto)
723 y = self.loads(s)
724 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000725
Tim Peters70b02d72003-02-02 17:26:40 +0000726 x = (1, ())
727 s = self.dumps(x, proto)
728 y = self.loads(s)
729 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000730
Tim Peters70b02d72003-02-02 17:26:40 +0000731 x = initarg(1, x)
732 s = self.dumps(x, proto)
733 y = self.loads(s)
734 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000735
Jeremy Hylton66426532001-10-15 21:38:56 +0000736 # XXX test __reduce__ protocol?
737
Tim Peters70b02d72003-02-02 17:26:40 +0000738 def test_roundtrip_equality(self):
739 expected = self._testdata
740 for proto in protocols:
741 s = self.dumps(expected, proto)
742 got = self.loads(s)
743 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000744
Tim Peters70b02d72003-02-02 17:26:40 +0000745 # There are gratuitous differences between pickles produced by
746 # pickle and cPickle, largely because cPickle starts PUT indices at
747 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
748 # there's a comment with an exclamation point there whose meaning
749 # is a mystery. cPickle also suppresses PUT for objects with a refcount
750 # of 1.
751 def dont_test_disassembly(self):
Tim Peters70b02d72003-02-02 17:26:40 +0000752 from pickletools import dis
753
754 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
755 s = self.dumps(self._testdata, proto)
Collin Winterf8089c72009-04-09 16:46:46 +0000756 filelike = cStringIO.StringIO()
Tim Peters70b02d72003-02-02 17:26:40 +0000757 dis(s, out=filelike)
758 got = filelike.getvalue()
759 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000760
761 def test_recursive_list(self):
762 l = []
763 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000764 for proto in protocols:
765 s = self.dumps(l, proto)
766 x = self.loads(s)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200767 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000768 self.assertEqual(len(x), 1)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200769 self.assertIs(x[0], x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000770
Serhiy Storchakada87e452015-11-07 11:15:32 +0200771 def test_recursive_tuple_and_list(self):
Collin Winter57bef682009-05-26 04:12:39 +0000772 t = ([],)
773 t[0].append(t)
774 for proto in protocols:
775 s = self.dumps(t, proto)
776 x = self.loads(s)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200777 self.assertIsInstance(x, tuple)
Collin Winter57bef682009-05-26 04:12:39 +0000778 self.assertEqual(len(x), 1)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200779 self.assertIsInstance(x[0], list)
Collin Winter57bef682009-05-26 04:12:39 +0000780 self.assertEqual(len(x[0]), 1)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200781 self.assertIs(x[0][0], x)
Collin Winter57bef682009-05-26 04:12:39 +0000782
Jeremy Hylton66426532001-10-15 21:38:56 +0000783 def test_recursive_dict(self):
784 d = {}
785 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000786 for proto in protocols:
787 s = self.dumps(d, proto)
788 x = self.loads(s)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200789 self.assertIsInstance(x, dict)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000790 self.assertEqual(x.keys(), [1])
Serhiy Storchakada87e452015-11-07 11:15:32 +0200791 self.assertIs(x[1], x)
792
793 def test_recursive_dict_key(self):
794 d = {}
795 k = K(d)
796 d[k] = 1
797 for proto in protocols:
798 s = self.dumps(d, proto)
799 x = self.loads(s)
800 self.assertIsInstance(x, dict)
801 self.assertEqual(len(x.keys()), 1)
802 self.assertIsInstance(x.keys()[0], K)
803 self.assertIs(x.keys()[0].value, x)
804
805 def test_recursive_list_subclass(self):
806 y = MyList()
807 y.append(y)
808 s = self.dumps(y, 2)
809 x = self.loads(s)
810 self.assertIsInstance(x, MyList)
811 self.assertEqual(len(x), 1)
812 self.assertIs(x[0], x)
813
814 def test_recursive_dict_subclass(self):
815 d = MyDict()
816 d[1] = d
817 s = self.dumps(d, 2)
818 x = self.loads(s)
819 self.assertIsInstance(x, MyDict)
820 self.assertEqual(x.keys(), [1])
821 self.assertIs(x[1], x)
822
823 def test_recursive_dict_subclass_key(self):
824 d = MyDict()
825 k = K(d)
826 d[k] = 1
827 s = self.dumps(d, 2)
828 x = self.loads(s)
829 self.assertIsInstance(x, MyDict)
830 self.assertEqual(len(x.keys()), 1)
831 self.assertIsInstance(x.keys()[0], K)
832 self.assertIs(x.keys()[0].value, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000833
834 def test_recursive_inst(self):
835 i = C()
836 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000837 for proto in protocols:
Ezio Melottia84ecc62013-03-04 15:23:12 +0200838 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +0000839 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000840 self.assertEqual(dir(x), dir(i))
Ezio Melottia84ecc62013-03-04 15:23:12 +0200841 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000842
843 def test_recursive_multi(self):
844 l = []
845 d = {1:l}
846 i = C()
847 i.attr = d
848 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000849 for proto in protocols:
850 s = self.dumps(l, proto)
851 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000852 self.assertEqual(len(x), 1)
853 self.assertEqual(dir(x[0]), dir(i))
854 self.assertEqual(x[0].attr.keys(), [1])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000855 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000856
Serhiy Storchakada87e452015-11-07 11:15:32 +0200857 def check_recursive_collection_and_inst(self, factory):
858 h = H()
859 y = factory([h])
860 h.attr = y
861 for proto in protocols:
862 s = self.dumps(y, proto)
863 x = self.loads(s)
864 self.assertIsInstance(x, type(y))
865 self.assertEqual(len(x), 1)
866 self.assertIsInstance(list(x)[0], H)
867 self.assertIs(list(x)[0].attr, x)
868
869 def test_recursive_list_and_inst(self):
870 self.check_recursive_collection_and_inst(list)
871
872 def test_recursive_tuple_and_inst(self):
873 self.check_recursive_collection_and_inst(tuple)
874
875 def test_recursive_dict_and_inst(self):
876 self.check_recursive_collection_and_inst(dict.fromkeys)
877
878 def test_recursive_set_and_inst(self):
879 self.check_recursive_collection_and_inst(set)
880
881 def test_recursive_frozenset_and_inst(self):
882 self.check_recursive_collection_and_inst(frozenset)
883
884 def test_recursive_list_subclass_and_inst(self):
885 self.check_recursive_collection_and_inst(MyList)
886
887 def test_recursive_tuple_subclass_and_inst(self):
888 self.check_recursive_collection_and_inst(MyTuple)
889
890 def test_recursive_dict_subclass_and_inst(self):
891 self.check_recursive_collection_and_inst(MyDict.fromkeys)
892
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000893 if have_unicode:
Jeremy Hylton66426532001-10-15 21:38:56 +0000894 def test_unicode(self):
Alexandre Vassalottie57e9992008-12-27 10:02:59 +0000895 endcases = [u'', u'<\\u>', u'<\\\u1234>', u'<\n>',
896 u'<\\>', u'<\\\U00012345>']
Tim Petersee1a53c2003-02-02 02:57:53 +0000897 for proto in protocols:
898 for u in endcases:
899 p = self.dumps(u, proto)
900 u2 = self.loads(p)
901 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000902
Alexandre Vassalottif852bf92008-12-27 07:08:47 +0000903 def test_unicode_high_plane(self):
904 t = u'\U00012345'
905 for proto in protocols:
906 p = self.dumps(t, proto)
907 t2 = self.loads(p)
908 self.assertEqual(t2, t)
909
Jeremy Hylton66426532001-10-15 21:38:56 +0000910 def test_ints(self):
911 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000912 for proto in protocols:
913 n = sys.maxint
914 while n:
915 for expected in (-n, n):
916 s = self.dumps(expected, proto)
917 n2 = self.loads(s)
918 self.assertEqual(expected, n2)
919 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000920
Tim Petersee1a53c2003-02-02 02:57:53 +0000921 def test_long(self):
922 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000923 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000924 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
925 nbase = 1L << nbits
926 for npos in nbase-1, nbase, nbase+1:
927 for n in npos, -npos:
928 pickle = self.dumps(n, proto)
929 got = self.loads(pickle)
930 self.assertEqual(n, got)
931 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
932 # bother with those.
Tim Petersee1a53c2003-02-02 02:57:53 +0000933 nbase = long("deadbeeffeedface", 16)
934 nbase += nbase << 1000000
935 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000936 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000937 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000938 self.assertEqual(n, got)
939
Mark Dickinsona3ecd2c2009-01-24 16:40:29 +0000940 def test_float(self):
941 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
942 3.14, 263.44582062374053, 6.022e23, 1e30]
943 test_values = test_values + [-x for x in test_values]
944 for proto in protocols:
945 for value in test_values:
946 pickle = self.dumps(value, proto)
947 got = self.loads(pickle)
948 self.assertEqual(value, got)
949
Georg Brandlde9b6242006-04-30 11:13:56 +0000950 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
951 def test_float_format(self):
952 # make sure that floats are formatted locale independent
953 self.assertEqual(self.dumps(1.2)[0:3], 'F1.')
954
Jeremy Hylton66426532001-10-15 21:38:56 +0000955 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000956 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000957
958 def test_getinitargs(self):
959 pass
960
Guido van Rossum04a86612001-12-19 16:58:54 +0000961 def test_metaclass(self):
962 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000963 for proto in protocols:
964 s = self.dumps(a, proto)
965 b = self.loads(s)
966 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000967
Antoine Pitrou561a8212011-10-04 09:34:48 +0200968 def test_dynamic_class(self):
969 a = create_dynamic_class("my_dynamic_class", (object,))
970 copy_reg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
971 for proto in protocols:
972 s = self.dumps(a, proto)
973 b = self.loads(s)
974 self.assertEqual(a, b)
975
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000976 def test_structseq(self):
977 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000978 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000979
980 t = time.localtime()
981 for proto in protocols:
982 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000983 u = self.loads(s)
984 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000985 if hasattr(os, "stat"):
986 t = os.stat(os.curdir)
987 s = self.dumps(t, proto)
988 u = self.loads(s)
989 self.assertEqual(t, u)
990 if hasattr(os, "statvfs"):
991 t = os.statvfs(os.curdir)
992 s = self.dumps(t, proto)
993 u = self.loads(s)
994 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000995
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000996 # Tests for protocol 2
997
Tim Peters4190fb82003-02-02 16:09:05 +0000998 def test_proto(self):
999 build_none = pickle.NONE + pickle.STOP
1000 for proto in protocols:
1001 expected = build_none
1002 if proto >= 2:
1003 expected = pickle.PROTO + chr(proto) + expected
1004 p = self.dumps(None, proto)
1005 self.assertEqual(p, expected)
1006
1007 oob = protocols[-1] + 1 # a future protocol
1008 badpickle = pickle.PROTO + chr(oob) + build_none
1009 try:
1010 self.loads(badpickle)
1011 except ValueError, detail:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001012 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +00001013 "unsupported pickle protocol"))
1014 else:
1015 self.fail("expected bad protocol number to raise ValueError")
1016
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001017 def test_long1(self):
1018 x = 12345678910111213141516178920L
Tim Peters61bf2572003-02-03 21:31:22 +00001019 for proto in protocols:
1020 s = self.dumps(x, proto)
1021 y = self.loads(s)
1022 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001023 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001024
1025 def test_long4(self):
1026 x = 12345678910111213141516178920L << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +00001027 for proto in protocols:
1028 s = self.dumps(x, proto)
1029 y = self.loads(s)
1030 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001031 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001032
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001033 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +00001034 # Map (proto, len(tuple)) to expected opcode.
1035 expected_opcode = {(0, 0): pickle.TUPLE,
1036 (0, 1): pickle.TUPLE,
1037 (0, 2): pickle.TUPLE,
1038 (0, 3): pickle.TUPLE,
1039 (0, 4): pickle.TUPLE,
1040
1041 (1, 0): pickle.EMPTY_TUPLE,
1042 (1, 1): pickle.TUPLE,
1043 (1, 2): pickle.TUPLE,
1044 (1, 3): pickle.TUPLE,
1045 (1, 4): pickle.TUPLE,
1046
1047 (2, 0): pickle.EMPTY_TUPLE,
1048 (2, 1): pickle.TUPLE1,
1049 (2, 2): pickle.TUPLE2,
1050 (2, 3): pickle.TUPLE3,
1051 (2, 4): pickle.TUPLE,
1052 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001053 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +00001054 b = (1,)
1055 c = (1, 2)
1056 d = (1, 2, 3)
1057 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +00001058 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001059 for x in a, b, c, d, e:
1060 s = self.dumps(x, proto)
1061 y = self.loads(s)
1062 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +00001063 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +00001064 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +00001065
Guido van Rossum7d97d312003-01-28 04:25:27 +00001066 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +00001067 # Map (proto, singleton) to expected opcode.
1068 expected_opcode = {(0, None): pickle.NONE,
1069 (1, None): pickle.NONE,
1070 (2, None): pickle.NONE,
1071
1072 (0, True): pickle.INT,
1073 (1, True): pickle.INT,
1074 (2, True): pickle.NEWTRUE,
1075
1076 (0, False): pickle.INT,
1077 (1, False): pickle.INT,
1078 (2, False): pickle.NEWFALSE,
1079 }
Tim Peters4190fb82003-02-02 16:09:05 +00001080 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +00001081 for x in None, False, True:
1082 s = self.dumps(x, proto)
1083 y = self.loads(s)
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001084 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +00001085 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +00001086 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +00001087
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001088 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001089 x = MyTuple([1, 2, 3])
1090 x.foo = 42
1091 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001092 for proto in protocols:
1093 s = self.dumps(x, proto)
1094 y = self.loads(s)
1095 self.assertEqual(tuple(x), tuple(y))
1096 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001097
1098 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001099 x = MyList([1, 2, 3])
1100 x.foo = 42
1101 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001102 for proto in protocols:
1103 s = self.dumps(x, proto)
1104 y = self.loads(s)
1105 self.assertEqual(list(x), list(y))
1106 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001107
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001108 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001109 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001110 for C in myclasses:
1111 B = C.__base__
1112 x = C(C.sample)
1113 x.foo = 42
1114 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001115 y = self.loads(s)
1116 detail = (proto, C, B, x, y, type(y))
1117 self.assertEqual(B(x), B(y), detail)
1118 self.assertEqual(x.__dict__, y.__dict__, detail)
1119
Georg Brandldffbf5f2008-05-20 07:49:57 +00001120 # Register a type with copy_reg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001121 # an object of that type. Check that the resulting pickle uses opcode
1122 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001123
Tim Peters22e71712003-02-03 22:27:38 +00001124 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001125 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001126 try:
Georg Brandldffbf5f2008-05-20 07:49:57 +00001127 copy_reg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001128 x = MyList([1, 2, 3])
1129 x.foo = 42
1130 x.bar = "hello"
1131
Tim Peters22e71712003-02-03 22:27:38 +00001132 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001133 s1 = self.dumps(x, 1)
Ezio Melottiaa980582010-01-23 23:04:36 +00001134 self.assertIn(__name__, s1)
1135 self.assertIn("MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +00001136 self.assertEqual(opcode_in_pickle(opcode, s1), False)
1137
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001138 y = self.loads(s1)
1139 self.assertEqual(list(x), list(y))
1140 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001141
Tim Peters22e71712003-02-03 22:27:38 +00001142 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001143 s2 = self.dumps(x, 2)
Ezio Melottiaa980582010-01-23 23:04:36 +00001144 self.assertNotIn(__name__, s2)
1145 self.assertNotIn("MyList", s2)
Tim Peters3e667d52003-02-04 21:47:44 +00001146 self.assertEqual(opcode_in_pickle(opcode, s2), True)
1147
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001148 y = self.loads(s2)
1149 self.assertEqual(list(x), list(y))
1150 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001151
1152 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001153 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001154
1155 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001156 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1157 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001158
1159 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001160 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1161 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1162 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001163
1164 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001165 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1166 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1167 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1168
Tim Peters8d2613a2003-02-11 16:40:16 +00001169 def test_list_chunking(self):
1170 n = 10 # too small to chunk
1171 x = range(n)
1172 for proto in protocols:
1173 s = self.dumps(x, proto)
1174 y = self.loads(s)
1175 self.assertEqual(x, y)
1176 num_appends = count_opcode(pickle.APPENDS, s)
1177 self.assertEqual(num_appends, proto > 0)
1178
1179 n = 2500 # expect at least two chunks when proto > 0
1180 x = range(n)
1181 for proto in protocols:
1182 s = self.dumps(x, proto)
1183 y = self.loads(s)
1184 self.assertEqual(x, y)
1185 num_appends = count_opcode(pickle.APPENDS, s)
1186 if proto == 0:
1187 self.assertEqual(num_appends, 0)
1188 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001189 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001190
1191 def test_dict_chunking(self):
1192 n = 10 # too small to chunk
1193 x = dict.fromkeys(range(n))
1194 for proto in protocols:
1195 s = self.dumps(x, proto)
1196 y = self.loads(s)
1197 self.assertEqual(x, y)
1198 num_setitems = count_opcode(pickle.SETITEMS, s)
1199 self.assertEqual(num_setitems, proto > 0)
1200
1201 n = 2500 # expect at least two chunks when proto > 0
1202 x = dict.fromkeys(range(n))
1203 for proto in protocols:
1204 s = self.dumps(x, proto)
1205 y = self.loads(s)
1206 self.assertEqual(x, y)
1207 num_setitems = count_opcode(pickle.SETITEMS, s)
1208 if proto == 0:
1209 self.assertEqual(num_setitems, 0)
1210 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001211 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001212
Tim Peterse9ef2032003-02-13 18:42:00 +00001213 def test_simple_newobj(self):
1214 x = object.__new__(SimpleNewObj) # avoid __init__
1215 x.abc = 666
1216 for proto in protocols:
1217 s = self.dumps(x, proto)
1218 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
1219 y = self.loads(s) # will raise TypeError if __init__ called
1220 self.assertEqual(y.abc, 666)
1221 self.assertEqual(x.__dict__, y.__dict__)
1222
Tim Peters42f08ac2003-02-11 22:43:24 +00001223 def test_newobj_list_slots(self):
1224 x = SlotList([1, 2, 3])
1225 x.foo = 42
1226 x.bar = "hello"
1227 s = self.dumps(x, 2)
1228 y = self.loads(s)
1229 self.assertEqual(list(x), list(y))
1230 self.assertEqual(x.__dict__, y.__dict__)
1231 self.assertEqual(x.foo, y.foo)
1232 self.assertEqual(x.bar, y.bar)
1233
Guido van Rossum2a30b212003-02-18 22:41:24 +00001234 def test_reduce_overrides_default_reduce_ex(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001235 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001236 x = REX_one()
1237 self.assertEqual(x._reduce_called, 0)
1238 s = self.dumps(x, proto)
1239 self.assertEqual(x._reduce_called, 1)
1240 y = self.loads(s)
1241 self.assertEqual(y._reduce_called, 0)
1242
1243 def test_reduce_ex_called(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001244 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001245 x = REX_two()
1246 self.assertEqual(x._proto, None)
1247 s = self.dumps(x, proto)
1248 self.assertEqual(x._proto, proto)
1249 y = self.loads(s)
1250 self.assertEqual(y._proto, None)
1251
1252 def test_reduce_ex_overrides_reduce(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001253 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001254 x = REX_three()
1255 self.assertEqual(x._proto, None)
1256 s = self.dumps(x, proto)
1257 self.assertEqual(x._proto, proto)
1258 y = self.loads(s)
1259 self.assertEqual(y._proto, None)
1260
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001261 def test_reduce_ex_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001262 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001263 x = REX_four()
1264 self.assertEqual(x._proto, None)
1265 s = self.dumps(x, proto)
1266 self.assertEqual(x._proto, proto)
1267 y = self.loads(s)
1268 self.assertEqual(y._proto, proto)
1269
1270 def test_reduce_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001271 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001272 x = REX_five()
1273 self.assertEqual(x._reduce_called, 0)
1274 s = self.dumps(x, proto)
1275 self.assertEqual(x._reduce_called, 1)
1276 y = self.loads(s)
1277 self.assertEqual(y._reduce_called, 1)
1278
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001279 def test_reduce_bad_iterator(self):
1280 # Issue4176: crash when 4th and 5th items of __reduce__()
1281 # are not iterators
1282 class C(object):
1283 def __reduce__(self):
1284 # 4th item is not an iterator
1285 return list, (), None, [], None
1286 class D(object):
1287 def __reduce__(self):
1288 # 5th item is not an iterator
1289 return dict, (), None, None, []
1290
1291 # Protocol 0 is less strict and also accept iterables.
Collin Winterf8089c72009-04-09 16:46:46 +00001292 for proto in protocols:
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001293 try:
1294 self.dumps(C(), proto)
1295 except (AttributeError, pickle.PickleError, cPickle.PickleError):
1296 pass
1297 try:
1298 self.dumps(D(), proto)
1299 except (AttributeError, pickle.PickleError, cPickle.PickleError):
1300 pass
1301
Collin Winterf8089c72009-04-09 16:46:46 +00001302 def test_many_puts_and_gets(self):
1303 # Test that internal data structures correctly deal with lots of
1304 # puts/gets.
1305 keys = ("aaa" + str(i) for i in xrange(100))
1306 large_dict = dict((k, [4, 5, 6]) for k in keys)
1307 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1308
1309 for proto in protocols:
1310 dumped = self.dumps(obj, proto)
1311 loaded = self.loads(dumped)
1312 self.assertEqual(loaded, obj,
1313 "Failed protocol %d: %r != %r"
1314 % (proto, obj, loaded))
1315
Antoine Pitrou74309892009-05-02 21:13:23 +00001316 def test_attribute_name_interning(self):
1317 # Test that attribute names of pickled objects are interned when
1318 # unpickling.
1319 for proto in protocols:
1320 x = C()
1321 x.foo = 42
1322 x.bar = "hello"
1323 s = self.dumps(x, proto)
1324 y = self.loads(s)
1325 x_keys = sorted(x.__dict__)
1326 y_keys = sorted(y.__dict__)
1327 for x_key, y_key in zip(x_keys, y_keys):
1328 self.assertIs(x_key, y_key)
1329
Collin Winterf8089c72009-04-09 16:46:46 +00001330
Guido van Rossum2a30b212003-02-18 22:41:24 +00001331# Test classes for reduce_ex
1332
1333class REX_one(object):
1334 _reduce_called = 0
1335 def __reduce__(self):
1336 self._reduce_called = 1
1337 return REX_one, ()
1338 # No __reduce_ex__ here, but inheriting it from object
1339
1340class REX_two(object):
1341 _proto = None
1342 def __reduce_ex__(self, proto):
1343 self._proto = proto
1344 return REX_two, ()
1345 # No __reduce__ here, but inheriting it from object
1346
1347class REX_three(object):
1348 _proto = None
1349 def __reduce_ex__(self, proto):
1350 self._proto = proto
1351 return REX_two, ()
1352 def __reduce__(self):
1353 raise TestFailed, "This __reduce__ shouldn't be called"
1354
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001355class REX_four(object):
1356 _proto = None
1357 def __reduce_ex__(self, proto):
1358 self._proto = proto
1359 return object.__reduce_ex__(self, proto)
1360 # Calling base class method should succeed
1361
1362class REX_five(object):
1363 _reduce_called = 0
1364 def __reduce__(self):
1365 self._reduce_called = 1
1366 return object.__reduce__(self)
1367 # This one used to fail with infinite recursion
1368
Guido van Rossum2a30b212003-02-18 22:41:24 +00001369# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001370
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001371class MyInt(int):
1372 sample = 1
1373
1374class MyLong(long):
1375 sample = 1L
1376
1377class MyFloat(float):
1378 sample = 1.0
1379
1380class MyComplex(complex):
1381 sample = 1.0 + 0.0j
1382
1383class MyStr(str):
1384 sample = "hello"
1385
1386class MyUnicode(unicode):
1387 sample = u"hello \u1234"
1388
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001389class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001390 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001391
1392class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001393 sample = [1, 2, 3]
1394
1395class MyDict(dict):
1396 sample = {"a": 1, "b": 2}
1397
1398myclasses = [MyInt, MyLong, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001399 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001400 MyStr, MyUnicode,
1401 MyTuple, MyList, MyDict]
1402
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001403
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001404class SlotList(MyList):
1405 __slots__ = ["foo"]
1406
Tim Peterse9ef2032003-02-13 18:42:00 +00001407class SimpleNewObj(object):
1408 def __init__(self, a, b, c):
1409 # raise an error, to make sure this isn't called
1410 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1411
Jeremy Hylton66426532001-10-15 21:38:56 +00001412class AbstractPickleModuleTests(unittest.TestCase):
1413
1414 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001415 import os
1416 f = open(TESTFN, "w")
1417 try:
1418 f.close()
1419 self.assertRaises(ValueError, self.module.dump, 123, f)
1420 finally:
1421 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001422
1423 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001424 import os
1425 f = open(TESTFN, "w")
1426 try:
1427 f.close()
1428 self.assertRaises(ValueError, self.module.dump, 123, f)
1429 finally:
1430 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001431
Collin Winterf8089c72009-04-09 16:46:46 +00001432 def test_load_from_and_dump_to_file(self):
1433 stream = cStringIO.StringIO()
1434 data = [123, {}, 124]
1435 self.module.dump(data, stream)
1436 stream.seek(0)
1437 unpickled = self.module.load(stream)
1438 self.assertEqual(unpickled, data)
1439
Tim Petersc0c93702003-02-13 19:30:57 +00001440 def test_highest_protocol(self):
1441 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
1442 self.assertEqual(self.module.HIGHEST_PROTOCOL, 2)
1443
Martin v. Löwis544f1192004-07-27 05:22:33 +00001444 def test_callapi(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001445 f = cStringIO.StringIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001446 # With and without keyword arguments
1447 self.module.dump(123, f, -1)
1448 self.module.dump(123, file=f, protocol=-1)
1449 self.module.dumps(123, -1)
1450 self.module.dumps(123, protocol=-1)
1451 self.module.Pickler(f, -1)
1452 self.module.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001453
Amaury Forgeot d'Arc74b30162009-07-23 19:26:02 +00001454 def test_incomplete_input(self):
1455 s = StringIO.StringIO("X''.")
1456 self.assertRaises(EOFError, self.module.load, s)
1457
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001458 def test_restricted(self):
1459 # issue7128: cPickle failed in restricted mode
1460 builtins = {self.module.__name__: self.module,
1461 '__import__': __import__}
1462 d = {}
1463 teststr = "def f(): {0}.dumps(0)".format(self.module.__name__)
1464 exec teststr in {'__builtins__': builtins}, d
1465 d['f']()
1466
Antoine Pitrou0d423b82010-01-07 17:46:49 +00001467 def test_bad_input(self):
1468 # Test issue4298
1469 s = '\x58\0\0\0\x54'
1470 self.assertRaises(EOFError, self.module.loads, s)
1471 # Test issue7455
1472 s = '0'
1473 # XXX Why doesn't pickle raise UnpicklingError?
1474 self.assertRaises((IndexError, cPickle.UnpicklingError),
1475 self.module.loads, s)
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001476
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001477class AbstractPersistentPicklerTests(unittest.TestCase):
1478
1479 # This class defines persistent_id() and persistent_load()
1480 # functions that should be used by the pickler. All even integers
1481 # are pickled using persistent ids.
1482
1483 def persistent_id(self, object):
1484 if isinstance(object, int) and object % 2 == 0:
1485 self.id_count += 1
1486 return str(object)
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001487 elif object == "test_false_value":
1488 self.false_count += 1
1489 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001490 else:
1491 return None
1492
1493 def persistent_load(self, oid):
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001494 if not oid:
1495 self.load_false_count += 1
1496 return "test_false_value"
1497 else:
1498 self.load_count += 1
1499 object = int(oid)
1500 assert object % 2 == 0
1501 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001502
1503 def test_persistence(self):
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001504 L = range(10) + ["test_false_value"]
1505 for proto in protocols:
1506 self.id_count = 0
1507 self.false_count = 0
1508 self.load_false_count = 0
1509 self.load_count = 0
1510 self.assertEqual(self.loads(self.dumps(L, proto)), L)
1511 self.assertEqual(self.id_count, 5)
1512 self.assertEqual(self.false_count, 1)
1513 self.assertEqual(self.load_count, 5)
1514 self.assertEqual(self.load_false_count, 1)
Collin Winterf8089c72009-04-09 16:46:46 +00001515
1516class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1517
1518 pickler_class = None
1519 unpickler_class = None
1520
1521 def setUp(self):
1522 assert self.pickler_class
1523 assert self.unpickler_class
1524
1525 def test_clear_pickler_memo(self):
1526 # To test whether clear_memo() has any effect, we pickle an object,
1527 # then pickle it again without clearing the memo; the two serialized
1528 # forms should be different. If we clear_memo() and then pickle the
1529 # object again, the third serialized form should be identical to the
1530 # first one we obtained.
1531 data = ["abcdefg", "abcdefg", 44]
1532 f = cStringIO.StringIO()
1533 pickler = self.pickler_class(f)
1534
1535 pickler.dump(data)
1536 first_pickled = f.getvalue()
1537
1538 # Reset StringIO object.
1539 f.seek(0)
1540 f.truncate()
1541
1542 pickler.dump(data)
1543 second_pickled = f.getvalue()
1544
1545 # Reset the Pickler and StringIO objects.
1546 pickler.clear_memo()
1547 f.seek(0)
1548 f.truncate()
1549
1550 pickler.dump(data)
1551 third_pickled = f.getvalue()
1552
1553 self.assertNotEqual(first_pickled, second_pickled)
1554 self.assertEqual(first_pickled, third_pickled)
1555
1556 def test_priming_pickler_memo(self):
1557 # Verify that we can set the Pickler's memo attribute.
1558 data = ["abcdefg", "abcdefg", 44]
1559 f = cStringIO.StringIO()
1560 pickler = self.pickler_class(f)
1561
1562 pickler.dump(data)
1563 first_pickled = f.getvalue()
1564
1565 f = cStringIO.StringIO()
1566 primed = self.pickler_class(f)
1567 primed.memo = pickler.memo
1568
1569 primed.dump(data)
1570 primed_pickled = f.getvalue()
1571
1572 self.assertNotEqual(first_pickled, primed_pickled)
1573
1574 def test_priming_unpickler_memo(self):
1575 # Verify that we can set the Unpickler's memo attribute.
1576 data = ["abcdefg", "abcdefg", 44]
1577 f = cStringIO.StringIO()
1578 pickler = self.pickler_class(f)
1579
1580 pickler.dump(data)
1581 first_pickled = f.getvalue()
1582
1583 f = cStringIO.StringIO()
1584 primed = self.pickler_class(f)
1585 primed.memo = pickler.memo
1586
1587 primed.dump(data)
1588 primed_pickled = f.getvalue()
1589
1590 unpickler = self.unpickler_class(cStringIO.StringIO(first_pickled))
1591 unpickled_data1 = unpickler.load()
1592
1593 self.assertEqual(unpickled_data1, data)
1594
1595 primed = self.unpickler_class(cStringIO.StringIO(primed_pickled))
1596 primed.memo = unpickler.memo
1597 unpickled_data2 = primed.load()
1598
1599 primed.memo.clear()
1600
1601 self.assertEqual(unpickled_data2, data)
1602 self.assertTrue(unpickled_data2 is unpickled_data1)
1603
1604 def test_reusing_unpickler_objects(self):
1605 data1 = ["abcdefg", "abcdefg", 44]
1606 f = cStringIO.StringIO()
1607 pickler = self.pickler_class(f)
1608 pickler.dump(data1)
1609 pickled1 = f.getvalue()
1610
1611 data2 = ["abcdefg", 44, 44]
1612 f = cStringIO.StringIO()
1613 pickler = self.pickler_class(f)
1614 pickler.dump(data2)
1615 pickled2 = f.getvalue()
1616
1617 f = cStringIO.StringIO()
1618 f.write(pickled1)
1619 f.seek(0)
1620 unpickler = self.unpickler_class(f)
1621 self.assertEqual(unpickler.load(), data1)
1622
1623 f.seek(0)
1624 f.truncate()
1625 f.write(pickled2)
1626 f.seek(0)
1627 self.assertEqual(unpickler.load(), data2)
Serhiy Storchakacdc7a912013-02-12 21:36:47 +02001628
1629class BigmemPickleTests(unittest.TestCase):
1630
1631 # Memory requirements: 1 byte per character for input strings, 1 byte
1632 # for pickled data, 1 byte for unpickled strings, 1 byte for internal
1633 # buffer and 1 byte of free space for resizing of internal buffer.
1634
1635 @precisionbigmemtest(size=_2G + 100*_1M, memuse=5)
1636 def test_huge_strlist(self, size):
1637 chunksize = 2**20
1638 data = []
1639 while size > chunksize:
1640 data.append('x' * chunksize)
1641 size -= chunksize
1642 chunksize += 1
1643 data.append('y' * size)
1644
1645 try:
1646 for proto in protocols:
1647 try:
1648 pickled = self.dumps(data, proto)
1649 res = self.loads(pickled)
1650 self.assertEqual(res, data)
1651 finally:
1652 res = None
1653 pickled = None
1654 finally:
1655 data = None