Home | History | Annotate | Download | only in test
      1 import unittest
      2 import pickle
      3 import cPickle
      4 import StringIO
      5 import cStringIO
      6 import pickletools
      7 import copy_reg
      8 
      9 from test.test_support import TestFailed, have_unicode, TESTFN
     10 
     11 # Tests that try a number of pickle protocols should have a

     12 #     for proto in protocols:

     13 # kind of outer loop.

     14 assert pickle.HIGHEST_PROTOCOL == cPickle.HIGHEST_PROTOCOL == 2
     15 protocols = range(pickle.HIGHEST_PROTOCOL + 1)
     16 
     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

     20 # compatibility.

     21 def 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 
     53 
     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):
     57         if op.code == code:
     58             return True
     59     return False
     60 
     61 # Return the number of times opcode code appears in pickle.

     62 def 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 
     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

     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 
     79 class 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
     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)
     87         else:
     88             self.pair = None
     89 
     90     # Restore previous registration for code.

     91     def restore(self):
     92         code = self.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)
     96         pair = self.pair
     97         if pair is not None:
     98             copy_reg.add_extension(pair[0], pair[1], code)
     99 
    100 class C:
    101     def __cmp__(self, other):
    102         return cmp(self.__dict__, other.__dict__)
    103 
    104 import __main__
    105 __main__.C = C
    106 C.__module__ = "__main__"
    107 
    108 class myint(int):
    109     def __init__(self, x):
    110         self.str = str(x)
    111 
    112 class initarg(C):
    113 
    114     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 
    121 class metaclass(type):
    122     pass
    123 
    124 class use_metaclass(object):
    125     __metaclass__ = metaclass
    126 
    127 # DATA0 .. DATA2 are the pickles we expect under the various protocols, for

    128 # the object returned by create_data().

    129 
    130 # break into multiple strings to avoid confusing font-lock-mode

    131 DATA0 = """(lp1
    132 I0
    133 aL1L
    134 aF2
    135 ac__builtin__
    136 complex
    137 p2
    138 """ + \
    139 """(F3
    140 F0
    141 tRp3
    142 aI1
    143 aI-1
    144 aI255
    145 aI-255
    146 aI-256
    147 aI65535
    148 aI-65535
    149 aI-65536
    150 aI2147483647
    151 aI-2147483647
    152 aI-2147483648
    153 a""" + \
    154 """(S'abc'
    155 p4
    156 g4
    157 """ + \
    158 """(i__main__
    159 C
    160 p5
    161 """ + \
    162 """(dp6
    163 S'foo'
    164 p7
    165 I1
    166 sS'bar'
    167 p8
    168 I2
    169 sbg5
    170 tp9
    171 ag9
    172 aI5
    173 a.
    174 """
    175 
    176 # Disassembly of DATA0.

    177 DATA0_DIS = """\
    178     0: (    MARK
    179     1: l        LIST       (MARK at 0)
    180     2: p    PUT        1
    181     5: I    INT        0
    182     8: a    APPEND
    183     9: L    LONG       1L
    184    13: a    APPEND
    185    14: F    FLOAT      2.0
    186    17: a    APPEND
    187    18: c    GLOBAL     '__builtin__ complex'
    188    39: p    PUT        2
    189    42: (    MARK
    190    43: F        FLOAT      3.0
    191    46: F        FLOAT      0.0
    192    49: t        TUPLE      (MARK at 42)
    193    50: R    REDUCE
    194    51: p    PUT        3
    195    54: a    APPEND
    196    55: I    INT        1
    197    58: a    APPEND
    198    59: I    INT        -1
    199    63: a    APPEND
    200    64: I    INT        255
    201    69: a    APPEND
    202    70: I    INT        -255
    203    76: a    APPEND
    204    77: I    INT        -256
    205    83: a    APPEND
    206    84: I    INT        65535
    207    91: a    APPEND
    208    92: I    INT        -65535
    209   100: a    APPEND
    210   101: I    INT        -65536
    211   109: a    APPEND
    212   110: I    INT        2147483647
    213   122: a    APPEND
    214   123: I    INT        -2147483647
    215   136: a    APPEND
    216   137: I    INT        -2147483648
    217   150: a    APPEND
    218   151: (    MARK
    219   152: S        STRING     'abc'
    220   159: p        PUT        4
    221   162: g        GET        4
    222   165: (        MARK
    223   166: i            INST       '__main__ C' (MARK at 165)
    224   178: p        PUT        5
    225   181: (        MARK
    226   182: d            DICT       (MARK at 181)
    227   183: p        PUT        6
    228   186: S        STRING     'foo'
    229   193: p        PUT        7
    230   196: I        INT        1
    231   199: s        SETITEM
    232   200: S        STRING     'bar'
    233   207: p        PUT        8
    234   210: I        INT        2
    235   213: s        SETITEM
    236   214: b        BUILD
    237   215: g        GET        5
    238   218: t        TUPLE      (MARK at 151)
    239   219: p    PUT        9
    240   222: a    APPEND
    241   223: g    GET        9
    242   226: a    APPEND
    243   227: I    INT        5
    244   230: a    APPEND
    245   231: .    STOP
    246 highest protocol among opcodes = 0
    247 """
    248 
    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'
    256          '\x06tq\nh\nK\x05e.'
    257         )
    258 
    259 # Disassembly of DATA1.

    260 DATA1_DIS = """\
    261     0: ]    EMPTY_LIST
    262     1: q    BINPUT     1
    263     3: (    MARK
    264     4: K        BININT1    0
    265     6: L        LONG       1L
    266    10: G        BINFLOAT   2.0
    267    19: c        GLOBAL     '__builtin__ complex'
    268    40: q        BINPUT     2
    269    42: (        MARK
    270    43: G            BINFLOAT   3.0
    271    52: G            BINFLOAT   0.0
    272    61: t            TUPLE      (MARK at 42)
    273    62: R        REDUCE
    274    63: q        BINPUT     3
    275    65: K        BININT1    1
    276    67: J        BININT     -1
    277    72: K        BININT1    255
    278    74: J        BININT     -255
    279    79: J        BININT     -256
    280    84: M        BININT2    65535
    281    87: J        BININT     -65535
    282    92: J        BININT     -65536
    283    97: J        BININT     2147483647
    284   102: J        BININT     -2147483647
    285   107: J        BININT     -2147483648
    286   112: (        MARK
    287   113: U            SHORT_BINSTRING 'abc'
    288   118: q            BINPUT     4
    289   120: h            BINGET     4
    290   122: (            MARK
    291   123: c                GLOBAL     '__main__ C'
    292   135: q                BINPUT     5
    293   137: o                OBJ        (MARK at 122)
    294   138: q            BINPUT     6
    295   140: }            EMPTY_DICT
    296   141: q            BINPUT     7
    297   143: (            MARK
    298   144: U                SHORT_BINSTRING 'foo'
    299   149: q                BINPUT     8
    300   151: K                BININT1    1
    301   153: U                SHORT_BINSTRING 'bar'
    302   158: q                BINPUT     9
    303   160: K                BININT1    2
    304   162: u                SETITEMS   (MARK at 143)
    305   163: b            BUILD
    306   164: h            BINGET     6
    307   166: t            TUPLE      (MARK at 112)
    308   167: q        BINPUT     10
    309   169: h        BINGET     10
    310   171: K        BININT1    5
    311   173: e        APPENDS    (MARK at 3)
    312   174: .    STOP
    313 highest protocol among opcodes = 1
    314 """
    315 
    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.')
    323 
    324 # Disassembly of DATA2.

    325 DATA2_DIS = """\
    326     0: \x80 PROTO      2
    327     2: ]    EMPTY_LIST
    328     3: q    BINPUT     1
    329     5: (    MARK
    330     6: K        BININT1    0
    331     8: \x8a     LONG1      1L
    332    11: G        BINFLOAT   2.0
    333    20: c        GLOBAL     '__builtin__ complex'
    334    41: q        BINPUT     2
    335    43: G        BINFLOAT   3.0
    336    52: G        BINFLOAT   0.0
    337    61: \x86     TUPLE2
    338    62: R        REDUCE
    339    63: q        BINPUT     3
    340    65: K        BININT1    1
    341    67: J        BININT     -1
    342    72: K        BININT1    255
    343    74: J        BININT     -255
    344    79: J        BININT     -256
    345    84: M        BININT2    65535
    346    87: J        BININT     -65535
    347    92: J        BININT     -65536
    348    97: J        BININT     2147483647
    349   102: J        BININT     -2147483647
    350   107: J        BININT     -2147483648
    351   112: (        MARK
    352   113: U            SHORT_BINSTRING 'abc'
    353   118: q            BINPUT     4
    354   120: h            BINGET     4
    355   122: (            MARK
    356   123: c                GLOBAL     '__main__ C'
    357   135: q                BINPUT     5
    358   137: o                OBJ        (MARK at 122)
    359   138: q            BINPUT     6
    360   140: }            EMPTY_DICT
    361   141: q            BINPUT     7
    362   143: (            MARK
    363   144: U                SHORT_BINSTRING 'foo'
    364   149: q                BINPUT     8
    365   151: K                BININT1    1
    366   153: U                SHORT_BINSTRING 'bar'
    367   158: q                BINPUT     9
    368   160: K                BININT1    2
    369   162: u                SETITEMS   (MARK at 143)
    370   163: b            BUILD
    371   164: h            BINGET     6
    372   166: t            TUPLE      (MARK at 112)
    373   167: q        BINPUT     10
    374   169: h        BINGET     10
    375   171: K        BININT1    5
    376   173: e        APPENDS    (MARK at 5)
    377   174: .    STOP
    378 highest protocol among opcodes = 2
    379 """
    380 
    381 def create_data():
    382     c = C()
    383     c.foo = 1
    384     c.bar = 2
    385     x = [0, 1L, 2.0, 3.0+0j]
    386     # Append some integer test cases at cPickle.c's internal size

    387     # cutoffs.

    388     uint1max = 0xff
    389     uint2max = 0xffff
    390     int4max = 0x7fffffff
    391     x.extend([1, -1,
    392               uint1max, -uint1max, -uint1max-1,
    393               uint2max, -uint2max, -uint2max-1,
    394                int4max,  -int4max,  -int4max-1])
    395     y = ('abc', 'abc', c, c)
    396     x.append(y)
    397     x.append(y)
    398     x.append(5)
    399     return x
    400 
    401 class AbstractPickleTests(unittest.TestCase):
    402     # Subclass must define self.dumps, self.loads, self.error.

    403 
    404     _testdata = create_data()
    405 
    406     def setUp(self):
    407         pass
    408 
    409     def test_misc(self):
    410         # test various datatypes not tested by testdata

    411         for proto in protocols:
    412             x = myint(4)
    413             s = self.dumps(x, proto)
    414             y = self.loads(s)
    415             self.assertEqual(x, y)
    416 
    417             x = (1, ())
    418             s = self.dumps(x, proto)
    419             y = self.loads(s)
    420             self.assertEqual(x, y)
    421 
    422             x = initarg(1, x)
    423             s = self.dumps(x, proto)
    424             y = self.loads(s)
    425             self.assertEqual(x, y)
    426 
    427         # XXX test __reduce__ protocol?

    428 
    429     def test_roundtrip_equality(self):
    430         expected = self._testdata
    431         for proto in protocols:
    432             s = self.dumps(expected, proto)
    433             got = self.loads(s)
    434             self.assertEqual(expected, got)
    435 
    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)
    441 
    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

    447     # of 1.

    448     def dont_test_disassembly(self):
    449         from pickletools import dis
    450 
    451         for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
    452             s = self.dumps(self._testdata, proto)
    453             filelike = cStringIO.StringIO()
    454             dis(s, out=filelike)
    455             got = filelike.getvalue()
    456             self.assertEqual(expected, got)
    457 
    458     def test_recursive_list(self):
    459         l = []
    460         l.append(l)
    461         for proto in protocols:
    462             s = self.dumps(l, proto)
    463             x = self.loads(s)
    464             self.assertEqual(len(x), 1)
    465             self.assertTrue(x is x[0])
    466 
    467     def test_recursive_tuple(self):
    468         t = ([],)
    469         t[0].append(t)
    470         for proto in protocols:
    471             s = self.dumps(t, proto)
    472             x = self.loads(s)
    473             self.assertEqual(len(x), 1)
    474             self.assertEqual(len(x[0]), 1)
    475             self.assertTrue(x is x[0][0])
    476 
    477     def test_recursive_dict(self):
    478         d = {}
    479         d[1] = d
    480         for proto in protocols:
    481             s = self.dumps(d, proto)
    482             x = self.loads(s)
    483             self.assertEqual(x.keys(), [1])
    484             self.assertTrue(x[1] is x)
    485 
    486     def test_recursive_inst(self):
    487         i = C()
    488         i.attr = i
    489         for proto in protocols:
    490             s = self.dumps(i, 2)
    491             x = self.loads(s)
    492             self.assertEqual(dir(x), dir(i))
    493             self.assertTrue(x.attr is x)
    494 
    495     def test_recursive_multi(self):
    496         l = []
    497         d = {1:l}
    498         i = C()
    499         i.attr = d
    500         l.append(i)
    501         for proto in protocols:
    502             s = self.dumps(l, proto)
    503             x = self.loads(s)
    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)
    508 
    509     def test_garyp(self):
    510         self.assertRaises(self.error, self.loads, 'garyp')
    511 
    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

    520                     #"'abc\"\''",

    521                     #"'\\\\a\'\'\'\\\'\\\\\''",

    522                     ]
    523         for s in insecure:
    524             buf = "S" + s + "\012p0\012."
    525             self.assertRaises(ValueError, self.loads, buf)
    526 
    527     if have_unicode:
    528         def test_unicode(self):
    529             endcases = [u'', u'<\\u>', u'<\\\u1234>', u'<\n>',
    530                         u'<\\>', u'<\\\U00012345>']
    531             for proto in protocols:
    532                 for u in endcases:
    533                     p = self.dumps(u, proto)
    534                     u2 = self.loads(p)
    535                     self.assertEqual(u2, u)
    536 
    537         def test_unicode_high_plane(self):
    538             t = u'\U00012345'
    539             for proto in protocols:
    540                 p = self.dumps(t, proto)
    541                 t2 = self.loads(p)
    542                 self.assertEqual(t2, t)
    543 
    544     def test_ints(self):
    545         import sys
    546         for proto in protocols:
    547             n = sys.maxint
    548             while n:
    549                 for expected in (-n, n):
    550                     s = self.dumps(expected, proto)
    551                     n2 = self.loads(s)
    552                     self.assertEqual(expected, n2)
    553                 n = n >> 1
    554 
    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)
    560 
    561         # Try too with a bogus literal.

    562         data = 'I' + str(maxint64) + 'JUNK\n.'
    563         self.assertRaises(ValueError, self.loads, data)
    564 
    565     def test_long(self):
    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:
    569                 nbase = 1L << nbits
    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

    576         # bother with those.

    577         nbase = long("deadbeeffeedface", 16)
    578         nbase += nbase << 1000000
    579         for n in nbase, -nbase:
    580             p = self.dumps(n, 2)
    581             got = self.loads(p)
    582             self.assertEqual(n, got)
    583 
    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)
    593 
    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.')
    598 
    599     def test_reduce(self):
    600         pass
    601 
    602     def test_getinitargs(self):
    603         pass
    604 
    605     def test_metaclass(self):
    606         a = use_metaclass()
    607         for proto in protocols:
    608             s = self.dumps(a, proto)
    609             b = self.loads(s)
    610             self.assertEqual(a.__class__, b.__class__)
    611 
    612     def test_structseq(self):
    613         import time
    614         import os
    615 
    616         t = time.localtime()
    617         for proto in protocols:
    618             s = self.dumps(t, proto)
    619             u = self.loads(s)
    620             self.assertEqual(t, u)
    621             if hasattr(os, "stat"):
    622                 t = os.stat(os.curdir)
    623                 s = self.dumps(t, proto)
    624                 u = self.loads(s)
    625                 self.assertEqual(t, u)
    626             if hasattr(os, "statvfs"):
    627                 t = os.statvfs(os.curdir)
    628                 s = self.dumps(t, proto)
    629                 u = self.loads(s)
    630                 self.assertEqual(t, u)
    631 
    632     # Tests for protocol 2

    633 
    634     def test_proto(self):
    635         build_none = pickle.NONE + pickle.STOP
    636         for proto in protocols:
    637             expected = build_none
    638             if proto >= 2:
    639                 expected = pickle.PROTO + chr(proto) + expected
    640             p = self.dumps(None, proto)
    641             self.assertEqual(p, expected)
    642 
    643         oob = protocols[-1] + 1     # a future protocol

    644         badpickle = pickle.PROTO + chr(oob) + build_none
    645         try:
    646             self.loads(badpickle)
    647         except ValueError, detail:
    648             self.assertTrue(str(detail).startswith(
    649                                             "unsupported pickle protocol"))
    650         else:
    651             self.fail("expected bad protocol number to raise ValueError")
    652 
    653     def test_long1(self):
    654         x = 12345678910111213141516178920L
    655         for proto in protocols:
    656             s = self.dumps(x, proto)
    657             y = self.loads(s)
    658             self.assertEqual(x, y)
    659             self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
    660 
    661     def test_long4(self):
    662         x = 12345678910111213141516178920L << (256*8)
    663         for proto in protocols:
    664             s = self.dumps(x, proto)
    665             y = self.loads(s)
    666             self.assertEqual(x, y)
    667             self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
    668 
    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,
    676 
    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,
    682 
    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,
    688                           }
    689         a = ()
    690         b = (1,)
    691         c = (1, 2)
    692         d = (1, 2, 3)
    693         e = (1, 2, 3, 4)
    694         for proto in protocols:
    695             for x in a, b, c, d, e:
    696                 s = self.dumps(x, proto)
    697                 y = self.loads(s)
    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)
    701 
    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,
    707 
    708                            (0, True): pickle.INT,
    709                            (1, True): pickle.INT,
    710                            (2, True): pickle.NEWTRUE,
    711 
    712                            (0, False): pickle.INT,
    713                            (1, False): pickle.INT,
    714                            (2, False): pickle.NEWFALSE,
    715                           }
    716         for proto in protocols:
    717             for x in None, False, True:
    718                 s = self.dumps(x, proto)
    719                 y = self.loads(s)
    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)
    723 
    724     def test_newobj_tuple(self):
    725         x = MyTuple([1, 2, 3])
    726         x.foo = 42
    727         x.bar = "hello"
    728         for proto in protocols:
    729             s = self.dumps(x, proto)
    730             y = self.loads(s)
    731             self.assertEqual(tuple(x), tuple(y))
    732             self.assertEqual(x.__dict__, y.__dict__)
    733 
    734     def test_newobj_list(self):
    735         x = MyList([1, 2, 3])
    736         x.foo = 42
    737         x.bar = "hello"
    738         for proto in protocols:
    739             s = self.dumps(x, proto)
    740             y = self.loads(s)
    741             self.assertEqual(list(x), list(y))
    742             self.assertEqual(x.__dict__, y.__dict__)
    743 
    744     def test_newobj_generic(self):
    745         for proto in protocols:
    746             for C in myclasses:
    747                 B = C.__base__
    748                 x = C(C.sample)
    749                 x.foo = 42
    750                 s = self.dumps(x, proto)
    751                 y = self.loads(s)
    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)
    755 
    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.

    759 
    760     def produce_global_ext(self, extcode, opcode):
    761         e = ExtensionSaver(extcode)
    762         try:
    763             copy_reg.add_extension(__name__, "MyList", extcode)
    764             x = MyList([1, 2, 3])
    765             x.foo = 42
    766             x.bar = "hello"
    767 
    768             # Dump using protocol 1 for comparison.

    769             s1 = self.dumps(x, 1)
    770             self.assertIn(__name__, s1)
    771             self.assertIn("MyList", s1)
    772             self.assertEqual(opcode_in_pickle(opcode, s1), False)
    773 
    774             y = self.loads(s1)
    775             self.assertEqual(list(x), list(y))
    776             self.assertEqual(x.__dict__, y.__dict__)
    777 
    778             # Dump using protocol 2 for test.

    779             s2 = self.dumps(x, 2)
    780             self.assertNotIn(__name__, s2)
    781             self.assertNotIn("MyList", s2)
    782             self.assertEqual(opcode_in_pickle(opcode, s2), True)
    783 
    784             y = self.loads(s2)
    785             self.assertEqual(list(x), list(y))
    786             self.assertEqual(x.__dict__, y.__dict__)
    787 
    788         finally:
    789             e.restore()
    790 
    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

    794 
    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

    799 
    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

    804 
    805     def test_list_chunking(self):
    806         n = 10  # too small to chunk

    807         x = range(n)
    808         for proto in protocols:
    809             s = self.dumps(x, proto)
    810             y = self.loads(s)
    811             self.assertEqual(x, y)
    812             num_appends = count_opcode(pickle.APPENDS, s)
    813             self.assertEqual(num_appends, proto > 0)
    814 
    815         n = 2500  # expect at least two chunks when proto > 0

    816         x = range(n)
    817         for proto in protocols:
    818             s = self.dumps(x, proto)
    819             y = self.loads(s)
    820             self.assertEqual(x, y)
    821             num_appends = count_opcode(pickle.APPENDS, s)
    822             if proto == 0:
    823                 self.assertEqual(num_appends, 0)
    824             else:
    825                 self.assertTrue(num_appends >= 2)
    826 
    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)
    832             y = self.loads(s)
    833             self.assertEqual(x, y)
    834             num_setitems = count_opcode(pickle.SETITEMS, s)
    835             self.assertEqual(num_setitems, proto > 0)
    836 
    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)
    841             y = self.loads(s)
    842             self.assertEqual(x, y)
    843             num_setitems = count_opcode(pickle.SETITEMS, s)
    844             if proto == 0:
    845                 self.assertEqual(num_setitems, 0)
    846             else:
    847                 self.assertTrue(num_setitems >= 2)
    848 
    849     def test_simple_newobj(self):
    850         x = object.__new__(SimpleNewObj)  # avoid __init__

    851         x.abc = 666
    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__)
    858 
    859     def test_newobj_list_slots(self):
    860         x = SlotList([1, 2, 3])
    861         x.foo = 42
    862         x.bar = "hello"
    863         s = self.dumps(x, 2)
    864         y = self.loads(s)
    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)
    869 
    870     def test_reduce_overrides_default_reduce_ex(self):
    871         for proto in protocols:
    872             x = REX_one()
    873             self.assertEqual(x._reduce_called, 0)
    874             s = self.dumps(x, proto)
    875             self.assertEqual(x._reduce_called, 1)
    876             y = self.loads(s)
    877             self.assertEqual(y._reduce_called, 0)
    878 
    879     def test_reduce_ex_called(self):
    880         for proto in protocols:
    881             x = REX_two()
    882             self.assertEqual(x._proto, None)
    883             s = self.dumps(x, proto)
    884             self.assertEqual(x._proto, proto)
    885             y = self.loads(s)
    886             self.assertEqual(y._proto, None)
    887 
    888     def test_reduce_ex_overrides_reduce(self):
    889         for proto in protocols:
    890             x = REX_three()
    891             self.assertEqual(x._proto, None)
    892             s = self.dumps(x, proto)
    893             self.assertEqual(x._proto, proto)
    894             y = self.loads(s)
    895             self.assertEqual(y._proto, None)
    896 
    897     def test_reduce_ex_calls_base(self):
    898         for proto in protocols:
    899             x = REX_four()
    900             self.assertEqual(x._proto, None)
    901             s = self.dumps(x, proto)
    902             self.assertEqual(x._proto, proto)
    903             y = self.loads(s)
    904             self.assertEqual(y._proto, proto)
    905 
    906     def test_reduce_calls_base(self):
    907         for proto in protocols:
    908             x = REX_five()
    909             self.assertEqual(x._reduce_called, 0)
    910             s = self.dumps(x, proto)
    911             self.assertEqual(x._reduce_called, 1)
    912             y = self.loads(s)
    913             self.assertEqual(y._reduce_called, 1)
    914 
    915     def test_reduce_bad_iterator(self):
    916         # Issue4176: crash when 4th and 5th items of __reduce__()

    917         # are not iterators

    918         class C(object):
    919             def __reduce__(self):
    920                 # 4th item is not an iterator

    921                 return list, (), None, [], None
    922         class D(object):
    923             def __reduce__(self):
    924                 # 5th item is not an iterator

    925                 return dict, (), None, None, []
    926 
    927         # Protocol 0 is less strict and also accept iterables.

    928         for proto in protocols:
    929             try:
    930                 self.dumps(C(), proto)
    931             except (AttributeError, pickle.PickleError, cPickle.PickleError):
    932                 pass
    933             try:
    934                 self.dumps(D(), proto)
    935             except (AttributeError, pickle.PickleError, cPickle.PickleError):
    936                 pass
    937 
    938     def test_many_puts_and_gets(self):
    939         # Test that internal data structures correctly deal with lots of

    940         # puts/gets.

    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)]
    944 
    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))
    951 
    952     def test_attribute_name_interning(self):
    953         # Test that attribute names of pickled objects are interned when

    954         # unpickling.

    955         for proto in protocols:
    956             x = C()
    957             x.foo = 42
    958             x.bar = "hello"
    959             s = self.dumps(x, proto)
    960             y = self.loads(s)
    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)
    965 
    966 
    967 # Test classes for reduce_ex

    968 
    969 class REX_one(object):
    970     _reduce_called = 0
    971     def __reduce__(self):
    972         self._reduce_called = 1
    973         return REX_one, ()
    974     # No __reduce_ex__ here, but inheriting it from object

    975 
    976 class REX_two(object):
    977     _proto = None
    978     def __reduce_ex__(self, proto):
    979         self._proto = proto
    980         return REX_two, ()
    981     # No __reduce__ here, but inheriting it from object

    982 
    983 class REX_three(object):
    984     _proto = None
    985     def __reduce_ex__(self, proto):
    986         self._proto = proto
    987         return REX_two, ()
    988     def __reduce__(self):
    989         raise TestFailed, "This __reduce__ shouldn't be called"
    990 
    991 class REX_four(object):
    992     _proto = None
    993     def __reduce_ex__(self, proto):
    994         self._proto = proto
    995         return object.__reduce_ex__(self, proto)
    996     # Calling base class method should succeed

    997 
    998 class REX_five(object):
    999     _reduce_called = 0
   1000     def __reduce__(self):
   1001         self._reduce_called = 1
   1002         return object.__reduce__(self)
   1003     # This one used to fail with infinite recursion

   1004 
   1005 # Test classes for newobj

   1006 
   1007 class MyInt(int):
   1008     sample = 1
   1009 
   1010 class MyLong(long):
   1011     sample = 1L
   1012 
   1013 class MyFloat(float):
   1014     sample = 1.0
   1015 
   1016 class MyComplex(complex):
   1017     sample = 1.0 + 0.0j
   1018 
   1019 class MyStr(str):
   1020     sample = "hello"
   1021 
   1022 class MyUnicode(unicode):
   1023     sample = u"hello \u1234"
   1024 
   1025 class MyTuple(tuple):
   1026     sample = (1, 2, 3)
   1027 
   1028 class MyList(list):
   1029     sample = [1, 2, 3]
   1030 
   1031 class MyDict(dict):
   1032     sample = {"a": 1, "b": 2}
   1033 
   1034 myclasses = [MyInt, MyLong, MyFloat,
   1035              MyComplex,
   1036              MyStr, MyUnicode,
   1037              MyTuple, MyList, MyDict]
   1038 
   1039 
   1040 class SlotList(MyList):
   1041     __slots__ = ["foo"]
   1042 
   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")
   1047 
   1048 class AbstractPickleModuleTests(unittest.TestCase):
   1049 
   1050     def test_dump_closed_file(self):
   1051         import os
   1052         f = open(TESTFN, "w")
   1053         try:
   1054             f.close()
   1055             self.assertRaises(ValueError, self.module.dump, 123, f)
   1056         finally:
   1057             os.remove(TESTFN)
   1058 
   1059     def test_load_closed_file(self):
   1060         import os
   1061         f = open(TESTFN, "w")
   1062         try:
   1063             f.close()
   1064             self.assertRaises(ValueError, self.module.dump, 123, f)
   1065         finally:
   1066             os.remove(TESTFN)
   1067 
   1068     def test_load_from_and_dump_to_file(self):
   1069         stream = cStringIO.StringIO()
   1070         data = [123, {}, 124]
   1071         self.module.dump(data, stream)
   1072         stream.seek(0)
   1073         unpickled = self.module.load(stream)
   1074         self.assertEqual(unpickled, data)
   1075 
   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)
   1079 
   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)
   1089 
   1090     def test_incomplete_input(self):
   1091         s = StringIO.StringIO("X''.")
   1092         self.assertRaises(EOFError, self.module.load, s)
   1093 
   1094     def test_restricted(self):
   1095         # issue7128: cPickle failed in restricted mode

   1096         builtins = {self.module.__name__: self.module,
   1097                     '__import__': __import__}
   1098         d = {}
   1099         teststr = "def f(): {0}.dumps(0)".format(self.module.__name__)
   1100         exec teststr in {'__builtins__': builtins}, d
   1101         d['f']()
   1102 
   1103     def test_bad_input(self):
   1104         # Test issue4298

   1105         s = '\x58\0\0\0\x54'
   1106         self.assertRaises(EOFError, self.module.loads, s)
   1107         # Test issue7455

   1108         s = '0'
   1109         # XXX Why doesn't pickle raise UnpicklingError?

   1110         self.assertRaises((IndexError, cPickle.UnpicklingError),
   1111                           self.module.loads, s)
   1112 
   1113 class AbstractPersistentPicklerTests(unittest.TestCase):
   1114 
   1115     # This class defines persistent_id() and persistent_load()

   1116     # functions that should be used by the pickler.  All even integers

   1117     # are pickled using persistent ids.

   1118 
   1119     def persistent_id(self, object):
   1120         if isinstance(object, int) and object % 2 == 0:
   1121             self.id_count += 1
   1122             return str(object)
   1123         else:
   1124             return None
   1125 
   1126     def persistent_load(self, oid):
   1127         self.load_count += 1
   1128         object = int(oid)
   1129         assert object % 2 == 0
   1130         return object
   1131 
   1132     def test_persistence(self):
   1133         self.id_count = 0
   1134         self.load_count = 0
   1135         L = range(10)
   1136         self.assertEqual(self.loads(self.dumps(L)), L)
   1137         self.assertEqual(self.id_count, 5)
   1138         self.assertEqual(self.load_count, 5)
   1139 
   1140     def test_bin_persistence(self):
   1141         self.id_count = 0
   1142         self.load_count = 0
   1143         L = range(10)
   1144         self.assertEqual(self.loads(self.dumps(L, 1)), L)
   1145         self.assertEqual(self.id_count, 5)
   1146         self.assertEqual(self.load_count, 5)
   1147 
   1148 class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
   1149 
   1150     pickler_class = None
   1151     unpickler_class = None
   1152 
   1153     def setUp(self):
   1154         assert self.pickler_class
   1155         assert self.unpickler_class
   1156 
   1157     def test_clear_pickler_memo(self):
   1158         # To test whether clear_memo() has any effect, we pickle an object,

   1159         # then pickle it again without clearing the memo; the two serialized

   1160         # forms should be different. If we clear_memo() and then pickle the

   1161         # object again, the third serialized form should be identical to the

   1162         # first one we obtained.

   1163         data = ["abcdefg", "abcdefg", 44]
   1164         f = cStringIO.StringIO()
   1165         pickler = self.pickler_class(f)
   1166 
   1167         pickler.dump(data)
   1168         first_pickled = f.getvalue()
   1169 
   1170         # Reset StringIO object.

   1171         f.seek(0)
   1172         f.truncate()
   1173 
   1174         pickler.dump(data)
   1175         second_pickled = f.getvalue()
   1176 
   1177         # Reset the Pickler and StringIO objects.

   1178         pickler.clear_memo()
   1179         f.seek(0)
   1180         f.truncate()
   1181 
   1182         pickler.dump(data)
   1183         third_pickled = f.getvalue()
   1184 
   1185         self.assertNotEqual(first_pickled, second_pickled)
   1186         self.assertEqual(first_pickled, third_pickled)
   1187 
   1188     def test_priming_pickler_memo(self):
   1189         # Verify that we can set the Pickler's memo attribute.

   1190         data = ["abcdefg", "abcdefg", 44]
   1191         f = cStringIO.StringIO()
   1192         pickler = self.pickler_class(f)
   1193 
   1194         pickler.dump(data)
   1195         first_pickled = f.getvalue()
   1196 
   1197         f = cStringIO.StringIO()
   1198         primed = self.pickler_class(f)
   1199         primed.memo = pickler.memo
   1200 
   1201         primed.dump(data)
   1202         primed_pickled = f.getvalue()
   1203 
   1204         self.assertNotEqual(first_pickled, primed_pickled)
   1205 
   1206     def test_priming_unpickler_memo(self):
   1207         # Verify that we can set the Unpickler's memo attribute.

   1208         data = ["abcdefg", "abcdefg", 44]
   1209         f = cStringIO.StringIO()
   1210         pickler = self.pickler_class(f)
   1211 
   1212         pickler.dump(data)
   1213         first_pickled = f.getvalue()
   1214 
   1215         f = cStringIO.StringIO()
   1216         primed = self.pickler_class(f)
   1217         primed.memo = pickler.memo
   1218 
   1219         primed.dump(data)
   1220         primed_pickled = f.getvalue()
   1221 
   1222         unpickler = self.unpickler_class(cStringIO.StringIO(first_pickled))
   1223         unpickled_data1 = unpickler.load()
   1224 
   1225         self.assertEqual(unpickled_data1, data)
   1226 
   1227         primed = self.unpickler_class(cStringIO.StringIO(primed_pickled))
   1228         primed.memo = unpickler.memo
   1229         unpickled_data2 = primed.load()
   1230 
   1231         primed.memo.clear()
   1232 
   1233         self.assertEqual(unpickled_data2, data)
   1234         self.assertTrue(unpickled_data2 is unpickled_data1)
   1235 
   1236     def test_reusing_unpickler_objects(self):
   1237         data1 = ["abcdefg", "abcdefg", 44]
   1238         f = cStringIO.StringIO()
   1239         pickler = self.pickler_class(f)
   1240         pickler.dump(data1)
   1241         pickled1 = f.getvalue()
   1242 
   1243         data2 = ["abcdefg", 44, 44]
   1244         f = cStringIO.StringIO()
   1245         pickler = self.pickler_class(f)
   1246         pickler.dump(data2)
   1247         pickled2 = f.getvalue()
   1248 
   1249         f = cStringIO.StringIO()
   1250         f.write(pickled1)
   1251         f.seek(0)
   1252         unpickler = self.unpickler_class(f)
   1253         self.assertEqual(unpickler.load(), data1)
   1254 
   1255         f.seek(0)
   1256         f.truncate()
   1257         f.write(pickled2)
   1258         f.seek(0)
   1259         self.assertEqual(unpickler.load(), data2)
   1260