9 from test
.test_support
import TestFailed
, have_unicode
, TESTFN
11 # Tests that try a number of pickle protocols should have a
12 # for proto in protocols:
14 assert pickle
.HIGHEST_PROTOCOL
== cPickle
.HIGHEST_PROTOCOL
== 2
15 protocols
= range(pickle
.HIGHEST_PROTOCOL
+ 1)
17 # 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
21 def run_with_locale(catstr
, *locales
):
23 def inner(*args
, **kwds
):
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
32 # cannot retrieve original locale, so do nothing
33 locale
= orig_locale
= None
37 locale
.setlocale(category
, loc
)
42 # now run the function, resetting the locale on exceptions
44 return func(*args
, **kwds
)
46 if locale
and orig_locale
:
47 locale
.setlocale(category
, orig_locale
)
48 inner
.func_name
= func
.func_name
49 inner
.__doc
__ = func
.__doc
__
54 # Return True if opcode code appears in the pickle, else False.
55 def opcode_in_pickle(code
, pickle
):
56 for op
, dummy
, dummy
in pickletools
.genops(pickle
):
61 # Return the number of times opcode code appears in pickle.
62 def count_opcode(code
, pickle
):
64 for op
, dummy
, dummy
in pickletools
.genops(pickle
):
69 # 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
73 # e = ExtensionSaver(extension_code)
75 # fiddle w/ the extension registry's stuff for extension_code
80 # Remember current registration for code (if any), and remove it (if
82 def __init__(self
, code
):
84 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
)
90 # Restore previous registration for code.
93 curpair
= copy_reg
._inverted
_registry
.get(code
)
94 if curpair
is not None:
95 copy_reg
.remove_extension(curpair
[0], curpair
[1], code
)
98 copy_reg
.add_extension(pair
[0], pair
[1], code
)
101 def __cmp__(self
, other
):
102 return cmp(self
.__dict
__, other
.__dict
__)
106 C
.__module
__ = "__main__"
109 def __init__(self
, x
):
114 def __init__(self
, a
, b
):
118 def __getinitargs__(self
):
119 return self
.a
, self
.b
121 class metaclass(type):
124 class use_metaclass(object):
125 __metaclass__
= metaclass
127 # DATA0 .. DATA2 are the pickles we expect under the various protocols, for
128 # the object returned by create_data().
130 # break into multiple strings to avoid confusing font-lock-mode
176 # Disassembly of DATA0.
179 1: l LIST (MARK at 0)
187 18: c GLOBAL '__builtin__ complex'
192 49: t TUPLE (MARK at 42)
212 110: I INT 2147483647
214 123: I INT -2147483647
216 137: I INT -2147483648
223 166: i INST '__main__ C' (MARK at 165)
226 182: d DICT (MARK at 181)
238 218: t TUPLE (MARK at 151)
246 highest protocol among opcodes = 0
249 DATA1
= (']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00'
250 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00'
251 '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff'
252 '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff'
253 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00'
254 '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n'
255 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh'
259 # Disassembly of DATA1.
267 19: c GLOBAL '__builtin__ complex'
272 61: t TUPLE (MARK at 42)
283 97: J BININT 2147483647
284 102: J BININT -2147483647
285 107: J BININT -2147483648
287 113: U SHORT_BINSTRING 'abc'
291 123: c GLOBAL '__main__ C'
293 137: o OBJ (MARK at 122)
298 144: U SHORT_BINSTRING 'foo'
301 153: U SHORT_BINSTRING 'bar'
304 162: u SETITEMS (MARK at 143)
307 166: t TUPLE (MARK at 112)
311 173: e APPENDS (MARK at 3)
313 highest protocol among opcodes = 1
316 DATA2
= ('\x80\x02]q\x01(K\x00\x8a\x01\x01G@\x00\x00\x00\x00\x00\x00\x00'
317 'c__builtin__\ncomplex\nq\x02G@\x08\x00\x00\x00\x00\x00\x00G\x00'
318 '\x00\x00\x00\x00\x00\x00\x00\x86Rq\x03K\x01J\xff\xff\xff\xffK'
319 '\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xff'
320 'J\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00'
321 '\x80(U\x03abcq\x04h\x04(c__main__\nC\nq\x05oq\x06}q\x07(U\x03foo'
322 'q\x08K\x01U\x03barq\tK\x02ubh\x06tq\nh\nK\x05e.')
324 # Disassembly of DATA2.
333 20: c GLOBAL '__builtin__ complex'
348 97: J BININT 2147483647
349 102: J BININT -2147483647
350 107: J BININT -2147483648
352 113: U SHORT_BINSTRING 'abc'
356 123: c GLOBAL '__main__ C'
358 137: o OBJ (MARK at 122)
363 144: U SHORT_BINSTRING 'foo'
366 153: U SHORT_BINSTRING 'bar'
369 162: u SETITEMS (MARK at 143)
372 166: t TUPLE (MARK at 112)
376 173: e APPENDS (MARK at 5)
378 highest protocol among opcodes = 2
385 x
= [0, 1L, 2.0, 3.0+0j
]
386 # Append some integer test cases at cPickle.c's internal size
392 uint1max
, -uint1max
, -uint1max
-1,
393 uint2max
, -uint2max
, -uint2max
-1,
394 int4max
, -int4max
, -int4max
-1])
395 y
= ('abc', 'abc', c
, c
)
401 class AbstractPickleTests(unittest
.TestCase
):
402 # Subclass must define self.dumps, self.loads, self.error.
404 _testdata
= create_data()
410 # test various datatypes not tested by testdata
411 for proto
in protocols
:
413 s
= self
.dumps(x
, proto
)
415 self
.assertEqual(x
, y
)
418 s
= self
.dumps(x
, proto
)
420 self
.assertEqual(x
, y
)
423 s
= self
.dumps(x
, proto
)
425 self
.assertEqual(x
, y
)
427 # XXX test __reduce__ protocol?
429 def test_roundtrip_equality(self
):
430 expected
= self
._testdata
431 for proto
in protocols
:
432 s
= self
.dumps(expected
, proto
)
434 self
.assertEqual(expected
, got
)
436 def test_load_from_canned_string(self
):
437 expected
= self
._testdata
438 for canned
in DATA0
, DATA1
, DATA2
:
439 got
= self
.loads(canned
)
440 self
.assertEqual(expected
, got
)
442 # There are gratuitous differences between pickles produced by
443 # pickle and cPickle, largely because cPickle starts PUT indices at
444 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
445 # there's a comment with an exclamation point there whose meaning
446 # is a mystery. cPickle also suppresses PUT for objects with a refcount
448 def dont_test_disassembly(self
):
449 from pickletools
import dis
451 for proto
, expected
in (0, DATA0_DIS
), (1, DATA1_DIS
):
452 s
= self
.dumps(self
._testdata
, proto
)
453 filelike
= cStringIO
.StringIO()
455 got
= filelike
.getvalue()
456 self
.assertEqual(expected
, got
)
458 def test_recursive_list(self
):
461 for proto
in protocols
:
462 s
= self
.dumps(l
, proto
)
464 self
.assertEqual(len(x
), 1)
465 self
.assertTrue(x
is x
[0])
467 def test_recursive_tuple(self
):
470 for proto
in protocols
:
471 s
= self
.dumps(t
, proto
)
473 self
.assertEqual(len(x
), 1)
474 self
.assertEqual(len(x
[0]), 1)
475 self
.assertTrue(x
is x
[0][0])
477 def test_recursive_dict(self
):
480 for proto
in protocols
:
481 s
= self
.dumps(d
, proto
)
483 self
.assertEqual(x
.keys(), [1])
484 self
.assertTrue(x
[1] is x
)
486 def test_recursive_inst(self
):
489 for proto
in protocols
:
492 self
.assertEqual(dir(x
), dir(i
))
493 self
.assertTrue(x
.attr
is x
)
495 def test_recursive_multi(self
):
501 for proto
in protocols
:
502 s
= self
.dumps(l
, proto
)
504 self
.assertEqual(len(x
), 1)
505 self
.assertEqual(dir(x
[0]), dir(i
))
506 self
.assertEqual(x
[0].attr
.keys(), [1])
507 self
.assertTrue(x
[0].attr
[1] is x
)
509 def test_garyp(self
):
510 self
.assertRaises(self
.error
, self
.loads
, 'garyp')
512 def test_insecure_strings(self
):
513 insecure
= ["abc", "2 + 2", # not quoted
514 #"'abc' + 'def'", # not a single quoted string
515 "'abc", # quote is not closed
516 "'abc\"", # open quote and close quote don't match
517 "'abc' ?", # junk after close quote
518 "'\\'", # trailing backslash
519 # some tests of the quoting rules
521 #"'\\\\a\'\'\'\\\'\\\\\''",
524 buf
= "S" + s
+ "\012p0\012."
525 self
.assertRaises(ValueError, self
.loads
, buf
)
528 def test_unicode(self
):
529 endcases
= [u
'', u
'<\\u>', u
'<\\\u1234>', u
'<\n>',
530 u
'<\\>', u
'<\\\U00012345>']
531 for proto
in protocols
:
533 p
= self
.dumps(u
, proto
)
535 self
.assertEqual(u2
, u
)
537 def test_unicode_high_plane(self
):
539 for proto
in protocols
:
540 p
= self
.dumps(t
, proto
)
542 self
.assertEqual(t2
, t
)
546 for proto
in protocols
:
549 for expected
in (-n
, n
):
550 s
= self
.dumps(expected
, proto
)
552 self
.assertEqual(expected
, n2
)
555 def test_maxint64(self
):
556 maxint64
= (1L << 63) - 1
557 data
= 'I' + str(maxint64
) + '\n.'
558 got
= self
.loads(data
)
559 self
.assertEqual(got
, maxint64
)
561 # Try too with a bogus literal.
562 data
= 'I' + str(maxint64
) + 'JUNK\n.'
563 self
.assertRaises(ValueError, self
.loads
, data
)
566 for proto
in protocols
:
567 # 256 bytes is where LONG4 begins.
568 for nbits
in 1, 8, 8*254, 8*255, 8*256, 8*257:
570 for npos
in nbase
-1, nbase
, nbase
+1:
571 for n
in npos
, -npos
:
572 pickle
= self
.dumps(n
, proto
)
573 got
= self
.loads(pickle
)
574 self
.assertEqual(n
, got
)
575 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
577 nbase
= long("deadbeeffeedface", 16)
578 nbase
+= nbase
<< 1000000
579 for n
in nbase
, -nbase
:
582 self
.assertEqual(n
, got
)
584 def test_float(self
):
585 test_values
= [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
586 3.14, 263.44582062374053, 6.022e23
, 1e30
]
587 test_values
= test_values
+ [-x
for x
in test_values
]
588 for proto
in protocols
:
589 for value
in test_values
:
590 pickle
= self
.dumps(value
, proto
)
591 got
= self
.loads(pickle
)
592 self
.assertEqual(value
, got
)
594 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
595 def test_float_format(self
):
596 # make sure that floats are formatted locale independent
597 self
.assertEqual(self
.dumps(1.2)[0:3], 'F1.')
599 def test_reduce(self
):
602 def test_getinitargs(self
):
605 def test_metaclass(self
):
607 for proto
in protocols
:
608 s
= self
.dumps(a
, proto
)
610 self
.assertEqual(a
.__class
__, b
.__class
__)
612 def test_structseq(self
):
617 for proto
in protocols
:
618 s
= self
.dumps(t
, proto
)
620 self
.assertEqual(t
, u
)
621 if hasattr(os
, "stat"):
622 t
= os
.stat(os
.curdir
)
623 s
= self
.dumps(t
, proto
)
625 self
.assertEqual(t
, u
)
626 if hasattr(os
, "statvfs"):
627 t
= os
.statvfs(os
.curdir
)
628 s
= self
.dumps(t
, proto
)
630 self
.assertEqual(t
, u
)
632 # Tests for protocol 2
634 def test_proto(self
):
635 build_none
= pickle
.NONE
+ pickle
.STOP
636 for proto
in protocols
:
637 expected
= build_none
639 expected
= pickle
.PROTO
+ chr(proto
) + expected
640 p
= self
.dumps(None, proto
)
641 self
.assertEqual(p
, expected
)
643 oob
= protocols
[-1] + 1 # a future protocol
644 badpickle
= pickle
.PROTO
+ chr(oob
) + build_none
646 self
.loads(badpickle
)
647 except ValueError, detail
:
648 self
.assertTrue(str(detail
).startswith(
649 "unsupported pickle protocol"))
651 self
.fail("expected bad protocol number to raise ValueError")
653 def test_long1(self
):
654 x
= 12345678910111213141516178920L
655 for proto
in protocols
:
656 s
= self
.dumps(x
, proto
)
658 self
.assertEqual(x
, y
)
659 self
.assertEqual(opcode_in_pickle(pickle
.LONG1
, s
), proto
>= 2)
661 def test_long4(self
):
662 x
= 12345678910111213141516178920L << (256*8)
663 for proto
in protocols
:
664 s
= self
.dumps(x
, proto
)
666 self
.assertEqual(x
, y
)
667 self
.assertEqual(opcode_in_pickle(pickle
.LONG4
, s
), proto
>= 2)
669 def test_short_tuples(self
):
670 # Map (proto, len(tuple)) to expected opcode.
671 expected_opcode
= {(0, 0): pickle
.TUPLE
,
672 (0, 1): pickle
.TUPLE
,
673 (0, 2): pickle
.TUPLE
,
674 (0, 3): pickle
.TUPLE
,
675 (0, 4): pickle
.TUPLE
,
677 (1, 0): pickle
.EMPTY_TUPLE
,
678 (1, 1): pickle
.TUPLE
,
679 (1, 2): pickle
.TUPLE
,
680 (1, 3): pickle
.TUPLE
,
681 (1, 4): pickle
.TUPLE
,
683 (2, 0): pickle
.EMPTY_TUPLE
,
684 (2, 1): pickle
.TUPLE1
,
685 (2, 2): pickle
.TUPLE2
,
686 (2, 3): pickle
.TUPLE3
,
687 (2, 4): pickle
.TUPLE
,
694 for proto
in protocols
:
695 for x
in a
, b
, c
, d
, e
:
696 s
= self
.dumps(x
, proto
)
698 self
.assertEqual(x
, y
, (proto
, x
, s
, y
))
699 expected
= expected_opcode
[proto
, len(x
)]
700 self
.assertEqual(opcode_in_pickle(expected
, s
), True)
702 def test_singletons(self
):
703 # Map (proto, singleton) to expected opcode.
704 expected_opcode
= {(0, None): pickle
.NONE
,
705 (1, None): pickle
.NONE
,
706 (2, None): pickle
.NONE
,
708 (0, True): pickle
.INT
,
709 (1, True): pickle
.INT
,
710 (2, True): pickle
.NEWTRUE
,
712 (0, False): pickle
.INT
,
713 (1, False): pickle
.INT
,
714 (2, False): pickle
.NEWFALSE
,
716 for proto
in protocols
:
717 for x
in None, False, True:
718 s
= self
.dumps(x
, proto
)
720 self
.assertTrue(x
is y
, (proto
, x
, s
, y
))
721 expected
= expected_opcode
[proto
, x
]
722 self
.assertEqual(opcode_in_pickle(expected
, s
), True)
724 def test_newobj_tuple(self
):
725 x
= MyTuple([1, 2, 3])
728 for proto
in protocols
:
729 s
= self
.dumps(x
, proto
)
731 self
.assertEqual(tuple(x
), tuple(y
))
732 self
.assertEqual(x
.__dict
__, y
.__dict
__)
734 def test_newobj_list(self
):
735 x
= MyList([1, 2, 3])
738 for proto
in protocols
:
739 s
= self
.dumps(x
, proto
)
741 self
.assertEqual(list(x
), list(y
))
742 self
.assertEqual(x
.__dict
__, y
.__dict
__)
744 def test_newobj_generic(self
):
745 for proto
in protocols
:
750 s
= self
.dumps(x
, proto
)
752 detail
= (proto
, C
, B
, x
, y
, type(y
))
753 self
.assertEqual(B(x
), B(y
), detail
)
754 self
.assertEqual(x
.__dict
__, y
.__dict
__, detail
)
756 # Register a type with copy_reg, with extension code extcode. Pickle
757 # an object of that type. Check that the resulting pickle uses opcode
758 # (EXT[124]) under proto 2, and not in proto 1.
760 def produce_global_ext(self
, extcode
, opcode
):
761 e
= ExtensionSaver(extcode
)
763 copy_reg
.add_extension(__name__
, "MyList", extcode
)
764 x
= MyList([1, 2, 3])
768 # Dump using protocol 1 for comparison.
769 s1
= self
.dumps(x
, 1)
770 self
.assertTrue(__name__
in s1
)
771 self
.assertTrue("MyList" in s1
)
772 self
.assertEqual(opcode_in_pickle(opcode
, s1
), False)
775 self
.assertEqual(list(x
), list(y
))
776 self
.assertEqual(x
.__dict
__, y
.__dict
__)
778 # Dump using protocol 2 for test.
779 s2
= self
.dumps(x
, 2)
780 self
.assertTrue(__name__
not in s2
)
781 self
.assertTrue("MyList" not in s2
)
782 self
.assertEqual(opcode_in_pickle(opcode
, s2
), True)
785 self
.assertEqual(list(x
), list(y
))
786 self
.assertEqual(x
.__dict
__, y
.__dict
__)
791 def test_global_ext1(self
):
792 self
.produce_global_ext(0x00000001, pickle
.EXT1
) # smallest EXT1 code
793 self
.produce_global_ext(0x000000ff, pickle
.EXT1
) # largest EXT1 code
795 def test_global_ext2(self
):
796 self
.produce_global_ext(0x00000100, pickle
.EXT2
) # smallest EXT2 code
797 self
.produce_global_ext(0x0000ffff, pickle
.EXT2
) # largest EXT2 code
798 self
.produce_global_ext(0x0000abcd, pickle
.EXT2
) # check endianness
800 def test_global_ext4(self
):
801 self
.produce_global_ext(0x00010000, pickle
.EXT4
) # smallest EXT4 code
802 self
.produce_global_ext(0x7fffffff, pickle
.EXT4
) # largest EXT4 code
803 self
.produce_global_ext(0x12abcdef, pickle
.EXT4
) # check endianness
805 def test_list_chunking(self
):
806 n
= 10 # too small to chunk
808 for proto
in protocols
:
809 s
= self
.dumps(x
, proto
)
811 self
.assertEqual(x
, y
)
812 num_appends
= count_opcode(pickle
.APPENDS
, s
)
813 self
.assertEqual(num_appends
, proto
> 0)
815 n
= 2500 # expect at least two chunks when proto > 0
817 for proto
in protocols
:
818 s
= self
.dumps(x
, proto
)
820 self
.assertEqual(x
, y
)
821 num_appends
= count_opcode(pickle
.APPENDS
, s
)
823 self
.assertEqual(num_appends
, 0)
825 self
.assertTrue(num_appends
>= 2)
827 def test_dict_chunking(self
):
828 n
= 10 # too small to chunk
829 x
= dict.fromkeys(range(n
))
830 for proto
in protocols
:
831 s
= self
.dumps(x
, proto
)
833 self
.assertEqual(x
, y
)
834 num_setitems
= count_opcode(pickle
.SETITEMS
, s
)
835 self
.assertEqual(num_setitems
, proto
> 0)
837 n
= 2500 # expect at least two chunks when proto > 0
838 x
= dict.fromkeys(range(n
))
839 for proto
in protocols
:
840 s
= self
.dumps(x
, proto
)
842 self
.assertEqual(x
, y
)
843 num_setitems
= count_opcode(pickle
.SETITEMS
, s
)
845 self
.assertEqual(num_setitems
, 0)
847 self
.assertTrue(num_setitems
>= 2)
849 def test_simple_newobj(self
):
850 x
= object.__new
__(SimpleNewObj
) # avoid __init__
852 for proto
in protocols
:
853 s
= self
.dumps(x
, proto
)
854 self
.assertEqual(opcode_in_pickle(pickle
.NEWOBJ
, s
), proto
>= 2)
855 y
= self
.loads(s
) # will raise TypeError if __init__ called
856 self
.assertEqual(y
.abc
, 666)
857 self
.assertEqual(x
.__dict
__, y
.__dict
__)
859 def test_newobj_list_slots(self
):
860 x
= SlotList([1, 2, 3])
865 self
.assertEqual(list(x
), list(y
))
866 self
.assertEqual(x
.__dict
__, y
.__dict
__)
867 self
.assertEqual(x
.foo
, y
.foo
)
868 self
.assertEqual(x
.bar
, y
.bar
)
870 def test_reduce_overrides_default_reduce_ex(self
):
871 for proto
in protocols
:
873 self
.assertEqual(x
._reduce
_called
, 0)
874 s
= self
.dumps(x
, proto
)
875 self
.assertEqual(x
._reduce
_called
, 1)
877 self
.assertEqual(y
._reduce
_called
, 0)
879 def test_reduce_ex_called(self
):
880 for proto
in protocols
:
882 self
.assertEqual(x
._proto
, None)
883 s
= self
.dumps(x
, proto
)
884 self
.assertEqual(x
._proto
, proto
)
886 self
.assertEqual(y
._proto
, None)
888 def test_reduce_ex_overrides_reduce(self
):
889 for proto
in protocols
:
891 self
.assertEqual(x
._proto
, None)
892 s
= self
.dumps(x
, proto
)
893 self
.assertEqual(x
._proto
, proto
)
895 self
.assertEqual(y
._proto
, None)
897 def test_reduce_ex_calls_base(self
):
898 for proto
in protocols
:
900 self
.assertEqual(x
._proto
, None)
901 s
= self
.dumps(x
, proto
)
902 self
.assertEqual(x
._proto
, proto
)
904 self
.assertEqual(y
._proto
, proto
)
906 def test_reduce_calls_base(self
):
907 for proto
in protocols
:
909 self
.assertEqual(x
._reduce
_called
, 0)
910 s
= self
.dumps(x
, proto
)
911 self
.assertEqual(x
._reduce
_called
, 1)
913 self
.assertEqual(y
._reduce
_called
, 1)
915 def test_reduce_bad_iterator(self
):
916 # Issue4176: crash when 4th and 5th items of __reduce__()
919 def __reduce__(self
):
920 # 4th item is not an iterator
921 return list, (), None, [], None
923 def __reduce__(self
):
924 # 5th item is not an iterator
925 return dict, (), None, None, []
927 # Protocol 0 is less strict and also accept iterables.
928 for proto
in protocols
:
930 self
.dumps(C(), proto
)
931 except (AttributeError, pickle
.PickleError
, cPickle
.PickleError
):
934 self
.dumps(D(), proto
)
935 except (AttributeError, pickle
.PickleError
, cPickle
.PickleError
):
938 def test_many_puts_and_gets(self
):
939 # Test that internal data structures correctly deal with lots of
941 keys
= ("aaa" + str(i
) for i
in xrange(100))
942 large_dict
= dict((k
, [4, 5, 6]) for k
in keys
)
943 obj
= [dict(large_dict
), dict(large_dict
), dict(large_dict
)]
945 for proto
in protocols
:
946 dumped
= self
.dumps(obj
, proto
)
947 loaded
= self
.loads(dumped
)
948 self
.assertEqual(loaded
, obj
,
949 "Failed protocol %d: %r != %r"
950 % (proto
, obj
, loaded
))
952 def test_attribute_name_interning(self
):
953 # Test that attribute names of pickled objects are interned when
955 for proto
in protocols
:
959 s
= self
.dumps(x
, proto
)
961 x_keys
= sorted(x
.__dict
__)
962 y_keys
= sorted(y
.__dict
__)
963 for x_key
, y_key
in zip(x_keys
, y_keys
):
964 self
.assertIs(x_key
, y_key
)
967 # Test classes for reduce_ex
969 class REX_one(object):
971 def __reduce__(self
):
972 self
._reduce
_called
= 1
974 # No __reduce_ex__ here, but inheriting it from object
976 class REX_two(object):
978 def __reduce_ex__(self
, proto
):
981 # No __reduce__ here, but inheriting it from object
983 class REX_three(object):
985 def __reduce_ex__(self
, proto
):
988 def __reduce__(self
):
989 raise TestFailed
, "This __reduce__ shouldn't be called"
991 class REX_four(object):
993 def __reduce_ex__(self
, proto
):
995 return object.__reduce
_ex
__(self
, proto
)
996 # Calling base class method should succeed
998 class REX_five(object):
1000 def __reduce__(self
):
1001 self
._reduce
_called
= 1
1002 return object.__reduce
__(self
)
1003 # This one used to fail with infinite recursion
1005 # Test classes for newobj
1013 class MyFloat(float):
1016 class MyComplex(complex):
1022 class MyUnicode(unicode):
1023 sample
= u
"hello \u1234"
1025 class MyTuple(tuple):
1032 sample
= {"a": 1, "b": 2}
1034 myclasses
= [MyInt
, MyLong
, MyFloat
,
1037 MyTuple
, MyList
, MyDict
]
1040 class SlotList(MyList
):
1043 class SimpleNewObj(object):
1044 def __init__(self
, a
, b
, c
):
1045 # raise an error, to make sure this isn't called
1046 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1048 class AbstractPickleModuleTests(unittest
.TestCase
):
1050 def test_dump_closed_file(self
):
1052 f
= open(TESTFN
, "w")
1055 self
.assertRaises(ValueError, self
.module
.dump
, 123, f
)
1059 def test_load_closed_file(self
):
1061 f
= open(TESTFN
, "w")
1064 self
.assertRaises(ValueError, self
.module
.dump
, 123, f
)
1068 def test_load_from_and_dump_to_file(self
):
1069 stream
= cStringIO
.StringIO()
1070 data
= [123, {}, 124]
1071 self
.module
.dump(data
, stream
)
1073 unpickled
= self
.module
.load(stream
)
1074 self
.assertEqual(unpickled
, data
)
1076 def test_highest_protocol(self
):
1077 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
1078 self
.assertEqual(self
.module
.HIGHEST_PROTOCOL
, 2)
1080 def test_callapi(self
):
1081 f
= cStringIO
.StringIO()
1082 # With and without keyword arguments
1083 self
.module
.dump(123, f
, -1)
1084 self
.module
.dump(123, file=f
, protocol
=-1)
1085 self
.module
.dumps(123, -1)
1086 self
.module
.dumps(123, protocol
=-1)
1087 self
.module
.Pickler(f
, -1)
1088 self
.module
.Pickler(f
, protocol
=-1)
1090 def test_incomplete_input(self
):
1091 s
= StringIO
.StringIO("X''.")
1092 self
.assertRaises(EOFError, self
.module
.load
, s
)
1094 class AbstractPersistentPicklerTests(unittest
.TestCase
):
1096 # This class defines persistent_id() and persistent_load()
1097 # functions that should be used by the pickler. All even integers
1098 # are pickled using persistent ids.
1100 def persistent_id(self
, object):
1101 if isinstance(object, int) and object % 2 == 0:
1107 def persistent_load(self
, oid
):
1108 self
.load_count
+= 1
1110 assert object % 2 == 0
1113 def test_persistence(self
):
1117 self
.assertEqual(self
.loads(self
.dumps(L
)), L
)
1118 self
.assertEqual(self
.id_count
, 5)
1119 self
.assertEqual(self
.load_count
, 5)
1121 def test_bin_persistence(self
):
1125 self
.assertEqual(self
.loads(self
.dumps(L
, 1)), L
)
1126 self
.assertEqual(self
.id_count
, 5)
1127 self
.assertEqual(self
.load_count
, 5)
1129 class AbstractPicklerUnpicklerObjectTests(unittest
.TestCase
):
1131 pickler_class
= None
1132 unpickler_class
= None
1135 assert self
.pickler_class
1136 assert self
.unpickler_class
1138 def test_clear_pickler_memo(self
):
1139 # To test whether clear_memo() has any effect, we pickle an object,
1140 # then pickle it again without clearing the memo; the two serialized
1141 # forms should be different. If we clear_memo() and then pickle the
1142 # object again, the third serialized form should be identical to the
1143 # first one we obtained.
1144 data
= ["abcdefg", "abcdefg", 44]
1145 f
= cStringIO
.StringIO()
1146 pickler
= self
.pickler_class(f
)
1149 first_pickled
= f
.getvalue()
1151 # Reset StringIO object.
1156 second_pickled
= f
.getvalue()
1158 # Reset the Pickler and StringIO objects.
1159 pickler
.clear_memo()
1164 third_pickled
= f
.getvalue()
1166 self
.assertNotEqual(first_pickled
, second_pickled
)
1167 self
.assertEqual(first_pickled
, third_pickled
)
1169 def test_priming_pickler_memo(self
):
1170 # Verify that we can set the Pickler's memo attribute.
1171 data
= ["abcdefg", "abcdefg", 44]
1172 f
= cStringIO
.StringIO()
1173 pickler
= self
.pickler_class(f
)
1176 first_pickled
= f
.getvalue()
1178 f
= cStringIO
.StringIO()
1179 primed
= self
.pickler_class(f
)
1180 primed
.memo
= pickler
.memo
1183 primed_pickled
= f
.getvalue()
1185 self
.assertNotEqual(first_pickled
, primed_pickled
)
1187 def test_priming_unpickler_memo(self
):
1188 # Verify that we can set the Unpickler's memo attribute.
1189 data
= ["abcdefg", "abcdefg", 44]
1190 f
= cStringIO
.StringIO()
1191 pickler
= self
.pickler_class(f
)
1194 first_pickled
= f
.getvalue()
1196 f
= cStringIO
.StringIO()
1197 primed
= self
.pickler_class(f
)
1198 primed
.memo
= pickler
.memo
1201 primed_pickled
= f
.getvalue()
1203 unpickler
= self
.unpickler_class(cStringIO
.StringIO(first_pickled
))
1204 unpickled_data1
= unpickler
.load()
1206 self
.assertEqual(unpickled_data1
, data
)
1208 primed
= self
.unpickler_class(cStringIO
.StringIO(primed_pickled
))
1209 primed
.memo
= unpickler
.memo
1210 unpickled_data2
= primed
.load()
1214 self
.assertEqual(unpickled_data2
, data
)
1215 self
.assertTrue(unpickled_data2
is unpickled_data1
)
1217 def test_reusing_unpickler_objects(self
):
1218 data1
= ["abcdefg", "abcdefg", 44]
1219 f
= cStringIO
.StringIO()
1220 pickler
= self
.pickler_class(f
)
1222 pickled1
= f
.getvalue()
1224 data2
= ["abcdefg", 44, 44]
1225 f
= cStringIO
.StringIO()
1226 pickler
= self
.pickler_class(f
)
1228 pickled2
= f
.getvalue()
1230 f
= cStringIO
.StringIO()
1233 unpickler
= self
.unpickler_class(f
)
1234 self
.assertEqual(unpickler
.load(), data1
)
1240 self
.assertEqual(unpickler
.load(), data2
)