blob: c321f8e78a593f8dade95d9538fd53e90c375019 [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
Collin Winterf8089c72009-04-09 16:46:46 +00009from test.test_support import TestFailed, have_unicode, TESTFN
Tim Peterse089c682001-04-10 03:41:41 +000010
Tim Petersee1a53c2003-02-02 02:57:53 +000011# Tests that try a number of pickle protocols should have a
12# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000013# kind of outer loop.
14assert pickle.HIGHEST_PROTOCOL == cPickle.HIGHEST_PROTOCOL == 2
15protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000016
Collin Winterf8089c72009-04-09 16:46:46 +000017# Copy of test.test_support.run_with_locale. This is needed to support Python
18# 2.4, which didn't include it. This is all to support test_xpickle, which
19# bounces pickled objects through older Python versions to test backwards
20# compatibility.
21def run_with_locale(catstr, *locales):
22 def decorator(func):
23 def inner(*args, **kwds):
24 try:
25 import locale
26 category = getattr(locale, catstr)
27 orig_locale = locale.setlocale(category)
28 except AttributeError:
29 # if the test author gives us an invalid category string
30 raise
31 except:
32 # cannot retrieve original locale, so do nothing
33 locale = orig_locale = None
34 else:
35 for loc in locales:
36 try:
37 locale.setlocale(category, loc)
38 break
39 except:
40 pass
41
42 # now run the function, resetting the locale on exceptions
43 try:
44 return func(*args, **kwds)
45 finally:
46 if locale and orig_locale:
47 locale.setlocale(category, orig_locale)
48 inner.func_name = func.func_name
49 inner.__doc__ = func.__doc__
50 return inner
51 return decorator
52
Tim Peters22e71712003-02-03 22:27:38 +000053
54# Return True if opcode code appears in the pickle, else False.
55def opcode_in_pickle(code, pickle):
56 for op, dummy, dummy in pickletools.genops(pickle):
57 if op.code == code:
58 return True
59 return False
60
Tim Peters8d2613a2003-02-11 16:40:16 +000061# Return the number of times opcode code appears in pickle.
62def count_opcode(code, pickle):
63 n = 0
64 for op, dummy, dummy in pickletools.genops(pickle):
65 if op.code == code:
66 n += 1
67 return n
68
Tim Peters3e667d52003-02-04 21:47:44 +000069# We can't very well test the extension registry without putting known stuff
70# in it, but we have to be careful to restore its original state. Code
71# should do this:
72#
73# e = ExtensionSaver(extension_code)
74# try:
75# fiddle w/ the extension registry's stuff for extension_code
76# finally:
77# e.restore()
78
79class ExtensionSaver:
80 # Remember current registration for code (if any), and remove it (if
81 # there is one).
82 def __init__(self, code):
83 self.code = code
Georg Brandldffbf5f2008-05-20 07:49:57 +000084 if code in copy_reg._inverted_registry:
85 self.pair = copy_reg._inverted_registry[code]
86 copy_reg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000087 else:
88 self.pair = None
89
90 # Restore previous registration for code.
91 def restore(self):
92 code = self.code
Georg Brandldffbf5f2008-05-20 07:49:57 +000093 curpair = copy_reg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000094 if curpair is not None:
Georg Brandldffbf5f2008-05-20 07:49:57 +000095 copy_reg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000096 pair = self.pair
97 if pair is not None:
Georg Brandldffbf5f2008-05-20 07:49:57 +000098 copy_reg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000099
Jeremy Hylton66426532001-10-15 21:38:56 +0000100class C:
101 def __cmp__(self, other):
102 return cmp(self.__dict__, other.__dict__)
103
104import __main__
105__main__.C = C
106C.__module__ = "__main__"
107
108class myint(int):
109 def __init__(self, x):
110 self.str = str(x)
111
112class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000113
Jeremy Hylton66426532001-10-15 21:38:56 +0000114 def __init__(self, a, b):
115 self.a = a
116 self.b = b
117
118 def __getinitargs__(self):
119 return self.a, self.b
120
Guido van Rossum04a86612001-12-19 16:58:54 +0000121class metaclass(type):
122 pass
123
124class use_metaclass(object):
125 __metaclass__ = metaclass
126
Antoine Pitrou561a8212011-10-04 09:34:48 +0200127class pickling_metaclass(type):
128 def __eq__(self, other):
129 return (type(self) == type(other) and
130 self.reduce_args == other.reduce_args)
131
132 def __reduce__(self):
133 return (create_dynamic_class, self.reduce_args)
134
Ezio Melotti030aa352011-11-06 18:50:32 +0200135 __hash__ = None
136
Antoine Pitrou561a8212011-10-04 09:34:48 +0200137def create_dynamic_class(name, bases):
138 result = pickling_metaclass(name, bases, dict())
139 result.reduce_args = (name, bases)
140 return result
141
Tim Peters70b02d72003-02-02 17:26:40 +0000142# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
143# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000144
Jeremy Hylton66426532001-10-15 21:38:56 +0000145# break into multiple strings to avoid confusing font-lock-mode
Tim Peters70b02d72003-02-02 17:26:40 +0000146DATA0 = """(lp1
Tim Peterse9358162001-01-22 22:05:20 +0000147I0
148aL1L
Tim Peters461922a2001-04-09 20:07:05 +0000149aF2
Tim Peterse9358162001-01-22 22:05:20 +0000150ac__builtin__
151complex
Tim Peters461922a2001-04-09 20:07:05 +0000152p2
153""" + \
154"""(F3
155F0
156tRp3
157aI1
158aI-1
159aI255
160aI-255
161aI-256
162aI65535
163aI-65535
164aI-65536
165aI2147483647
166aI-2147483647
167aI-2147483648
168a""" + \
169"""(S'abc'
Tim Peterse9358162001-01-22 22:05:20 +0000170p4
171g4
Tim Peters461922a2001-04-09 20:07:05 +0000172""" + \
Guido van Rossum42f92da2001-04-16 00:28:21 +0000173"""(i__main__
Tim Peterse9358162001-01-22 22:05:20 +0000174C
175p5
Tim Peters461922a2001-04-09 20:07:05 +0000176""" + \
Tim Peterse9358162001-01-22 22:05:20 +0000177"""(dp6
178S'foo'
179p7
180I1
181sS'bar'
182p8
183I2
184sbg5
185tp9
186ag9
187aI5
188a.
189"""
190
Tim Peters70b02d72003-02-02 17:26:40 +0000191# Disassembly of DATA0.
192DATA0_DIS = """\
193 0: ( MARK
194 1: l LIST (MARK at 0)
195 2: p PUT 1
196 5: I INT 0
197 8: a APPEND
198 9: L LONG 1L
199 13: a APPEND
200 14: F FLOAT 2.0
201 17: a APPEND
202 18: c GLOBAL '__builtin__ complex'
203 39: p PUT 2
204 42: ( MARK
205 43: F FLOAT 3.0
206 46: F FLOAT 0.0
207 49: t TUPLE (MARK at 42)
208 50: R REDUCE
209 51: p PUT 3
210 54: a APPEND
211 55: I INT 1
212 58: a APPEND
213 59: I INT -1
214 63: a APPEND
215 64: I INT 255
216 69: a APPEND
217 70: I INT -255
218 76: a APPEND
219 77: I INT -256
220 83: a APPEND
221 84: I INT 65535
222 91: a APPEND
223 92: I INT -65535
224 100: a APPEND
225 101: I INT -65536
226 109: a APPEND
227 110: I INT 2147483647
228 122: a APPEND
229 123: I INT -2147483647
230 136: a APPEND
231 137: I INT -2147483648
232 150: a APPEND
233 151: ( MARK
234 152: S STRING 'abc'
235 159: p PUT 4
236 162: g GET 4
237 165: ( MARK
238 166: i INST '__main__ C' (MARK at 165)
239 178: p PUT 5
240 181: ( MARK
241 182: d DICT (MARK at 181)
242 183: p PUT 6
243 186: S STRING 'foo'
244 193: p PUT 7
245 196: I INT 1
246 199: s SETITEM
247 200: S STRING 'bar'
248 207: p PUT 8
249 210: I INT 2
250 213: s SETITEM
251 214: b BUILD
252 215: g GET 5
253 218: t TUPLE (MARK at 151)
254 219: p PUT 9
255 222: a APPEND
256 223: g GET 9
257 226: a APPEND
258 227: I INT 5
259 230: a APPEND
260 231: . STOP
261highest protocol among opcodes = 0
262"""
263
264DATA1 = (']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00'
265 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00'
266 '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff'
267 '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff'
268 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00'
269 '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n'
270 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh'
271 '\x06tq\nh\nK\x05e.'
272 )
273
274# Disassembly of DATA1.
275DATA1_DIS = """\
276 0: ] EMPTY_LIST
277 1: q BINPUT 1
278 3: ( MARK
279 4: K BININT1 0
280 6: L LONG 1L
281 10: G BINFLOAT 2.0
282 19: c GLOBAL '__builtin__ complex'
283 40: q BINPUT 2
284 42: ( MARK
285 43: G BINFLOAT 3.0
286 52: G BINFLOAT 0.0
287 61: t TUPLE (MARK at 42)
288 62: R REDUCE
289 63: q BINPUT 3
290 65: K BININT1 1
291 67: J BININT -1
292 72: K BININT1 255
293 74: J BININT -255
294 79: J BININT -256
295 84: M BININT2 65535
296 87: J BININT -65535
297 92: J BININT -65536
298 97: J BININT 2147483647
299 102: J BININT -2147483647
300 107: J BININT -2147483648
301 112: ( MARK
302 113: U SHORT_BINSTRING 'abc'
303 118: q BINPUT 4
304 120: h BINGET 4
305 122: ( MARK
306 123: c GLOBAL '__main__ C'
307 135: q BINPUT 5
308 137: o OBJ (MARK at 122)
309 138: q BINPUT 6
310 140: } EMPTY_DICT
311 141: q BINPUT 7
312 143: ( MARK
313 144: U SHORT_BINSTRING 'foo'
314 149: q BINPUT 8
315 151: K BININT1 1
316 153: U SHORT_BINSTRING 'bar'
317 158: q BINPUT 9
318 160: K BININT1 2
319 162: u SETITEMS (MARK at 143)
320 163: b BUILD
321 164: h BINGET 6
322 166: t TUPLE (MARK at 112)
323 167: q BINPUT 10
324 169: h BINGET 10
325 171: K BININT1 5
326 173: e APPENDS (MARK at 3)
327 174: . STOP
328highest protocol among opcodes = 1
329"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000330
Tim Petersfc273752003-03-02 04:54:24 +0000331DATA2 = ('\x80\x02]q\x01(K\x00\x8a\x01\x01G@\x00\x00\x00\x00\x00\x00\x00'
332 'c__builtin__\ncomplex\nq\x02G@\x08\x00\x00\x00\x00\x00\x00G\x00'
333 '\x00\x00\x00\x00\x00\x00\x00\x86Rq\x03K\x01J\xff\xff\xff\xffK'
334 '\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xff'
335 'J\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00'
336 '\x80(U\x03abcq\x04h\x04(c__main__\nC\nq\x05oq\x06}q\x07(U\x03foo'
337 'q\x08K\x01U\x03barq\tK\x02ubh\x06tq\nh\nK\x05e.')
338
339# Disassembly of DATA2.
340DATA2_DIS = """\
341 0: \x80 PROTO 2
342 2: ] EMPTY_LIST
343 3: q BINPUT 1
344 5: ( MARK
345 6: K BININT1 0
346 8: \x8a LONG1 1L
347 11: G BINFLOAT 2.0
348 20: c GLOBAL '__builtin__ complex'
349 41: q BINPUT 2
350 43: G BINFLOAT 3.0
351 52: G BINFLOAT 0.0
352 61: \x86 TUPLE2
353 62: R REDUCE
354 63: q BINPUT 3
355 65: K BININT1 1
356 67: J BININT -1
357 72: K BININT1 255
358 74: J BININT -255
359 79: J BININT -256
360 84: M BININT2 65535
361 87: J BININT -65535
362 92: J BININT -65536
363 97: J BININT 2147483647
364 102: J BININT -2147483647
365 107: J BININT -2147483648
366 112: ( MARK
367 113: U SHORT_BINSTRING 'abc'
368 118: q BINPUT 4
369 120: h BINGET 4
370 122: ( MARK
371 123: c GLOBAL '__main__ C'
372 135: q BINPUT 5
373 137: o OBJ (MARK at 122)
374 138: q BINPUT 6
375 140: } EMPTY_DICT
376 141: q BINPUT 7
377 143: ( MARK
378 144: U SHORT_BINSTRING 'foo'
379 149: q BINPUT 8
380 151: K BININT1 1
381 153: U SHORT_BINSTRING 'bar'
382 158: q BINPUT 9
383 160: K BININT1 2
384 162: u SETITEMS (MARK at 143)
385 163: b BUILD
386 164: h BINGET 6
387 166: t TUPLE (MARK at 112)
388 167: q BINPUT 10
389 169: h BINGET 10
390 171: K BININT1 5
391 173: e APPENDS (MARK at 5)
392 174: . STOP
393highest protocol among opcodes = 2
394"""
395
Jeremy Hylton66426532001-10-15 21:38:56 +0000396def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000397 c = C()
398 c.foo = 1
399 c.bar = 2
400 x = [0, 1L, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000401 # Append some integer test cases at cPickle.c's internal size
402 # cutoffs.
403 uint1max = 0xff
404 uint2max = 0xffff
405 int4max = 0x7fffffff
406 x.extend([1, -1,
407 uint1max, -uint1max, -uint1max-1,
408 uint2max, -uint2max, -uint2max-1,
409 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000410 y = ('abc', 'abc', c, c)
411 x.append(y)
412 x.append(y)
413 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000414 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000415
Jeremy Hylton66426532001-10-15 21:38:56 +0000416class AbstractPickleTests(unittest.TestCase):
Tim Peters70b02d72003-02-02 17:26:40 +0000417 # Subclass must define self.dumps, self.loads, self.error.
Tim Petersc58440f2001-04-09 17:16:31 +0000418
Jeremy Hylton66426532001-10-15 21:38:56 +0000419 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000420
Jeremy Hylton66426532001-10-15 21:38:56 +0000421 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000422 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000423
Jeremy Hylton66426532001-10-15 21:38:56 +0000424 def test_misc(self):
425 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000426 for proto in protocols:
427 x = myint(4)
428 s = self.dumps(x, proto)
429 y = self.loads(s)
430 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000431
Tim Peters70b02d72003-02-02 17:26:40 +0000432 x = (1, ())
433 s = self.dumps(x, proto)
434 y = self.loads(s)
435 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000436
Tim Peters70b02d72003-02-02 17:26:40 +0000437 x = initarg(1, x)
438 s = self.dumps(x, proto)
439 y = self.loads(s)
440 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000441
Jeremy Hylton66426532001-10-15 21:38:56 +0000442 # XXX test __reduce__ protocol?
443
Tim Peters70b02d72003-02-02 17:26:40 +0000444 def test_roundtrip_equality(self):
445 expected = self._testdata
446 for proto in protocols:
447 s = self.dumps(expected, proto)
448 got = self.loads(s)
449 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000450
Tim Peters70b02d72003-02-02 17:26:40 +0000451 def test_load_from_canned_string(self):
452 expected = self._testdata
Tim Petersfc273752003-03-02 04:54:24 +0000453 for canned in DATA0, DATA1, DATA2:
Tim Peters70b02d72003-02-02 17:26:40 +0000454 got = self.loads(canned)
455 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000456
Tim Peters70b02d72003-02-02 17:26:40 +0000457 # There are gratuitous differences between pickles produced by
458 # pickle and cPickle, largely because cPickle starts PUT indices at
459 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
460 # there's a comment with an exclamation point there whose meaning
461 # is a mystery. cPickle also suppresses PUT for objects with a refcount
462 # of 1.
463 def dont_test_disassembly(self):
Tim Peters70b02d72003-02-02 17:26:40 +0000464 from pickletools import dis
465
466 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
467 s = self.dumps(self._testdata, proto)
Collin Winterf8089c72009-04-09 16:46:46 +0000468 filelike = cStringIO.StringIO()
Tim Peters70b02d72003-02-02 17:26:40 +0000469 dis(s, out=filelike)
470 got = filelike.getvalue()
471 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000472
473 def test_recursive_list(self):
474 l = []
475 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000476 for proto in protocols:
477 s = self.dumps(l, proto)
478 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000479 self.assertEqual(len(x), 1)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000480 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000481
Collin Winter57bef682009-05-26 04:12:39 +0000482 def test_recursive_tuple(self):
483 t = ([],)
484 t[0].append(t)
485 for proto in protocols:
486 s = self.dumps(t, proto)
487 x = self.loads(s)
488 self.assertEqual(len(x), 1)
489 self.assertEqual(len(x[0]), 1)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000490 self.assertTrue(x is x[0][0])
Collin Winter57bef682009-05-26 04:12:39 +0000491
Jeremy Hylton66426532001-10-15 21:38:56 +0000492 def test_recursive_dict(self):
493 d = {}
494 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000495 for proto in protocols:
496 s = self.dumps(d, proto)
497 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000498 self.assertEqual(x.keys(), [1])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000499 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000500
501 def test_recursive_inst(self):
502 i = C()
503 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000504 for proto in protocols:
505 s = self.dumps(i, 2)
506 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000507 self.assertEqual(dir(x), dir(i))
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000508 self.assertTrue(x.attr is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000509
510 def test_recursive_multi(self):
511 l = []
512 d = {1:l}
513 i = C()
514 i.attr = d
515 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000516 for proto in protocols:
517 s = self.dumps(l, proto)
518 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000519 self.assertEqual(len(x), 1)
520 self.assertEqual(dir(x[0]), dir(i))
521 self.assertEqual(x[0].attr.keys(), [1])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000522 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000523
524 def test_garyp(self):
525 self.assertRaises(self.error, self.loads, 'garyp')
526
527 def test_insecure_strings(self):
528 insecure = ["abc", "2 + 2", # not quoted
Martin v. Löwis8a8da792002-08-14 07:46:28 +0000529 #"'abc' + 'def'", # not a single quoted string
Jeremy Hylton66426532001-10-15 21:38:56 +0000530 "'abc", # quote is not closed
531 "'abc\"", # open quote and close quote don't match
532 "'abc' ?", # junk after close quote
Martin v. Löwiseb3f00a2002-08-14 08:22:50 +0000533 "'\\'", # trailing backslash
Jeremy Hylton66426532001-10-15 21:38:56 +0000534 # some tests of the quoting rules
Martin v. Löwis8a8da792002-08-14 07:46:28 +0000535 #"'abc\"\''",
536 #"'\\\\a\'\'\'\\\'\\\\\''",
Jeremy Hylton66426532001-10-15 21:38:56 +0000537 ]
538 for s in insecure:
539 buf = "S" + s + "\012p0\012."
540 self.assertRaises(ValueError, self.loads, buf)
541
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000542 if have_unicode:
Jeremy Hylton66426532001-10-15 21:38:56 +0000543 def test_unicode(self):
Alexandre Vassalottie57e9992008-12-27 10:02:59 +0000544 endcases = [u'', u'<\\u>', u'<\\\u1234>', u'<\n>',
545 u'<\\>', u'<\\\U00012345>']
Tim Petersee1a53c2003-02-02 02:57:53 +0000546 for proto in protocols:
547 for u in endcases:
548 p = self.dumps(u, proto)
549 u2 = self.loads(p)
550 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000551
Alexandre Vassalottif852bf92008-12-27 07:08:47 +0000552 def test_unicode_high_plane(self):
553 t = u'\U00012345'
554 for proto in protocols:
555 p = self.dumps(t, proto)
556 t2 = self.loads(p)
557 self.assertEqual(t2, t)
558
Jeremy Hylton66426532001-10-15 21:38:56 +0000559 def test_ints(self):
560 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000561 for proto in protocols:
562 n = sys.maxint
563 while n:
564 for expected in (-n, n):
565 s = self.dumps(expected, proto)
566 n2 = self.loads(s)
567 self.assertEqual(expected, n2)
568 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000569
Jeremy Hylton66426532001-10-15 21:38:56 +0000570 def test_maxint64(self):
571 maxint64 = (1L << 63) - 1
572 data = 'I' + str(maxint64) + '\n.'
573 got = self.loads(data)
574 self.assertEqual(got, maxint64)
575
576 # Try too with a bogus literal.
577 data = 'I' + str(maxint64) + 'JUNK\n.'
578 self.assertRaises(ValueError, self.loads, data)
579
Tim Petersee1a53c2003-02-02 02:57:53 +0000580 def test_long(self):
581 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000582 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000583 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
584 nbase = 1L << nbits
585 for npos in nbase-1, nbase, nbase+1:
586 for n in npos, -npos:
587 pickle = self.dumps(n, proto)
588 got = self.loads(pickle)
589 self.assertEqual(n, got)
590 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
591 # bother with those.
Tim Petersee1a53c2003-02-02 02:57:53 +0000592 nbase = long("deadbeeffeedface", 16)
593 nbase += nbase << 1000000
594 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000595 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000596 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000597 self.assertEqual(n, got)
598
Mark Dickinsona3ecd2c2009-01-24 16:40:29 +0000599 def test_float(self):
600 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
601 3.14, 263.44582062374053, 6.022e23, 1e30]
602 test_values = test_values + [-x for x in test_values]
603 for proto in protocols:
604 for value in test_values:
605 pickle = self.dumps(value, proto)
606 got = self.loads(pickle)
607 self.assertEqual(value, got)
608
Georg Brandlde9b6242006-04-30 11:13:56 +0000609 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
610 def test_float_format(self):
611 # make sure that floats are formatted locale independent
612 self.assertEqual(self.dumps(1.2)[0:3], 'F1.')
613
Jeremy Hylton66426532001-10-15 21:38:56 +0000614 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000615 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000616
617 def test_getinitargs(self):
618 pass
619
Guido van Rossum04a86612001-12-19 16:58:54 +0000620 def test_metaclass(self):
621 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000622 for proto in protocols:
623 s = self.dumps(a, proto)
624 b = self.loads(s)
625 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000626
Antoine Pitrou561a8212011-10-04 09:34:48 +0200627 def test_dynamic_class(self):
628 a = create_dynamic_class("my_dynamic_class", (object,))
629 copy_reg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
630 for proto in protocols:
631 s = self.dumps(a, proto)
632 b = self.loads(s)
633 self.assertEqual(a, b)
634
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000635 def test_structseq(self):
636 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000637 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000638
639 t = time.localtime()
640 for proto in protocols:
641 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000642 u = self.loads(s)
643 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000644 if hasattr(os, "stat"):
645 t = os.stat(os.curdir)
646 s = self.dumps(t, proto)
647 u = self.loads(s)
648 self.assertEqual(t, u)
649 if hasattr(os, "statvfs"):
650 t = os.statvfs(os.curdir)
651 s = self.dumps(t, proto)
652 u = self.loads(s)
653 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000654
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000655 # Tests for protocol 2
656
Tim Peters4190fb82003-02-02 16:09:05 +0000657 def test_proto(self):
658 build_none = pickle.NONE + pickle.STOP
659 for proto in protocols:
660 expected = build_none
661 if proto >= 2:
662 expected = pickle.PROTO + chr(proto) + expected
663 p = self.dumps(None, proto)
664 self.assertEqual(p, expected)
665
666 oob = protocols[-1] + 1 # a future protocol
667 badpickle = pickle.PROTO + chr(oob) + build_none
668 try:
669 self.loads(badpickle)
670 except ValueError, detail:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000671 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +0000672 "unsupported pickle protocol"))
673 else:
674 self.fail("expected bad protocol number to raise ValueError")
675
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000676 def test_long1(self):
677 x = 12345678910111213141516178920L
Tim Peters61bf2572003-02-03 21:31:22 +0000678 for proto in protocols:
679 s = self.dumps(x, proto)
680 y = self.loads(s)
681 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000682 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000683
684 def test_long4(self):
685 x = 12345678910111213141516178920L << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000686 for proto in protocols:
687 s = self.dumps(x, proto)
688 y = self.loads(s)
689 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000690 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000691
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000692 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000693 # Map (proto, len(tuple)) to expected opcode.
694 expected_opcode = {(0, 0): pickle.TUPLE,
695 (0, 1): pickle.TUPLE,
696 (0, 2): pickle.TUPLE,
697 (0, 3): pickle.TUPLE,
698 (0, 4): pickle.TUPLE,
699
700 (1, 0): pickle.EMPTY_TUPLE,
701 (1, 1): pickle.TUPLE,
702 (1, 2): pickle.TUPLE,
703 (1, 3): pickle.TUPLE,
704 (1, 4): pickle.TUPLE,
705
706 (2, 0): pickle.EMPTY_TUPLE,
707 (2, 1): pickle.TUPLE1,
708 (2, 2): pickle.TUPLE2,
709 (2, 3): pickle.TUPLE3,
710 (2, 4): pickle.TUPLE,
711 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000712 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000713 b = (1,)
714 c = (1, 2)
715 d = (1, 2, 3)
716 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000717 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000718 for x in a, b, c, d, e:
719 s = self.dumps(x, proto)
720 y = self.loads(s)
721 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000722 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +0000723 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +0000724
Guido van Rossum7d97d312003-01-28 04:25:27 +0000725 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000726 # Map (proto, singleton) to expected opcode.
727 expected_opcode = {(0, None): pickle.NONE,
728 (1, None): pickle.NONE,
729 (2, None): pickle.NONE,
730
731 (0, True): pickle.INT,
732 (1, True): pickle.INT,
733 (2, True): pickle.NEWTRUE,
734
735 (0, False): pickle.INT,
736 (1, False): pickle.INT,
737 (2, False): pickle.NEWFALSE,
738 }
Tim Peters4190fb82003-02-02 16:09:05 +0000739 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000740 for x in None, False, True:
741 s = self.dumps(x, proto)
742 y = self.loads(s)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000743 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +0000744 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +0000745 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +0000746
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000747 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000748 x = MyTuple([1, 2, 3])
749 x.foo = 42
750 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000751 for proto in protocols:
752 s = self.dumps(x, proto)
753 y = self.loads(s)
754 self.assertEqual(tuple(x), tuple(y))
755 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000756
757 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000758 x = MyList([1, 2, 3])
759 x.foo = 42
760 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000761 for proto in protocols:
762 s = self.dumps(x, proto)
763 y = self.loads(s)
764 self.assertEqual(list(x), list(y))
765 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000766
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000767 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +0000768 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000769 for C in myclasses:
770 B = C.__base__
771 x = C(C.sample)
772 x.foo = 42
773 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000774 y = self.loads(s)
775 detail = (proto, C, B, x, y, type(y))
776 self.assertEqual(B(x), B(y), detail)
777 self.assertEqual(x.__dict__, y.__dict__, detail)
778
Georg Brandldffbf5f2008-05-20 07:49:57 +0000779 # Register a type with copy_reg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +0000780 # an object of that type. Check that the resulting pickle uses opcode
781 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +0000782
Tim Peters22e71712003-02-03 22:27:38 +0000783 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +0000784 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000785 try:
Georg Brandldffbf5f2008-05-20 07:49:57 +0000786 copy_reg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000787 x = MyList([1, 2, 3])
788 x.foo = 42
789 x.bar = "hello"
790
Tim Peters22e71712003-02-03 22:27:38 +0000791 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000792 s1 = self.dumps(x, 1)
Ezio Melottiaa980582010-01-23 23:04:36 +0000793 self.assertIn(__name__, s1)
794 self.assertIn("MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +0000795 self.assertEqual(opcode_in_pickle(opcode, s1), False)
796
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000797 y = self.loads(s1)
798 self.assertEqual(list(x), list(y))
799 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000800
Tim Peters22e71712003-02-03 22:27:38 +0000801 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000802 s2 = self.dumps(x, 2)
Ezio Melottiaa980582010-01-23 23:04:36 +0000803 self.assertNotIn(__name__, s2)
804 self.assertNotIn("MyList", s2)
Tim Peters3e667d52003-02-04 21:47:44 +0000805 self.assertEqual(opcode_in_pickle(opcode, s2), True)
806
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000807 y = self.loads(s2)
808 self.assertEqual(list(x), list(y))
809 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000810
811 finally:
Tim Peters3e667d52003-02-04 21:47:44 +0000812 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +0000813
814 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000815 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
816 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000817
818 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000819 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
820 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
821 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000822
823 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000824 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
825 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
826 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
827
Tim Peters8d2613a2003-02-11 16:40:16 +0000828 def test_list_chunking(self):
829 n = 10 # too small to chunk
830 x = range(n)
831 for proto in protocols:
832 s = self.dumps(x, proto)
833 y = self.loads(s)
834 self.assertEqual(x, y)
835 num_appends = count_opcode(pickle.APPENDS, s)
836 self.assertEqual(num_appends, proto > 0)
837
838 n = 2500 # expect at least two chunks when proto > 0
839 x = range(n)
840 for proto in protocols:
841 s = self.dumps(x, proto)
842 y = self.loads(s)
843 self.assertEqual(x, y)
844 num_appends = count_opcode(pickle.APPENDS, s)
845 if proto == 0:
846 self.assertEqual(num_appends, 0)
847 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000848 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +0000849
850 def test_dict_chunking(self):
851 n = 10 # too small to chunk
852 x = dict.fromkeys(range(n))
853 for proto in protocols:
854 s = self.dumps(x, proto)
855 y = self.loads(s)
856 self.assertEqual(x, y)
857 num_setitems = count_opcode(pickle.SETITEMS, s)
858 self.assertEqual(num_setitems, proto > 0)
859
860 n = 2500 # expect at least two chunks when proto > 0
861 x = dict.fromkeys(range(n))
862 for proto in protocols:
863 s = self.dumps(x, proto)
864 y = self.loads(s)
865 self.assertEqual(x, y)
866 num_setitems = count_opcode(pickle.SETITEMS, s)
867 if proto == 0:
868 self.assertEqual(num_setitems, 0)
869 else:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000870 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000871
Tim Peterse9ef2032003-02-13 18:42:00 +0000872 def test_simple_newobj(self):
873 x = object.__new__(SimpleNewObj) # avoid __init__
874 x.abc = 666
875 for proto in protocols:
876 s = self.dumps(x, proto)
877 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
878 y = self.loads(s) # will raise TypeError if __init__ called
879 self.assertEqual(y.abc, 666)
880 self.assertEqual(x.__dict__, y.__dict__)
881
Tim Peters42f08ac2003-02-11 22:43:24 +0000882 def test_newobj_list_slots(self):
883 x = SlotList([1, 2, 3])
884 x.foo = 42
885 x.bar = "hello"
886 s = self.dumps(x, 2)
887 y = self.loads(s)
888 self.assertEqual(list(x), list(y))
889 self.assertEqual(x.__dict__, y.__dict__)
890 self.assertEqual(x.foo, y.foo)
891 self.assertEqual(x.bar, y.bar)
892
Guido van Rossum2a30b212003-02-18 22:41:24 +0000893 def test_reduce_overrides_default_reduce_ex(self):
Collin Winterf8089c72009-04-09 16:46:46 +0000894 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000895 x = REX_one()
896 self.assertEqual(x._reduce_called, 0)
897 s = self.dumps(x, proto)
898 self.assertEqual(x._reduce_called, 1)
899 y = self.loads(s)
900 self.assertEqual(y._reduce_called, 0)
901
902 def test_reduce_ex_called(self):
Collin Winterf8089c72009-04-09 16:46:46 +0000903 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000904 x = REX_two()
905 self.assertEqual(x._proto, None)
906 s = self.dumps(x, proto)
907 self.assertEqual(x._proto, proto)
908 y = self.loads(s)
909 self.assertEqual(y._proto, None)
910
911 def test_reduce_ex_overrides_reduce(self):
Collin Winterf8089c72009-04-09 16:46:46 +0000912 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000913 x = REX_three()
914 self.assertEqual(x._proto, None)
915 s = self.dumps(x, proto)
916 self.assertEqual(x._proto, proto)
917 y = self.loads(s)
918 self.assertEqual(y._proto, None)
919
Žiga Seilnacht20f43d32007-03-15 11:44:55 +0000920 def test_reduce_ex_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +0000921 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +0000922 x = REX_four()
923 self.assertEqual(x._proto, None)
924 s = self.dumps(x, proto)
925 self.assertEqual(x._proto, proto)
926 y = self.loads(s)
927 self.assertEqual(y._proto, proto)
928
929 def test_reduce_calls_base(self):
Collin Winterf8089c72009-04-09 16:46:46 +0000930 for proto in protocols:
Žiga Seilnacht20f43d32007-03-15 11:44:55 +0000931 x = REX_five()
932 self.assertEqual(x._reduce_called, 0)
933 s = self.dumps(x, proto)
934 self.assertEqual(x._reduce_called, 1)
935 y = self.loads(s)
936 self.assertEqual(y._reduce_called, 1)
937
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +0000938 def test_reduce_bad_iterator(self):
939 # Issue4176: crash when 4th and 5th items of __reduce__()
940 # are not iterators
941 class C(object):
942 def __reduce__(self):
943 # 4th item is not an iterator
944 return list, (), None, [], None
945 class D(object):
946 def __reduce__(self):
947 # 5th item is not an iterator
948 return dict, (), None, None, []
949
950 # Protocol 0 is less strict and also accept iterables.
Collin Winterf8089c72009-04-09 16:46:46 +0000951 for proto in protocols:
Amaury Forgeot d'Arc69a9c5b2008-10-30 21:18:34 +0000952 try:
953 self.dumps(C(), proto)
954 except (AttributeError, pickle.PickleError, cPickle.PickleError):
955 pass
956 try:
957 self.dumps(D(), proto)
958 except (AttributeError, pickle.PickleError, cPickle.PickleError):
959 pass
960
Collin Winterf8089c72009-04-09 16:46:46 +0000961 def test_many_puts_and_gets(self):
962 # Test that internal data structures correctly deal with lots of
963 # puts/gets.
964 keys = ("aaa" + str(i) for i in xrange(100))
965 large_dict = dict((k, [4, 5, 6]) for k in keys)
966 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
967
968 for proto in protocols:
969 dumped = self.dumps(obj, proto)
970 loaded = self.loads(dumped)
971 self.assertEqual(loaded, obj,
972 "Failed protocol %d: %r != %r"
973 % (proto, obj, loaded))
974
Antoine Pitrou74309892009-05-02 21:13:23 +0000975 def test_attribute_name_interning(self):
976 # Test that attribute names of pickled objects are interned when
977 # unpickling.
978 for proto in protocols:
979 x = C()
980 x.foo = 42
981 x.bar = "hello"
982 s = self.dumps(x, proto)
983 y = self.loads(s)
984 x_keys = sorted(x.__dict__)
985 y_keys = sorted(y.__dict__)
986 for x_key, y_key in zip(x_keys, y_keys):
987 self.assertIs(x_key, y_key)
988
Collin Winterf8089c72009-04-09 16:46:46 +0000989
Guido van Rossum2a30b212003-02-18 22:41:24 +0000990# Test classes for reduce_ex
991
992class REX_one(object):
993 _reduce_called = 0
994 def __reduce__(self):
995 self._reduce_called = 1
996 return REX_one, ()
997 # No __reduce_ex__ here, but inheriting it from object
998
999class REX_two(object):
1000 _proto = None
1001 def __reduce_ex__(self, proto):
1002 self._proto = proto
1003 return REX_two, ()
1004 # No __reduce__ here, but inheriting it from object
1005
1006class REX_three(object):
1007 _proto = None
1008 def __reduce_ex__(self, proto):
1009 self._proto = proto
1010 return REX_two, ()
1011 def __reduce__(self):
1012 raise TestFailed, "This __reduce__ shouldn't be called"
1013
Žiga Seilnacht20f43d32007-03-15 11:44:55 +00001014class REX_four(object):
1015 _proto = None
1016 def __reduce_ex__(self, proto):
1017 self._proto = proto
1018 return object.__reduce_ex__(self, proto)
1019 # Calling base class method should succeed
1020
1021class REX_five(object):
1022 _reduce_called = 0
1023 def __reduce__(self):
1024 self._reduce_called = 1
1025 return object.__reduce__(self)
1026 # This one used to fail with infinite recursion
1027
Guido van Rossum2a30b212003-02-18 22:41:24 +00001028# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001029
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001030class MyInt(int):
1031 sample = 1
1032
1033class MyLong(long):
1034 sample = 1L
1035
1036class MyFloat(float):
1037 sample = 1.0
1038
1039class MyComplex(complex):
1040 sample = 1.0 + 0.0j
1041
1042class MyStr(str):
1043 sample = "hello"
1044
1045class MyUnicode(unicode):
1046 sample = u"hello \u1234"
1047
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001048class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001049 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001050
1051class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001052 sample = [1, 2, 3]
1053
1054class MyDict(dict):
1055 sample = {"a": 1, "b": 2}
1056
1057myclasses = [MyInt, MyLong, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001058 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001059 MyStr, MyUnicode,
1060 MyTuple, MyList, MyDict]
1061
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001062
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001063class SlotList(MyList):
1064 __slots__ = ["foo"]
1065
Tim Peterse9ef2032003-02-13 18:42:00 +00001066class SimpleNewObj(object):
1067 def __init__(self, a, b, c):
1068 # raise an error, to make sure this isn't called
1069 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1070
Jeremy Hylton66426532001-10-15 21:38:56 +00001071class AbstractPickleModuleTests(unittest.TestCase):
1072
1073 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001074 import os
1075 f = open(TESTFN, "w")
1076 try:
1077 f.close()
1078 self.assertRaises(ValueError, self.module.dump, 123, f)
1079 finally:
1080 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001081
1082 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001083 import os
1084 f = open(TESTFN, "w")
1085 try:
1086 f.close()
1087 self.assertRaises(ValueError, self.module.dump, 123, f)
1088 finally:
1089 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001090
Collin Winterf8089c72009-04-09 16:46:46 +00001091 def test_load_from_and_dump_to_file(self):
1092 stream = cStringIO.StringIO()
1093 data = [123, {}, 124]
1094 self.module.dump(data, stream)
1095 stream.seek(0)
1096 unpickled = self.module.load(stream)
1097 self.assertEqual(unpickled, data)
1098
Tim Petersc0c93702003-02-13 19:30:57 +00001099 def test_highest_protocol(self):
1100 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
1101 self.assertEqual(self.module.HIGHEST_PROTOCOL, 2)
1102
Martin v. Löwis544f1192004-07-27 05:22:33 +00001103 def test_callapi(self):
Collin Winterf8089c72009-04-09 16:46:46 +00001104 f = cStringIO.StringIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001105 # With and without keyword arguments
1106 self.module.dump(123, f, -1)
1107 self.module.dump(123, file=f, protocol=-1)
1108 self.module.dumps(123, -1)
1109 self.module.dumps(123, protocol=-1)
1110 self.module.Pickler(f, -1)
1111 self.module.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001112
Amaury Forgeot d'Arc74b30162009-07-23 19:26:02 +00001113 def test_incomplete_input(self):
1114 s = StringIO.StringIO("X''.")
1115 self.assertRaises(EOFError, self.module.load, s)
1116
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001117 def test_restricted(self):
1118 # issue7128: cPickle failed in restricted mode
1119 builtins = {self.module.__name__: self.module,
1120 '__import__': __import__}
1121 d = {}
1122 teststr = "def f(): {0}.dumps(0)".format(self.module.__name__)
1123 exec teststr in {'__builtins__': builtins}, d
1124 d['f']()
1125
Antoine Pitrou0d423b82010-01-07 17:46:49 +00001126 def test_bad_input(self):
1127 # Test issue4298
1128 s = '\x58\0\0\0\x54'
1129 self.assertRaises(EOFError, self.module.loads, s)
1130 # Test issue7455
1131 s = '0'
1132 # XXX Why doesn't pickle raise UnpicklingError?
1133 self.assertRaises((IndexError, cPickle.UnpicklingError),
1134 self.module.loads, s)
Alexandre Vassalotti8b2d7132009-11-24 17:53:23 +00001135
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001136class AbstractPersistentPicklerTests(unittest.TestCase):
1137
1138 # This class defines persistent_id() and persistent_load()
1139 # functions that should be used by the pickler. All even integers
1140 # are pickled using persistent ids.
1141
1142 def persistent_id(self, object):
1143 if isinstance(object, int) and object % 2 == 0:
1144 self.id_count += 1
1145 return str(object)
1146 else:
1147 return None
1148
1149 def persistent_load(self, oid):
1150 self.load_count += 1
1151 object = int(oid)
1152 assert object % 2 == 0
1153 return object
1154
1155 def test_persistence(self):
1156 self.id_count = 0
1157 self.load_count = 0
1158 L = range(10)
1159 self.assertEqual(self.loads(self.dumps(L)), L)
1160 self.assertEqual(self.id_count, 5)
1161 self.assertEqual(self.load_count, 5)
1162
1163 def test_bin_persistence(self):
1164 self.id_count = 0
1165 self.load_count = 0
1166 L = range(10)
1167 self.assertEqual(self.loads(self.dumps(L, 1)), L)
1168 self.assertEqual(self.id_count, 5)
1169 self.assertEqual(self.load_count, 5)
Collin Winterf8089c72009-04-09 16:46:46 +00001170
1171class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1172
1173 pickler_class = None
1174 unpickler_class = None
1175
1176 def setUp(self):
1177 assert self.pickler_class
1178 assert self.unpickler_class
1179
1180 def test_clear_pickler_memo(self):
1181 # To test whether clear_memo() has any effect, we pickle an object,
1182 # then pickle it again without clearing the memo; the two serialized
1183 # forms should be different. If we clear_memo() and then pickle the
1184 # object again, the third serialized form should be identical to the
1185 # first one we obtained.
1186 data = ["abcdefg", "abcdefg", 44]
1187 f = cStringIO.StringIO()
1188 pickler = self.pickler_class(f)
1189
1190 pickler.dump(data)
1191 first_pickled = f.getvalue()
1192
1193 # Reset StringIO object.
1194 f.seek(0)
1195 f.truncate()
1196
1197 pickler.dump(data)
1198 second_pickled = f.getvalue()
1199
1200 # Reset the Pickler and StringIO objects.
1201 pickler.clear_memo()
1202 f.seek(0)
1203 f.truncate()
1204
1205 pickler.dump(data)
1206 third_pickled = f.getvalue()
1207
1208 self.assertNotEqual(first_pickled, second_pickled)
1209 self.assertEqual(first_pickled, third_pickled)
1210
1211 def test_priming_pickler_memo(self):
1212 # Verify that we can set the Pickler's memo attribute.
1213 data = ["abcdefg", "abcdefg", 44]
1214 f = cStringIO.StringIO()
1215 pickler = self.pickler_class(f)
1216
1217 pickler.dump(data)
1218 first_pickled = f.getvalue()
1219
1220 f = cStringIO.StringIO()
1221 primed = self.pickler_class(f)
1222 primed.memo = pickler.memo
1223
1224 primed.dump(data)
1225 primed_pickled = f.getvalue()
1226
1227 self.assertNotEqual(first_pickled, primed_pickled)
1228
1229 def test_priming_unpickler_memo(self):
1230 # Verify that we can set the Unpickler's memo attribute.
1231 data = ["abcdefg", "abcdefg", 44]
1232 f = cStringIO.StringIO()
1233 pickler = self.pickler_class(f)
1234
1235 pickler.dump(data)
1236 first_pickled = f.getvalue()
1237
1238 f = cStringIO.StringIO()
1239 primed = self.pickler_class(f)
1240 primed.memo = pickler.memo
1241
1242 primed.dump(data)
1243 primed_pickled = f.getvalue()
1244
1245 unpickler = self.unpickler_class(cStringIO.StringIO(first_pickled))
1246 unpickled_data1 = unpickler.load()
1247
1248 self.assertEqual(unpickled_data1, data)
1249
1250 primed = self.unpickler_class(cStringIO.StringIO(primed_pickled))
1251 primed.memo = unpickler.memo
1252 unpickled_data2 = primed.load()
1253
1254 primed.memo.clear()
1255
1256 self.assertEqual(unpickled_data2, data)
1257 self.assertTrue(unpickled_data2 is unpickled_data1)
1258
1259 def test_reusing_unpickler_objects(self):
1260 data1 = ["abcdefg", "abcdefg", 44]
1261 f = cStringIO.StringIO()
1262 pickler = self.pickler_class(f)
1263 pickler.dump(data1)
1264 pickled1 = f.getvalue()
1265
1266 data2 = ["abcdefg", 44, 44]
1267 f = cStringIO.StringIO()
1268 pickler = self.pickler_class(f)
1269 pickler.dump(data2)
1270 pickled2 = f.getvalue()
1271
1272 f = cStringIO.StringIO()
1273 f.write(pickled1)
1274 f.seek(0)
1275 unpickler = self.unpickler_class(f)
1276 self.assertEqual(unpickler.load(), data1)
1277
1278 f.seek(0)
1279 f.truncate()
1280 f.write(pickled2)
1281 f.seek(0)
1282 self.assertEqual(unpickler.load(), data2)