source: python/vendor/Python-2.6.5/Lib/test/pickletester.py

Last change on this file was 2, checked in by Yuri Dario, 15 years ago

Initial import for vendor code.

  • Property svn:eol-style set to native
File size: 32.9 KB
Line 
1import unittest
2import pickle
3import cPickle
4import StringIO
5import pickletools
6import copy_reg
7
8from test.test_support import TestFailed, have_unicode, TESTFN, \
9 run_with_locale
10
11# Tests that try a number of pickle protocols should have a
12# for proto in protocols:
13# kind of outer loop.
14assert pickle.HIGHEST_PROTOCOL == cPickle.HIGHEST_PROTOCOL == 2
15protocols = range(pickle.HIGHEST_PROTOCOL + 1)
16
17
18# Return True if opcode code appears in the pickle, else False.
19def opcode_in_pickle(code, pickle):
20 for op, dummy, dummy in pickletools.genops(pickle):
21 if op.code == code:
22 return True
23 return False
24
25# Return the number of times opcode code appears in pickle.
26def count_opcode(code, pickle):
27 n = 0
28 for op, dummy, dummy in pickletools.genops(pickle):
29 if op.code == code:
30 n += 1
31 return n
32
33# We can't very well test the extension registry without putting known stuff
34# in it, but we have to be careful to restore its original state. Code
35# should do this:
36#
37# e = ExtensionSaver(extension_code)
38# try:
39# fiddle w/ the extension registry's stuff for extension_code
40# finally:
41# e.restore()
42
43class ExtensionSaver:
44 # Remember current registration for code (if any), and remove it (if
45 # there is one).
46 def __init__(self, code):
47 self.code = code
48 if code in copy_reg._inverted_registry:
49 self.pair = copy_reg._inverted_registry[code]
50 copy_reg.remove_extension(self.pair[0], self.pair[1], code)
51 else:
52 self.pair = None
53
54 # Restore previous registration for code.
55 def restore(self):
56 code = self.code
57 curpair = copy_reg._inverted_registry.get(code)
58 if curpair is not None:
59 copy_reg.remove_extension(curpair[0], curpair[1], code)
60 pair = self.pair
61 if pair is not None:
62 copy_reg.add_extension(pair[0], pair[1], code)
63
64class C:
65 def __cmp__(self, other):
66 return cmp(self.__dict__, other.__dict__)
67
68import __main__
69__main__.C = C
70C.__module__ = "__main__"
71
72class myint(int):
73 def __init__(self, x):
74 self.str = str(x)
75
76class initarg(C):
77
78 def __init__(self, a, b):
79 self.a = a
80 self.b = b
81
82 def __getinitargs__(self):
83 return self.a, self.b
84
85class metaclass(type):
86 pass
87
88class use_metaclass(object):
89 __metaclass__ = metaclass
90
91# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
92# the object returned by create_data().
93
94# break into multiple strings to avoid confusing font-lock-mode
95DATA0 = """(lp1
96I0
97aL1L
98aF2
99ac__builtin__
100complex
101p2
102""" + \
103"""(F3
104F0
105tRp3
106aI1
107aI-1
108aI255
109aI-255
110aI-256
111aI65535
112aI-65535
113aI-65536
114aI2147483647
115aI-2147483647
116aI-2147483648
117a""" + \
118"""(S'abc'
119p4
120g4
121""" + \
122"""(i__main__
123C
124p5
125""" + \
126"""(dp6
127S'foo'
128p7
129I1
130sS'bar'
131p8
132I2
133sbg5
134tp9
135ag9
136aI5
137a.
138"""
139
140# Disassembly of DATA0.
141DATA0_DIS = """\
142 0: ( MARK
143 1: l LIST (MARK at 0)
144 2: p PUT 1
145 5: I INT 0
146 8: a APPEND
147 9: L LONG 1L
148 13: a APPEND
149 14: F FLOAT 2.0
150 17: a APPEND
151 18: c GLOBAL '__builtin__ complex'
152 39: p PUT 2
153 42: ( MARK
154 43: F FLOAT 3.0
155 46: F FLOAT 0.0
156 49: t TUPLE (MARK at 42)
157 50: R REDUCE
158 51: p PUT 3
159 54: a APPEND
160 55: I INT 1
161 58: a APPEND
162 59: I INT -1
163 63: a APPEND
164 64: I INT 255
165 69: a APPEND
166 70: I INT -255
167 76: a APPEND
168 77: I INT -256
169 83: a APPEND
170 84: I INT 65535
171 91: a APPEND
172 92: I INT -65535
173 100: a APPEND
174 101: I INT -65536
175 109: a APPEND
176 110: I INT 2147483647
177 122: a APPEND
178 123: I INT -2147483647
179 136: a APPEND
180 137: I INT -2147483648
181 150: a APPEND
182 151: ( MARK
183 152: S STRING 'abc'
184 159: p PUT 4
185 162: g GET 4
186 165: ( MARK
187 166: i INST '__main__ C' (MARK at 165)
188 178: p PUT 5
189 181: ( MARK
190 182: d DICT (MARK at 181)
191 183: p PUT 6
192 186: S STRING 'foo'
193 193: p PUT 7
194 196: I INT 1
195 199: s SETITEM
196 200: S STRING 'bar'
197 207: p PUT 8
198 210: I INT 2
199 213: s SETITEM
200 214: b BUILD
201 215: g GET 5
202 218: t TUPLE (MARK at 151)
203 219: p PUT 9
204 222: a APPEND
205 223: g GET 9
206 226: a APPEND
207 227: I INT 5
208 230: a APPEND
209 231: . STOP
210highest protocol among opcodes = 0
211"""
212
213DATA1 = (']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00'
214 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00'
215 '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff'
216 '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff'
217 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00'
218 '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n'
219 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh'
220 '\x06tq\nh\nK\x05e.'
221 )
222
223# Disassembly of DATA1.
224DATA1_DIS = """\
225 0: ] EMPTY_LIST
226 1: q BINPUT 1
227 3: ( MARK
228 4: K BININT1 0
229 6: L LONG 1L
230 10: G BINFLOAT 2.0
231 19: c GLOBAL '__builtin__ complex'
232 40: q BINPUT 2
233 42: ( MARK
234 43: G BINFLOAT 3.0
235 52: G BINFLOAT 0.0
236 61: t TUPLE (MARK at 42)
237 62: R REDUCE
238 63: q BINPUT 3
239 65: K BININT1 1
240 67: J BININT -1
241 72: K BININT1 255
242 74: J BININT -255
243 79: J BININT -256
244 84: M BININT2 65535
245 87: J BININT -65535
246 92: J BININT -65536
247 97: J BININT 2147483647
248 102: J BININT -2147483647
249 107: J BININT -2147483648
250 112: ( MARK
251 113: U SHORT_BINSTRING 'abc'
252 118: q BINPUT 4
253 120: h BINGET 4
254 122: ( MARK
255 123: c GLOBAL '__main__ C'
256 135: q BINPUT 5
257 137: o OBJ (MARK at 122)
258 138: q BINPUT 6
259 140: } EMPTY_DICT
260 141: q BINPUT 7
261 143: ( MARK
262 144: U SHORT_BINSTRING 'foo'
263 149: q BINPUT 8
264 151: K BININT1 1
265 153: U SHORT_BINSTRING 'bar'
266 158: q BINPUT 9
267 160: K BININT1 2
268 162: u SETITEMS (MARK at 143)
269 163: b BUILD
270 164: h BINGET 6
271 166: t TUPLE (MARK at 112)
272 167: q BINPUT 10
273 169: h BINGET 10
274 171: K BININT1 5
275 173: e APPENDS (MARK at 3)
276 174: . STOP
277highest protocol among opcodes = 1
278"""
279
280DATA2 = ('\x80\x02]q\x01(K\x00\x8a\x01\x01G@\x00\x00\x00\x00\x00\x00\x00'
281 'c__builtin__\ncomplex\nq\x02G@\x08\x00\x00\x00\x00\x00\x00G\x00'
282 '\x00\x00\x00\x00\x00\x00\x00\x86Rq\x03K\x01J\xff\xff\xff\xffK'
283 '\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xff'
284 'J\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00'
285 '\x80(U\x03abcq\x04h\x04(c__main__\nC\nq\x05oq\x06}q\x07(U\x03foo'
286 'q\x08K\x01U\x03barq\tK\x02ubh\x06tq\nh\nK\x05e.')
287
288# Disassembly of DATA2.
289DATA2_DIS = """\
290 0: \x80 PROTO 2
291 2: ] EMPTY_LIST
292 3: q BINPUT 1
293 5: ( MARK
294 6: K BININT1 0
295 8: \x8a LONG1 1L
296 11: G BINFLOAT 2.0
297 20: c GLOBAL '__builtin__ complex'
298 41: q BINPUT 2
299 43: G BINFLOAT 3.0
300 52: G BINFLOAT 0.0
301 61: \x86 TUPLE2
302 62: R REDUCE
303 63: q BINPUT 3
304 65: K BININT1 1
305 67: J BININT -1
306 72: K BININT1 255
307 74: J BININT -255
308 79: J BININT -256
309 84: M BININT2 65535
310 87: J BININT -65535
311 92: J BININT -65536
312 97: J BININT 2147483647
313 102: J BININT -2147483647
314 107: J BININT -2147483648
315 112: ( MARK
316 113: U SHORT_BINSTRING 'abc'
317 118: q BINPUT 4
318 120: h BINGET 4
319 122: ( MARK
320 123: c GLOBAL '__main__ C'
321 135: q BINPUT 5
322 137: o OBJ (MARK at 122)
323 138: q BINPUT 6
324 140: } EMPTY_DICT
325 141: q BINPUT 7
326 143: ( MARK
327 144: U SHORT_BINSTRING 'foo'
328 149: q BINPUT 8
329 151: K BININT1 1
330 153: U SHORT_BINSTRING 'bar'
331 158: q BINPUT 9
332 160: K BININT1 2
333 162: u SETITEMS (MARK at 143)
334 163: b BUILD
335 164: h BINGET 6
336 166: t TUPLE (MARK at 112)
337 167: q BINPUT 10
338 169: h BINGET 10
339 171: K BININT1 5
340 173: e APPENDS (MARK at 5)
341 174: . STOP
342highest protocol among opcodes = 2
343"""
344
345def create_data():
346 c = C()
347 c.foo = 1
348 c.bar = 2
349 x = [0, 1L, 2.0, 3.0+0j]
350 # Append some integer test cases at cPickle.c's internal size
351 # cutoffs.
352 uint1max = 0xff
353 uint2max = 0xffff
354 int4max = 0x7fffffff
355 x.extend([1, -1,
356 uint1max, -uint1max, -uint1max-1,
357 uint2max, -uint2max, -uint2max-1,
358 int4max, -int4max, -int4max-1])
359 y = ('abc', 'abc', c, c)
360 x.append(y)
361 x.append(y)
362 x.append(5)
363 return x
364
365class AbstractPickleTests(unittest.TestCase):
366 # Subclass must define self.dumps, self.loads, self.error.
367
368 _testdata = create_data()
369
370 def setUp(self):
371 pass
372
373 def test_misc(self):
374 # test various datatypes not tested by testdata
375 for proto in protocols:
376 x = myint(4)
377 s = self.dumps(x, proto)
378 y = self.loads(s)
379 self.assertEqual(x, y)
380
381 x = (1, ())
382 s = self.dumps(x, proto)
383 y = self.loads(s)
384 self.assertEqual(x, y)
385
386 x = initarg(1, x)
387 s = self.dumps(x, proto)
388 y = self.loads(s)
389 self.assertEqual(x, y)
390
391 # XXX test __reduce__ protocol?
392
393 def test_roundtrip_equality(self):
394 expected = self._testdata
395 for proto in protocols:
396 s = self.dumps(expected, proto)
397 got = self.loads(s)
398 self.assertEqual(expected, got)
399
400 def test_load_from_canned_string(self):
401 expected = self._testdata
402 for canned in DATA0, DATA1, DATA2:
403 got = self.loads(canned)
404 self.assertEqual(expected, got)
405
406 # There are gratuitous differences between pickles produced by
407 # pickle and cPickle, largely because cPickle starts PUT indices at
408 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
409 # there's a comment with an exclamation point there whose meaning
410 # is a mystery. cPickle also suppresses PUT for objects with a refcount
411 # of 1.
412 def dont_test_disassembly(self):
413 from cStringIO import StringIO
414 from pickletools import dis
415
416 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
417 s = self.dumps(self._testdata, proto)
418 filelike = StringIO()
419 dis(s, out=filelike)
420 got = filelike.getvalue()
421 self.assertEqual(expected, got)
422
423 def test_recursive_list(self):
424 l = []
425 l.append(l)
426 for proto in protocols:
427 s = self.dumps(l, proto)
428 x = self.loads(s)
429 self.assertEqual(len(x), 1)
430 self.assert_(x is x[0])
431
432 def test_recursive_tuple(self):
433 t = ([],)
434 t[0].append(t)
435 for proto in protocols:
436 s = self.dumps(t, proto)
437 x = self.loads(s)
438 self.assertEqual(len(x), 1)
439 self.assertEqual(len(x[0]), 1)
440 self.assert_(x is x[0][0])
441
442 def test_recursive_dict(self):
443 d = {}
444 d[1] = d
445 for proto in protocols:
446 s = self.dumps(d, proto)
447 x = self.loads(s)
448 self.assertEqual(x.keys(), [1])
449 self.assert_(x[1] is x)
450
451 def test_recursive_inst(self):
452 i = C()
453 i.attr = i
454 for proto in protocols:
455 s = self.dumps(i, 2)
456 x = self.loads(s)
457 self.assertEqual(dir(x), dir(i))
458 self.assert_(x.attr is x)
459
460 def test_recursive_multi(self):
461 l = []
462 d = {1:l}
463 i = C()
464 i.attr = d
465 l.append(i)
466 for proto in protocols:
467 s = self.dumps(l, proto)
468 x = self.loads(s)
469 self.assertEqual(len(x), 1)
470 self.assertEqual(dir(x[0]), dir(i))
471 self.assertEqual(x[0].attr.keys(), [1])
472 self.assert_(x[0].attr[1] is x)
473
474 def test_garyp(self):
475 self.assertRaises(self.error, self.loads, 'garyp')
476
477 def test_insecure_strings(self):
478 insecure = ["abc", "2 + 2", # not quoted
479 #"'abc' + 'def'", # not a single quoted string
480 "'abc", # quote is not closed
481 "'abc\"", # open quote and close quote don't match
482 "'abc' ?", # junk after close quote
483 "'\\'", # trailing backslash
484 # some tests of the quoting rules
485 #"'abc\"\''",
486 #"'\\\\a\'\'\'\\\'\\\\\''",
487 ]
488 for s in insecure:
489 buf = "S" + s + "\012p0\012."
490 self.assertRaises(ValueError, self.loads, buf)
491
492 if have_unicode:
493 def test_unicode(self):
494 endcases = [u'', u'<\\u>', u'<\\\u1234>', u'<\n>',
495 u'<\\>', u'<\\\U00012345>']
496 for proto in protocols:
497 for u in endcases:
498 p = self.dumps(u, proto)
499 u2 = self.loads(p)
500 self.assertEqual(u2, u)
501
502 def test_unicode_high_plane(self):
503 t = u'\U00012345'
504 for proto in protocols:
505 p = self.dumps(t, proto)
506 t2 = self.loads(p)
507 self.assertEqual(t2, t)
508
509 def test_ints(self):
510 import sys
511 for proto in protocols:
512 n = sys.maxint
513 while n:
514 for expected in (-n, n):
515 s = self.dumps(expected, proto)
516 n2 = self.loads(s)
517 self.assertEqual(expected, n2)
518 n = n >> 1
519
520 def test_maxint64(self):
521 maxint64 = (1L << 63) - 1
522 data = 'I' + str(maxint64) + '\n.'
523 got = self.loads(data)
524 self.assertEqual(got, maxint64)
525
526 # Try too with a bogus literal.
527 data = 'I' + str(maxint64) + 'JUNK\n.'
528 self.assertRaises(ValueError, self.loads, data)
529
530 def test_long(self):
531 for proto in protocols:
532 # 256 bytes is where LONG4 begins.
533 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
534 nbase = 1L << nbits
535 for npos in nbase-1, nbase, nbase+1:
536 for n in npos, -npos:
537 pickle = self.dumps(n, proto)
538 got = self.loads(pickle)
539 self.assertEqual(n, got)
540 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
541 # bother with those.
542 nbase = long("deadbeeffeedface", 16)
543 nbase += nbase << 1000000
544 for n in nbase, -nbase:
545 p = self.dumps(n, 2)
546 got = self.loads(p)
547 self.assertEqual(n, got)
548
549 def test_float(self):
550 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
551 3.14, 263.44582062374053, 6.022e23, 1e30]
552 test_values = test_values + [-x for x in test_values]
553 for proto in protocols:
554 for value in test_values:
555 pickle = self.dumps(value, proto)
556 got = self.loads(pickle)
557 self.assertEqual(value, got)
558
559 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
560 def test_float_format(self):
561 # make sure that floats are formatted locale independent
562 self.assertEqual(self.dumps(1.2)[0:3], 'F1.')
563
564 def test_reduce(self):
565 pass
566
567 def test_getinitargs(self):
568 pass
569
570 def test_metaclass(self):
571 a = use_metaclass()
572 for proto in protocols:
573 s = self.dumps(a, proto)
574 b = self.loads(s)
575 self.assertEqual(a.__class__, b.__class__)
576
577 def test_structseq(self):
578 import time
579 import os
580
581 t = time.localtime()
582 for proto in protocols:
583 s = self.dumps(t, proto)
584 u = self.loads(s)
585 self.assertEqual(t, u)
586 if hasattr(os, "stat"):
587 t = os.stat(os.curdir)
588 s = self.dumps(t, proto)
589 u = self.loads(s)
590 self.assertEqual(t, u)
591 if hasattr(os, "statvfs"):
592 t = os.statvfs(os.curdir)
593 s = self.dumps(t, proto)
594 u = self.loads(s)
595 self.assertEqual(t, u)
596
597 # Tests for protocol 2
598
599 def test_proto(self):
600 build_none = pickle.NONE + pickle.STOP
601 for proto in protocols:
602 expected = build_none
603 if proto >= 2:
604 expected = pickle.PROTO + chr(proto) + expected
605 p = self.dumps(None, proto)
606 self.assertEqual(p, expected)
607
608 oob = protocols[-1] + 1 # a future protocol
609 badpickle = pickle.PROTO + chr(oob) + build_none
610 try:
611 self.loads(badpickle)
612 except ValueError, detail:
613 self.failUnless(str(detail).startswith(
614 "unsupported pickle protocol"))
615 else:
616 self.fail("expected bad protocol number to raise ValueError")
617
618 def test_long1(self):
619 x = 12345678910111213141516178920L
620 for proto in protocols:
621 s = self.dumps(x, proto)
622 y = self.loads(s)
623 self.assertEqual(x, y)
624 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
625
626 def test_long4(self):
627 x = 12345678910111213141516178920L << (256*8)
628 for proto in protocols:
629 s = self.dumps(x, proto)
630 y = self.loads(s)
631 self.assertEqual(x, y)
632 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
633
634 def test_short_tuples(self):
635 # Map (proto, len(tuple)) to expected opcode.
636 expected_opcode = {(0, 0): pickle.TUPLE,
637 (0, 1): pickle.TUPLE,
638 (0, 2): pickle.TUPLE,
639 (0, 3): pickle.TUPLE,
640 (0, 4): pickle.TUPLE,
641
642 (1, 0): pickle.EMPTY_TUPLE,
643 (1, 1): pickle.TUPLE,
644 (1, 2): pickle.TUPLE,
645 (1, 3): pickle.TUPLE,
646 (1, 4): pickle.TUPLE,
647
648 (2, 0): pickle.EMPTY_TUPLE,
649 (2, 1): pickle.TUPLE1,
650 (2, 2): pickle.TUPLE2,
651 (2, 3): pickle.TUPLE3,
652 (2, 4): pickle.TUPLE,
653 }
654 a = ()
655 b = (1,)
656 c = (1, 2)
657 d = (1, 2, 3)
658 e = (1, 2, 3, 4)
659 for proto in protocols:
660 for x in a, b, c, d, e:
661 s = self.dumps(x, proto)
662 y = self.loads(s)
663 self.assertEqual(x, y, (proto, x, s, y))
664 expected = expected_opcode[proto, len(x)]
665 self.assertEqual(opcode_in_pickle(expected, s), True)
666
667 def test_singletons(self):
668 # Map (proto, singleton) to expected opcode.
669 expected_opcode = {(0, None): pickle.NONE,
670 (1, None): pickle.NONE,
671 (2, None): pickle.NONE,
672
673 (0, True): pickle.INT,
674 (1, True): pickle.INT,
675 (2, True): pickle.NEWTRUE,
676
677 (0, False): pickle.INT,
678 (1, False): pickle.INT,
679 (2, False): pickle.NEWFALSE,
680 }
681 for proto in protocols:
682 for x in None, False, True:
683 s = self.dumps(x, proto)
684 y = self.loads(s)
685 self.assert_(x is y, (proto, x, s, y))
686 expected = expected_opcode[proto, x]
687 self.assertEqual(opcode_in_pickle(expected, s), True)
688
689 def test_newobj_tuple(self):
690 x = MyTuple([1, 2, 3])
691 x.foo = 42
692 x.bar = "hello"
693 for proto in protocols:
694 s = self.dumps(x, proto)
695 y = self.loads(s)
696 self.assertEqual(tuple(x), tuple(y))
697 self.assertEqual(x.__dict__, y.__dict__)
698
699 def test_newobj_list(self):
700 x = MyList([1, 2, 3])
701 x.foo = 42
702 x.bar = "hello"
703 for proto in protocols:
704 s = self.dumps(x, proto)
705 y = self.loads(s)
706 self.assertEqual(list(x), list(y))
707 self.assertEqual(x.__dict__, y.__dict__)
708
709 def test_newobj_generic(self):
710 for proto in protocols:
711 for C in myclasses:
712 B = C.__base__
713 x = C(C.sample)
714 x.foo = 42
715 s = self.dumps(x, proto)
716 y = self.loads(s)
717 detail = (proto, C, B, x, y, type(y))
718 self.assertEqual(B(x), B(y), detail)
719 self.assertEqual(x.__dict__, y.__dict__, detail)
720
721 # Register a type with copy_reg, with extension code extcode. Pickle
722 # an object of that type. Check that the resulting pickle uses opcode
723 # (EXT[124]) under proto 2, and not in proto 1.
724
725 def produce_global_ext(self, extcode, opcode):
726 e = ExtensionSaver(extcode)
727 try:
728 copy_reg.add_extension(__name__, "MyList", extcode)
729 x = MyList([1, 2, 3])
730 x.foo = 42
731 x.bar = "hello"
732
733 # Dump using protocol 1 for comparison.
734 s1 = self.dumps(x, 1)
735 self.assert_(__name__ in s1)
736 self.assert_("MyList" in s1)
737 self.assertEqual(opcode_in_pickle(opcode, s1), False)
738
739 y = self.loads(s1)
740 self.assertEqual(list(x), list(y))
741 self.assertEqual(x.__dict__, y.__dict__)
742
743 # Dump using protocol 2 for test.
744 s2 = self.dumps(x, 2)
745 self.assert_(__name__ not in s2)
746 self.assert_("MyList" not in s2)
747 self.assertEqual(opcode_in_pickle(opcode, s2), True)
748
749 y = self.loads(s2)
750 self.assertEqual(list(x), list(y))
751 self.assertEqual(x.__dict__, y.__dict__)
752
753 finally:
754 e.restore()
755
756 def test_global_ext1(self):
757 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
758 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
759
760 def test_global_ext2(self):
761 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
762 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
763 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
764
765 def test_global_ext4(self):
766 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
767 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
768 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
769
770 def test_list_chunking(self):
771 n = 10 # too small to chunk
772 x = range(n)
773 for proto in protocols:
774 s = self.dumps(x, proto)
775 y = self.loads(s)
776 self.assertEqual(x, y)
777 num_appends = count_opcode(pickle.APPENDS, s)
778 self.assertEqual(num_appends, proto > 0)
779
780 n = 2500 # expect at least two chunks when proto > 0
781 x = range(n)
782 for proto in protocols:
783 s = self.dumps(x, proto)
784 y = self.loads(s)
785 self.assertEqual(x, y)
786 num_appends = count_opcode(pickle.APPENDS, s)
787 if proto == 0:
788 self.assertEqual(num_appends, 0)
789 else:
790 self.failUnless(num_appends >= 2)
791
792 def test_dict_chunking(self):
793 n = 10 # too small to chunk
794 x = dict.fromkeys(range(n))
795 for proto in protocols:
796 s = self.dumps(x, proto)
797 y = self.loads(s)
798 self.assertEqual(x, y)
799 num_setitems = count_opcode(pickle.SETITEMS, s)
800 self.assertEqual(num_setitems, proto > 0)
801
802 n = 2500 # expect at least two chunks when proto > 0
803 x = dict.fromkeys(range(n))
804 for proto in protocols:
805 s = self.dumps(x, proto)
806 y = self.loads(s)
807 self.assertEqual(x, y)
808 num_setitems = count_opcode(pickle.SETITEMS, s)
809 if proto == 0:
810 self.assertEqual(num_setitems, 0)
811 else:
812 self.failUnless(num_setitems >= 2)
813
814 def test_simple_newobj(self):
815 x = object.__new__(SimpleNewObj) # avoid __init__
816 x.abc = 666
817 for proto in protocols:
818 s = self.dumps(x, proto)
819 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
820 y = self.loads(s) # will raise TypeError if __init__ called
821 self.assertEqual(y.abc, 666)
822 self.assertEqual(x.__dict__, y.__dict__)
823
824 def test_newobj_list_slots(self):
825 x = SlotList([1, 2, 3])
826 x.foo = 42
827 x.bar = "hello"
828 s = self.dumps(x, 2)
829 y = self.loads(s)
830 self.assertEqual(list(x), list(y))
831 self.assertEqual(x.__dict__, y.__dict__)
832 self.assertEqual(x.foo, y.foo)
833 self.assertEqual(x.bar, y.bar)
834
835 def test_reduce_overrides_default_reduce_ex(self):
836 for proto in 0, 1, 2:
837 x = REX_one()
838 self.assertEqual(x._reduce_called, 0)
839 s = self.dumps(x, proto)
840 self.assertEqual(x._reduce_called, 1)
841 y = self.loads(s)
842 self.assertEqual(y._reduce_called, 0)
843
844 def test_reduce_ex_called(self):
845 for proto in 0, 1, 2:
846 x = REX_two()
847 self.assertEqual(x._proto, None)
848 s = self.dumps(x, proto)
849 self.assertEqual(x._proto, proto)
850 y = self.loads(s)
851 self.assertEqual(y._proto, None)
852
853 def test_reduce_ex_overrides_reduce(self):
854 for proto in 0, 1, 2:
855 x = REX_three()
856 self.assertEqual(x._proto, None)
857 s = self.dumps(x, proto)
858 self.assertEqual(x._proto, proto)
859 y = self.loads(s)
860 self.assertEqual(y._proto, None)
861
862 def test_reduce_ex_calls_base(self):
863 for proto in 0, 1, 2:
864 x = REX_four()
865 self.assertEqual(x._proto, None)
866 s = self.dumps(x, proto)
867 self.assertEqual(x._proto, proto)
868 y = self.loads(s)
869 self.assertEqual(y._proto, proto)
870
871 def test_reduce_calls_base(self):
872 for proto in 0, 1, 2:
873 x = REX_five()
874 self.assertEqual(x._reduce_called, 0)
875 s = self.dumps(x, proto)
876 self.assertEqual(x._reduce_called, 1)
877 y = self.loads(s)
878 self.assertEqual(y._reduce_called, 1)
879
880 def test_reduce_bad_iterator(self):
881 # Issue4176: crash when 4th and 5th items of __reduce__()
882 # are not iterators
883 class C(object):
884 def __reduce__(self):
885 # 4th item is not an iterator
886 return list, (), None, [], None
887 class D(object):
888 def __reduce__(self):
889 # 5th item is not an iterator
890 return dict, (), None, None, []
891
892 # Protocol 0 is less strict and also accept iterables.
893 for proto in 0, 1, 2:
894 try:
895 self.dumps(C(), proto)
896 except (AttributeError, pickle.PickleError, cPickle.PickleError):
897 pass
898 try:
899 self.dumps(D(), proto)
900 except (AttributeError, pickle.PickleError, cPickle.PickleError):
901 pass
902
903# Test classes for reduce_ex
904
905class REX_one(object):
906 _reduce_called = 0
907 def __reduce__(self):
908 self._reduce_called = 1
909 return REX_one, ()
910 # No __reduce_ex__ here, but inheriting it from object
911
912class REX_two(object):
913 _proto = None
914 def __reduce_ex__(self, proto):
915 self._proto = proto
916 return REX_two, ()
917 # No __reduce__ here, but inheriting it from object
918
919class REX_three(object):
920 _proto = None
921 def __reduce_ex__(self, proto):
922 self._proto = proto
923 return REX_two, ()
924 def __reduce__(self):
925 raise TestFailed, "This __reduce__ shouldn't be called"
926
927class REX_four(object):
928 _proto = None
929 def __reduce_ex__(self, proto):
930 self._proto = proto
931 return object.__reduce_ex__(self, proto)
932 # Calling base class method should succeed
933
934class REX_five(object):
935 _reduce_called = 0
936 def __reduce__(self):
937 self._reduce_called = 1
938 return object.__reduce__(self)
939 # This one used to fail with infinite recursion
940
941# Test classes for newobj
942
943class MyInt(int):
944 sample = 1
945
946class MyLong(long):
947 sample = 1L
948
949class MyFloat(float):
950 sample = 1.0
951
952class MyComplex(complex):
953 sample = 1.0 + 0.0j
954
955class MyStr(str):
956 sample = "hello"
957
958class MyUnicode(unicode):
959 sample = u"hello \u1234"
960
961class MyTuple(tuple):
962 sample = (1, 2, 3)
963
964class MyList(list):
965 sample = [1, 2, 3]
966
967class MyDict(dict):
968 sample = {"a": 1, "b": 2}
969
970myclasses = [MyInt, MyLong, MyFloat,
971 MyComplex,
972 MyStr, MyUnicode,
973 MyTuple, MyList, MyDict]
974
975
976class SlotList(MyList):
977 __slots__ = ["foo"]
978
979class SimpleNewObj(object):
980 def __init__(self, a, b, c):
981 # raise an error, to make sure this isn't called
982 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
983
984class AbstractPickleModuleTests(unittest.TestCase):
985
986 def test_dump_closed_file(self):
987 import os
988 f = open(TESTFN, "w")
989 try:
990 f.close()
991 self.assertRaises(ValueError, self.module.dump, 123, f)
992 finally:
993 os.remove(TESTFN)
994
995 def test_load_closed_file(self):
996 import os
997 f = open(TESTFN, "w")
998 try:
999 f.close()
1000 self.assertRaises(ValueError, self.module.dump, 123, f)
1001 finally:
1002 os.remove(TESTFN)
1003
1004 def test_highest_protocol(self):
1005 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
1006 self.assertEqual(self.module.HIGHEST_PROTOCOL, 2)
1007
1008 def test_callapi(self):
1009 from cStringIO import StringIO
1010 f = StringIO()
1011 # With and without keyword arguments
1012 self.module.dump(123, f, -1)
1013 self.module.dump(123, file=f, protocol=-1)
1014 self.module.dumps(123, -1)
1015 self.module.dumps(123, protocol=-1)
1016 self.module.Pickler(f, -1)
1017 self.module.Pickler(f, protocol=-1)
1018
1019 def test_incomplete_input(self):
1020 s = StringIO.StringIO("X''.")
1021 self.assertRaises(EOFError, self.module.load, s)
1022
1023 def test_restricted(self):
1024 # issue7128: cPickle failed in restricted mode
1025 builtins = {self.module.__name__: self.module,
1026 '__import__': __import__}
1027 d = {}
1028 teststr = "def f(): {0}.dumps(0)".format(self.module.__name__)
1029 exec teststr in {'__builtins__': builtins}, d
1030 d['f']()
1031
1032 def test_bad_input(self):
1033 # Test issue4298
1034 s = '\x58\0\0\0\x54'
1035 self.assertRaises(EOFError, self.module.loads, s)
1036 # Test issue7455
1037 s = '0'
1038 # XXX Why doesn't pickle raise UnpicklingError?
1039 self.assertRaises((IndexError, cPickle.UnpicklingError),
1040 self.module.loads, s)
1041
1042class AbstractPersistentPicklerTests(unittest.TestCase):
1043
1044 # This class defines persistent_id() and persistent_load()
1045 # functions that should be used by the pickler. All even integers
1046 # are pickled using persistent ids.
1047
1048 def persistent_id(self, object):
1049 if isinstance(object, int) and object % 2 == 0:
1050 self.id_count += 1
1051 return str(object)
1052 else:
1053 return None
1054
1055 def persistent_load(self, oid):
1056 self.load_count += 1
1057 object = int(oid)
1058 assert object % 2 == 0
1059 return object
1060
1061 def test_persistence(self):
1062 self.id_count = 0
1063 self.load_count = 0
1064 L = range(10)
1065 self.assertEqual(self.loads(self.dumps(L)), L)
1066 self.assertEqual(self.id_count, 5)
1067 self.assertEqual(self.load_count, 5)
1068
1069 def test_bin_persistence(self):
1070 self.id_count = 0
1071 self.load_count = 0
1072 L = range(10)
1073 self.assertEqual(self.loads(self.dumps(L, 1)), L)
1074 self.assertEqual(self.id_count, 5)
1075 self.assertEqual(self.load_count, 5)
Note: See TracBrowser for help on using the repository browser.