blob: 3e7e11da4d4d20f66a66dda7a47adb6221a321f9 [file] [log] [blame]
Jeremy Hylton66426532001-10-15 21:38:56 +00001import unittest
Tim Peters4190fb82003-02-02 16:09:05 +00002import pickle
Tim Peters8587b3c2003-02-13 15:44:41 +00003import cPickle
Amaury Forgeot d'Arc74b30162009-07-23 19:26:02 +00004import StringIO
Collin Winterf8089c72009-04-09 16:46:46 +00005import cStringIO
Tim Peters31f119e2003-02-03 16:20:13 +00006import pickletools
Georg Brandldffbf5f2008-05-20 07:49:57 +00007import copy_reg
Tim Peters4190fb82003-02-02 16:09:05 +00008
Serhiy Storchakacdc7a912013-02-12 21:36:47 +02009from test.test_support import (TestFailed, have_unicode, TESTFN, _2G, _1M,
10 precisionbigmemtest)
Tim Peterse089c682001-04-10 03:41:41 +000011
Tim Petersee1a53c2003-02-02 02:57:53 +000012# Tests that try a number of pickle protocols should have a
13# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000014# kind of outer loop.
15assert pickle.HIGHEST_PROTOCOL == cPickle.HIGHEST_PROTOCOL == 2
16protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000017
Collin Winterf8089c72009-04-09 16:46:46 +000018# Copy of test.test_support.run_with_locale. This is needed to support Python
19# 2.4, which didn't include it. This is all to support test_xpickle, which
20# bounces pickled objects through older Python versions to test backwards
21# compatibility.
22def run_with_locale(catstr, *locales):
23 def decorator(func):
24 def inner(*args, **kwds):
25 try:
26 import locale
27 category = getattr(locale, catstr)
28 orig_locale = locale.setlocale(category)
29 except AttributeError:
30 # if the test author gives us an invalid category string
31 raise
32 except:
33 # cannot retrieve original locale, so do nothing
34 locale = orig_locale = None
35 else:
36 for loc in locales:
37 try:
38 locale.setlocale(category, loc)
39 break
40 except:
41 pass
42
43 # now run the function, resetting the locale on exceptions
44 try:
45 return func(*args, **kwds)
46 finally:
47 if locale and orig_locale:
48 locale.setlocale(category, orig_locale)
49 inner.func_name = func.func_name
50 inner.__doc__ = func.__doc__
51 return inner
52 return decorator
53
Tim Peters22e71712003-02-03 22:27:38 +000054
55# Return True if opcode code appears in the pickle, else False.
56def opcode_in_pickle(code, pickle):
57 for op, dummy, dummy in pickletools.genops(pickle):
58 if op.code == code:
59 return True
60 return False
61
Tim Peters8d2613a2003-02-11 16:40:16 +000062# Return the number of times opcode code appears in pickle.
63def count_opcode(code, pickle):
64 n = 0
65 for op, dummy, dummy in pickletools.genops(pickle):
66 if op.code == code:
67 n += 1
68 return n
69
Tim Peters3e667d52003-02-04 21:47:44 +000070# We can't very well test the extension registry without putting known stuff
71# in it, but we have to be careful to restore its original state. Code
72# should do this:
73#
74# e = ExtensionSaver(extension_code)
75# try:
76# fiddle w/ the extension registry's stuff for extension_code
77# finally:
78# e.restore()
79
80class ExtensionSaver:
81 # Remember current registration for code (if any), and remove it (if
82 # there is one).
83 def __init__(self, code):
84 self.code = code
Georg Brandldffbf5f2008-05-20 07:49:57 +000085 if code in copy_reg._inverted_registry:
86 self.pair = copy_reg._inverted_registry[code]
87 copy_reg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000088 else:
89 self.pair = None
90
91 # Restore previous registration for code.
92 def restore(self):
93 code = self.code
Georg Brandldffbf5f2008-05-20 07:49:57 +000094 curpair = copy_reg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000095 if curpair is not None:
Georg Brandldffbf5f2008-05-20 07:49:57 +000096 copy_reg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000097 pair = self.pair
98 if pair is not None:
Georg Brandldffbf5f2008-05-20 07:49:57 +000099 copy_reg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000100
Jeremy Hylton66426532001-10-15 21:38:56 +0000101class C:
102 def __cmp__(self, other):
103 return cmp(self.__dict__, other.__dict__)
104
105import __main__
106__main__.C = C
107C.__module__ = "__main__"
108
109class myint(int):
110 def __init__(self, x):
111 self.str = str(x)
112
113class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000114
Jeremy Hylton66426532001-10-15 21:38:56 +0000115 def __init__(self, a, b):
116 self.a = a
117 self.b = b
118
119 def __getinitargs__(self):
120 return self.a, self.b
121
Guido van Rossum04a86612001-12-19 16:58:54 +0000122class metaclass(type):
123 pass
124
125class use_metaclass(object):
126 __metaclass__ = metaclass
127
Antoine Pitrou561a8212011-10-04 09:34:48 +0200128class pickling_metaclass(type):
129 def __eq__(self, other):
130 return (type(self) == type(other) and
131 self.reduce_args == other.reduce_args)
132
133 def __reduce__(self):
134 return (create_dynamic_class, self.reduce_args)
135
Ezio Melotti030aa352011-11-06 18:50:32 +0200136 __hash__ = None
137
Antoine Pitrou561a8212011-10-04 09:34:48 +0200138def create_dynamic_class(name, bases):
139 result = pickling_metaclass(name, bases, dict())
140 result.reduce_args = (name, bases)
141 return result
142
Tim Peters70b02d72003-02-02 17:26:40 +0000143# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
144# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000145
Jeremy Hylton66426532001-10-15 21:38:56 +0000146# break into multiple strings to avoid confusing font-lock-mode
Tim Peters70b02d72003-02-02 17:26:40 +0000147DATA0 = """(lp1
Tim Peterse9358162001-01-22 22:05:20 +0000148I0
149aL1L
Tim Peters461922a2001-04-09 20:07:05 +0000150aF2
Tim Peterse9358162001-01-22 22:05:20 +0000151ac__builtin__
152complex
Tim Peters461922a2001-04-09 20:07:05 +0000153p2
154""" + \
155"""(F3
156F0
157tRp3
158aI1
159aI-1
160aI255
161aI-255
162aI-256
163aI65535
164aI-65535
165aI-65536
166aI2147483647
167aI-2147483647
168aI-2147483648
169a""" + \
170"""(S'abc'
Tim Peterse9358162001-01-22 22:05:20 +0000171p4
172g4
Tim Peters461922a2001-04-09 20:07:05 +0000173""" + \
Guido van Rossum42f92da2001-04-16 00:28:21 +0000174"""(i__main__
Tim Peterse9358162001-01-22 22:05:20 +0000175C
176p5
Tim Peters461922a2001-04-09 20:07:05 +0000177""" + \
Tim Peterse9358162001-01-22 22:05:20 +0000178"""(dp6
179S'foo'
180p7
181I1
182sS'bar'
183p8
184I2
185sbg5
186tp9
187ag9
188aI5
189a.
190"""
191
Tim Peters70b02d72003-02-02 17:26:40 +0000192# Disassembly of DATA0.
193DATA0_DIS = """\
194 0: ( MARK
195 1: l LIST (MARK at 0)
196 2: p PUT 1
197 5: I INT 0
198 8: a APPEND
199 9: L LONG 1L
200 13: a APPEND
201 14: F FLOAT 2.0
202 17: a APPEND
203 18: c GLOBAL '__builtin__ complex'
204 39: p PUT 2
205 42: ( MARK
206 43: F FLOAT 3.0
207 46: F FLOAT 0.0
208 49: t TUPLE (MARK at 42)
209 50: R REDUCE
210 51: p PUT 3
211 54: a APPEND
212 55: I INT 1
213 58: a APPEND
214 59: I INT -1
215 63: a APPEND
216 64: I INT 255
217 69: a APPEND
218 70: I INT -255
219 76: a APPEND
220 77: I INT -256
221 83: a APPEND
222 84: I INT 65535
223 91: a APPEND
224 92: I INT -65535
225 100: a APPEND
226 101: I INT -65536
227 109: a APPEND
228 110: I INT 2147483647
229 122: a APPEND
230 123: I INT -2147483647
231 136: a APPEND
232 137: I INT -2147483648
233 150: a APPEND
234 151: ( MARK
235 152: S STRING 'abc'
236 159: p PUT 4
237 162: g GET 4
238 165: ( MARK
239 166: i INST '__main__ C' (MARK at 165)
240 178: p PUT 5
241 181: ( MARK
242 182: d DICT (MARK at 181)
243 183: p PUT 6
244 186: S STRING 'foo'
245 193: p PUT 7
246 196: I INT 1
247 199: s SETITEM
248 200: S STRING 'bar'
249 207: p PUT 8
250 210: I INT 2
251 213: s SETITEM
252 214: b BUILD
253 215: g GET 5
254 218: t TUPLE (MARK at 151)
255 219: p PUT 9
256 222: a APPEND
257 223: g GET 9
258 226: a APPEND
259 227: I INT 5
260 230: a APPEND
261 231: . STOP
262highest protocol among opcodes = 0
263"""
264
265DATA1 = (']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00'
266 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00'
267 '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff'
268 '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff'
269 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00'
270 '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n'
271 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh'
272 '\x06tq\nh\nK\x05e.'
273 )
274
275# Disassembly of DATA1.
276DATA1_DIS = """\
277 0: ] EMPTY_LIST
278 1: q BINPUT 1
279 3: ( MARK
280 4: K BININT1 0
281 6: L LONG 1L
282 10: G BINFLOAT 2.0
283 19: c GLOBAL '__builtin__ complex'
284 40: q BINPUT 2
285 42: ( MARK
286 43: G BINFLOAT 3.0
287 52: G BINFLOAT 0.0
288 61: t TUPLE (MARK at 42)
289 62: R REDUCE
290 63: q BINPUT 3
291 65: K BININT1 1
292 67: J BININT -1
293 72: K BININT1 255
294 74: J BININT -255
295 79: J BININT -256
296 84: M BININT2 65535
297 87: J BININT -65535
298 92: J BININT -65536
299 97: J BININT 2147483647
300 102: J BININT -2147483647
301 107: J BININT -2147483648
302 112: ( MARK
303 113: U SHORT_BINSTRING 'abc'
304 118: q BINPUT 4
305 120: h BINGET 4
306 122: ( MARK
307 123: c GLOBAL '__main__ C'
308 135: q BINPUT 5
309 137: o OBJ (MARK at 122)
310 138: q BINPUT 6
311 140: } EMPTY_DICT
312 141: q BINPUT 7
313 143: ( MARK
314 144: U SHORT_BINSTRING 'foo'
315 149: q BINPUT 8
316 151: K BININT1 1
317 153: U SHORT_BINSTRING 'bar'
318 158: q BINPUT 9
319 160: K BININT1 2
320 162: u SETITEMS (MARK at 143)
321 163: b BUILD
322 164: h BINGET 6
323 166: t TUPLE (MARK at 112)
324 167: q BINPUT 10
325 169: h BINGET 10
326 171: K BININT1 5
327 173: e APPENDS (MARK at 3)
328 174: . STOP
329highest protocol among opcodes = 1
330"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000331
Tim Petersfc273752003-03-02 04:54:24 +0000332DATA2 = ('\x80\x02]q\x01(K\x00\x8a\x01\x01G@\x00\x00\x00\x00\x00\x00\x00'
333 'c__builtin__\ncomplex\nq\x02G@\x08\x00\x00\x00\x00\x00\x00G\x00'
334 '\x00\x00\x00\x00\x00\x00\x00\x86Rq\x03K\x01J\xff\xff\xff\xffK'
335 '\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xff'
336 'J\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00'
337 '\x80(U\x03abcq\x04h\x04(c__main__\nC\nq\x05oq\x06}q\x07(U\x03foo'
338 'q\x08K\x01U\x03barq\tK\x02ubh\x06tq\nh\nK\x05e.')
339
340# Disassembly of DATA2.
341DATA2_DIS = """\
342 0: \x80 PROTO 2
343 2: ] EMPTY_LIST
344 3: q BINPUT 1
345 5: ( MARK
346 6: K BININT1 0
347 8: \x8a LONG1 1L
348 11: G BINFLOAT 2.0
349 20: c GLOBAL '__builtin__ complex'
350 41: q BINPUT 2
351 43: G BINFLOAT 3.0
352 52: G BINFLOAT 0.0
353 61: \x86 TUPLE2
354 62: R REDUCE
355 63: q BINPUT 3
356 65: K BININT1 1
357 67: J BININT -1
358 72: K BININT1 255
359 74: J BININT -255
360 79: J BININT -256
361 84: M BININT2 65535
362 87: J BININT -65535
363 92: J BININT -65536
364 97: J BININT 2147483647
365 102: J BININT -2147483647
366 107: J BININT -2147483648
367 112: ( MARK
368 113: U SHORT_BINSTRING 'abc'
369 118: q BINPUT 4
370 120: h BINGET 4
371 122: ( MARK
372 123: c GLOBAL '__main__ C'
373 135: q BINPUT 5
374 137: o OBJ (MARK at 122)
375 138: q BINPUT 6
376 140: } EMPTY_DICT
377 141: q BINPUT 7
378 143: ( MARK
379 144: U SHORT_BINSTRING 'foo'
380 149: q BINPUT 8
381 151: K BININT1 1
382 153: U SHORT_BINSTRING 'bar'
383 158: q BINPUT 9
384 160: K BININT1 2
385 162: u SETITEMS (MARK at 143)
386 163: b BUILD
387 164: h BINGET 6
388 166: t TUPLE (MARK at 112)
389 167: q BINPUT 10
390 169: h BINGET 10
391 171: K BININT1 5
392 173: e APPENDS (MARK at 5)
393 174: . STOP
394highest protocol among opcodes = 2
395"""
396
Jeremy Hylton66426532001-10-15 21:38:56 +0000397def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000398 c = C()
399 c.foo = 1
400 c.bar = 2
401 x = [0, 1L, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000402 # Append some integer test cases at cPickle.c's internal size
403 # cutoffs.
404 uint1max = 0xff
405 uint2max = 0xffff
406 int4max = 0x7fffffff
407 x.extend([1, -1,
408 uint1max, -uint1max, -uint1max-1,
409 uint2max, -uint2max, -uint2max-1,
410 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000411 y = ('abc', 'abc', c, c)
412 x.append(y)
413 x.append(y)
414 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000415 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000416
Jeremy Hylton66426532001-10-15 21:38:56 +0000417class AbstractPickleTests(unittest.TestCase):
Tim Peters70b02d72003-02-02 17:26:40 +0000418 # Subclass must define self.dumps, self.loads, self.error.
Tim Petersc58440f2001-04-09 17:16:31 +0000419
Jeremy Hylton66426532001-10-15 21:38:56 +0000420 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000421
Jeremy Hylton66426532001-10-15 21:38:56 +0000422 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000423 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000424
Jeremy Hylton66426532001-10-15 21:38:56 +0000425 def test_misc(self):
426 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000427 for proto in protocols:
428 x = myint(4)
429 s = self.dumps(x, proto)
430 y = self.loads(s)
431 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000432
Tim Peters70b02d72003-02-02 17:26:40 +0000433 x = (1, ())
434 s = self.dumps(x, proto)
435 y = self.loads(s)
436 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000437
Tim Peters70b02d72003-02-02 17:26:40 +0000438 x = initarg(1, x)
439 s = self.dumps(x, proto)
440 y = self.loads(s)
441 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000442
Jeremy Hylton66426532001-10-15 21:38:56 +0000443 # XXX test __reduce__ protocol?
444
Tim Peters70b02d72003-02-02 17:26:40 +0000445 def test_roundtrip_equality(self):
446 expected = self._testdata
447 for proto in protocols:
448 s = self.dumps(expected, proto)
449 got = self.loads(s)
450 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000451
Tim Peters70b02d72003-02-02 17:26:40 +0000452 def test_load_from_canned_string(self):
453 expected = self._testdata
Tim Petersfc273752003-03-02 04:54:24 +0000454 for canned in DATA0, DATA1, DATA2:
Tim Peters70b02d72003-02-02 17:26:40 +0000455 got = self.loads(canned)
456 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000457
Tim Peters70b02d72003-02-02 17:26:40 +0000458 # There are gratuitous differences between pickles produced by
459 # pickle and cPickle, largely because cPickle starts PUT indices at
460 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
461 # there's a comment with an exclamation point there whose meaning
462 # is a mystery. cPickle also suppresses PUT for objects with a refcount
463 # of 1.
464 def dont_test_disassembly(self):
Tim Peters70b02d72003-02-02 17:26:40 +0000465 from pickletools import dis
466
467 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
468 s = self.dumps(self._testdata, proto)
Collin Winterf8089c72009-04-09 16:46:46 +0000469 filelike = cStringIO.StringIO()
Tim Peters70b02d72003-02-02 17:26:40 +0000470 dis(s, out=filelike)
471 got = filelike.getvalue()
472 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000473
474 def test_recursive_list(self):
475 l = []
476 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000477 for proto in protocols:
478 s = self.dumps(l, proto)
479 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000480 self.assertEqual(len(x), 1)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000481 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000482
Collin Winter57bef682009-05-26 04:12:39 +0000483 def test_recursive_tuple(self):
484 t = ([],)
485 t[0].append(t)
486 for proto in protocols:
487 s = self.dumps(t, proto)
488 x = self.loads(s)
489 self.assertEqual(len(x), 1)
490 self.assertEqual(len(x[0]), 1)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000491 self.assertTrue(x is x[0][0])
Collin Winter57bef682009-05-26 04:12:39 +0000492
Jeremy Hylton66426532001-10-15 21:38:56 +0000493 def test_recursive_dict(self):
494 d = {}
495 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000496 for proto in protocols:
497 s = self.dumps(d, proto)
498 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000499 self.assertEqual(x.keys(), [1])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000500 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000501
502 def test_recursive_inst(self):
503 i = C()
504 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000505 for proto in protocols:
Ezio Melottia84ecc62013-03-04 15:23:12 +0200506 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +0000507 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000508 self.assertEqual(dir(x), dir(i))
Ezio Melottia84ecc62013-03-04 15:23:12 +0200509 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000510
511 def test_recursive_multi(self):
512 l = []
513 d = {1:l}
514 i = C()
515 i.attr = d
516 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000517 for proto in protocols:
518 s = self.dumps(l, proto)
519 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000520 self.assertEqual(len(x), 1)
521 self.assertEqual(dir(x[0]), dir(i))
522 self.assertEqual(x[0].attr.keys(), [1])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000523 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000524
525 def test_garyp(self):
526 self.assertRaises(self.error, self.loads, 'garyp')
527
528 def test_insecure_strings(self):
529 insecure = ["abc", "2 + 2", # not quoted
Martin v. Löwis8a8da792002-08-14 07:46:28 +0000530 #"'abc' + 'def'", # not a single quoted string
Jeremy Hylton66426532001-10-15 21:38:56 +0000531 "'abc", # quote is not closed
532 "'abc\"", # open quote and close quote don't match
533 "'abc' ?", # junk after close quote
Martin v. Löwiseb3f00a2002-08-14 08:22:50 +0000534 "'\\'", # trailing backslash
Jeremy Hylton66426532001-10-15 21:38:56 +0000535 # some tests of the quoting rules
Martin v. Löwis8a8da792002-08-14 07:46:28 +0000536 #"'abc\"\''",
537 #"'\\\\a\'\'\'\\\'\\\\\''",
Jeremy Hylton66426532001-10-15 21:38:56 +0000538 ]
539 for s in insecure:
540 buf = "S" + s + "\012p0\012."
541 self.assertRaises(ValueError, self.loads, buf)
542
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000543 if have_unicode:
Jeremy Hylton66426532001-10-15 21:38:56 +0000544 def test_unicode(self):
Alexandre Vassalottie57e9992008-12-27 10:02:59 +0000545 endcases = [u'', u'<\\u>', u'<\\\u1234>', u'<\n>',
546 u'<\\>', u'<\\\U00012345>']
Tim Petersee1a53c2003-02-02 02:57:53 +0000547 for proto in protocols:
548 for u in endcases:
549 p = self.dumps(u, proto)
550 u2 = self.loads(p)
551 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000552
Alexandre Vassalottif852bf92008-12-27 07:08:47 +0000553 def test_unicode_high_plane(self):
554 t = u'\U00012345'
555 for proto in protocols:
556 p = self.dumps(t, proto)
557 t2 = self.loads(p)
558 self.assertEqual(t2, t)
559
Jeremy Hylton66426532001-10-15 21:38:56 +0000560 def test_ints(self):
561 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000562 for proto in protocols:
563 n = sys.maxint
564 while n:
565 for expected in (-n, n):
566 s = self.dumps(expected, proto)
567 n2 = self.loads(s)
568 self.assertEqual(expected, n2)
569 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000570
Jeremy Hylton66426532001-10-15 21:38:56 +0000571 def test_maxint64(self):
572 maxint64 = (1L << 63) - 1
573 data = 'I' + str(maxint64) + '\n.'
574 got = self.loads(data)
575 self.assertEqual(got, maxint64)
576
577 # Try too with a bogus literal.
578 data = 'I' + str(maxint64) + 'JUNK\n.'
579 self.assertRaises(ValueError, self.loads, data)
580
Tim Petersee1a53c2003-02-02 02:57:53 +0000581 def test_long(self):
582 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000583 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000584 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
585 nbase = 1L << nbits
586 for npos in nbase-1, nbase, nbase+1:
587 for n in npos, -npos:
588 pickle = self.dumps(n, proto)
589 got = self.loads(pickle)
590 self.assertEqual(n, got)
591 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
592 # bother with those.
Tim Petersee1a53c2003-02-02 02:57:53 +0000593 nbase = long("deadbeeffeedface", 16)
594 nbase += nbase << 1000000
595 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000596 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000597 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000598 self.assertEqual(n, got)
599
Mark Dickinsona3ecd2c2009-01-24 16:40:29 +0000600 def test_float(self):
601 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
602 3.14, 263.44582062374053, 6.022e23, 1e30]
603 test_values = test_values + [-x for x in test_values]
604 for proto in protocols:
605 for value in test_values:
606 pickle = self.dumps(value, proto)
607 got = self.loads(pickle)
608 self.assertEqual(value, got)
609
Georg Brandlde9b6242006-04-30 11:13:56 +0000610 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
611 def test_float_format(self):
612 # make sure that floats are formatted locale independent
613 self.assertEqual(self.dumps(1.2)[0:3], 'F1.')
614
Jeremy Hylton66426532001-10-15 21:38:56 +0000615 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000616 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000617
618 def test_getinitargs(self):
619 pass
620
Guido van Rossum04a86612001-12-19 16:58:54 +0000621 def test_metaclass(self):
622 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000623 for proto in protocols:
624 s = self.dumps(a, proto)
625 b = self.loads(s)
626 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000627
Antoine Pitrou561a8212011-10-04 09:34:48 +0200628 def test_dynamic_class(self):
629 a = create_dynamic_class("my_dynamic_class", (object,))
630 copy_reg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
631 for proto in protocols:
632 s = self.dumps(a, proto)
633 b = self.loads(s)
634 self.assertEqual(a, b)
635
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000636 def test_structseq(self):
637 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000638 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000639
640 t = time.localtime()
641 for proto in protocols:
642 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000643 u = self.loads(s)
644 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000645 if hasattr(os, "stat"):
646 t = os.stat(os.curdir)
647 s = self.dumps(t, proto)
648 u = self.loads(s)
649 self.assertEqual(t, u)
650 if hasattr(os, "statvfs"):
651 t = os.statvfs(os.curdir)
652 s = self.dumps(t, proto)
653 u = self.loads(s)
654 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000655
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000656 # Tests for protocol 2
657
Tim Peters4190fb82003-02-02 16:09:05 +0000658 def test_proto(self):
659 build_none = pickle.NONE + pickle.STOP
660 for proto in protocols:
661 expected = build_none
662 if proto >= 2:
663 expected = pickle.PROTO + chr(proto) + expected
664 p = self.dumps(None, proto)
665 self.assertEqual(p, expected)
666
667 oob = protocols[-1] + 1 # a future protocol
668 badpickle = pickle.PROTO + chr(oob) + build_none
669 try:
670 self.loads(badpickle)
671 except ValueError, detail:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000672 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +0000673 "unsupported pickle protocol"))
674 else:
675 self.fail("expected bad protocol number to raise ValueError")
676
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000677 def test_long1(self):
678 x = 12345678910111213141516178920L
Tim Peters61bf2572003-02-03 21:31:22 +0000679 for proto in protocols:
680 s = self.dumps(x, proto)
681 y = self.loads(s)
682 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000683 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000684
685 def test_long4(self):
686 x = 12345678910111213141516178920L << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000687 for proto in protocols:
688 s = self.dumps(x, proto)
689 y = self.loads(s)
690 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000691 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000692
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000693 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000694 # Map (proto, len(tuple)) to expected opcode.
695 expected_opcode = {(0, 0): pickle.TUPLE,
696 (0, 1): pickle.TUPLE,
697 (0, 2): pickle.TUPLE,
698 (0, 3): pickle.TUPLE,
699 (0, 4): pickle.TUPLE,
700
701 (1, 0): pickle.EMPTY_TUPLE,
702 (1, 1): pickle.TUPLE,
703 (1, 2): pickle.TUPLE,
704 (1, 3): pickle.TUPLE,
705 (1, 4): pickle.TUPLE,
706
707 (2, 0): pickle.EMPTY_TUPLE,
708 (2, 1): pickle.TUPLE1,
709 (2, 2): pickle.TUPLE2,
710 (2, 3): pickle.TUPLE3,
711 (2, 4): pickle.TUPLE,
712 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000713 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000714 b = (1,)
715 c = (1, 2)
716 d = (1, 2, 3)
717 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000718 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000719 for x in a, b, c, d, e:
720 s = self.dumps(x, proto)
721 y = self.loads(s)
722 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000723 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +0000724 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +0000725
Guido van Rossum7d97d312003-01-28 04:25:27 +0000726 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000727 # Map (proto, singleton) to expected opcode.
728 expected_opcode = {(0, None): pickle.NONE,
729 (1, None): pickle.NONE,
730 (2, None): pickle.NONE,
731
732 (0, True): pickle.INT,
733 (1, True): pickle.INT,
734 (2, True): pickle.NEWTRUE,
735
736 (0, False): pickle.INT,
737 (1, False): pickle.INT,
738 (2, False): pickle.NEWFALSE,
739 }
Tim Peters4190fb82003-02-02 16:09:05 +0000740 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000741 for x in None, False, True:
742 s = self.dumps(x, proto)
743 y = self.loads(s)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000744 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +0000745 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +0000746 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +0000747
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000748 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000749 x = MyTuple([1, 2, 3])
750 x.foo = 42
751 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000752 for proto in protocols:
753 s = self.dumps(x, proto)
754 y = self.loads(s)
755 self.assertEqual(tuple(x), tuple(y))
756 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000757
758 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000759 x = MyList([1, 2, 3])
760 x.foo = 42
761 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000762 for proto in protocols:
763 s = self.dumps(x, proto)
764 y = self.loads(s)
765 self.assertEqual(list(x), list(y))
766 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000767
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000768 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +0000769 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000770 for C in myclasses:
771 B = C.__base__
772 x = C(C.sample)
773 x.foo = 42
774 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000775 y = self.loads(s)
776 detail = (proto, C, B, x, y, type(y))
777 self.assertEqual(B(x), B(y), detail)
778 self.assertEqual(x.__dict__, y.__dict__, detail)
779
Georg Brandldffbf5f2008-05-20 07:49:57 +0000780 # Register a type with copy_reg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +0000781 # an object of that type. Check that the resulting pickle uses opcode
782 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +0000783
Tim Peters22e71712003-02-03 22:27:38 +0000784 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +0000785 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000786 try:
Georg Brandldffbf5f2008-05-20 07:49:57 +0000787 copy_reg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000788 x = MyList([1, 2, 3])
789 x.foo = 42
790 x.bar = "hello"
791
Tim Peters22e71712003-02-03 22:27:38 +0000792 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000793 s1 = self.dumps(x, 1)
Ezio Melottiaa980582010-01-23 23:04:36 +0000794 self.assertIn(__name__, s1)
795 self.assertIn("MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +0000796 self.assertEqual(opcode_in_pickle(opcode, s1), False)
797
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000798 y = self.loads(s1)
799 self.assertEqual(list(x), list(y))
800 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000801
Tim Peters22e71712003-02-03 22:27:38 +0000802 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000803 s2 = self.dumps(x, 2)
Ezio Melottiaa980582010-01-23 23:04:36 +0000804 self.assertNotIn(__name__, s2)
805 self.assertNotIn("MyList", s2)
Tim Peters3e667d52003-02-04 21:47:44 +0000806 self.assertEqual(opcode_in_pickle(opcode, s2), True)
807
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000808 y = self.loads(s2)
809 self.assertEqual(list(x), list(y))
810 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000811
812 finally:
Tim Peters3e667d52003-02-04 21:47:44 +0000813 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +0000814
815 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000816 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
817 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000818
819 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000820 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
821 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
822 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000823
824 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000825 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
826 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
827 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
828
Tim Peters8d2613a2003-02-11 16:40:16 +0000829 def test_list_chunking(self):
830 n = 10 # too small to chunk
831 x = range(n)
832 for proto in protocols:
833 s = self.dumps(x, proto)
834 y = self.loads(s)
835 self.assertEqual(x, y)
836 num_appends = count_opcode(pickle.APPENDS, s)
837 self.assertEqual(num_appends, proto > 0)
838
839 n = 2500 # expect at least two chunks when proto > 0
840 x = range(n)
841 for proto in protocols:
842 s = self.dumps(x, proto)
843 y = self.loads(s)
844 self.assertEqual(x, y)
845 num_appends = count_opcode(pickle.APPENDS, s)
846 if proto == 0:
847 self.assertEqual(num_appends, 0)
848 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000849 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +0000850
851 def test_dict_chunking(self):
852 n = 10 # too small to chunk
853 x = dict.fromkeys(range(n))
854 for proto in protocols:
855 s = self.dumps(x, proto)
856 y = self.loads(s)
857 self.assertEqual(x, y)
858 num_setitems = count_opcode(pickle.SETITEMS, s)
859 self.assertEqual(num_setitems, proto > 0)
860
861 n = 2500 # expect at least two chunks when proto > 0
862 x = dict.fromkeys(range(n))
863 for proto in protocols:
864 s = self.dumps(x, proto)
865 y = self.loads(s)
866 self.assertEqual(x, y)
867 num_setitems = count_opcode(pickle.SETITEMS, s)
868 if proto == 0:
869 self.assertEqual(num_setitems, 0)
870 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000871 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000872
Tim Peterse9ef2032003-02-13 18:42:00 +0000873 def test_simple_newobj(self):
874 x = object.__new__(SimpleNewObj) # avoid __init__
875 x.abc = 666
876 for proto in protocols:
877 s = self.dumps(x, proto)
878 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
879 y = self.loads(s) # will raise TypeError if __init__ called
880 self.assertEqual(y.abc, 666)
881 self.assertEqual(x.__dict__, y.__dict__)
882
Tim Peters42f08ac2003-02-11 22:43:24 +0000883 def test_newobj_list_slots(self):
884 x = SlotList([1, 2, 3])
885 x.foo = 42
886 x.bar = "hello"
887 s = self.dumps(x, 2)
888 y = self.loads(s)
889 self.assertEqual(list(x), list(y))
890 self.assertEqual(x.__dict__, y.__dict__)
891 self.assertEqual(x.foo, y.foo)
892 self.assertEqual(x.bar, y.bar)
893
Guido van Rossum2a30b212003-02-18 22:41:24 +0000894 def test_reduce_overrides_default_reduce_ex(self):
Collin Winterf8089c72009-04-09 16:46:46 +0000895 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000896 x = REX_one()
897 self.assertEqual(x._reduce_called, 0)
898 s = self.dumps(x, proto)
899 self.assertEqual(x._reduce_called, 1)
900 y = self.loads(s)
901 self.assertEqual(y._reduce_called, 0)
902
903 def test_reduce_ex_called(self):
Collin Winterf8089c72009-04-09 16:46:46 +0000904 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000905 x = REX_two()
906 self.assertEqual(x._proto, None)
907 s = self.dumps(x, proto)
908 self.assertEqual(x._proto, proto)
909 y = self.loads(s)
910 self.assertEqual(y._proto, None)
911
912 def test_reduce_ex_overrides_reduce(self):
Collin Winterf8089c72009-04-09 16:46:46 +0000913 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000914 x = REX_three()
915 self.assertEqual(x._proto, None)
916 s = self.dumps(x, proto)
917 self.assertEqual(x._proto, proto)
918 y = self.loads(s)
919 self.assertEqual(y._proto, None)
920
Žiga Seilnacht20f43d32007-03-15 11:44:55 +0000921 def test_reduce_ex_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +0000922 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +0000923 x = REX_four()
924 self.assertEqual(x._proto, None)
925 s = self.dumps(x, proto)
926 self.assertEqual(x._proto, proto)
927 y = self.loads(s)
928 self.assertEqual(y._proto, proto)
929
930 def test_reduce_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +0000931 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +0000932 x = REX_five()
933 self.assertEqual(x._reduce_called, 0)
934 s = self.dumps(x, proto)
935 self.assertEqual(x._reduce_called, 1)
936 y = self.loads(s)
937 self.assertEqual(y._reduce_called, 1)
938
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +0000939 def test_reduce_bad_iterator(self):
940 # Issue4176: crash when 4th and 5th items of __reduce__()
941 # are not iterators
942 class C(object):
943 def __reduce__(self):
944 # 4th item is not an iterator
945 return list, (), None, [], None
946 class D(object):
947 def __reduce__(self):
948 # 5th item is not an iterator
949 return dict, (), None, None, []
950
951 # Protocol 0 is less strict and also accept iterables.
Collin Winterf8089c72009-04-09 16:46:46 +0000952 for proto in protocols:
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +0000953 try:
954 self.dumps(C(), proto)
955 except (AttributeError, pickle.PickleError, cPickle.PickleError):
956 pass
957 try:
958 self.dumps(D(), proto)
959 except (AttributeError, pickle.PickleError, cPickle.PickleError):
960 pass
961
Collin Winterf8089c72009-04-09 16:46:46 +0000962 def test_many_puts_and_gets(self):
963 # Test that internal data structures correctly deal with lots of
964 # puts/gets.
965 keys = ("aaa" + str(i) for i in xrange(100))
966 large_dict = dict((k, [4, 5, 6]) for k in keys)
967 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
968
969 for proto in protocols:
970 dumped = self.dumps(obj, proto)
971 loaded = self.loads(dumped)
972 self.assertEqual(loaded, obj,
973 "Failed protocol %d: %r != %r"
974 % (proto, obj, loaded))
975
Antoine Pitrou74309892009-05-02 21:13:23 +0000976 def test_attribute_name_interning(self):
977 # Test that attribute names of pickled objects are interned when
978 # unpickling.
979 for proto in protocols:
980 x = C()
981 x.foo = 42
982 x.bar = "hello"
983 s = self.dumps(x, proto)
984 y = self.loads(s)
985 x_keys = sorted(x.__dict__)
986 y_keys = sorted(y.__dict__)
987 for x_key, y_key in zip(x_keys, y_keys):
988 self.assertIs(x_key, y_key)
989
Collin Winterf8089c72009-04-09 16:46:46 +0000990
Guido van Rossum2a30b212003-02-18 22:41:24 +0000991# Test classes for reduce_ex
992
993class REX_one(object):
994 _reduce_called = 0
995 def __reduce__(self):
996 self._reduce_called = 1
997 return REX_one, ()
998 # No __reduce_ex__ here, but inheriting it from object
999
1000class REX_two(object):
1001 _proto = None
1002 def __reduce_ex__(self, proto):
1003 self._proto = proto
1004 return REX_two, ()
1005 # No __reduce__ here, but inheriting it from object
1006
1007class REX_three(object):
1008 _proto = None
1009 def __reduce_ex__(self, proto):
1010 self._proto = proto
1011 return REX_two, ()
1012 def __reduce__(self):
1013 raise TestFailed, "This __reduce__ shouldn't be called"
1014
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001015class REX_four(object):
1016 _proto = None
1017 def __reduce_ex__(self, proto):
1018 self._proto = proto
1019 return object.__reduce_ex__(self, proto)
1020 # Calling base class method should succeed
1021
1022class REX_five(object):
1023 _reduce_called = 0
1024 def __reduce__(self):
1025 self._reduce_called = 1
1026 return object.__reduce__(self)
1027 # This one used to fail with infinite recursion
1028
Guido van Rossum2a30b212003-02-18 22:41:24 +00001029# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001030
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001031class MyInt(int):
1032 sample = 1
1033
1034class MyLong(long):
1035 sample = 1L
1036
1037class MyFloat(float):
1038 sample = 1.0
1039
1040class MyComplex(complex):
1041 sample = 1.0 + 0.0j
1042
1043class MyStr(str):
1044 sample = "hello"
1045
1046class MyUnicode(unicode):
1047 sample = u"hello \u1234"
1048
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001049class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001050 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001051
1052class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001053 sample = [1, 2, 3]
1054
1055class MyDict(dict):
1056 sample = {"a": 1, "b": 2}
1057
1058myclasses = [MyInt, MyLong, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001059 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001060 MyStr, MyUnicode,
1061 MyTuple, MyList, MyDict]
1062
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001063
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001064class SlotList(MyList):
1065 __slots__ = ["foo"]
1066
Tim Peterse9ef2032003-02-13 18:42:00 +00001067class SimpleNewObj(object):
1068 def __init__(self, a, b, c):
1069 # raise an error, to make sure this isn't called
1070 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1071
Jeremy Hylton66426532001-10-15 21:38:56 +00001072class AbstractPickleModuleTests(unittest.TestCase):
1073
1074 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001075 import os
1076 f = open(TESTFN, "w")
1077 try:
1078 f.close()
1079 self.assertRaises(ValueError, self.module.dump, 123, f)
1080 finally:
1081 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001082
1083 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001084 import os
1085 f = open(TESTFN, "w")
1086 try:
1087 f.close()
1088 self.assertRaises(ValueError, self.module.dump, 123, f)
1089 finally:
1090 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001091
Collin Winterf8089c72009-04-09 16:46:46 +00001092 def test_load_from_and_dump_to_file(self):
1093 stream = cStringIO.StringIO()
1094 data = [123, {}, 124]
1095 self.module.dump(data, stream)
1096 stream.seek(0)
1097 unpickled = self.module.load(stream)
1098 self.assertEqual(unpickled, data)
1099
Tim Petersc0c93702003-02-13 19:30:57 +00001100 def test_highest_protocol(self):
1101 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
1102 self.assertEqual(self.module.HIGHEST_PROTOCOL, 2)
1103
Martin v. Löwis544f1192004-07-27 05:22:33 +00001104 def test_callapi(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001105 f = cStringIO.StringIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001106 # With and without keyword arguments
1107 self.module.dump(123, f, -1)
1108 self.module.dump(123, file=f, protocol=-1)
1109 self.module.dumps(123, -1)
1110 self.module.dumps(123, protocol=-1)
1111 self.module.Pickler(f, -1)
1112 self.module.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001113
Amaury Forgeot d'Arc74b30162009-07-23 19:26:02 +00001114 def test_incomplete_input(self):
1115 s = StringIO.StringIO("X''.")
1116 self.assertRaises(EOFError, self.module.load, s)
1117
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001118 def test_restricted(self):
1119 # issue7128: cPickle failed in restricted mode
1120 builtins = {self.module.__name__: self.module,
1121 '__import__': __import__}
1122 d = {}
1123 teststr = "def f(): {0}.dumps(0)".format(self.module.__name__)
1124 exec teststr in {'__builtins__': builtins}, d
1125 d['f']()
1126
Antoine Pitrou0d423b82010-01-07 17:46:49 +00001127 def test_bad_input(self):
1128 # Test issue4298
1129 s = '\x58\0\0\0\x54'
1130 self.assertRaises(EOFError, self.module.loads, s)
1131 # Test issue7455
1132 s = '0'
1133 # XXX Why doesn't pickle raise UnpicklingError?
1134 self.assertRaises((IndexError, cPickle.UnpicklingError),
1135 self.module.loads, s)
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001136
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001137class AbstractPersistentPicklerTests(unittest.TestCase):
1138
1139 # This class defines persistent_id() and persistent_load()
1140 # functions that should be used by the pickler. All even integers
1141 # are pickled using persistent ids.
1142
1143 def persistent_id(self, object):
1144 if isinstance(object, int) and object % 2 == 0:
1145 self.id_count += 1
1146 return str(object)
1147 else:
1148 return None
1149
1150 def persistent_load(self, oid):
1151 self.load_count += 1
1152 object = int(oid)
1153 assert object % 2 == 0
1154 return object
1155
1156 def test_persistence(self):
1157 self.id_count = 0
1158 self.load_count = 0
1159 L = range(10)
1160 self.assertEqual(self.loads(self.dumps(L)), L)
1161 self.assertEqual(self.id_count, 5)
1162 self.assertEqual(self.load_count, 5)
1163
1164 def test_bin_persistence(self):
1165 self.id_count = 0
1166 self.load_count = 0
1167 L = range(10)
1168 self.assertEqual(self.loads(self.dumps(L, 1)), L)
1169 self.assertEqual(self.id_count, 5)
1170 self.assertEqual(self.load_count, 5)
Collin Winterf8089c72009-04-09 16:46:46 +00001171
1172class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1173
1174 pickler_class = None
1175 unpickler_class = None
1176
1177 def setUp(self):
1178 assert self.pickler_class
1179 assert self.unpickler_class
1180
1181 def test_clear_pickler_memo(self):
1182 # To test whether clear_memo() has any effect, we pickle an object,
1183 # then pickle it again without clearing the memo; the two serialized
1184 # forms should be different. If we clear_memo() and then pickle the
1185 # object again, the third serialized form should be identical to the
1186 # first one we obtained.
1187 data = ["abcdefg", "abcdefg", 44]
1188 f = cStringIO.StringIO()
1189 pickler = self.pickler_class(f)
1190
1191 pickler.dump(data)
1192 first_pickled = f.getvalue()
1193
1194 # Reset StringIO object.
1195 f.seek(0)
1196 f.truncate()
1197
1198 pickler.dump(data)
1199 second_pickled = f.getvalue()
1200
1201 # Reset the Pickler and StringIO objects.
1202 pickler.clear_memo()
1203 f.seek(0)
1204 f.truncate()
1205
1206 pickler.dump(data)
1207 third_pickled = f.getvalue()
1208
1209 self.assertNotEqual(first_pickled, second_pickled)
1210 self.assertEqual(first_pickled, third_pickled)
1211
1212 def test_priming_pickler_memo(self):
1213 # Verify that we can set the Pickler's memo attribute.
1214 data = ["abcdefg", "abcdefg", 44]
1215 f = cStringIO.StringIO()
1216 pickler = self.pickler_class(f)
1217
1218 pickler.dump(data)
1219 first_pickled = f.getvalue()
1220
1221 f = cStringIO.StringIO()
1222 primed = self.pickler_class(f)
1223 primed.memo = pickler.memo
1224
1225 primed.dump(data)
1226 primed_pickled = f.getvalue()
1227
1228 self.assertNotEqual(first_pickled, primed_pickled)
1229
1230 def test_priming_unpickler_memo(self):
1231 # Verify that we can set the Unpickler's memo attribute.
1232 data = ["abcdefg", "abcdefg", 44]
1233 f = cStringIO.StringIO()
1234 pickler = self.pickler_class(f)
1235
1236 pickler.dump(data)
1237 first_pickled = f.getvalue()
1238
1239 f = cStringIO.StringIO()
1240 primed = self.pickler_class(f)
1241 primed.memo = pickler.memo
1242
1243 primed.dump(data)
1244 primed_pickled = f.getvalue()
1245
1246 unpickler = self.unpickler_class(cStringIO.StringIO(first_pickled))
1247 unpickled_data1 = unpickler.load()
1248
1249 self.assertEqual(unpickled_data1, data)
1250
1251 primed = self.unpickler_class(cStringIO.StringIO(primed_pickled))
1252 primed.memo = unpickler.memo
1253 unpickled_data2 = primed.load()
1254
1255 primed.memo.clear()
1256
1257 self.assertEqual(unpickled_data2, data)
1258 self.assertTrue(unpickled_data2 is unpickled_data1)
1259
1260 def test_reusing_unpickler_objects(self):
1261 data1 = ["abcdefg", "abcdefg", 44]
1262 f = cStringIO.StringIO()
1263 pickler = self.pickler_class(f)
1264 pickler.dump(data1)
1265 pickled1 = f.getvalue()
1266
1267 data2 = ["abcdefg", 44, 44]
1268 f = cStringIO.StringIO()
1269 pickler = self.pickler_class(f)
1270 pickler.dump(data2)
1271 pickled2 = f.getvalue()
1272
1273 f = cStringIO.StringIO()
1274 f.write(pickled1)
1275 f.seek(0)
1276 unpickler = self.unpickler_class(f)
1277 self.assertEqual(unpickler.load(), data1)
1278
1279 f.seek(0)
1280 f.truncate()
1281 f.write(pickled2)
1282 f.seek(0)
1283 self.assertEqual(unpickler.load(), data2)
Serhiy Storchakacdc7a912013-02-12 21:36:47 +02001284
1285class BigmemPickleTests(unittest.TestCase):
1286
1287 # Memory requirements: 1 byte per character for input strings, 1 byte
1288 # for pickled data, 1 byte for unpickled strings, 1 byte for internal
1289 # buffer and 1 byte of free space for resizing of internal buffer.
1290
1291 @precisionbigmemtest(size=_2G + 100*_1M, memuse=5)
1292 def test_huge_strlist(self, size):
1293 chunksize = 2**20
1294 data = []
1295 while size > chunksize:
1296 data.append('x' * chunksize)
1297 size -= chunksize
1298 chunksize += 1
1299 data.append('y' * size)
1300
1301 try:
1302 for proto in protocols:
1303 try:
1304 pickled = self.dumps(data, proto)
1305 res = self.loads(pickled)
1306 self.assertEqual(res, data)
1307 finally:
1308 res = None
1309 pickled = None
1310 finally:
1311 data = None