blob: d8346ea757b6f9bf1131f1ff2cdb57a13e57115b [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
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 Storchaka4d2cf552015-09-29 15:36:28 +0300637
638class AbstractPickleTests(unittest.TestCase):
639 # Subclass must define self.dumps, self.loads.
640
641 _testdata = AbstractUnpickleTests._testdata
642
Jeremy Hylton66426532001-10-15 21:38:56 +0000643 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000644 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000645
Jeremy Hylton66426532001-10-15 21:38:56 +0000646 def test_misc(self):
647 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000648 for proto in protocols:
649 x = myint(4)
650 s = self.dumps(x, proto)
651 y = self.loads(s)
652 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000653
Tim Peters70b02d72003-02-02 17:26:40 +0000654 x = (1, ())
655 s = self.dumps(x, proto)
656 y = self.loads(s)
657 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000658
Tim Peters70b02d72003-02-02 17:26:40 +0000659 x = initarg(1, x)
660 s = self.dumps(x, proto)
661 y = self.loads(s)
662 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000663
Jeremy Hylton66426532001-10-15 21:38:56 +0000664 # XXX test __reduce__ protocol?
665
Tim Peters70b02d72003-02-02 17:26:40 +0000666 def test_roundtrip_equality(self):
667 expected = self._testdata
668 for proto in protocols:
669 s = self.dumps(expected, proto)
670 got = self.loads(s)
671 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000672
Tim Peters70b02d72003-02-02 17:26:40 +0000673 # There are gratuitous differences between pickles produced by
674 # pickle and cPickle, largely because cPickle starts PUT indices at
675 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
676 # there's a comment with an exclamation point there whose meaning
677 # is a mystery. cPickle also suppresses PUT for objects with a refcount
678 # of 1.
679 def dont_test_disassembly(self):
Tim Peters70b02d72003-02-02 17:26:40 +0000680 from pickletools import dis
681
682 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
683 s = self.dumps(self._testdata, proto)
Collin Winterf8089c72009-04-09 16:46:46 +0000684 filelike = cStringIO.StringIO()
Tim Peters70b02d72003-02-02 17:26:40 +0000685 dis(s, out=filelike)
686 got = filelike.getvalue()
687 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000688
689 def test_recursive_list(self):
690 l = []
691 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000692 for proto in protocols:
693 s = self.dumps(l, proto)
694 x = self.loads(s)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200695 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000696 self.assertEqual(len(x), 1)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200697 self.assertIs(x[0], x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000698
Serhiy Storchakada87e452015-11-07 11:15:32 +0200699 def test_recursive_tuple_and_list(self):
Collin Winter57bef682009-05-26 04:12:39 +0000700 t = ([],)
701 t[0].append(t)
702 for proto in protocols:
703 s = self.dumps(t, proto)
704 x = self.loads(s)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200705 self.assertIsInstance(x, tuple)
Collin Winter57bef682009-05-26 04:12:39 +0000706 self.assertEqual(len(x), 1)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200707 self.assertIsInstance(x[0], list)
Collin Winter57bef682009-05-26 04:12:39 +0000708 self.assertEqual(len(x[0]), 1)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200709 self.assertIs(x[0][0], x)
Collin Winter57bef682009-05-26 04:12:39 +0000710
Jeremy Hylton66426532001-10-15 21:38:56 +0000711 def test_recursive_dict(self):
712 d = {}
713 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000714 for proto in protocols:
715 s = self.dumps(d, proto)
716 x = self.loads(s)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200717 self.assertIsInstance(x, dict)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000718 self.assertEqual(x.keys(), [1])
Serhiy Storchakada87e452015-11-07 11:15:32 +0200719 self.assertIs(x[1], x)
720
721 def test_recursive_dict_key(self):
722 d = {}
723 k = K(d)
724 d[k] = 1
725 for proto in protocols:
726 s = self.dumps(d, proto)
727 x = self.loads(s)
728 self.assertIsInstance(x, dict)
729 self.assertEqual(len(x.keys()), 1)
730 self.assertIsInstance(x.keys()[0], K)
731 self.assertIs(x.keys()[0].value, x)
732
733 def test_recursive_list_subclass(self):
734 y = MyList()
735 y.append(y)
736 s = self.dumps(y, 2)
737 x = self.loads(s)
738 self.assertIsInstance(x, MyList)
739 self.assertEqual(len(x), 1)
740 self.assertIs(x[0], x)
741
742 def test_recursive_dict_subclass(self):
743 d = MyDict()
744 d[1] = d
745 s = self.dumps(d, 2)
746 x = self.loads(s)
747 self.assertIsInstance(x, MyDict)
748 self.assertEqual(x.keys(), [1])
749 self.assertIs(x[1], x)
750
751 def test_recursive_dict_subclass_key(self):
752 d = MyDict()
753 k = K(d)
754 d[k] = 1
755 s = self.dumps(d, 2)
756 x = self.loads(s)
757 self.assertIsInstance(x, MyDict)
758 self.assertEqual(len(x.keys()), 1)
759 self.assertIsInstance(x.keys()[0], K)
760 self.assertIs(x.keys()[0].value, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000761
762 def test_recursive_inst(self):
763 i = C()
764 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000765 for proto in protocols:
Ezio Melottia84ecc62013-03-04 15:23:12 +0200766 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +0000767 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000768 self.assertEqual(dir(x), dir(i))
Ezio Melottia84ecc62013-03-04 15:23:12 +0200769 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000770
771 def test_recursive_multi(self):
772 l = []
773 d = {1:l}
774 i = C()
775 i.attr = d
776 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000777 for proto in protocols:
778 s = self.dumps(l, proto)
779 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000780 self.assertEqual(len(x), 1)
781 self.assertEqual(dir(x[0]), dir(i))
782 self.assertEqual(x[0].attr.keys(), [1])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000783 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000784
Serhiy Storchakada87e452015-11-07 11:15:32 +0200785 def check_recursive_collection_and_inst(self, factory):
786 h = H()
787 y = factory([h])
788 h.attr = y
789 for proto in protocols:
790 s = self.dumps(y, proto)
791 x = self.loads(s)
792 self.assertIsInstance(x, type(y))
793 self.assertEqual(len(x), 1)
794 self.assertIsInstance(list(x)[0], H)
795 self.assertIs(list(x)[0].attr, x)
796
797 def test_recursive_list_and_inst(self):
798 self.check_recursive_collection_and_inst(list)
799
800 def test_recursive_tuple_and_inst(self):
801 self.check_recursive_collection_and_inst(tuple)
802
803 def test_recursive_dict_and_inst(self):
804 self.check_recursive_collection_and_inst(dict.fromkeys)
805
806 def test_recursive_set_and_inst(self):
807 self.check_recursive_collection_and_inst(set)
808
809 def test_recursive_frozenset_and_inst(self):
810 self.check_recursive_collection_and_inst(frozenset)
811
812 def test_recursive_list_subclass_and_inst(self):
813 self.check_recursive_collection_and_inst(MyList)
814
815 def test_recursive_tuple_subclass_and_inst(self):
816 self.check_recursive_collection_and_inst(MyTuple)
817
818 def test_recursive_dict_subclass_and_inst(self):
819 self.check_recursive_collection_and_inst(MyDict.fromkeys)
820
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000821 if have_unicode:
Jeremy Hylton66426532001-10-15 21:38:56 +0000822 def test_unicode(self):
Alexandre Vassalottie57e9992008-12-27 10:02:59 +0000823 endcases = [u'', u'<\\u>', u'<\\\u1234>', u'<\n>',
824 u'<\\>', u'<\\\U00012345>']
Tim Petersee1a53c2003-02-02 02:57:53 +0000825 for proto in protocols:
826 for u in endcases:
827 p = self.dumps(u, proto)
828 u2 = self.loads(p)
829 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000830
Alexandre Vassalottif852bf92008-12-27 07:08:47 +0000831 def test_unicode_high_plane(self):
832 t = u'\U00012345'
833 for proto in protocols:
834 p = self.dumps(t, proto)
835 t2 = self.loads(p)
836 self.assertEqual(t2, t)
837
Jeremy Hylton66426532001-10-15 21:38:56 +0000838 def test_ints(self):
839 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000840 for proto in protocols:
841 n = sys.maxint
842 while n:
843 for expected in (-n, n):
844 s = self.dumps(expected, proto)
845 n2 = self.loads(s)
846 self.assertEqual(expected, n2)
847 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000848
Tim Petersee1a53c2003-02-02 02:57:53 +0000849 def test_long(self):
850 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000851 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000852 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
853 nbase = 1L << nbits
854 for npos in nbase-1, nbase, nbase+1:
855 for n in npos, -npos:
856 pickle = self.dumps(n, proto)
857 got = self.loads(pickle)
858 self.assertEqual(n, got)
859 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
860 # bother with those.
Tim Petersee1a53c2003-02-02 02:57:53 +0000861 nbase = long("deadbeeffeedface", 16)
862 nbase += nbase << 1000000
863 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000864 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000865 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000866 self.assertEqual(n, got)
867
Mark Dickinsona3ecd2c2009-01-24 16:40:29 +0000868 def test_float(self):
869 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
870 3.14, 263.44582062374053, 6.022e23, 1e30]
871 test_values = test_values + [-x for x in test_values]
872 for proto in protocols:
873 for value in test_values:
874 pickle = self.dumps(value, proto)
875 got = self.loads(pickle)
876 self.assertEqual(value, got)
877
Georg Brandlde9b6242006-04-30 11:13:56 +0000878 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
879 def test_float_format(self):
880 # make sure that floats are formatted locale independent
881 self.assertEqual(self.dumps(1.2)[0:3], 'F1.')
882
Jeremy Hylton66426532001-10-15 21:38:56 +0000883 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000884 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000885
886 def test_getinitargs(self):
887 pass
888
Guido van Rossum04a86612001-12-19 16:58:54 +0000889 def test_metaclass(self):
890 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000891 for proto in protocols:
892 s = self.dumps(a, proto)
893 b = self.loads(s)
894 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000895
Antoine Pitrou561a8212011-10-04 09:34:48 +0200896 def test_dynamic_class(self):
897 a = create_dynamic_class("my_dynamic_class", (object,))
898 copy_reg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
899 for proto in protocols:
900 s = self.dumps(a, proto)
901 b = self.loads(s)
902 self.assertEqual(a, b)
903
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000904 def test_structseq(self):
905 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000906 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000907
908 t = time.localtime()
909 for proto in protocols:
910 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000911 u = self.loads(s)
912 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000913 if hasattr(os, "stat"):
914 t = os.stat(os.curdir)
915 s = self.dumps(t, proto)
916 u = self.loads(s)
917 self.assertEqual(t, u)
918 if hasattr(os, "statvfs"):
919 t = os.statvfs(os.curdir)
920 s = self.dumps(t, proto)
921 u = self.loads(s)
922 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000923
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000924 # Tests for protocol 2
925
Tim Peters4190fb82003-02-02 16:09:05 +0000926 def test_proto(self):
927 build_none = pickle.NONE + pickle.STOP
928 for proto in protocols:
929 expected = build_none
930 if proto >= 2:
931 expected = pickle.PROTO + chr(proto) + expected
932 p = self.dumps(None, proto)
933 self.assertEqual(p, expected)
934
935 oob = protocols[-1] + 1 # a future protocol
936 badpickle = pickle.PROTO + chr(oob) + build_none
937 try:
938 self.loads(badpickle)
939 except ValueError, detail:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000940 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +0000941 "unsupported pickle protocol"))
942 else:
943 self.fail("expected bad protocol number to raise ValueError")
944
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000945 def test_long1(self):
946 x = 12345678910111213141516178920L
Tim Peters61bf2572003-02-03 21:31:22 +0000947 for proto in protocols:
948 s = self.dumps(x, proto)
949 y = self.loads(s)
950 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000951 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000952
953 def test_long4(self):
954 x = 12345678910111213141516178920L << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000955 for proto in protocols:
956 s = self.dumps(x, proto)
957 y = self.loads(s)
958 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000959 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000960
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000961 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000962 # Map (proto, len(tuple)) to expected opcode.
963 expected_opcode = {(0, 0): pickle.TUPLE,
964 (0, 1): pickle.TUPLE,
965 (0, 2): pickle.TUPLE,
966 (0, 3): pickle.TUPLE,
967 (0, 4): pickle.TUPLE,
968
969 (1, 0): pickle.EMPTY_TUPLE,
970 (1, 1): pickle.TUPLE,
971 (1, 2): pickle.TUPLE,
972 (1, 3): pickle.TUPLE,
973 (1, 4): pickle.TUPLE,
974
975 (2, 0): pickle.EMPTY_TUPLE,
976 (2, 1): pickle.TUPLE1,
977 (2, 2): pickle.TUPLE2,
978 (2, 3): pickle.TUPLE3,
979 (2, 4): pickle.TUPLE,
980 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000981 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000982 b = (1,)
983 c = (1, 2)
984 d = (1, 2, 3)
985 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000986 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000987 for x in a, b, c, d, e:
988 s = self.dumps(x, proto)
989 y = self.loads(s)
990 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000991 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +0000992 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +0000993
Guido van Rossum7d97d312003-01-28 04:25:27 +0000994 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000995 # Map (proto, singleton) to expected opcode.
996 expected_opcode = {(0, None): pickle.NONE,
997 (1, None): pickle.NONE,
998 (2, None): pickle.NONE,
999
1000 (0, True): pickle.INT,
1001 (1, True): pickle.INT,
1002 (2, True): pickle.NEWTRUE,
1003
1004 (0, False): pickle.INT,
1005 (1, False): pickle.INT,
1006 (2, False): pickle.NEWFALSE,
1007 }
Tim Peters4190fb82003-02-02 16:09:05 +00001008 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +00001009 for x in None, False, True:
1010 s = self.dumps(x, proto)
1011 y = self.loads(s)
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001012 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +00001013 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +00001014 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +00001015
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001016 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001017 x = MyTuple([1, 2, 3])
1018 x.foo = 42
1019 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001020 for proto in protocols:
1021 s = self.dumps(x, proto)
1022 y = self.loads(s)
1023 self.assertEqual(tuple(x), tuple(y))
1024 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001025
1026 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001027 x = MyList([1, 2, 3])
1028 x.foo = 42
1029 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001030 for proto in protocols:
1031 s = self.dumps(x, proto)
1032 y = self.loads(s)
1033 self.assertEqual(list(x), list(y))
1034 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001035
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001036 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001037 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001038 for C in myclasses:
1039 B = C.__base__
1040 x = C(C.sample)
1041 x.foo = 42
1042 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001043 y = self.loads(s)
1044 detail = (proto, C, B, x, y, type(y))
1045 self.assertEqual(B(x), B(y), detail)
1046 self.assertEqual(x.__dict__, y.__dict__, detail)
1047
Georg Brandldffbf5f2008-05-20 07:49:57 +00001048 # Register a type with copy_reg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001049 # an object of that type. Check that the resulting pickle uses opcode
1050 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001051
Tim Peters22e71712003-02-03 22:27:38 +00001052 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001053 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001054 try:
Georg Brandldffbf5f2008-05-20 07:49:57 +00001055 copy_reg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001056 x = MyList([1, 2, 3])
1057 x.foo = 42
1058 x.bar = "hello"
1059
Tim Peters22e71712003-02-03 22:27:38 +00001060 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001061 s1 = self.dumps(x, 1)
Ezio Melottiaa980582010-01-23 23:04:36 +00001062 self.assertIn(__name__, s1)
1063 self.assertIn("MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +00001064 self.assertEqual(opcode_in_pickle(opcode, s1), False)
1065
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001066 y = self.loads(s1)
1067 self.assertEqual(list(x), list(y))
1068 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001069
Tim Peters22e71712003-02-03 22:27:38 +00001070 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001071 s2 = self.dumps(x, 2)
Ezio Melottiaa980582010-01-23 23:04:36 +00001072 self.assertNotIn(__name__, s2)
1073 self.assertNotIn("MyList", s2)
Tim Peters3e667d52003-02-04 21:47:44 +00001074 self.assertEqual(opcode_in_pickle(opcode, s2), True)
1075
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001076 y = self.loads(s2)
1077 self.assertEqual(list(x), list(y))
1078 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001079
1080 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001081 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001082
1083 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001084 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1085 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001086
1087 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001088 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1089 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1090 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001091
1092 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001093 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1094 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1095 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1096
Tim Peters8d2613a2003-02-11 16:40:16 +00001097 def test_list_chunking(self):
1098 n = 10 # too small to chunk
1099 x = range(n)
1100 for proto in protocols:
1101 s = self.dumps(x, proto)
1102 y = self.loads(s)
1103 self.assertEqual(x, y)
1104 num_appends = count_opcode(pickle.APPENDS, s)
1105 self.assertEqual(num_appends, proto > 0)
1106
1107 n = 2500 # expect at least two chunks when proto > 0
1108 x = range(n)
1109 for proto in protocols:
1110 s = self.dumps(x, proto)
1111 y = self.loads(s)
1112 self.assertEqual(x, y)
1113 num_appends = count_opcode(pickle.APPENDS, s)
1114 if proto == 0:
1115 self.assertEqual(num_appends, 0)
1116 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001117 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001118
1119 def test_dict_chunking(self):
1120 n = 10 # too small to chunk
1121 x = dict.fromkeys(range(n))
1122 for proto in protocols:
1123 s = self.dumps(x, proto)
1124 y = self.loads(s)
1125 self.assertEqual(x, y)
1126 num_setitems = count_opcode(pickle.SETITEMS, s)
1127 self.assertEqual(num_setitems, proto > 0)
1128
1129 n = 2500 # expect at least two chunks when proto > 0
1130 x = dict.fromkeys(range(n))
1131 for proto in protocols:
1132 s = self.dumps(x, proto)
1133 y = self.loads(s)
1134 self.assertEqual(x, y)
1135 num_setitems = count_opcode(pickle.SETITEMS, s)
1136 if proto == 0:
1137 self.assertEqual(num_setitems, 0)
1138 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001139 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001140
Tim Peterse9ef2032003-02-13 18:42:00 +00001141 def test_simple_newobj(self):
1142 x = object.__new__(SimpleNewObj) # avoid __init__
1143 x.abc = 666
1144 for proto in protocols:
1145 s = self.dumps(x, proto)
1146 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
1147 y = self.loads(s) # will raise TypeError if __init__ called
1148 self.assertEqual(y.abc, 666)
1149 self.assertEqual(x.__dict__, y.__dict__)
1150
Tim Peters42f08ac2003-02-11 22:43:24 +00001151 def test_newobj_list_slots(self):
1152 x = SlotList([1, 2, 3])
1153 x.foo = 42
1154 x.bar = "hello"
1155 s = self.dumps(x, 2)
1156 y = self.loads(s)
1157 self.assertEqual(list(x), list(y))
1158 self.assertEqual(x.__dict__, y.__dict__)
1159 self.assertEqual(x.foo, y.foo)
1160 self.assertEqual(x.bar, y.bar)
1161
Guido van Rossum2a30b212003-02-18 22:41:24 +00001162 def test_reduce_overrides_default_reduce_ex(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001163 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001164 x = REX_one()
1165 self.assertEqual(x._reduce_called, 0)
1166 s = self.dumps(x, proto)
1167 self.assertEqual(x._reduce_called, 1)
1168 y = self.loads(s)
1169 self.assertEqual(y._reduce_called, 0)
1170
1171 def test_reduce_ex_called(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001172 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001173 x = REX_two()
1174 self.assertEqual(x._proto, None)
1175 s = self.dumps(x, proto)
1176 self.assertEqual(x._proto, proto)
1177 y = self.loads(s)
1178 self.assertEqual(y._proto, None)
1179
1180 def test_reduce_ex_overrides_reduce(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001181 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001182 x = REX_three()
1183 self.assertEqual(x._proto, None)
1184 s = self.dumps(x, proto)
1185 self.assertEqual(x._proto, proto)
1186 y = self.loads(s)
1187 self.assertEqual(y._proto, None)
1188
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001189 def test_reduce_ex_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001190 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001191 x = REX_four()
1192 self.assertEqual(x._proto, None)
1193 s = self.dumps(x, proto)
1194 self.assertEqual(x._proto, proto)
1195 y = self.loads(s)
1196 self.assertEqual(y._proto, proto)
1197
1198 def test_reduce_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001199 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001200 x = REX_five()
1201 self.assertEqual(x._reduce_called, 0)
1202 s = self.dumps(x, proto)
1203 self.assertEqual(x._reduce_called, 1)
1204 y = self.loads(s)
1205 self.assertEqual(y._reduce_called, 1)
1206
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001207 def test_reduce_bad_iterator(self):
1208 # Issue4176: crash when 4th and 5th items of __reduce__()
1209 # are not iterators
1210 class C(object):
1211 def __reduce__(self):
1212 # 4th item is not an iterator
1213 return list, (), None, [], None
1214 class D(object):
1215 def __reduce__(self):
1216 # 5th item is not an iterator
1217 return dict, (), None, None, []
1218
1219 # Protocol 0 is less strict and also accept iterables.
Collin Winterf8089c72009-04-09 16:46:46 +00001220 for proto in protocols:
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001221 try:
1222 self.dumps(C(), proto)
1223 except (AttributeError, pickle.PickleError, cPickle.PickleError):
1224 pass
1225 try:
1226 self.dumps(D(), proto)
1227 except (AttributeError, pickle.PickleError, cPickle.PickleError):
1228 pass
1229
Collin Winterf8089c72009-04-09 16:46:46 +00001230 def test_many_puts_and_gets(self):
1231 # Test that internal data structures correctly deal with lots of
1232 # puts/gets.
1233 keys = ("aaa" + str(i) for i in xrange(100))
1234 large_dict = dict((k, [4, 5, 6]) for k in keys)
1235 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1236
1237 for proto in protocols:
1238 dumped = self.dumps(obj, proto)
1239 loaded = self.loads(dumped)
1240 self.assertEqual(loaded, obj,
1241 "Failed protocol %d: %r != %r"
1242 % (proto, obj, loaded))
1243
Antoine Pitrou74309892009-05-02 21:13:23 +00001244 def test_attribute_name_interning(self):
1245 # Test that attribute names of pickled objects are interned when
1246 # unpickling.
1247 for proto in protocols:
1248 x = C()
1249 x.foo = 42
1250 x.bar = "hello"
1251 s = self.dumps(x, proto)
1252 y = self.loads(s)
1253 x_keys = sorted(x.__dict__)
1254 y_keys = sorted(y.__dict__)
1255 for x_key, y_key in zip(x_keys, y_keys):
1256 self.assertIs(x_key, y_key)
1257
Collin Winterf8089c72009-04-09 16:46:46 +00001258
Guido van Rossum2a30b212003-02-18 22:41:24 +00001259# Test classes for reduce_ex
1260
1261class REX_one(object):
1262 _reduce_called = 0
1263 def __reduce__(self):
1264 self._reduce_called = 1
1265 return REX_one, ()
1266 # No __reduce_ex__ here, but inheriting it from object
1267
1268class REX_two(object):
1269 _proto = None
1270 def __reduce_ex__(self, proto):
1271 self._proto = proto
1272 return REX_two, ()
1273 # No __reduce__ here, but inheriting it from object
1274
1275class REX_three(object):
1276 _proto = None
1277 def __reduce_ex__(self, proto):
1278 self._proto = proto
1279 return REX_two, ()
1280 def __reduce__(self):
1281 raise TestFailed, "This __reduce__ shouldn't be called"
1282
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001283class REX_four(object):
1284 _proto = None
1285 def __reduce_ex__(self, proto):
1286 self._proto = proto
1287 return object.__reduce_ex__(self, proto)
1288 # Calling base class method should succeed
1289
1290class REX_five(object):
1291 _reduce_called = 0
1292 def __reduce__(self):
1293 self._reduce_called = 1
1294 return object.__reduce__(self)
1295 # This one used to fail with infinite recursion
1296
Guido van Rossum2a30b212003-02-18 22:41:24 +00001297# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001298
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001299class MyInt(int):
1300 sample = 1
1301
1302class MyLong(long):
1303 sample = 1L
1304
1305class MyFloat(float):
1306 sample = 1.0
1307
1308class MyComplex(complex):
1309 sample = 1.0 + 0.0j
1310
1311class MyStr(str):
1312 sample = "hello"
1313
1314class MyUnicode(unicode):
1315 sample = u"hello \u1234"
1316
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001317class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001318 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001319
1320class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001321 sample = [1, 2, 3]
1322
1323class MyDict(dict):
1324 sample = {"a": 1, "b": 2}
1325
1326myclasses = [MyInt, MyLong, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001327 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001328 MyStr, MyUnicode,
1329 MyTuple, MyList, MyDict]
1330
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001331
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001332class SlotList(MyList):
1333 __slots__ = ["foo"]
1334
Tim Peterse9ef2032003-02-13 18:42:00 +00001335class SimpleNewObj(object):
1336 def __init__(self, a, b, c):
1337 # raise an error, to make sure this isn't called
1338 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1339
Jeremy Hylton66426532001-10-15 21:38:56 +00001340class AbstractPickleModuleTests(unittest.TestCase):
1341
1342 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001343 import os
1344 f = open(TESTFN, "w")
1345 try:
1346 f.close()
1347 self.assertRaises(ValueError, self.module.dump, 123, f)
1348 finally:
1349 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001350
1351 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001352 import os
1353 f = open(TESTFN, "w")
1354 try:
1355 f.close()
1356 self.assertRaises(ValueError, self.module.dump, 123, f)
1357 finally:
1358 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001359
Collin Winterf8089c72009-04-09 16:46:46 +00001360 def test_load_from_and_dump_to_file(self):
1361 stream = cStringIO.StringIO()
1362 data = [123, {}, 124]
1363 self.module.dump(data, stream)
1364 stream.seek(0)
1365 unpickled = self.module.load(stream)
1366 self.assertEqual(unpickled, data)
1367
Tim Petersc0c93702003-02-13 19:30:57 +00001368 def test_highest_protocol(self):
1369 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
1370 self.assertEqual(self.module.HIGHEST_PROTOCOL, 2)
1371
Martin v. Löwis544f1192004-07-27 05:22:33 +00001372 def test_callapi(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001373 f = cStringIO.StringIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001374 # With and without keyword arguments
1375 self.module.dump(123, f, -1)
1376 self.module.dump(123, file=f, protocol=-1)
1377 self.module.dumps(123, -1)
1378 self.module.dumps(123, protocol=-1)
1379 self.module.Pickler(f, -1)
1380 self.module.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001381
Amaury Forgeot d'Arc74b30162009-07-23 19:26:02 +00001382 def test_incomplete_input(self):
1383 s = StringIO.StringIO("X''.")
1384 self.assertRaises(EOFError, self.module.load, s)
1385
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001386 def test_restricted(self):
1387 # issue7128: cPickle failed in restricted mode
1388 builtins = {self.module.__name__: self.module,
1389 '__import__': __import__}
1390 d = {}
1391 teststr = "def f(): {0}.dumps(0)".format(self.module.__name__)
1392 exec teststr in {'__builtins__': builtins}, d
1393 d['f']()
1394
Antoine Pitrou0d423b82010-01-07 17:46:49 +00001395 def test_bad_input(self):
1396 # Test issue4298
1397 s = '\x58\0\0\0\x54'
1398 self.assertRaises(EOFError, self.module.loads, s)
1399 # Test issue7455
1400 s = '0'
1401 # XXX Why doesn't pickle raise UnpicklingError?
1402 self.assertRaises((IndexError, cPickle.UnpicklingError),
1403 self.module.loads, s)
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001404
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001405class AbstractPersistentPicklerTests(unittest.TestCase):
1406
1407 # This class defines persistent_id() and persistent_load()
1408 # functions that should be used by the pickler. All even integers
1409 # are pickled using persistent ids.
1410
1411 def persistent_id(self, object):
1412 if isinstance(object, int) and object % 2 == 0:
1413 self.id_count += 1
1414 return str(object)
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001415 elif object == "test_false_value":
1416 self.false_count += 1
1417 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001418 else:
1419 return None
1420
1421 def persistent_load(self, oid):
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001422 if not oid:
1423 self.load_false_count += 1
1424 return "test_false_value"
1425 else:
1426 self.load_count += 1
1427 object = int(oid)
1428 assert object % 2 == 0
1429 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001430
1431 def test_persistence(self):
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001432 L = range(10) + ["test_false_value"]
1433 for proto in protocols:
1434 self.id_count = 0
1435 self.false_count = 0
1436 self.load_false_count = 0
1437 self.load_count = 0
1438 self.assertEqual(self.loads(self.dumps(L, proto)), L)
1439 self.assertEqual(self.id_count, 5)
1440 self.assertEqual(self.false_count, 1)
1441 self.assertEqual(self.load_count, 5)
1442 self.assertEqual(self.load_false_count, 1)
Collin Winterf8089c72009-04-09 16:46:46 +00001443
1444class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1445
1446 pickler_class = None
1447 unpickler_class = None
1448
1449 def setUp(self):
1450 assert self.pickler_class
1451 assert self.unpickler_class
1452
1453 def test_clear_pickler_memo(self):
1454 # To test whether clear_memo() has any effect, we pickle an object,
1455 # then pickle it again without clearing the memo; the two serialized
1456 # forms should be different. If we clear_memo() and then pickle the
1457 # object again, the third serialized form should be identical to the
1458 # first one we obtained.
1459 data = ["abcdefg", "abcdefg", 44]
1460 f = cStringIO.StringIO()
1461 pickler = self.pickler_class(f)
1462
1463 pickler.dump(data)
1464 first_pickled = f.getvalue()
1465
1466 # Reset StringIO object.
1467 f.seek(0)
1468 f.truncate()
1469
1470 pickler.dump(data)
1471 second_pickled = f.getvalue()
1472
1473 # Reset the Pickler and StringIO objects.
1474 pickler.clear_memo()
1475 f.seek(0)
1476 f.truncate()
1477
1478 pickler.dump(data)
1479 third_pickled = f.getvalue()
1480
1481 self.assertNotEqual(first_pickled, second_pickled)
1482 self.assertEqual(first_pickled, third_pickled)
1483
1484 def test_priming_pickler_memo(self):
1485 # Verify that we can set the Pickler's memo attribute.
1486 data = ["abcdefg", "abcdefg", 44]
1487 f = cStringIO.StringIO()
1488 pickler = self.pickler_class(f)
1489
1490 pickler.dump(data)
1491 first_pickled = f.getvalue()
1492
1493 f = cStringIO.StringIO()
1494 primed = self.pickler_class(f)
1495 primed.memo = pickler.memo
1496
1497 primed.dump(data)
1498 primed_pickled = f.getvalue()
1499
1500 self.assertNotEqual(first_pickled, primed_pickled)
1501
1502 def test_priming_unpickler_memo(self):
1503 # Verify that we can set the Unpickler's memo attribute.
1504 data = ["abcdefg", "abcdefg", 44]
1505 f = cStringIO.StringIO()
1506 pickler = self.pickler_class(f)
1507
1508 pickler.dump(data)
1509 first_pickled = f.getvalue()
1510
1511 f = cStringIO.StringIO()
1512 primed = self.pickler_class(f)
1513 primed.memo = pickler.memo
1514
1515 primed.dump(data)
1516 primed_pickled = f.getvalue()
1517
1518 unpickler = self.unpickler_class(cStringIO.StringIO(first_pickled))
1519 unpickled_data1 = unpickler.load()
1520
1521 self.assertEqual(unpickled_data1, data)
1522
1523 primed = self.unpickler_class(cStringIO.StringIO(primed_pickled))
1524 primed.memo = unpickler.memo
1525 unpickled_data2 = primed.load()
1526
1527 primed.memo.clear()
1528
1529 self.assertEqual(unpickled_data2, data)
1530 self.assertTrue(unpickled_data2 is unpickled_data1)
1531
1532 def test_reusing_unpickler_objects(self):
1533 data1 = ["abcdefg", "abcdefg", 44]
1534 f = cStringIO.StringIO()
1535 pickler = self.pickler_class(f)
1536 pickler.dump(data1)
1537 pickled1 = f.getvalue()
1538
1539 data2 = ["abcdefg", 44, 44]
1540 f = cStringIO.StringIO()
1541 pickler = self.pickler_class(f)
1542 pickler.dump(data2)
1543 pickled2 = f.getvalue()
1544
1545 f = cStringIO.StringIO()
1546 f.write(pickled1)
1547 f.seek(0)
1548 unpickler = self.unpickler_class(f)
1549 self.assertEqual(unpickler.load(), data1)
1550
1551 f.seek(0)
1552 f.truncate()
1553 f.write(pickled2)
1554 f.seek(0)
1555 self.assertEqual(unpickler.load(), data2)
Serhiy Storchakacdc7a912013-02-12 21:36:47 +02001556
1557class BigmemPickleTests(unittest.TestCase):
1558
1559 # Memory requirements: 1 byte per character for input strings, 1 byte
1560 # for pickled data, 1 byte for unpickled strings, 1 byte for internal
1561 # buffer and 1 byte of free space for resizing of internal buffer.
1562
1563 @precisionbigmemtest(size=_2G + 100*_1M, memuse=5)
1564 def test_huge_strlist(self, size):
1565 chunksize = 2**20
1566 data = []
1567 while size > chunksize:
1568 data.append('x' * chunksize)
1569 size -= chunksize
1570 chunksize += 1
1571 data.append('y' * size)
1572
1573 try:
1574 for proto in protocols:
1575 try:
1576 pickled = self.dumps(data, proto)
1577 res = self.loads(pickled)
1578 self.assertEqual(res, data)
1579 finally:
1580 res = None
1581 pickled = None
1582 finally:
1583 data = None