blob: 022789d495e54d8f24e217e3447d6464623956dd [file] [log] [blame]
Serhiy Storchaka22afc502015-09-29 15:51:40 +03001# -*- coding: utf-8 -*-
Jeremy Hylton66426532001-10-15 21:38:56 +00002import unittest
Tim Peters4190fb82003-02-02 16:09:05 +00003import pickle
Tim Peters8587b3c2003-02-13 15:44:41 +00004import cPickle
Amaury Forgeot d'Arc74b30162009-07-23 19:26:02 +00005import StringIO
Collin Winterf8089c72009-04-09 16:46:46 +00006import cStringIO
Tim Peters31f119e2003-02-03 16:20:13 +00007import pickletools
Georg Brandldffbf5f2008-05-20 07:49:57 +00008import copy_reg
Serhiy Storchakabf19ce22015-11-29 13:12:40 +02009import sys
Tim Peters4190fb82003-02-02 16:09:05 +000010
Serhiy Storchakabf19ce22015-11-29 13:12:40 +020011from test import test_support as support
Zachary Ware916c7c72015-11-27 01:21:51 -060012from test.test_support import TestFailed, verbose, have_unicode, TESTFN
Benjamin Petersond627e122013-03-30 10:36:31 -040013try:
14 from test.test_support import _2G, _1M, precisionbigmemtest
15except ImportError:
16 # this import might fail when run on older Python versions by test_xpickle
Benjamin Petersonf3ad0302013-03-30 15:30:28 -040017 _2G = _1M = 0
Benjamin Petersond627e122013-03-30 10:36:31 -040018 def precisionbigmemtest(*args, **kwargs):
19 return lambda self: None
Tim Peterse089c682001-04-10 03:41:41 +000020
Tim Petersee1a53c2003-02-02 02:57:53 +000021# Tests that try a number of pickle protocols should have a
22# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000023# kind of outer loop.
24assert pickle.HIGHEST_PROTOCOL == cPickle.HIGHEST_PROTOCOL == 2
25protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000026
Collin Winterf8089c72009-04-09 16:46:46 +000027# Copy of test.test_support.run_with_locale. This is needed to support Python
28# 2.4, which didn't include it. This is all to support test_xpickle, which
29# bounces pickled objects through older Python versions to test backwards
30# compatibility.
31def run_with_locale(catstr, *locales):
32 def decorator(func):
33 def inner(*args, **kwds):
34 try:
35 import locale
36 category = getattr(locale, catstr)
37 orig_locale = locale.setlocale(category)
38 except AttributeError:
39 # if the test author gives us an invalid category string
40 raise
41 except:
42 # cannot retrieve original locale, so do nothing
43 locale = orig_locale = None
44 else:
45 for loc in locales:
46 try:
47 locale.setlocale(category, loc)
48 break
49 except:
50 pass
51
52 # now run the function, resetting the locale on exceptions
53 try:
54 return func(*args, **kwds)
55 finally:
56 if locale and orig_locale:
57 locale.setlocale(category, orig_locale)
58 inner.func_name = func.func_name
59 inner.__doc__ = func.__doc__
60 return inner
61 return decorator
62
Serhiy Storchaka7c033e62016-03-06 09:05:47 +020063def no_tracing(func):
64 """Decorator to temporarily turn off tracing for the duration of a test."""
65 if not hasattr(sys, 'gettrace'):
66 return func
67 else:
68 def wrapper(*args, **kwargs):
69 original_trace = sys.gettrace()
70 try:
71 sys.settrace(None)
72 return func(*args, **kwargs)
73 finally:
74 sys.settrace(original_trace)
75 wrapper.__name__ = func.__name__
76 return wrapper
77
Tim Peters22e71712003-02-03 22:27:38 +000078
79# Return True if opcode code appears in the pickle, else False.
80def opcode_in_pickle(code, pickle):
81 for op, dummy, dummy in pickletools.genops(pickle):
82 if op.code == code:
83 return True
84 return False
85
Tim Peters8d2613a2003-02-11 16:40:16 +000086# Return the number of times opcode code appears in pickle.
87def count_opcode(code, pickle):
88 n = 0
89 for op, dummy, dummy in pickletools.genops(pickle):
90 if op.code == code:
91 n += 1
92 return n
93
Serhiy Storchaka7c033e62016-03-06 09:05:47 +020094class UnseekableIO(StringIO.StringIO):
95 def peek(self, *args):
96 raise NotImplementedError
97
98 def seek(self, *args):
99 raise NotImplementedError
100
101 def tell(self):
102 raise NotImplementedError
103
Tim Peters3e667d52003-02-04 21:47:44 +0000104# We can't very well test the extension registry without putting known stuff
105# in it, but we have to be careful to restore its original state. Code
106# should do this:
107#
108# e = ExtensionSaver(extension_code)
109# try:
110# fiddle w/ the extension registry's stuff for extension_code
111# finally:
112# e.restore()
113
114class ExtensionSaver:
115 # Remember current registration for code (if any), and remove it (if
116 # there is one).
117 def __init__(self, code):
118 self.code = code
Georg Brandldffbf5f2008-05-20 07:49:57 +0000119 if code in copy_reg._inverted_registry:
120 self.pair = copy_reg._inverted_registry[code]
121 copy_reg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000122 else:
123 self.pair = None
124
125 # Restore previous registration for code.
126 def restore(self):
127 code = self.code
Georg Brandldffbf5f2008-05-20 07:49:57 +0000128 curpair = copy_reg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +0000129 if curpair is not None:
Georg Brandldffbf5f2008-05-20 07:49:57 +0000130 copy_reg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000131 pair = self.pair
132 if pair is not None:
Georg Brandldffbf5f2008-05-20 07:49:57 +0000133 copy_reg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000134
Jeremy Hylton66426532001-10-15 21:38:56 +0000135class C:
136 def __cmp__(self, other):
137 return cmp(self.__dict__, other.__dict__)
138
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300139class D(C):
140 def __init__(self, arg):
141 pass
142
143class E(C):
144 def __getinitargs__(self):
145 return ()
146
Serhiy Storchakada87e452015-11-07 11:15:32 +0200147class H(object):
148 pass
149
150# Hashable mutable key
151class K(object):
152 def __init__(self, value):
153 self.value = value
154
155 def __reduce__(self):
156 # Shouldn't support the recursion itself
157 return K, (self.value,)
158
Jeremy Hylton66426532001-10-15 21:38:56 +0000159import __main__
160__main__.C = C
161C.__module__ = "__main__"
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300162__main__.D = D
163D.__module__ = "__main__"
164__main__.E = E
165E.__module__ = "__main__"
Serhiy Storchakada87e452015-11-07 11:15:32 +0200166__main__.H = H
167H.__module__ = "__main__"
168__main__.K = K
169K.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000170
171class myint(int):
172 def __init__(self, x):
173 self.str = str(x)
174
175class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000176
Jeremy Hylton66426532001-10-15 21:38:56 +0000177 def __init__(self, a, b):
178 self.a = a
179 self.b = b
180
181 def __getinitargs__(self):
182 return self.a, self.b
183
Guido van Rossum04a86612001-12-19 16:58:54 +0000184class metaclass(type):
185 pass
186
187class use_metaclass(object):
188 __metaclass__ = metaclass
189
Antoine Pitrou561a8212011-10-04 09:34:48 +0200190class pickling_metaclass(type):
191 def __eq__(self, other):
192 return (type(self) == type(other) and
193 self.reduce_args == other.reduce_args)
194
195 def __reduce__(self):
196 return (create_dynamic_class, self.reduce_args)
197
Ezio Melotti030aa352011-11-06 18:50:32 +0200198 __hash__ = None
199
Antoine Pitrou561a8212011-10-04 09:34:48 +0200200def create_dynamic_class(name, bases):
201 result = pickling_metaclass(name, bases, dict())
202 result.reduce_args = (name, bases)
203 return result
204
Tim Peters70b02d72003-02-02 17:26:40 +0000205# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
206# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000207
Jeremy Hylton66426532001-10-15 21:38:56 +0000208# break into multiple strings to avoid confusing font-lock-mode
Tim Peters70b02d72003-02-02 17:26:40 +0000209DATA0 = """(lp1
Tim Peterse9358162001-01-22 22:05:20 +0000210I0
211aL1L
Tim Peters461922a2001-04-09 20:07:05 +0000212aF2
Tim Peterse9358162001-01-22 22:05:20 +0000213ac__builtin__
214complex
Tim Peters461922a2001-04-09 20:07:05 +0000215p2
216""" + \
217"""(F3
218F0
219tRp3
220aI1
221aI-1
222aI255
223aI-255
224aI-256
225aI65535
226aI-65535
227aI-65536
228aI2147483647
229aI-2147483647
230aI-2147483648
231a""" + \
232"""(S'abc'
Tim Peterse9358162001-01-22 22:05:20 +0000233p4
234g4
Tim Peters461922a2001-04-09 20:07:05 +0000235""" + \
Guido van Rossum42f92da2001-04-16 00:28:21 +0000236"""(i__main__
Tim Peterse9358162001-01-22 22:05:20 +0000237C
238p5
Tim Peters461922a2001-04-09 20:07:05 +0000239""" + \
Tim Peterse9358162001-01-22 22:05:20 +0000240"""(dp6
241S'foo'
242p7
243I1
244sS'bar'
245p8
246I2
247sbg5
248tp9
249ag9
250aI5
251a.
252"""
253
Tim Peters70b02d72003-02-02 17:26:40 +0000254# Disassembly of DATA0.
255DATA0_DIS = """\
256 0: ( MARK
257 1: l LIST (MARK at 0)
258 2: p PUT 1
259 5: I INT 0
260 8: a APPEND
261 9: L LONG 1L
262 13: a APPEND
263 14: F FLOAT 2.0
264 17: a APPEND
265 18: c GLOBAL '__builtin__ complex'
266 39: p PUT 2
267 42: ( MARK
268 43: F FLOAT 3.0
269 46: F FLOAT 0.0
270 49: t TUPLE (MARK at 42)
271 50: R REDUCE
272 51: p PUT 3
273 54: a APPEND
274 55: I INT 1
275 58: a APPEND
276 59: I INT -1
277 63: a APPEND
278 64: I INT 255
279 69: a APPEND
280 70: I INT -255
281 76: a APPEND
282 77: I INT -256
283 83: a APPEND
284 84: I INT 65535
285 91: a APPEND
286 92: I INT -65535
287 100: a APPEND
288 101: I INT -65536
289 109: a APPEND
290 110: I INT 2147483647
291 122: a APPEND
292 123: I INT -2147483647
293 136: a APPEND
294 137: I INT -2147483648
295 150: a APPEND
296 151: ( MARK
297 152: S STRING 'abc'
298 159: p PUT 4
299 162: g GET 4
300 165: ( MARK
301 166: i INST '__main__ C' (MARK at 165)
302 178: p PUT 5
303 181: ( MARK
304 182: d DICT (MARK at 181)
305 183: p PUT 6
306 186: S STRING 'foo'
307 193: p PUT 7
308 196: I INT 1
309 199: s SETITEM
310 200: S STRING 'bar'
311 207: p PUT 8
312 210: I INT 2
313 213: s SETITEM
314 214: b BUILD
315 215: g GET 5
316 218: t TUPLE (MARK at 151)
317 219: p PUT 9
318 222: a APPEND
319 223: g GET 9
320 226: a APPEND
321 227: I INT 5
322 230: a APPEND
323 231: . STOP
324highest protocol among opcodes = 0
325"""
326
327DATA1 = (']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00'
328 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00'
329 '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff'
330 '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff'
331 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00'
332 '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n'
333 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh'
334 '\x06tq\nh\nK\x05e.'
335 )
336
337# Disassembly of DATA1.
338DATA1_DIS = """\
339 0: ] EMPTY_LIST
340 1: q BINPUT 1
341 3: ( MARK
342 4: K BININT1 0
343 6: L LONG 1L
344 10: G BINFLOAT 2.0
345 19: c GLOBAL '__builtin__ complex'
346 40: q BINPUT 2
347 42: ( MARK
348 43: G BINFLOAT 3.0
349 52: G BINFLOAT 0.0
350 61: t TUPLE (MARK at 42)
351 62: R REDUCE
352 63: q BINPUT 3
353 65: K BININT1 1
354 67: J BININT -1
355 72: K BININT1 255
356 74: J BININT -255
357 79: J BININT -256
358 84: M BININT2 65535
359 87: J BININT -65535
360 92: J BININT -65536
361 97: J BININT 2147483647
362 102: J BININT -2147483647
363 107: J BININT -2147483648
364 112: ( MARK
365 113: U SHORT_BINSTRING 'abc'
366 118: q BINPUT 4
367 120: h BINGET 4
368 122: ( MARK
369 123: c GLOBAL '__main__ C'
370 135: q BINPUT 5
371 137: o OBJ (MARK at 122)
372 138: q BINPUT 6
373 140: } EMPTY_DICT
374 141: q BINPUT 7
375 143: ( MARK
376 144: U SHORT_BINSTRING 'foo'
377 149: q BINPUT 8
378 151: K BININT1 1
379 153: U SHORT_BINSTRING 'bar'
380 158: q BINPUT 9
381 160: K BININT1 2
382 162: u SETITEMS (MARK at 143)
383 163: b BUILD
384 164: h BINGET 6
385 166: t TUPLE (MARK at 112)
386 167: q BINPUT 10
387 169: h BINGET 10
388 171: K BININT1 5
389 173: e APPENDS (MARK at 3)
390 174: . STOP
391highest protocol among opcodes = 1
392"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000393
Tim Petersfc273752003-03-02 04:54:24 +0000394DATA2 = ('\x80\x02]q\x01(K\x00\x8a\x01\x01G@\x00\x00\x00\x00\x00\x00\x00'
395 'c__builtin__\ncomplex\nq\x02G@\x08\x00\x00\x00\x00\x00\x00G\x00'
396 '\x00\x00\x00\x00\x00\x00\x00\x86Rq\x03K\x01J\xff\xff\xff\xffK'
397 '\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xff'
398 'J\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00'
399 '\x80(U\x03abcq\x04h\x04(c__main__\nC\nq\x05oq\x06}q\x07(U\x03foo'
400 'q\x08K\x01U\x03barq\tK\x02ubh\x06tq\nh\nK\x05e.')
401
402# Disassembly of DATA2.
403DATA2_DIS = """\
404 0: \x80 PROTO 2
405 2: ] EMPTY_LIST
406 3: q BINPUT 1
407 5: ( MARK
408 6: K BININT1 0
409 8: \x8a LONG1 1L
410 11: G BINFLOAT 2.0
411 20: c GLOBAL '__builtin__ complex'
412 41: q BINPUT 2
413 43: G BINFLOAT 3.0
414 52: G BINFLOAT 0.0
415 61: \x86 TUPLE2
416 62: R REDUCE
417 63: q BINPUT 3
418 65: K BININT1 1
419 67: J BININT -1
420 72: K BININT1 255
421 74: J BININT -255
422 79: J BININT -256
423 84: M BININT2 65535
424 87: J BININT -65535
425 92: J BININT -65536
426 97: J BININT 2147483647
427 102: J BININT -2147483647
428 107: J BININT -2147483648
429 112: ( MARK
430 113: U SHORT_BINSTRING 'abc'
431 118: q BINPUT 4
432 120: h BINGET 4
433 122: ( MARK
434 123: c GLOBAL '__main__ C'
435 135: q BINPUT 5
436 137: o OBJ (MARK at 122)
437 138: q BINPUT 6
438 140: } EMPTY_DICT
439 141: q BINPUT 7
440 143: ( MARK
441 144: U SHORT_BINSTRING 'foo'
442 149: q BINPUT 8
443 151: K BININT1 1
444 153: U SHORT_BINSTRING 'bar'
445 158: q BINPUT 9
446 160: K BININT1 2
447 162: u SETITEMS (MARK at 143)
448 163: b BUILD
449 164: h BINGET 6
450 166: t TUPLE (MARK at 112)
451 167: q BINPUT 10
452 169: h BINGET 10
453 171: K BININT1 5
454 173: e APPENDS (MARK at 5)
455 174: . STOP
456highest protocol among opcodes = 2
457"""
458
Jeremy Hylton66426532001-10-15 21:38:56 +0000459def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000460 c = C()
461 c.foo = 1
462 c.bar = 2
463 x = [0, 1L, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000464 # Append some integer test cases at cPickle.c's internal size
465 # cutoffs.
466 uint1max = 0xff
467 uint2max = 0xffff
468 int4max = 0x7fffffff
469 x.extend([1, -1,
470 uint1max, -uint1max, -uint1max-1,
471 uint2max, -uint2max, -uint2max-1,
472 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000473 y = ('abc', 'abc', c, c)
474 x.append(y)
475 x.append(y)
476 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000477 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000478
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300479
480class AbstractUnpickleTests(unittest.TestCase):
481 # Subclass must define self.loads, self.error.
Tim Petersc58440f2001-04-09 17:16:31 +0000482
Jeremy Hylton66426532001-10-15 21:38:56 +0000483 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000484
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300485 def assert_is_copy(self, obj, objcopy, msg=None):
486 """Utility method to verify if two objects are copies of each others.
487 """
488 if msg is None:
489 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
490 self.assertEqual(obj, objcopy, msg=msg)
491 self.assertIs(type(obj), type(objcopy), msg=msg)
492 if hasattr(obj, '__dict__'):
493 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
494 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
495 if hasattr(obj, '__slots__'):
496 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
497 for slot in obj.__slots__:
498 self.assertEqual(
499 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
500 self.assertEqual(getattr(obj, slot, None),
501 getattr(objcopy, slot, None), msg=msg)
502
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200503 def check_unpickling_error(self, errors, data):
Serhiy Storchakad26b6632015-11-29 16:13:51 +0200504 try:
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200505 try:
506 self.loads(data)
507 except:
508 if support.verbose > 1:
Serhiy Storchakad26b6632015-11-29 16:13:51 +0200509 exc_type, exc, tb = sys.exc_info()
510 print '%-32r - %s: %s' % (data, exc_type.__name__, exc)
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200511 raise
Serhiy Storchakad26b6632015-11-29 16:13:51 +0200512 except errors:
513 pass
514 else:
515 try:
516 exc_name = errors.__name__
517 except AttributeError:
518 exc_name = str(errors)
519 raise self.failureException('%s not raised' % exc_name)
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200520
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300521 def test_load_from_canned_string(self):
522 expected = self._testdata
523 for canned in DATA0, DATA1, DATA2:
524 got = self.loads(canned)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300525 self.assert_is_copy(expected, got)
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300526
527 def test_garyp(self):
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200528 self.check_unpickling_error(self.error, 'garyp')
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300529
530 def test_maxint64(self):
531 maxint64 = (1L << 63) - 1
532 data = 'I' + str(maxint64) + '\n.'
533 got = self.loads(data)
534 self.assertEqual(got, maxint64)
535
536 # Try too with a bogus literal.
537 data = 'I' + str(maxint64) + 'JUNK\n.'
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200538 self.check_unpickling_error(ValueError, data)
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300539
540 def test_insecure_strings(self):
541 insecure = ["abc", "2 + 2", # not quoted
542 #"'abc' + 'def'", # not a single quoted string
543 "'abc", # quote is not closed
544 "'abc\"", # open quote and close quote don't match
545 "'abc' ?", # junk after close quote
546 "'\\'", # trailing backslash
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300547 # issue #17710
548 "'", '"',
549 "' ", '" ',
550 '\'"', '"\'',
551 " ''", ' ""',
552 ' ',
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300553 # some tests of the quoting rules
554 #"'abc\"\''",
555 #"'\\\\a\'\'\'\\\'\\\\\''",
556 ]
557 for s in insecure:
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300558 buf = "S" + s + "\n."
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200559 self.check_unpickling_error(ValueError, buf)
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300560
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300561 def test_correctly_quoted_string(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300562 goodpickles = [("S''\n.", ''),
563 ('S""\n.', ''),
564 ('S"\\n"\n.', '\n'),
565 ("S'\\n'\n.", '\n')]
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300566 for p, expected in goodpickles:
567 self.assertEqual(self.loads(p), expected)
568
569 def test_load_classic_instance(self):
570 # See issue5180. Test loading 2.x pickles that
571 # contain an instance of old style class.
572 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
573 xname = X.__name__.encode('ascii')
574 # Protocol 0 (text mode pickle):
575 """
576 0: ( MARK
577 1: i INST '__main__ X' (MARK at 0)
578 13: p PUT 0
579 16: ( MARK
580 17: d DICT (MARK at 16)
581 18: p PUT 1
582 21: b BUILD
583 22: . STOP
584 """
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300585 pickle0 = ("(i__main__\n"
586 "X\n"
587 "p0\n"
588 "(dp1\nb.").replace('X', xname)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300589 self.assert_is_copy(X(*args), self.loads(pickle0))
590
591 # Protocol 1 (binary mode pickle)
592 """
593 0: ( MARK
594 1: c GLOBAL '__main__ X'
595 13: q BINPUT 0
596 15: o OBJ (MARK at 0)
597 16: q BINPUT 1
598 18: } EMPTY_DICT
599 19: q BINPUT 2
600 21: b BUILD
601 22: . STOP
602 """
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300603 pickle1 = ('(c__main__\n'
604 'X\n'
605 'q\x00oq\x01}q\x02b.').replace('X', xname)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300606 self.assert_is_copy(X(*args), self.loads(pickle1))
607
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300608 # Protocol 2 (pickle2 = '\x80\x02' + pickle1)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300609 """
610 0: \x80 PROTO 2
611 2: ( MARK
612 3: c GLOBAL '__main__ X'
613 15: q BINPUT 0
614 17: o OBJ (MARK at 2)
615 18: q BINPUT 1
616 20: } EMPTY_DICT
617 21: q BINPUT 2
618 23: b BUILD
619 24: . STOP
620 """
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300621 pickle2 = ('\x80\x02(c__main__\n'
622 'X\n'
623 'q\x00oq\x01}q\x02b.').replace('X', xname)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300624 self.assert_is_copy(X(*args), self.loads(pickle2))
625
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300626 def test_load_str(self):
627 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300628 self.assertEqual(self.loads("S'a\\x00\\xa0'\n."), 'a\x00\xa0')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300629 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300630 self.assertEqual(self.loads('U\x03a\x00\xa0.'), 'a\x00\xa0')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300631 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300632 self.assertEqual(self.loads('\x80\x02U\x03a\x00\xa0.'), 'a\x00\xa0')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300633
634 def test_load_unicode(self):
635 # From Python 2: pickle.dumps(u'Ï€', protocol=0)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300636 self.assertEqual(self.loads('V\\u03c0\n.'), u'Ï€')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300637 # From Python 2: pickle.dumps(u'Ï€', protocol=1)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300638 self.assertEqual(self.loads('X\x02\x00\x00\x00\xcf\x80.'), u'Ï€')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300639 # From Python 2: pickle.dumps(u'Ï€', protocol=2)
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300640 self.assertEqual(self.loads('\x80\x02X\x02\x00\x00\x00\xcf\x80.'), u'Ï€')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300641
642 def test_constants(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300643 self.assertIsNone(self.loads('N.'))
644 self.assertIs(self.loads('\x88.'), True)
645 self.assertIs(self.loads('\x89.'), False)
646 self.assertIs(self.loads('I01\n.'), True)
647 self.assertIs(self.loads('I00\n.'), False)
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300648
649 def test_misc_get(self):
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200650 self.check_unpickling_error(self.error, 'g0\np0\n')
651 self.check_unpickling_error(self.error, 'h\x00q\x00')
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300652
653 def test_get(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300654 pickled = '((lp100000\ng100000\nt.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300655 unpickled = self.loads(pickled)
656 self.assertEqual(unpickled, ([],)*2)
657 self.assertIs(unpickled[0], unpickled[1])
658
659 def test_binget(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300660 pickled = '(]q\xffh\xfft.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300661 unpickled = self.loads(pickled)
662 self.assertEqual(unpickled, ([],)*2)
663 self.assertIs(unpickled[0], unpickled[1])
664
665 def test_long_binget(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300666 pickled = '(]r\x00\x00\x01\x00j\x00\x00\x01\x00t.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300667 unpickled = self.loads(pickled)
668 self.assertEqual(unpickled, ([],)*2)
669 self.assertIs(unpickled[0], unpickled[1])
670
671 def test_dup(self):
Serhiy Storchakaf6eced52015-10-02 20:23:46 +0300672 pickled = '((l2t.'
Serhiy Storchaka22afc502015-09-29 15:51:40 +0300673 unpickled = self.loads(pickled)
674 self.assertEqual(unpickled, ([],)*2)
675 self.assertIs(unpickled[0], unpickled[1])
676
Serhiy Storchaka5c137662015-11-23 15:20:43 +0200677 def test_bad_stack(self):
678 badpickles = [
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200679 '.', # STOP
680 '0', # POP
681 '1', # POP_MARK
682 '2', # DUP
683 # '(2', # PyUnpickler doesn't raise
684 'R', # REDUCE
685 ')R',
686 'a', # APPEND
687 'Na',
688 'b', # BUILD
689 'Nb',
690 'd', # DICT
691 'e', # APPENDS
692 # '(e', # PyUnpickler raises AttributeError
693 'i__builtin__\nlist\n', # INST
694 'l', # LIST
695 'o', # OBJ
696 '(o',
697 'p1\n', # PUT
698 'q\x00', # BINPUT
699 'r\x00\x00\x00\x00', # LONG_BINPUT
700 's', # SETITEM
701 'Ns',
702 'NNs',
703 't', # TUPLE
704 'u', # SETITEMS
705 # '(u', # PyUnpickler doesn't raise
706 '}(Nu',
707 '\x81', # NEWOBJ
708 ')\x81',
709 '\x85', # TUPLE1
710 '\x86', # TUPLE2
711 'N\x86',
712 '\x87', # TUPLE3
713 'N\x87',
714 'NN\x87',
Serhiy Storchaka5c137662015-11-23 15:20:43 +0200715 ]
716 for p in badpickles:
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200717 self.check_unpickling_error(self.bad_stack_errors, p)
Serhiy Storchaka5c137662015-11-23 15:20:43 +0200718
719 def test_bad_mark(self):
720 badpickles = [
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200721 # 'N(.', # STOP
722 'N(2', # DUP
723 'c__builtin__\nlist\n)(R', # REDUCE
724 'c__builtin__\nlist\n()R',
725 ']N(a', # APPEND
726 # BUILD
727 'c__builtin__\nValueError\n)R}(b',
728 'c__builtin__\nValueError\n)R(}b',
729 '(Nd', # DICT
730 'N(p1\n', # PUT
731 'N(q\x00', # BINPUT
732 'N(r\x00\x00\x00\x00', # LONG_BINPUT
733 '}NN(s', # SETITEM
734 '}N(Ns',
735 '}(NNs',
736 '}((u', # SETITEMS
737 # NEWOBJ
738 'c__builtin__\nlist\n)(\x81',
739 'c__builtin__\nlist\n()\x81',
740 'N(\x85', # TUPLE1
741 'NN(\x86', # TUPLE2
742 'N(N\x86',
743 'NNN(\x87', # TUPLE3
744 'NN(N\x87',
745 'N(NN\x87',
Serhiy Storchaka5c137662015-11-23 15:20:43 +0200746 ]
747 for p in badpickles:
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200748 self.check_unpickling_error(self.bad_mark_errors, p)
749
750 def test_truncated_data(self):
Serhiy Storchaka81772f12015-11-29 19:20:11 +0200751 self.check_unpickling_error(EOFError, '')
752 self.check_unpickling_error(EOFError, 'N')
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200753 badpickles = [
754 'F', # FLOAT
755 'F0.0',
756 'F0.00',
757 'G', # BINFLOAT
758 'G\x00\x00\x00\x00\x00\x00\x00',
759 'I', # INT
760 'I0',
761 'J', # BININT
762 'J\x00\x00\x00',
763 'K', # BININT1
764 'L', # LONG
765 'L0',
766 'L10',
767 'L0L',
768 'L10L',
769 'M', # BININT2
770 'M\x00',
771 # 'P', # PERSID
772 # 'Pabc',
773 'S', # STRING
Serhiy Storchaka03f3c2f2015-11-29 20:18:27 +0200774 "S'abc'",
Serhiy Storchakabf19ce22015-11-29 13:12:40 +0200775 'T', # BINSTRING
776 'T\x03\x00\x00',
777 'T\x03\x00\x00\x00',
778 'T\x03\x00\x00\x00ab',
779 'U', # SHORT_BINSTRING
780 'U\x03',
781 'U\x03ab',
782 'V', # UNICODE
783 'Vabc',
784 'X', # BINUNICODE
785 'X\x03\x00\x00',
786 'X\x03\x00\x00\x00',
787 'X\x03\x00\x00\x00ab',
788 '(c', # GLOBAL
789 '(c__builtin__',
790 '(c__builtin__\n',
791 '(c__builtin__\nlist',
792 'Ng', # GET
793 'Ng0',
794 '(i', # INST
795 '(i__builtin__',
796 '(i__builtin__\n',
797 '(i__builtin__\nlist',
798 'Nh', # BINGET
799 'Nj', # LONG_BINGET
800 'Nj\x00\x00\x00',
801 'Np', # PUT
802 'Np0',
803 'Nq', # BINPUT
804 'Nr', # LONG_BINPUT
805 'Nr\x00\x00\x00',
806 '\x80', # PROTO
807 '\x82', # EXT1
808 '\x83', # EXT2
809 '\x84\x01',
810 '\x84', # EXT4
811 '\x84\x01\x00\x00',
812 '\x8a', # LONG1
813 '\x8b', # LONG4
814 '\x8b\x00\x00\x00',
815 ]
816 for p in badpickles:
817 self.check_unpickling_error(self.truncated_errors, p)
Serhiy Storchaka5c137662015-11-23 15:20:43 +0200818
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300819
820class AbstractPickleTests(unittest.TestCase):
821 # Subclass must define self.dumps, self.loads.
822
823 _testdata = AbstractUnpickleTests._testdata
824
Jeremy Hylton66426532001-10-15 21:38:56 +0000825 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000826 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000827
Jeremy Hylton66426532001-10-15 21:38:56 +0000828 def test_misc(self):
829 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000830 for proto in protocols:
831 x = myint(4)
832 s = self.dumps(x, proto)
833 y = self.loads(s)
834 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000835
Tim Peters70b02d72003-02-02 17:26:40 +0000836 x = (1, ())
837 s = self.dumps(x, proto)
838 y = self.loads(s)
839 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000840
Tim Peters70b02d72003-02-02 17:26:40 +0000841 x = initarg(1, x)
842 s = self.dumps(x, proto)
843 y = self.loads(s)
844 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000845
Jeremy Hylton66426532001-10-15 21:38:56 +0000846 # XXX test __reduce__ protocol?
847
Tim Peters70b02d72003-02-02 17:26:40 +0000848 def test_roundtrip_equality(self):
849 expected = self._testdata
850 for proto in protocols:
851 s = self.dumps(expected, proto)
852 got = self.loads(s)
853 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000854
Tim Peters70b02d72003-02-02 17:26:40 +0000855 # There are gratuitous differences between pickles produced by
856 # pickle and cPickle, largely because cPickle starts PUT indices at
857 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
858 # there's a comment with an exclamation point there whose meaning
859 # is a mystery. cPickle also suppresses PUT for objects with a refcount
860 # of 1.
861 def dont_test_disassembly(self):
Tim Peters70b02d72003-02-02 17:26:40 +0000862 from pickletools import dis
863
864 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
865 s = self.dumps(self._testdata, proto)
Collin Winterf8089c72009-04-09 16:46:46 +0000866 filelike = cStringIO.StringIO()
Tim Peters70b02d72003-02-02 17:26:40 +0000867 dis(s, out=filelike)
868 got = filelike.getvalue()
869 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000870
871 def test_recursive_list(self):
872 l = []
873 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000874 for proto in protocols:
875 s = self.dumps(l, proto)
876 x = self.loads(s)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200877 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000878 self.assertEqual(len(x), 1)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200879 self.assertIs(x[0], x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000880
Serhiy Storchakada87e452015-11-07 11:15:32 +0200881 def test_recursive_tuple_and_list(self):
Collin Winter57bef682009-05-26 04:12:39 +0000882 t = ([],)
883 t[0].append(t)
884 for proto in protocols:
885 s = self.dumps(t, proto)
886 x = self.loads(s)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200887 self.assertIsInstance(x, tuple)
Collin Winter57bef682009-05-26 04:12:39 +0000888 self.assertEqual(len(x), 1)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200889 self.assertIsInstance(x[0], list)
Collin Winter57bef682009-05-26 04:12:39 +0000890 self.assertEqual(len(x[0]), 1)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200891 self.assertIs(x[0][0], x)
Collin Winter57bef682009-05-26 04:12:39 +0000892
Jeremy Hylton66426532001-10-15 21:38:56 +0000893 def test_recursive_dict(self):
894 d = {}
895 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000896 for proto in protocols:
897 s = self.dumps(d, proto)
898 x = self.loads(s)
Serhiy Storchakada87e452015-11-07 11:15:32 +0200899 self.assertIsInstance(x, dict)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000900 self.assertEqual(x.keys(), [1])
Serhiy Storchakada87e452015-11-07 11:15:32 +0200901 self.assertIs(x[1], x)
902
903 def test_recursive_dict_key(self):
904 d = {}
905 k = K(d)
906 d[k] = 1
907 for proto in protocols:
908 s = self.dumps(d, proto)
909 x = self.loads(s)
910 self.assertIsInstance(x, dict)
911 self.assertEqual(len(x.keys()), 1)
912 self.assertIsInstance(x.keys()[0], K)
913 self.assertIs(x.keys()[0].value, x)
914
915 def test_recursive_list_subclass(self):
916 y = MyList()
917 y.append(y)
918 s = self.dumps(y, 2)
919 x = self.loads(s)
920 self.assertIsInstance(x, MyList)
921 self.assertEqual(len(x), 1)
922 self.assertIs(x[0], x)
923
924 def test_recursive_dict_subclass(self):
925 d = MyDict()
926 d[1] = d
927 s = self.dumps(d, 2)
928 x = self.loads(s)
929 self.assertIsInstance(x, MyDict)
930 self.assertEqual(x.keys(), [1])
931 self.assertIs(x[1], x)
932
933 def test_recursive_dict_subclass_key(self):
934 d = MyDict()
935 k = K(d)
936 d[k] = 1
937 s = self.dumps(d, 2)
938 x = self.loads(s)
939 self.assertIsInstance(x, MyDict)
940 self.assertEqual(len(x.keys()), 1)
941 self.assertIsInstance(x.keys()[0], K)
942 self.assertIs(x.keys()[0].value, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000943
944 def test_recursive_inst(self):
945 i = C()
946 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000947 for proto in protocols:
Ezio Melottia84ecc62013-03-04 15:23:12 +0200948 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +0000949 x = self.loads(s)
Serhiy Storchaka7c033e62016-03-06 09:05:47 +0200950 self.assertIsInstance(x, C)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000951 self.assertEqual(dir(x), dir(i))
Ezio Melottia84ecc62013-03-04 15:23:12 +0200952 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000953
954 def test_recursive_multi(self):
955 l = []
956 d = {1:l}
957 i = C()
958 i.attr = d
959 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000960 for proto in protocols:
961 s = self.dumps(l, proto)
962 x = self.loads(s)
Serhiy Storchaka7c033e62016-03-06 09:05:47 +0200963 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000964 self.assertEqual(len(x), 1)
965 self.assertEqual(dir(x[0]), dir(i))
966 self.assertEqual(x[0].attr.keys(), [1])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000967 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000968
Serhiy Storchakada87e452015-11-07 11:15:32 +0200969 def check_recursive_collection_and_inst(self, factory):
970 h = H()
971 y = factory([h])
972 h.attr = y
973 for proto in protocols:
974 s = self.dumps(y, proto)
975 x = self.loads(s)
976 self.assertIsInstance(x, type(y))
977 self.assertEqual(len(x), 1)
978 self.assertIsInstance(list(x)[0], H)
979 self.assertIs(list(x)[0].attr, x)
980
981 def test_recursive_list_and_inst(self):
982 self.check_recursive_collection_and_inst(list)
983
984 def test_recursive_tuple_and_inst(self):
985 self.check_recursive_collection_and_inst(tuple)
986
987 def test_recursive_dict_and_inst(self):
988 self.check_recursive_collection_and_inst(dict.fromkeys)
989
990 def test_recursive_set_and_inst(self):
991 self.check_recursive_collection_and_inst(set)
992
993 def test_recursive_frozenset_and_inst(self):
994 self.check_recursive_collection_and_inst(frozenset)
995
996 def test_recursive_list_subclass_and_inst(self):
997 self.check_recursive_collection_and_inst(MyList)
998
999 def test_recursive_tuple_subclass_and_inst(self):
1000 self.check_recursive_collection_and_inst(MyTuple)
1001
1002 def test_recursive_dict_subclass_and_inst(self):
1003 self.check_recursive_collection_and_inst(MyDict.fromkeys)
1004
Martin v. Löwis339d0f72001-08-17 18:39:25 +00001005 if have_unicode:
Jeremy Hylton66426532001-10-15 21:38:56 +00001006 def test_unicode(self):
Alexandre Vassalottie57e9992008-12-27 10:02:59 +00001007 endcases = [u'', u'<\\u>', u'<\\\u1234>', u'<\n>',
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001008 u'<\\>', u'<\\\U00012345>',
1009 # surrogates
1010 u'<\udc80>']
Tim Petersee1a53c2003-02-02 02:57:53 +00001011 for proto in protocols:
1012 for u in endcases:
1013 p = self.dumps(u, proto)
1014 u2 = self.loads(p)
1015 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +00001016
Alexandre Vassalottif852bf92008-12-27 07:08:47 +00001017 def test_unicode_high_plane(self):
1018 t = u'\U00012345'
1019 for proto in protocols:
1020 p = self.dumps(t, proto)
1021 t2 = self.loads(p)
1022 self.assertEqual(t2, t)
1023
Jeremy Hylton66426532001-10-15 21:38:56 +00001024 def test_ints(self):
1025 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +00001026 for proto in protocols:
1027 n = sys.maxint
1028 while n:
1029 for expected in (-n, n):
1030 s = self.dumps(expected, proto)
1031 n2 = self.loads(s)
1032 self.assertEqual(expected, n2)
1033 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +00001034
Tim Petersee1a53c2003-02-02 02:57:53 +00001035 def test_long(self):
1036 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +00001037 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +00001038 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
1039 nbase = 1L << nbits
1040 for npos in nbase-1, nbase, nbase+1:
1041 for n in npos, -npos:
1042 pickle = self.dumps(n, proto)
1043 got = self.loads(pickle)
1044 self.assertEqual(n, got)
1045 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
1046 # bother with those.
Tim Petersee1a53c2003-02-02 02:57:53 +00001047 nbase = long("deadbeeffeedface", 16)
1048 nbase += nbase << 1000000
1049 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +00001050 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +00001051 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +00001052 self.assertEqual(n, got)
1053
Mark Dickinsona3ecd2c2009-01-24 16:40:29 +00001054 def test_float(self):
1055 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
1056 3.14, 263.44582062374053, 6.022e23, 1e30]
1057 test_values = test_values + [-x for x in test_values]
1058 for proto in protocols:
1059 for value in test_values:
1060 pickle = self.dumps(value, proto)
1061 got = self.loads(pickle)
1062 self.assertEqual(value, got)
1063
Georg Brandlde9b6242006-04-30 11:13:56 +00001064 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
1065 def test_float_format(self):
1066 # make sure that floats are formatted locale independent
1067 self.assertEqual(self.dumps(1.2)[0:3], 'F1.')
1068
Jeremy Hylton66426532001-10-15 21:38:56 +00001069 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +00001070 pass
Jeremy Hylton66426532001-10-15 21:38:56 +00001071
1072 def test_getinitargs(self):
1073 pass
1074
Guido van Rossum04a86612001-12-19 16:58:54 +00001075 def test_metaclass(self):
1076 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +00001077 for proto in protocols:
1078 s = self.dumps(a, proto)
1079 b = self.loads(s)
1080 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +00001081
Antoine Pitrou561a8212011-10-04 09:34:48 +02001082 def test_dynamic_class(self):
1083 a = create_dynamic_class("my_dynamic_class", (object,))
1084 copy_reg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
1085 for proto in protocols:
1086 s = self.dumps(a, proto)
1087 b = self.loads(s)
1088 self.assertEqual(a, b)
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001089 self.assertIs(a.__class__, b.__class__)
Antoine Pitrou561a8212011-10-04 09:34:48 +02001090
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001091 def test_structseq(self):
1092 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +00001093 import os
Tim Peters70b02d72003-02-02 17:26:40 +00001094
1095 t = time.localtime()
1096 for proto in protocols:
1097 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +00001098 u = self.loads(s)
1099 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +00001100 if hasattr(os, "stat"):
1101 t = os.stat(os.curdir)
1102 s = self.dumps(t, proto)
1103 u = self.loads(s)
1104 self.assertEqual(t, u)
1105 if hasattr(os, "statvfs"):
1106 t = os.statvfs(os.curdir)
1107 s = self.dumps(t, proto)
1108 u = self.loads(s)
1109 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001110
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001111 # Tests for protocol 2
1112
Tim Peters4190fb82003-02-02 16:09:05 +00001113 def test_proto(self):
1114 build_none = pickle.NONE + pickle.STOP
1115 for proto in protocols:
1116 expected = build_none
1117 if proto >= 2:
1118 expected = pickle.PROTO + chr(proto) + expected
1119 p = self.dumps(None, proto)
1120 self.assertEqual(p, expected)
1121
1122 oob = protocols[-1] + 1 # a future protocol
1123 badpickle = pickle.PROTO + chr(oob) + build_none
1124 try:
1125 self.loads(badpickle)
1126 except ValueError, detail:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001127 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +00001128 "unsupported pickle protocol"))
1129 else:
1130 self.fail("expected bad protocol number to raise ValueError")
1131
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001132 def test_long1(self):
1133 x = 12345678910111213141516178920L
Tim Peters61bf2572003-02-03 21:31:22 +00001134 for proto in protocols:
1135 s = self.dumps(x, proto)
1136 y = self.loads(s)
1137 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001138 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001139
1140 def test_long4(self):
1141 x = 12345678910111213141516178920L << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +00001142 for proto in protocols:
1143 s = self.dumps(x, proto)
1144 y = self.loads(s)
1145 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001146 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001147
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001148 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +00001149 # Map (proto, len(tuple)) to expected opcode.
1150 expected_opcode = {(0, 0): pickle.TUPLE,
1151 (0, 1): pickle.TUPLE,
1152 (0, 2): pickle.TUPLE,
1153 (0, 3): pickle.TUPLE,
1154 (0, 4): pickle.TUPLE,
1155
1156 (1, 0): pickle.EMPTY_TUPLE,
1157 (1, 1): pickle.TUPLE,
1158 (1, 2): pickle.TUPLE,
1159 (1, 3): pickle.TUPLE,
1160 (1, 4): pickle.TUPLE,
1161
1162 (2, 0): pickle.EMPTY_TUPLE,
1163 (2, 1): pickle.TUPLE1,
1164 (2, 2): pickle.TUPLE2,
1165 (2, 3): pickle.TUPLE3,
1166 (2, 4): pickle.TUPLE,
1167 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001168 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +00001169 b = (1,)
1170 c = (1, 2)
1171 d = (1, 2, 3)
1172 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +00001173 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001174 for x in a, b, c, d, e:
1175 s = self.dumps(x, proto)
1176 y = self.loads(s)
1177 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +00001178 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +00001179 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +00001180
Guido van Rossum7d97d312003-01-28 04:25:27 +00001181 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +00001182 # Map (proto, singleton) to expected opcode.
1183 expected_opcode = {(0, None): pickle.NONE,
1184 (1, None): pickle.NONE,
1185 (2, None): pickle.NONE,
1186
1187 (0, True): pickle.INT,
1188 (1, True): pickle.INT,
1189 (2, True): pickle.NEWTRUE,
1190
1191 (0, False): pickle.INT,
1192 (1, False): pickle.INT,
1193 (2, False): pickle.NEWFALSE,
1194 }
Tim Peters4190fb82003-02-02 16:09:05 +00001195 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +00001196 for x in None, False, True:
1197 s = self.dumps(x, proto)
1198 y = self.loads(s)
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001199 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +00001200 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +00001201 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +00001202
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001203 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001204 x = MyTuple([1, 2, 3])
1205 x.foo = 42
1206 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001207 for proto in protocols:
1208 s = self.dumps(x, proto)
1209 y = self.loads(s)
1210 self.assertEqual(tuple(x), tuple(y))
1211 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001212
1213 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001214 x = MyList([1, 2, 3])
1215 x.foo = 42
1216 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001217 for proto in protocols:
1218 s = self.dumps(x, proto)
1219 y = self.loads(s)
1220 self.assertEqual(list(x), list(y))
1221 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001222
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001223 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001224 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001225 for C in myclasses:
1226 B = C.__base__
1227 x = C(C.sample)
1228 x.foo = 42
1229 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001230 y = self.loads(s)
1231 detail = (proto, C, B, x, y, type(y))
1232 self.assertEqual(B(x), B(y), detail)
1233 self.assertEqual(x.__dict__, y.__dict__, detail)
1234
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001235 def test_newobj_proxies(self):
1236 # NEWOBJ should use the __class__ rather than the raw type
1237 import weakref
1238 classes = myclasses[:]
1239 # Cannot create weakproxies to these classes
1240 for c in (MyInt, MyLong, MyStr, MyTuple):
1241 classes.remove(c)
1242 for proto in protocols:
1243 for C in classes:
1244 B = C.__base__
1245 x = C(C.sample)
1246 x.foo = 42
1247 p = weakref.proxy(x)
1248 s = self.dumps(p, proto)
1249 y = self.loads(s)
1250 self.assertEqual(type(y), type(x)) # rather than type(p)
1251 detail = (proto, C, B, x, y, type(y))
1252 self.assertEqual(B(x), B(y), detail)
1253 self.assertEqual(x.__dict__, y.__dict__, detail)
1254
Georg Brandldffbf5f2008-05-20 07:49:57 +00001255 # Register a type with copy_reg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001256 # an object of that type. Check that the resulting pickle uses opcode
1257 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001258
Tim Peters22e71712003-02-03 22:27:38 +00001259 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001260 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001261 try:
Georg Brandldffbf5f2008-05-20 07:49:57 +00001262 copy_reg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001263 x = MyList([1, 2, 3])
1264 x.foo = 42
1265 x.bar = "hello"
1266
Tim Peters22e71712003-02-03 22:27:38 +00001267 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001268 s1 = self.dumps(x, 1)
Ezio Melottiaa980582010-01-23 23:04:36 +00001269 self.assertIn(__name__, s1)
1270 self.assertIn("MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +00001271 self.assertEqual(opcode_in_pickle(opcode, s1), False)
1272
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001273 y = self.loads(s1)
1274 self.assertEqual(list(x), list(y))
1275 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001276
Tim Peters22e71712003-02-03 22:27:38 +00001277 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001278 s2 = self.dumps(x, 2)
Ezio Melottiaa980582010-01-23 23:04:36 +00001279 self.assertNotIn(__name__, s2)
1280 self.assertNotIn("MyList", s2)
Tim Peters3e667d52003-02-04 21:47:44 +00001281 self.assertEqual(opcode_in_pickle(opcode, s2), True)
1282
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001283 y = self.loads(s2)
1284 self.assertEqual(list(x), list(y))
1285 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001286
1287 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001288 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001289
1290 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001291 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1292 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001293
1294 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001295 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1296 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1297 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001298
1299 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001300 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1301 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1302 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1303
Tim Peters8d2613a2003-02-11 16:40:16 +00001304 def test_list_chunking(self):
1305 n = 10 # too small to chunk
1306 x = range(n)
1307 for proto in protocols:
1308 s = self.dumps(x, proto)
1309 y = self.loads(s)
1310 self.assertEqual(x, y)
1311 num_appends = count_opcode(pickle.APPENDS, s)
1312 self.assertEqual(num_appends, proto > 0)
1313
1314 n = 2500 # expect at least two chunks when proto > 0
1315 x = range(n)
1316 for proto in protocols:
1317 s = self.dumps(x, proto)
1318 y = self.loads(s)
1319 self.assertEqual(x, y)
1320 num_appends = count_opcode(pickle.APPENDS, s)
1321 if proto == 0:
1322 self.assertEqual(num_appends, 0)
1323 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001324 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001325
1326 def test_dict_chunking(self):
1327 n = 10 # too small to chunk
1328 x = dict.fromkeys(range(n))
1329 for proto in protocols:
1330 s = self.dumps(x, proto)
1331 y = self.loads(s)
1332 self.assertEqual(x, y)
1333 num_setitems = count_opcode(pickle.SETITEMS, s)
1334 self.assertEqual(num_setitems, proto > 0)
1335
1336 n = 2500 # expect at least two chunks when proto > 0
1337 x = dict.fromkeys(range(n))
1338 for proto in protocols:
1339 s = self.dumps(x, proto)
1340 y = self.loads(s)
1341 self.assertEqual(x, y)
1342 num_setitems = count_opcode(pickle.SETITEMS, s)
1343 if proto == 0:
1344 self.assertEqual(num_setitems, 0)
1345 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001346 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001347
Tim Peterse9ef2032003-02-13 18:42:00 +00001348 def test_simple_newobj(self):
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001349 x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__
Tim Peterse9ef2032003-02-13 18:42:00 +00001350 x.abc = 666
1351 for proto in protocols:
1352 s = self.dumps(x, proto)
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001353 if proto < 1:
1354 self.assertIn('\nI64206', s) # INT
1355 else:
1356 self.assertIn('M\xce\xfa', s) # BININT2
1357 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
1358 y = self.loads(s) # will raise TypeError if __init__ called
1359 self.assertEqual(y.abc, 666)
1360 self.assertEqual(x.__dict__, y.__dict__)
1361
1362 def test_complex_newobj(self):
1363 x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__
1364 x.abc = 666
1365 for proto in protocols:
1366 s = self.dumps(x, proto)
1367 if proto < 1:
1368 self.assertIn('\nI64206', s) # INT
1369 elif proto < 2:
1370 self.assertIn('M\xce\xfa', s) # BININT2
1371 else:
1372 self.assertIn('U\x04FACE', s) # SHORT_BINSTRING
Tim Peterse9ef2032003-02-13 18:42:00 +00001373 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
1374 y = self.loads(s) # will raise TypeError if __init__ called
1375 self.assertEqual(y.abc, 666)
1376 self.assertEqual(x.__dict__, y.__dict__)
1377
Tim Peters42f08ac2003-02-11 22:43:24 +00001378 def test_newobj_list_slots(self):
1379 x = SlotList([1, 2, 3])
1380 x.foo = 42
1381 x.bar = "hello"
1382 s = self.dumps(x, 2)
1383 y = self.loads(s)
1384 self.assertEqual(list(x), list(y))
1385 self.assertEqual(x.__dict__, y.__dict__)
1386 self.assertEqual(x.foo, y.foo)
1387 self.assertEqual(x.bar, y.bar)
1388
Guido van Rossum2a30b212003-02-18 22:41:24 +00001389 def test_reduce_overrides_default_reduce_ex(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001390 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001391 x = REX_one()
1392 self.assertEqual(x._reduce_called, 0)
1393 s = self.dumps(x, proto)
1394 self.assertEqual(x._reduce_called, 1)
1395 y = self.loads(s)
1396 self.assertEqual(y._reduce_called, 0)
1397
1398 def test_reduce_ex_called(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001399 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001400 x = REX_two()
1401 self.assertEqual(x._proto, None)
1402 s = self.dumps(x, proto)
1403 self.assertEqual(x._proto, proto)
1404 y = self.loads(s)
1405 self.assertEqual(y._proto, None)
1406
1407 def test_reduce_ex_overrides_reduce(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001408 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001409 x = REX_three()
1410 self.assertEqual(x._proto, None)
1411 s = self.dumps(x, proto)
1412 self.assertEqual(x._proto, proto)
1413 y = self.loads(s)
1414 self.assertEqual(y._proto, None)
1415
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001416 def test_reduce_ex_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001417 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001418 x = REX_four()
1419 self.assertEqual(x._proto, None)
1420 s = self.dumps(x, proto)
1421 self.assertEqual(x._proto, proto)
1422 y = self.loads(s)
1423 self.assertEqual(y._proto, proto)
1424
1425 def test_reduce_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001426 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001427 x = REX_five()
1428 self.assertEqual(x._reduce_called, 0)
1429 s = self.dumps(x, proto)
1430 self.assertEqual(x._reduce_called, 1)
1431 y = self.loads(s)
1432 self.assertEqual(y._reduce_called, 1)
1433
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001434 @no_tracing
1435 def test_bad_getattr(self):
1436 # Issue #3514: crash when there is an infinite loop in __getattr__
1437 x = BadGetattr()
1438 for proto in protocols:
1439 self.assertRaises(RuntimeError, self.dumps, x, proto)
1440
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001441 def test_reduce_bad_iterator(self):
1442 # Issue4176: crash when 4th and 5th items of __reduce__()
1443 # are not iterators
1444 class C(object):
1445 def __reduce__(self):
1446 # 4th item is not an iterator
1447 return list, (), None, [], None
1448 class D(object):
1449 def __reduce__(self):
1450 # 5th item is not an iterator
1451 return dict, (), None, None, []
1452
Serhiy Storchakaff41d452015-12-30 20:59:32 +02001453 # Protocol 0 in Python implementation is less strict and also accepts
1454 # iterables.
Collin Winterf8089c72009-04-09 16:46:46 +00001455 for proto in protocols:
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001456 try:
1457 self.dumps(C(), proto)
Serhiy Storchakaff41d452015-12-30 20:59:32 +02001458 except (AttributeError, pickle.PicklingError, cPickle.PicklingError):
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001459 pass
1460 try:
1461 self.dumps(D(), proto)
Serhiy Storchakaff41d452015-12-30 20:59:32 +02001462 except (AttributeError, pickle.PicklingError, cPickle.PicklingError):
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +00001463 pass
1464
Collin Winterf8089c72009-04-09 16:46:46 +00001465 def test_many_puts_and_gets(self):
1466 # Test that internal data structures correctly deal with lots of
1467 # puts/gets.
1468 keys = ("aaa" + str(i) for i in xrange(100))
1469 large_dict = dict((k, [4, 5, 6]) for k in keys)
1470 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1471
1472 for proto in protocols:
1473 dumped = self.dumps(obj, proto)
1474 loaded = self.loads(dumped)
1475 self.assertEqual(loaded, obj,
1476 "Failed protocol %d: %r != %r"
1477 % (proto, obj, loaded))
1478
Antoine Pitrou74309892009-05-02 21:13:23 +00001479 def test_attribute_name_interning(self):
1480 # Test that attribute names of pickled objects are interned when
1481 # unpickling.
1482 for proto in protocols:
1483 x = C()
1484 x.foo = 42
1485 x.bar = "hello"
1486 s = self.dumps(x, proto)
1487 y = self.loads(s)
1488 x_keys = sorted(x.__dict__)
1489 y_keys = sorted(y.__dict__)
1490 for x_key, y_key in zip(x_keys, y_keys):
1491 self.assertIs(x_key, y_key)
1492
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001493 def test_large_pickles(self):
1494 # Test the correctness of internal buffering routines when handling
1495 # large data.
1496 for proto in protocols:
1497 data = (1, min, 'xy' * (30 * 1024), len)
1498 dumped = self.dumps(data, proto)
1499 loaded = self.loads(dumped)
1500 self.assertEqual(len(loaded), len(data))
1501 self.assertEqual(loaded, data)
1502
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001503 def _check_pickling_with_opcode(self, obj, opcode, proto):
1504 pickled = self.dumps(obj, proto)
1505 self.assertTrue(opcode_in_pickle(opcode, pickled))
1506 unpickled = self.loads(pickled)
1507 self.assertEqual(obj, unpickled)
1508
1509 def test_appends_on_non_lists(self):
1510 # Issue #17720
1511 obj = REX_six([1, 2, 3])
1512 for proto in protocols:
1513 if proto == 0:
1514 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1515 else:
1516 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1517
1518 def test_setitems_on_non_dicts(self):
1519 obj = REX_seven({1: -1, 2: -2, 3: -3})
1520 for proto in protocols:
1521 if proto == 0:
1522 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1523 else:
1524 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1525
Collin Winterf8089c72009-04-09 16:46:46 +00001526
Guido van Rossum2a30b212003-02-18 22:41:24 +00001527# Test classes for reduce_ex
1528
1529class REX_one(object):
1530 _reduce_called = 0
1531 def __reduce__(self):
1532 self._reduce_called = 1
1533 return REX_one, ()
1534 # No __reduce_ex__ here, but inheriting it from object
1535
1536class REX_two(object):
1537 _proto = None
1538 def __reduce_ex__(self, proto):
1539 self._proto = proto
1540 return REX_two, ()
1541 # No __reduce__ here, but inheriting it from object
1542
1543class REX_three(object):
1544 _proto = None
1545 def __reduce_ex__(self, proto):
1546 self._proto = proto
1547 return REX_two, ()
1548 def __reduce__(self):
1549 raise TestFailed, "This __reduce__ shouldn't be called"
1550
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001551class REX_four(object):
1552 _proto = None
1553 def __reduce_ex__(self, proto):
1554 self._proto = proto
1555 return object.__reduce_ex__(self, proto)
1556 # Calling base class method should succeed
1557
1558class REX_five(object):
1559 _reduce_called = 0
1560 def __reduce__(self):
1561 self._reduce_called = 1
1562 return object.__reduce__(self)
1563 # This one used to fail with infinite recursion
1564
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001565class REX_six(object):
1566 """This class is used to check the 4th argument (list iterator) of
1567 the reduce protocol.
1568 """
1569 def __init__(self, items=None):
1570 if items is None:
1571 items = []
1572 self.items = items
1573 def __eq__(self, other):
1574 return type(self) is type(other) and self.items == other.items
Serhiy Storchakaf8cc2872016-10-25 09:51:38 +03001575 __hash__ = None
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001576 def append(self, item):
1577 self.items.append(item)
1578 def extend(self, items):
1579 for item in items:
1580 self.append(item)
1581 def __reduce__(self):
1582 return type(self), (), None, iter(self.items), None
1583
1584class REX_seven(object):
1585 """This class is used to check the 5th argument (dict iterator) of
1586 the reduce protocol.
1587 """
1588 def __init__(self, table=None):
1589 if table is None:
1590 table = {}
1591 self.table = table
1592 def __eq__(self, other):
1593 return type(self) is type(other) and self.table == other.table
Serhiy Storchakaf8cc2872016-10-25 09:51:38 +03001594 __hash__ = None
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001595 def __setitem__(self, key, value):
1596 self.table[key] = value
1597 def __reduce__(self):
1598 return type(self), (), None, None, iter(self.table.items())
1599
Guido van Rossum2a30b212003-02-18 22:41:24 +00001600# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001601
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001602class MyInt(int):
1603 sample = 1
1604
1605class MyLong(long):
1606 sample = 1L
1607
1608class MyFloat(float):
1609 sample = 1.0
1610
1611class MyComplex(complex):
1612 sample = 1.0 + 0.0j
1613
1614class MyStr(str):
1615 sample = "hello"
1616
1617class MyUnicode(unicode):
1618 sample = u"hello \u1234"
1619
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001620class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001621 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001622
1623class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001624 sample = [1, 2, 3]
1625
1626class MyDict(dict):
1627 sample = {"a": 1, "b": 2}
1628
1629myclasses = [MyInt, MyLong, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001630 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001631 MyStr, MyUnicode,
1632 MyTuple, MyList, MyDict]
1633
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001634
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001635class SlotList(MyList):
1636 __slots__ = ["foo"]
1637
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001638class SimpleNewObj(int):
1639 def __init__(self, *args, **kwargs):
Tim Peterse9ef2032003-02-13 18:42:00 +00001640 # raise an error, to make sure this isn't called
1641 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001642 def __eq__(self, other):
1643 return int(self) == int(other) and self.__dict__ == other.__dict__
Serhiy Storchakaf8cc2872016-10-25 09:51:38 +03001644 __hash__ = None
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001645
1646class ComplexNewObj(SimpleNewObj):
1647 def __getnewargs__(self):
1648 return ('%X' % self, 16)
1649
1650class BadGetattr:
1651 def __getattr__(self, key):
1652 self.foo
Tim Peterse9ef2032003-02-13 18:42:00 +00001653
Jeremy Hylton66426532001-10-15 21:38:56 +00001654class AbstractPickleModuleTests(unittest.TestCase):
1655
1656 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001657 import os
1658 f = open(TESTFN, "w")
1659 try:
1660 f.close()
1661 self.assertRaises(ValueError, self.module.dump, 123, f)
1662 finally:
1663 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001664
1665 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001666 import os
1667 f = open(TESTFN, "w")
1668 try:
1669 f.close()
1670 self.assertRaises(ValueError, self.module.dump, 123, f)
1671 finally:
1672 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001673
Collin Winterf8089c72009-04-09 16:46:46 +00001674 def test_load_from_and_dump_to_file(self):
1675 stream = cStringIO.StringIO()
1676 data = [123, {}, 124]
1677 self.module.dump(data, stream)
1678 stream.seek(0)
1679 unpickled = self.module.load(stream)
1680 self.assertEqual(unpickled, data)
1681
Tim Petersc0c93702003-02-13 19:30:57 +00001682 def test_highest_protocol(self):
1683 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
1684 self.assertEqual(self.module.HIGHEST_PROTOCOL, 2)
1685
Martin v. Löwis544f1192004-07-27 05:22:33 +00001686 def test_callapi(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001687 f = cStringIO.StringIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001688 # With and without keyword arguments
1689 self.module.dump(123, f, -1)
1690 self.module.dump(123, file=f, protocol=-1)
1691 self.module.dumps(123, -1)
1692 self.module.dumps(123, protocol=-1)
1693 self.module.Pickler(f, -1)
1694 self.module.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001695
Amaury Forgeot d'Arc74b30162009-07-23 19:26:02 +00001696 def test_incomplete_input(self):
1697 s = StringIO.StringIO("X''.")
1698 self.assertRaises(EOFError, self.module.load, s)
1699
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001700 def test_restricted(self):
1701 # issue7128: cPickle failed in restricted mode
1702 builtins = {self.module.__name__: self.module,
1703 '__import__': __import__}
1704 d = {}
1705 teststr = "def f(): {0}.dumps(0)".format(self.module.__name__)
1706 exec teststr in {'__builtins__': builtins}, d
1707 d['f']()
1708
Antoine Pitrou0d423b82010-01-07 17:46:49 +00001709 def test_bad_input(self):
1710 # Test issue4298
1711 s = '\x58\0\0\0\x54'
1712 self.assertRaises(EOFError, self.module.loads, s)
Serhiy Storchakabf19ce22015-11-29 13:12:40 +02001713
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001714
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001715class AbstractPersistentPicklerTests(unittest.TestCase):
1716
1717 # This class defines persistent_id() and persistent_load()
1718 # functions that should be used by the pickler. All even integers
1719 # are pickled using persistent ids.
1720
1721 def persistent_id(self, object):
1722 if isinstance(object, int) and object % 2 == 0:
1723 self.id_count += 1
1724 return str(object)
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001725 elif object == "test_false_value":
1726 self.false_count += 1
1727 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001728 else:
1729 return None
1730
1731 def persistent_load(self, oid):
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001732 if not oid:
1733 self.load_false_count += 1
1734 return "test_false_value"
1735 else:
1736 self.load_count += 1
1737 object = int(oid)
1738 assert object % 2 == 0
1739 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001740
1741 def test_persistence(self):
Alexandre Vassalotti1d3a1732013-11-30 13:24:13 -08001742 L = range(10) + ["test_false_value"]
1743 for proto in protocols:
1744 self.id_count = 0
1745 self.false_count = 0
1746 self.load_false_count = 0
1747 self.load_count = 0
1748 self.assertEqual(self.loads(self.dumps(L, proto)), L)
1749 self.assertEqual(self.id_count, 5)
1750 self.assertEqual(self.false_count, 1)
1751 self.assertEqual(self.load_count, 5)
1752 self.assertEqual(self.load_false_count, 1)
Collin Winterf8089c72009-04-09 16:46:46 +00001753
1754class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1755
1756 pickler_class = None
1757 unpickler_class = None
1758
1759 def setUp(self):
1760 assert self.pickler_class
1761 assert self.unpickler_class
1762
1763 def test_clear_pickler_memo(self):
1764 # To test whether clear_memo() has any effect, we pickle an object,
1765 # then pickle it again without clearing the memo; the two serialized
1766 # forms should be different. If we clear_memo() and then pickle the
1767 # object again, the third serialized form should be identical to the
1768 # first one we obtained.
1769 data = ["abcdefg", "abcdefg", 44]
1770 f = cStringIO.StringIO()
1771 pickler = self.pickler_class(f)
1772
1773 pickler.dump(data)
1774 first_pickled = f.getvalue()
1775
1776 # Reset StringIO object.
1777 f.seek(0)
1778 f.truncate()
1779
1780 pickler.dump(data)
1781 second_pickled = f.getvalue()
1782
1783 # Reset the Pickler and StringIO objects.
1784 pickler.clear_memo()
1785 f.seek(0)
1786 f.truncate()
1787
1788 pickler.dump(data)
1789 third_pickled = f.getvalue()
1790
1791 self.assertNotEqual(first_pickled, second_pickled)
1792 self.assertEqual(first_pickled, third_pickled)
1793
1794 def test_priming_pickler_memo(self):
1795 # Verify that we can set the Pickler's memo attribute.
1796 data = ["abcdefg", "abcdefg", 44]
1797 f = cStringIO.StringIO()
1798 pickler = self.pickler_class(f)
1799
1800 pickler.dump(data)
1801 first_pickled = f.getvalue()
1802
1803 f = cStringIO.StringIO()
1804 primed = self.pickler_class(f)
1805 primed.memo = pickler.memo
1806
1807 primed.dump(data)
1808 primed_pickled = f.getvalue()
1809
1810 self.assertNotEqual(first_pickled, primed_pickled)
1811
1812 def test_priming_unpickler_memo(self):
1813 # Verify that we can set the Unpickler's memo attribute.
1814 data = ["abcdefg", "abcdefg", 44]
1815 f = cStringIO.StringIO()
1816 pickler = self.pickler_class(f)
1817
1818 pickler.dump(data)
1819 first_pickled = f.getvalue()
1820
1821 f = cStringIO.StringIO()
1822 primed = self.pickler_class(f)
1823 primed.memo = pickler.memo
1824
1825 primed.dump(data)
1826 primed_pickled = f.getvalue()
1827
1828 unpickler = self.unpickler_class(cStringIO.StringIO(first_pickled))
1829 unpickled_data1 = unpickler.load()
1830
1831 self.assertEqual(unpickled_data1, data)
1832
1833 primed = self.unpickler_class(cStringIO.StringIO(primed_pickled))
1834 primed.memo = unpickler.memo
1835 unpickled_data2 = primed.load()
1836
1837 primed.memo.clear()
1838
1839 self.assertEqual(unpickled_data2, data)
1840 self.assertTrue(unpickled_data2 is unpickled_data1)
1841
1842 def test_reusing_unpickler_objects(self):
1843 data1 = ["abcdefg", "abcdefg", 44]
1844 f = cStringIO.StringIO()
1845 pickler = self.pickler_class(f)
1846 pickler.dump(data1)
1847 pickled1 = f.getvalue()
1848
1849 data2 = ["abcdefg", 44, 44]
1850 f = cStringIO.StringIO()
1851 pickler = self.pickler_class(f)
1852 pickler.dump(data2)
1853 pickled2 = f.getvalue()
1854
1855 f = cStringIO.StringIO()
1856 f.write(pickled1)
1857 f.seek(0)
1858 unpickler = self.unpickler_class(f)
1859 self.assertEqual(unpickler.load(), data1)
1860
1861 f.seek(0)
1862 f.truncate()
1863 f.write(pickled2)
1864 f.seek(0)
1865 self.assertEqual(unpickler.load(), data2)
Serhiy Storchakacdc7a912013-02-12 21:36:47 +02001866
Serhiy Storchaka7c033e62016-03-06 09:05:47 +02001867 def _check_multiple_unpicklings(self, ioclass, seekable):
1868 for proto in protocols:
1869 data1 = [(x, str(x)) for x in xrange(2000)] + ["abcde", len]
1870 f = ioclass()
1871 pickler = self.pickler_class(f, protocol=proto)
1872 pickler.dump(data1)
1873 pickled = f.getvalue()
1874
1875 N = 5
1876 f = ioclass(pickled * N)
1877 unpickler = self.unpickler_class(f)
1878 for i in xrange(N):
1879 if seekable:
1880 pos = f.tell()
1881 self.assertEqual(unpickler.load(), data1)
1882 if seekable:
1883 self.assertEqual(f.tell(), pos + len(pickled))
1884 self.assertRaises(EOFError, unpickler.load)
1885
1886 def test_multiple_unpicklings_seekable(self):
1887 self._check_multiple_unpicklings(StringIO.StringIO, True)
1888
1889 def test_multiple_unpicklings_unseekable(self):
1890 self._check_multiple_unpicklings(UnseekableIO, False)
1891
1892 def test_unpickling_buffering_readline(self):
1893 # Issue #12687: the unpickler's buffering logic could fail with
1894 # text mode opcodes.
1895 import io
1896 data = list(xrange(10))
1897 for proto in protocols:
1898 for buf_size in xrange(1, 11):
1899 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
1900 pickler = self.pickler_class(f, protocol=proto)
1901 pickler.dump(data)
1902 f.seek(0)
1903 unpickler = self.unpickler_class(f)
1904 self.assertEqual(unpickler.load(), data)
1905
1906
Serhiy Storchakacdc7a912013-02-12 21:36:47 +02001907class BigmemPickleTests(unittest.TestCase):
1908
1909 # Memory requirements: 1 byte per character for input strings, 1 byte
1910 # for pickled data, 1 byte for unpickled strings, 1 byte for internal
1911 # buffer and 1 byte of free space for resizing of internal buffer.
1912
1913 @precisionbigmemtest(size=_2G + 100*_1M, memuse=5)
1914 def test_huge_strlist(self, size):
1915 chunksize = 2**20
1916 data = []
1917 while size > chunksize:
1918 data.append('x' * chunksize)
1919 size -= chunksize
1920 chunksize += 1
1921 data.append('y' * size)
1922
1923 try:
1924 for proto in protocols:
1925 try:
1926 pickled = self.dumps(data, proto)
1927 res = self.loads(pickled)
1928 self.assertEqual(res, data)
1929 finally:
1930 res = None
1931 pickled = None
1932 finally:
1933 data = None