Home | History | Annotate | Download | only in test
      1 import cPickle
      2 import cStringIO
      3 import io
      4 import functools
      5 import unittest
      6 from test.pickletester import (AbstractUnpickleTests,
      7                                AbstractPickleTests,
      8                                AbstractPickleModuleTests,
      9                                AbstractPicklerUnpicklerObjectTests,
     10                                BigmemPickleTests)
     11 from test import test_support
     12 
     13 class cStringIOMixin:
     14     output = input = cStringIO.StringIO
     15 
     16     def close(self, f):
     17         pass
     18 
     19 class BytesIOMixin:
     20     output = input = io.BytesIO
     21 
     22     def close(self, f):
     23         pass
     24 
     25 class FileIOMixin:
     26 
     27     def output(self):
     28         return open(test_support.TESTFN, 'wb+')
     29 
     30     def input(self, data):
     31         f = open(test_support.TESTFN, 'wb+')
     32         try:
     33             f.write(data)
     34             f.seek(0)
     35             return f
     36         except:
     37             f.close()
     38             raise
     39 
     40     def close(self, f):
     41         f.close()
     42         test_support.unlink(test_support.TESTFN)
     43 
     44 
     45 class cPickleTests(AbstractUnpickleTests, AbstractPickleTests,
     46                    AbstractPickleModuleTests):
     47 
     48     def setUp(self):
     49         self.dumps = cPickle.dumps
     50         self.loads = cPickle.loads
     51 
     52     error = cPickle.BadPickleGet
     53     module = cPickle
     54     bad_stack_errors = (cPickle.UnpicklingError,)
     55     bad_mark_errors = (EOFError,)
     56     truncated_errors = (cPickle.UnpicklingError, EOFError,
     57                         AttributeError, ValueError)
     58 
     59 class cPickleUnpicklerTests(AbstractUnpickleTests):
     60 
     61     def loads(self, buf):
     62         f = self.input(buf)
     63         try:
     64             p = cPickle.Unpickler(f)
     65             return p.load()
     66         finally:
     67             self.close(f)
     68 
     69     error = cPickle.BadPickleGet
     70     bad_stack_errors = (cPickle.UnpicklingError,)
     71     bad_mark_errors = (EOFError,)
     72     truncated_errors = (cPickle.UnpicklingError, EOFError,
     73                         AttributeError, ValueError)
     74 
     75 class cStringIOCUnpicklerTests(cStringIOMixin, cPickleUnpicklerTests):
     76     pass
     77 
     78 class BytesIOCUnpicklerTests(BytesIOMixin, cPickleUnpicklerTests):
     79     pass
     80 
     81 class FileIOCUnpicklerTests(FileIOMixin, cPickleUnpicklerTests):
     82     pass
     83 
     84 
     85 class cPicklePicklerTests(AbstractPickleTests):
     86 
     87     def dumps(self, arg, proto=0):
     88         f = self.output()
     89         try:
     90             p = cPickle.Pickler(f, proto)
     91             p.dump(arg)
     92             f.seek(0)
     93             return f.read()
     94         finally:
     95             self.close(f)
     96 
     97     def loads(self, buf):
     98         f = self.input(buf)
     99         try:
    100             p = cPickle.Unpickler(f)
    101             return p.load()
    102         finally:
    103             self.close(f)
    104 
    105 class cStringIOCPicklerTests(cStringIOMixin, cPicklePicklerTests):
    106     pass
    107 
    108 class BytesIOCPicklerTests(BytesIOMixin, cPicklePicklerTests):
    109     pass
    110 
    111 class FileIOCPicklerTests(FileIOMixin, cPicklePicklerTests):
    112     pass
    113 
    114 
    115 class cPickleListPicklerTests(AbstractPickleTests):
    116 
    117     def dumps(self, arg, proto=0):
    118         p = cPickle.Pickler(proto)
    119         p.dump(arg)
    120         return p.getvalue()
    121 
    122     def loads(self, *args):
    123         f = self.input(args[0])
    124         try:
    125             p = cPickle.Unpickler(f)
    126             return p.load()
    127         finally:
    128             self.close(f)
    129 
    130     error = cPickle.BadPickleGet
    131 
    132 class cStringIOCPicklerListTests(cStringIOMixin, cPickleListPicklerTests):
    133     pass
    134 
    135 class BytesIOCPicklerListTests(BytesIOMixin, cPickleListPicklerTests):
    136     pass
    137 
    138 class FileIOCPicklerListTests(FileIOMixin, cPickleListPicklerTests):
    139     pass
    140 
    141 
    142 class cPickleFastPicklerTests(AbstractPickleTests):
    143 
    144     def dumps(self, arg, proto=0):
    145         f = self.output()
    146         try:
    147             p = cPickle.Pickler(f, proto)
    148             p.fast = 1
    149             p.dump(arg)
    150             f.seek(0)
    151             return f.read()
    152         finally:
    153             self.close(f)
    154 
    155     def loads(self, *args):
    156         f = self.input(args[0])
    157         try:
    158             p = cPickle.Unpickler(f)
    159             return p.load()
    160         finally:
    161             self.close(f)
    162 
    163     def test_nonrecursive_deep(self):
    164         # If it's not cyclic, it should pickle OK even if the nesting
    165         # depth exceeds PY_CPICKLE_FAST_LIMIT.  That happens to be
    166         # 50 today.  Jack Jansen reported stack overflow on Mac OS 9
    167         # at 64.
    168         a = []
    169         for i in range(60):
    170             a = [a]
    171         b = self.loads(self.dumps(a))
    172         self.assertEqual(a, b)
    173 
    174 for name in dir(AbstractPickleTests):
    175     if name.startswith('test_recursive_'):
    176         func = getattr(AbstractPickleTests, name)
    177         if '_subclass' in name and '_and_inst' not in name:
    178             assert_args = RuntimeError, 'maximum recursion depth exceeded'
    179         else:
    180             assert_args = ValueError, "can't pickle cyclic objects"
    181         def wrapper(self, func=func, assert_args=assert_args):
    182             with self.assertRaisesRegexp(*assert_args):
    183                 func(self)
    184         functools.update_wrapper(wrapper, func)
    185         setattr(cPickleFastPicklerTests, name, wrapper)
    186 
    187 class cStringIOCPicklerFastTests(cStringIOMixin, cPickleFastPicklerTests):
    188     pass
    189 
    190 class BytesIOCPicklerFastTests(BytesIOMixin, cPickleFastPicklerTests):
    191     pass
    192 
    193 class FileIOCPicklerFastTests(FileIOMixin, cPickleFastPicklerTests):
    194     pass
    195 
    196 
    197 class cPicklePicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests):
    198 
    199     pickler_class = cPickle.Pickler
    200     unpickler_class = cPickle.Unpickler
    201 
    202 class cPickleBigmemPickleTests(BigmemPickleTests):
    203 
    204     def dumps(self, arg, proto=0, fast=0):
    205         # Ignore fast
    206         return cPickle.dumps(arg, proto)
    207 
    208     def loads(self, buf):
    209         # Ignore fast
    210         return cPickle.loads(buf)
    211 
    212 
    213 class Node(object):
    214     pass
    215 
    216 class cPickleDeepRecursive(unittest.TestCase):
    217     def test_issue2702(self):
    218         # This should raise a RecursionLimit but in some
    219         # platforms (FreeBSD, win32) sometimes raises KeyError instead,
    220         # or just silently terminates the interpreter (=crashes).
    221         nodes = [Node() for i in range(500)]
    222         for n in nodes:
    223             n.connections = list(nodes)
    224             n.connections.remove(n)
    225         self.assertRaises((AttributeError, RuntimeError), cPickle.dumps, n)
    226 
    227     def test_issue3179(self):
    228         # Safe test, because I broke this case when fixing the
    229         # behaviour for the previous test.
    230         res=[]
    231         for x in range(1,2000):
    232             res.append(dict(doc=x, similar=[]))
    233         cPickle.dumps(res)
    234 
    235 
    236 def test_main():
    237     test_support.run_unittest(
    238         cPickleTests,
    239         cStringIOCUnpicklerTests,
    240         BytesIOCUnpicklerTests,
    241         FileIOCUnpicklerTests,
    242         cStringIOCPicklerTests,
    243         BytesIOCPicklerTests,
    244         FileIOCPicklerTests,
    245         cStringIOCPicklerListTests,
    246         BytesIOCPicklerListTests,
    247         FileIOCPicklerListTests,
    248         cStringIOCPicklerFastTests,
    249         BytesIOCPicklerFastTests,
    250         FileIOCPicklerFastTests,
    251         cPickleDeepRecursive,
    252         cPicklePicklerUnpicklerObjectTests,
    253         cPickleBigmemPickleTests,
    254     )
    255 
    256 if __name__ == "__main__":
    257     test_main()
    258