blob: c9ec7883363aaeda83283d31e98cfa73613f50a6 [file] [log] [blame]
Serhiy Storchaka2556c832013-03-14 20:59:09 +02001import cPickle
2import cStringIO
3import io
Serhiy Storchakada87e452015-11-07 11:15:32 +02004import functools
Serhiy Storchaka2556c832013-03-14 20:59:09 +02005import unittest
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +03006from test.pickletester import (AbstractUnpickleTests,
7 AbstractPickleTests,
Serhiy Storchakacdc7a912013-02-12 21:36:47 +02008 AbstractPickleModuleTests,
9 AbstractPicklerUnpicklerObjectTests,
10 BigmemPickleTests)
Barry Warsaw04f357c2002-07-23 19:04:11 +000011from test import test_support
Jeremy Hylton66426532001-10-15 21:38:56 +000012
Serhiy Storchaka2556c832013-03-14 20:59:09 +020013class cStringIOMixin:
14 output = input = cStringIO.StringIO
15
16 def close(self, f):
17 pass
18
19class BytesIOMixin:
20 output = input = io.BytesIO
21
22 def close(self, f):
23 pass
24
25class FileIOMixin:
26
27 def output(self):
Benjamin Petersonbebf75f2013-03-17 21:28:29 -070028 return open(test_support.TESTFN, 'wb+')
Serhiy Storchaka2556c832013-03-14 20:59:09 +020029
30 def input(self, data):
Benjamin Petersonbebf75f2013-03-17 21:28:29 -070031 f = open(test_support.TESTFN, 'wb+')
Serhiy Storchaka2556c832013-03-14 20:59:09 +020032 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
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +030045class cPickleTests(AbstractUnpickleTests, AbstractPickleTests,
46 AbstractPickleModuleTests):
Tim Peterse0c446b2001-10-18 21:57:37 +000047
Jeremy Hylton66426532001-10-15 21:38:56 +000048 def setUp(self):
49 self.dumps = cPickle.dumps
50 self.loads = cPickle.loads
51
52 error = cPickle.BadPickleGet
53 module = cPickle
Serhiy Storchaka5c137662015-11-23 15:20:43 +020054 bad_stack_errors = (cPickle.UnpicklingError,)
Serhiy Storchakabf19ce22015-11-29 13:12:40 +020055 bad_mark_errors = (EOFError,)
56 truncated_errors = (cPickle.UnpicklingError, EOFError,
57 AttributeError, ValueError)
Jeremy Hylton66426532001-10-15 21:38:56 +000058
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +030059class 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
Serhiy Storchaka5c137662015-11-23 15:20:43 +020070 bad_stack_errors = (cPickle.UnpicklingError,)
Serhiy Storchakabf19ce22015-11-29 13:12:40 +020071 bad_mark_errors = (EOFError,)
72 truncated_errors = (cPickle.UnpicklingError, EOFError,
73 AttributeError, ValueError)
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +030074
75class cStringIOCUnpicklerTests(cStringIOMixin, cPickleUnpicklerTests):
76 pass
77
78class BytesIOCUnpicklerTests(BytesIOMixin, cPickleUnpicklerTests):
79 pass
80
81class FileIOCUnpicklerTests(FileIOMixin, cPickleUnpicklerTests):
82 pass
83
84
Jeremy Hylton66426532001-10-15 21:38:56 +000085class cPicklePicklerTests(AbstractPickleTests):
86
Tim Petersdcaa24e2003-01-28 22:26:28 +000087 def dumps(self, arg, proto=0):
Serhiy Storchaka2556c832013-03-14 20:59:09 +020088 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)
Jeremy Hylton66426532001-10-15 21:38:56 +000096
97 def loads(self, buf):
Serhiy Storchaka2556c832013-03-14 20:59:09 +020098 f = self.input(buf)
99 try:
100 p = cPickle.Unpickler(f)
101 return p.load()
102 finally:
103 self.close(f)
Jeremy Hylton66426532001-10-15 21:38:56 +0000104
Serhiy Storchaka2556c832013-03-14 20:59:09 +0200105class cStringIOCPicklerTests(cStringIOMixin, cPicklePicklerTests):
106 pass
107
108class BytesIOCPicklerTests(BytesIOMixin, cPicklePicklerTests):
109 pass
110
111class FileIOCPicklerTests(FileIOMixin, cPicklePicklerTests):
112 pass
113
114
Jeremy Hylton66426532001-10-15 21:38:56 +0000115class cPickleListPicklerTests(AbstractPickleTests):
116
Tim Petersdcaa24e2003-01-28 22:26:28 +0000117 def dumps(self, arg, proto=0):
118 p = cPickle.Pickler(proto)
Jeremy Hylton66426532001-10-15 21:38:56 +0000119 p.dump(arg)
120 return p.getvalue()
121
122 def loads(self, *args):
Serhiy Storchaka2556c832013-03-14 20:59:09 +0200123 f = self.input(args[0])
124 try:
125 p = cPickle.Unpickler(f)
126 return p.load()
127 finally:
128 self.close(f)
Jeremy Hylton66426532001-10-15 21:38:56 +0000129
130 error = cPickle.BadPickleGet
131
Serhiy Storchaka2556c832013-03-14 20:59:09 +0200132class cStringIOCPicklerListTests(cStringIOMixin, cPickleListPicklerTests):
133 pass
134
135class BytesIOCPicklerListTests(BytesIOMixin, cPickleListPicklerTests):
136 pass
137
138class FileIOCPicklerListTests(FileIOMixin, cPickleListPicklerTests):
139 pass
140
141
Jeremy Hylton66426532001-10-15 21:38:56 +0000142class cPickleFastPicklerTests(AbstractPickleTests):
143
Tim Petersdcaa24e2003-01-28 22:26:28 +0000144 def dumps(self, arg, proto=0):
Serhiy Storchaka2556c832013-03-14 20:59:09 +0200145 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)
Jeremy Hylton66426532001-10-15 21:38:56 +0000154
155 def loads(self, *args):
Serhiy Storchaka2556c832013-03-14 20:59:09 +0200156 f = self.input(args[0])
157 try:
158 p = cPickle.Unpickler(f)
159 return p.load()
160 finally:
161 self.close(f)
Jeremy Hylton66426532001-10-15 21:38:56 +0000162
Barry Warsaw52acb492001-12-21 20:04:22 +0000163 def test_nonrecursive_deep(self):
Tim Peters7107a7f2003-02-21 20:14:35 +0000164 # 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.
Barry Warsaw52acb492001-12-21 20:04:22 +0000168 a = []
Tim Peters7107a7f2003-02-21 20:14:35 +0000169 for i in range(60):
Barry Warsaw52acb492001-12-21 20:04:22 +0000170 a = [a]
171 b = self.loads(self.dumps(a))
172 self.assertEqual(a, b)
173
Serhiy Storchakada87e452015-11-07 11:15:32 +0200174for 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
Serhiy Storchaka2556c832013-03-14 20:59:09 +0200187class cStringIOCPicklerFastTests(cStringIOMixin, cPickleFastPicklerTests):
188 pass
189
190class BytesIOCPicklerFastTests(BytesIOMixin, cPickleFastPicklerTests):
191 pass
192
193class FileIOCPicklerFastTests(FileIOMixin, cPickleFastPicklerTests):
194 pass
195
196
Collin Winterf8089c72009-04-09 16:46:46 +0000197class cPicklePicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests):
198
199 pickler_class = cPickle.Pickler
200 unpickler_class = cPickle.Unpickler
201
Serhiy Storchakacdc7a912013-02-12 21:36:47 +0200202class 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
Collin Winterf8089c72009-04-09 16:46:46 +0000212
Facundo Batista9da18b32008-06-22 23:19:14 +0000213class Node(object):
214 pass
215
216class cPickleDeepRecursive(unittest.TestCase):
Facundo Batista763d3092008-06-30 01:10:55 +0000217 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)
Benjamin Peterson704dc262009-03-22 22:24:58 +0000225 self.assertRaises((AttributeError, RuntimeError), cPickle.dumps, n)
Facundo Batista68dc0522008-06-25 19:24:53 +0000226
227 def test_issue3179(self):
Facundo Batista763d3092008-06-30 01:10:55 +0000228 # Safe test, because I broke this case when fixing the
229 # behaviour for the previous test.
Facundo Batista68dc0522008-06-25 19:24:53 +0000230 res=[]
231 for x in range(1,2000):
232 res.append(dict(doc=x, similar=[]))
233 cPickle.dumps(res)
234
Facundo Batista9da18b32008-06-22 23:19:14 +0000235
Fred Drake694ed092001-12-19 16:42:15 +0000236def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000237 test_support.run_unittest(
238 cPickleTests,
Serhiy Storchaka4d2cf552015-09-29 15:36:28 +0300239 cStringIOCUnpicklerTests,
240 BytesIOCUnpicklerTests,
241 FileIOCUnpicklerTests,
Serhiy Storchaka2556c832013-03-14 20:59:09 +0200242 cStringIOCPicklerTests,
243 BytesIOCPicklerTests,
244 FileIOCPicklerTests,
245 cStringIOCPicklerListTests,
246 BytesIOCPicklerListTests,
247 FileIOCPicklerListTests,
248 cStringIOCPicklerFastTests,
249 BytesIOCPicklerFastTests,
250 FileIOCPicklerFastTests,
Facundo Batista9da18b32008-06-22 23:19:14 +0000251 cPickleDeepRecursive,
Collin Winterf8089c72009-04-09 16:46:46 +0000252 cPicklePicklerUnpicklerObjectTests,
Serhiy Storchakacdc7a912013-02-12 21:36:47 +0200253 cPickleBigmemPickleTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000254 )
Fred Drake694ed092001-12-19 16:42:15 +0000255
Jeremy Hylton66426532001-10-15 21:38:56 +0000256if __name__ == "__main__":
Fred Drake694ed092001-12-19 16:42:15 +0000257 test_main()