blob: 51dd0fc439ad7bb7a25037b26d9c2549fa89b7fb [file] [log] [blame]
Jeremy Hylton66426532001-10-15 21:38:56 +00001import unittest
Tim Peters4190fb82003-02-02 16:09:05 +00002import pickle
Tim Peters31f119e2003-02-03 16:20:13 +00003import pickletools
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00004import copyreg
Tim Peters4190fb82003-02-02 16:09:05 +00005
Benjamin Petersonee8712c2008-05-20 21:35:26 +00006from test.support import TestFailed, TESTFN, run_with_locale
Tim Peterse089c682001-04-10 03:41:41 +00007
Guido van Rossum98297ee2007-11-06 21:34:58 +00008from pickle import bytes_types
9
Tim Petersee1a53c2003-02-02 02:57:53 +000010# Tests that try a number of pickle protocols should have a
11# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000012# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000013protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000014
Tim Peters22e71712003-02-03 22:27:38 +000015
16# Return True if opcode code appears in the pickle, else False.
17def opcode_in_pickle(code, pickle):
18 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000019 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000020 return True
21 return False
22
Tim Peters8d2613a2003-02-11 16:40:16 +000023# Return the number of times opcode code appears in pickle.
24def count_opcode(code, pickle):
25 n = 0
26 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000027 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000028 n += 1
29 return n
30
Tim Peters3e667d52003-02-04 21:47:44 +000031# We can't very well test the extension registry without putting known stuff
32# in it, but we have to be careful to restore its original state. Code
33# should do this:
34#
35# e = ExtensionSaver(extension_code)
36# try:
37# fiddle w/ the extension registry's stuff for extension_code
38# finally:
39# e.restore()
40
41class ExtensionSaver:
42 # Remember current registration for code (if any), and remove it (if
43 # there is one).
44 def __init__(self, code):
45 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000046 if code in copyreg._inverted_registry:
47 self.pair = copyreg._inverted_registry[code]
48 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000049 else:
50 self.pair = None
51
52 # Restore previous registration for code.
53 def restore(self):
54 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000055 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000056 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000057 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000058 pair = self.pair
59 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000060 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000061
Jeremy Hylton66426532001-10-15 21:38:56 +000062class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000063 def __eq__(self, other):
64 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000065
66import __main__
67__main__.C = C
68C.__module__ = "__main__"
69
70class myint(int):
71 def __init__(self, x):
72 self.str = str(x)
73
74class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +000075
Jeremy Hylton66426532001-10-15 21:38:56 +000076 def __init__(self, a, b):
77 self.a = a
78 self.b = b
79
80 def __getinitargs__(self):
81 return self.a, self.b
82
Guido van Rossum04a86612001-12-19 16:58:54 +000083class metaclass(type):
84 pass
85
Guido van Rossum52cc1d82007-03-18 15:41:51 +000086class use_metaclass(object, metaclass=metaclass):
87 pass
Guido van Rossum04a86612001-12-19 16:58:54 +000088
Tim Peters70b02d72003-02-02 17:26:40 +000089# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
90# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +000091
Guido van Rossum98297ee2007-11-06 21:34:58 +000092DATA0 = (
Mark Dickinson8dd05142009-01-20 20:43:58 +000093 b'(lp0\nL0L\naL1L\naF2.0\nac'
Georg Brandl1a3284e2007-12-02 09:40:06 +000094 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +000095 b'p1\n(F3.0\nF0.0\ntp2\nRp'
Mark Dickinson8dd05142009-01-20 20:43:58 +000096 b'3\naL1L\naL-1L\naL255L\naL-'
97 b'255L\naL-256L\naL65535L\na'
98 b'L-65535L\naL-65536L\naL2'
99 b'147483647L\naL-2147483'
100 b'647L\naL-2147483648L\na('
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000101 b'Vabc\np4\ng4\nccopyreg'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000102 b'\n_reconstructor\np5\n('
Georg Brandl1a3284e2007-12-02 09:40:06 +0000103 b'c__main__\nC\np6\ncbu'
104 b'iltins\nobject\np7\nNt'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000105 b'p8\nRp9\n(dp10\nVfoo\np1'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000106 b'1\nL1L\nsVbar\np12\nL2L\nsb'
107 b'g9\ntp13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000108)
Tim Peterse9358162001-01-22 22:05:20 +0000109
Guido van Rossum98297ee2007-11-06 21:34:58 +0000110# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000111DATA0_DIS = """\
112 0: ( MARK
113 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000114 2: p PUT 0
115 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000116 9: a APPEND
117 10: L LONG 1
118 14: a APPEND
119 15: F FLOAT 2.0
120 20: a APPEND
121 21: c GLOBAL 'builtins complex'
122 39: p PUT 1
123 42: ( MARK
124 43: F FLOAT 3.0
125 48: F FLOAT 0.0
126 53: t TUPLE (MARK at 42)
127 54: p PUT 2
128 57: R REDUCE
129 58: p PUT 3
130 61: a APPEND
131 62: L LONG 1
132 66: a APPEND
133 67: L LONG -1
134 72: a APPEND
135 73: L LONG 255
136 79: a APPEND
137 80: L LONG -255
138 87: a APPEND
139 88: L LONG -256
140 95: a APPEND
141 96: L LONG 65535
142 104: a APPEND
143 105: L LONG -65535
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000144 114: a APPEND
Mark Dickinson8dd05142009-01-20 20:43:58 +0000145 115: L LONG -65536
146 124: a APPEND
147 125: L LONG 2147483647
148 138: a APPEND
149 139: L LONG -2147483647
150 153: a APPEND
151 154: L LONG -2147483648
152 168: a APPEND
153 169: ( MARK
154 170: V UNICODE 'abc'
155 175: p PUT 4
156 178: g GET 4
157 181: c GLOBAL 'copyreg _reconstructor'
158 205: p PUT 5
159 208: ( MARK
160 209: c GLOBAL '__main__ C'
161 221: p PUT 6
162 224: c GLOBAL 'builtins object'
163 241: p PUT 7
164 244: N NONE
165 245: t TUPLE (MARK at 208)
166 246: p PUT 8
167 249: R REDUCE
168 250: p PUT 9
169 253: ( MARK
170 254: d DICT (MARK at 253)
171 255: p PUT 10
172 259: V UNICODE 'foo'
173 264: p PUT 11
174 268: L LONG 1
175 272: s SETITEM
176 273: V UNICODE 'bar'
177 278: p PUT 12
178 282: L LONG 2
179 286: s SETITEM
180 287: b BUILD
181 288: g GET 9
182 291: t TUPLE (MARK at 169)
183 292: p PUT 13
184 296: a APPEND
185 297: g GET 13
186 301: a APPEND
187 302: L LONG 5
188 306: a APPEND
189 307: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000190highest protocol among opcodes = 0
191"""
192
Guido van Rossum98297ee2007-11-06 21:34:58 +0000193DATA1 = (
Georg Brandl1a3284e2007-12-02 09:40:06 +0000194 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
195 b'builtins\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000196 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
197 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
198 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
199 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000200 b'cq\x04h\x04ccopyreg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000201 b'nstructor\nq\x05(c__main'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000202 b'__\nC\nq\x06cbuiltins\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000203 b'object\nq\x07Ntq\x08Rq\t}q\n('
204 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
205 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
206)
Tim Peters70b02d72003-02-02 17:26:40 +0000207
Guido van Rossum98297ee2007-11-06 21:34:58 +0000208# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000209DATA1_DIS = """\
210 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000211 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000212 3: ( MARK
213 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000214 6: K BININT1 1
215 8: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000216 17: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000217 35: q BINPUT 1
218 37: ( MARK
219 38: G BINFLOAT 3.0
220 47: G BINFLOAT 0.0
221 56: t TUPLE (MARK at 37)
222 57: q BINPUT 2
223 59: R REDUCE
224 60: q BINPUT 3
225 62: K BININT1 1
226 64: J BININT -1
227 69: K BININT1 255
228 71: J BININT -255
229 76: J BININT -256
230 81: M BININT2 65535
231 84: J BININT -65535
232 89: J BININT -65536
233 94: J BININT 2147483647
234 99: J BININT -2147483647
235 104: J BININT -2147483648
236 109: ( MARK
237 110: X BINUNICODE 'abc'
238 118: q BINPUT 4
239 120: h BINGET 4
240 122: c GLOBAL 'copyreg _reconstructor'
241 146: q BINPUT 5
242 148: ( MARK
243 149: c GLOBAL '__main__ C'
244 161: q BINPUT 6
245 163: c GLOBAL 'builtins object'
246 180: q BINPUT 7
247 182: N NONE
248 183: t TUPLE (MARK at 148)
249 184: q BINPUT 8
250 186: R REDUCE
251 187: q BINPUT 9
252 189: } EMPTY_DICT
253 190: q BINPUT 10
254 192: ( MARK
255 193: X BINUNICODE 'foo'
256 201: q BINPUT 11
257 203: K BININT1 1
258 205: X BINUNICODE 'bar'
259 213: q BINPUT 12
260 215: K BININT1 2
261 217: u SETITEMS (MARK at 192)
262 218: b BUILD
263 219: h BINGET 9
264 221: t TUPLE (MARK at 109)
265 222: q BINPUT 13
266 224: h BINGET 13
267 226: K BININT1 5
268 228: e APPENDS (MARK at 3)
269 229: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000270highest protocol among opcodes = 1
271"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000272
Guido van Rossum98297ee2007-11-06 21:34:58 +0000273DATA2 = (
274 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000275 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000276 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
277 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
278 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
279 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
280 b'bcq\x04h\x04c__main__\nC\nq\x05'
281 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
282 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
283 b'\nK\x05e.'
284)
Tim Petersfc273752003-03-02 04:54:24 +0000285
Guido van Rossum98297ee2007-11-06 21:34:58 +0000286# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000287DATA2_DIS = """\
288 0: \x80 PROTO 2
289 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000290 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000291 5: ( MARK
292 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000293 8: K BININT1 1
294 10: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000295 19: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000296 37: q BINPUT 1
297 39: G BINFLOAT 3.0
298 48: G BINFLOAT 0.0
299 57: \x86 TUPLE2
300 58: q BINPUT 2
301 60: R REDUCE
302 61: q BINPUT 3
303 63: K BININT1 1
304 65: J BININT -1
305 70: K BININT1 255
306 72: J BININT -255
307 77: J BININT -256
308 82: M BININT2 65535
309 85: J BININT -65535
310 90: J BININT -65536
311 95: J BININT 2147483647
312 100: J BININT -2147483647
313 105: J BININT -2147483648
314 110: ( MARK
315 111: X BINUNICODE 'abc'
316 119: q BINPUT 4
317 121: h BINGET 4
318 123: c GLOBAL '__main__ C'
319 135: q BINPUT 5
320 137: ) EMPTY_TUPLE
321 138: \x81 NEWOBJ
322 139: q BINPUT 6
323 141: } EMPTY_DICT
324 142: q BINPUT 7
325 144: ( MARK
326 145: X BINUNICODE 'foo'
327 153: q BINPUT 8
328 155: K BININT1 1
329 157: X BINUNICODE 'bar'
330 165: q BINPUT 9
331 167: K BININT1 2
332 169: u SETITEMS (MARK at 144)
333 170: b BUILD
334 171: h BINGET 6
335 173: t TUPLE (MARK at 110)
336 174: q BINPUT 10
337 176: h BINGET 10
338 178: K BININT1 5
339 180: e APPENDS (MARK at 5)
340 181: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000341highest protocol among opcodes = 2
342"""
343
Jeremy Hylton66426532001-10-15 21:38:56 +0000344def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000345 c = C()
346 c.foo = 1
347 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000348 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000349 # Append some integer test cases at cPickle.c's internal size
350 # cutoffs.
351 uint1max = 0xff
352 uint2max = 0xffff
353 int4max = 0x7fffffff
354 x.extend([1, -1,
355 uint1max, -uint1max, -uint1max-1,
356 uint2max, -uint2max, -uint2max-1,
357 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000358 y = ('abc', 'abc', c, c)
359 x.append(y)
360 x.append(y)
361 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000362 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000363
Jeremy Hylton66426532001-10-15 21:38:56 +0000364class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000365 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000366
Jeremy Hylton66426532001-10-15 21:38:56 +0000367 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000368
Jeremy Hylton66426532001-10-15 21:38:56 +0000369 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000370 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000371
Jeremy Hylton66426532001-10-15 21:38:56 +0000372 def test_misc(self):
373 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000374 for proto in protocols:
375 x = myint(4)
376 s = self.dumps(x, proto)
377 y = self.loads(s)
378 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000379
Tim Peters70b02d72003-02-02 17:26:40 +0000380 x = (1, ())
381 s = self.dumps(x, proto)
382 y = self.loads(s)
383 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000384
Tim Peters70b02d72003-02-02 17:26:40 +0000385 x = initarg(1, x)
386 s = self.dumps(x, proto)
387 y = self.loads(s)
388 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000389
Jeremy Hylton66426532001-10-15 21:38:56 +0000390 # XXX test __reduce__ protocol?
391
Tim Peters70b02d72003-02-02 17:26:40 +0000392 def test_roundtrip_equality(self):
393 expected = self._testdata
394 for proto in protocols:
395 s = self.dumps(expected, proto)
396 got = self.loads(s)
397 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000398
Guido van Rossum98297ee2007-11-06 21:34:58 +0000399 def test_load_from_data0(self):
400 self.assertEqual(self._testdata, self.loads(DATA0))
401
402 def test_load_from_data1(self):
403 self.assertEqual(self._testdata, self.loads(DATA1))
404
405 def test_load_from_data2(self):
406 self.assertEqual(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000407
Tim Peters70b02d72003-02-02 17:26:40 +0000408 # There are gratuitous differences between pickles produced by
409 # pickle and cPickle, largely because cPickle starts PUT indices at
410 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
411 # there's a comment with an exclamation point there whose meaning
412 # is a mystery. cPickle also suppresses PUT for objects with a refcount
413 # of 1.
414 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000415 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000416 from pickletools import dis
417
418 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
419 s = self.dumps(self._testdata, proto)
420 filelike = StringIO()
421 dis(s, out=filelike)
422 got = filelike.getvalue()
423 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000424
425 def test_recursive_list(self):
426 l = []
427 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000428 for proto in protocols:
429 s = self.dumps(l, proto)
430 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000431 self.assertEqual(len(x), 1)
432 self.assert_(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000433
434 def test_recursive_dict(self):
435 d = {}
436 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000437 for proto in protocols:
438 s = self.dumps(d, proto)
439 x = self.loads(s)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000440 self.assertEqual(list(x.keys()), [1])
Armin Rigo2b3eb402003-10-28 12:05:48 +0000441 self.assert_(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000442
443 def test_recursive_inst(self):
444 i = C()
445 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000446 for proto in protocols:
447 s = self.dumps(i, 2)
448 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000449 self.assertEqual(dir(x), dir(i))
450 self.assert_(x.attr is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000451
452 def test_recursive_multi(self):
453 l = []
454 d = {1:l}
455 i = C()
456 i.attr = d
457 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000458 for proto in protocols:
459 s = self.dumps(l, proto)
460 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000461 self.assertEqual(len(x), 1)
462 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000463 self.assertEqual(list(x[0].attr.keys()), [1])
Armin Rigo2b3eb402003-10-28 12:05:48 +0000464 self.assert_(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000465
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000466 def test_get(self):
467 self.assertRaises(KeyError, self.loads, b'g0\np0')
468 self.assertEquals(self.loads(b'((Kdtp0\nh\x00l.))'), [(100,), (100,)])
Jeremy Hylton66426532001-10-15 21:38:56 +0000469
470 def test_insecure_strings(self):
Guido van Rossum39478e82007-08-27 17:23:59 +0000471 # XXX Some of these tests are temporarily disabled
472 insecure = [b"abc", b"2 + 2", # not quoted
473 ## b"'abc' + 'def'", # not a single quoted string
474 b"'abc", # quote is not closed
475 b"'abc\"", # open quote and close quote don't match
476 b"'abc' ?", # junk after close quote
477 b"'\\'", # trailing backslash
Jeremy Hylton66426532001-10-15 21:38:56 +0000478 # some tests of the quoting rules
Guido van Rossum39478e82007-08-27 17:23:59 +0000479 ## b"'abc\"\''",
480 ## b"'\\\\a\'\'\'\\\'\\\\\''",
Jeremy Hylton66426532001-10-15 21:38:56 +0000481 ]
Guido van Rossum39478e82007-08-27 17:23:59 +0000482 for b in insecure:
483 buf = b"S" + b + b"\012p0\012."
Jeremy Hylton66426532001-10-15 21:38:56 +0000484 self.assertRaises(ValueError, self.loads, buf)
485
Walter Dörwald9b775532007-06-08 14:30:53 +0000486 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000487 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
488 '<\\>', '<\\\U00012345>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000489 for proto in protocols:
490 for u in endcases:
491 p = self.dumps(u, proto)
492 u2 = self.loads(p)
493 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000494
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000495 def test_unicode_high_plane(self):
496 t = '\U00012345'
497 for proto in protocols:
498 p = self.dumps(t, proto)
499 t2 = self.loads(p)
500 self.assertEqual(t2, t)
501
Guido van Rossumf4169812008-03-17 22:56:06 +0000502 def test_bytes(self):
503 for proto in protocols:
504 for u in b'', b'xyz', b'xyz'*100:
505 p = self.dumps(u)
506 self.assertEqual(self.loads(p), u)
507
Jeremy Hylton66426532001-10-15 21:38:56 +0000508 def test_ints(self):
509 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000510 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000511 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000512 while n:
513 for expected in (-n, n):
514 s = self.dumps(expected, proto)
515 n2 = self.loads(s)
516 self.assertEqual(expected, n2)
517 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000518
Jeremy Hylton66426532001-10-15 21:38:56 +0000519 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000520 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000521 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000522 got = self.loads(data)
523 self.assertEqual(got, maxint64)
524
525 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000526 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000527 self.assertRaises(ValueError, self.loads, data)
528
Tim Petersee1a53c2003-02-02 02:57:53 +0000529 def test_long(self):
530 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000531 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000532 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000533 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000534 for npos in nbase-1, nbase, nbase+1:
535 for n in npos, -npos:
536 pickle = self.dumps(n, proto)
537 got = self.loads(pickle)
538 self.assertEqual(n, got)
539 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
540 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000541 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000542 nbase += nbase << 1000000
543 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000544 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000545 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000546 self.assertEqual(n, got)
547
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000548 def test_float(self):
549 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
550 3.14, 263.44582062374053, 6.022e23, 1e30]
551 test_values = test_values + [-x for x in test_values]
552 for proto in protocols:
553 for value in test_values:
554 pickle = self.dumps(value, proto)
555 got = self.loads(pickle)
556 self.assertEqual(value, got)
557
Thomas Wouters477c8d52006-05-27 19:21:47 +0000558 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
559 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000560 # make sure that floats are formatted locale independent with proto 0
561 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000562
Jeremy Hylton66426532001-10-15 21:38:56 +0000563 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000564 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000565
566 def test_getinitargs(self):
567 pass
568
Guido van Rossum04a86612001-12-19 16:58:54 +0000569 def test_metaclass(self):
570 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000571 for proto in protocols:
572 s = self.dumps(a, proto)
573 b = self.loads(s)
574 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000575
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000576 def test_structseq(self):
577 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000578 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000579
580 t = time.localtime()
581 for proto in protocols:
582 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000583 u = self.loads(s)
584 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000585 if hasattr(os, "stat"):
586 t = os.stat(os.curdir)
587 s = self.dumps(t, proto)
588 u = self.loads(s)
589 self.assertEqual(t, u)
590 if hasattr(os, "statvfs"):
591 t = os.statvfs(os.curdir)
592 s = self.dumps(t, proto)
593 u = self.loads(s)
594 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000595
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000596 # Tests for protocol 2
597
Tim Peters4190fb82003-02-02 16:09:05 +0000598 def test_proto(self):
599 build_none = pickle.NONE + pickle.STOP
600 for proto in protocols:
601 expected = build_none
602 if proto >= 2:
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000603 expected = pickle.PROTO + bytes([proto]) + expected
Tim Peters4190fb82003-02-02 16:09:05 +0000604 p = self.dumps(None, proto)
605 self.assertEqual(p, expected)
606
607 oob = protocols[-1] + 1 # a future protocol
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000608 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000609 try:
610 self.loads(badpickle)
Guido van Rossumb940e112007-01-10 16:19:56 +0000611 except ValueError as detail:
Tim Peters4190fb82003-02-02 16:09:05 +0000612 self.failUnless(str(detail).startswith(
613 "unsupported pickle protocol"))
614 else:
615 self.fail("expected bad protocol number to raise ValueError")
616
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000617 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000618 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000619 for proto in protocols:
620 s = self.dumps(x, proto)
621 y = self.loads(s)
622 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000623 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000624
625 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000626 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000627 for proto in protocols:
628 s = self.dumps(x, proto)
629 y = self.loads(s)
630 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000631 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000632
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000633 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000634 # Map (proto, len(tuple)) to expected opcode.
635 expected_opcode = {(0, 0): pickle.TUPLE,
636 (0, 1): pickle.TUPLE,
637 (0, 2): pickle.TUPLE,
638 (0, 3): pickle.TUPLE,
639 (0, 4): pickle.TUPLE,
640
641 (1, 0): pickle.EMPTY_TUPLE,
642 (1, 1): pickle.TUPLE,
643 (1, 2): pickle.TUPLE,
644 (1, 3): pickle.TUPLE,
645 (1, 4): pickle.TUPLE,
646
647 (2, 0): pickle.EMPTY_TUPLE,
648 (2, 1): pickle.TUPLE1,
649 (2, 2): pickle.TUPLE2,
650 (2, 3): pickle.TUPLE3,
651 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000652
653 (3, 0): pickle.EMPTY_TUPLE,
654 (3, 1): pickle.TUPLE1,
655 (3, 2): pickle.TUPLE2,
656 (3, 3): pickle.TUPLE3,
657 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000658 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000659 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000660 b = (1,)
661 c = (1, 2)
662 d = (1, 2, 3)
663 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000664 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000665 for x in a, b, c, d, e:
666 s = self.dumps(x, proto)
667 y = self.loads(s)
668 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000669 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +0000670 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +0000671
Guido van Rossum7d97d312003-01-28 04:25:27 +0000672 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000673 # Map (proto, singleton) to expected opcode.
674 expected_opcode = {(0, None): pickle.NONE,
675 (1, None): pickle.NONE,
676 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000677 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000678
679 (0, True): pickle.INT,
680 (1, True): pickle.INT,
681 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000682 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000683
684 (0, False): pickle.INT,
685 (1, False): pickle.INT,
686 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000687 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000688 }
Tim Peters4190fb82003-02-02 16:09:05 +0000689 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000690 for x in None, False, True:
691 s = self.dumps(x, proto)
692 y = self.loads(s)
693 self.assert_(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +0000694 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +0000695 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +0000696
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000697 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000698 x = MyTuple([1, 2, 3])
699 x.foo = 42
700 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000701 for proto in protocols:
702 s = self.dumps(x, proto)
703 y = self.loads(s)
704 self.assertEqual(tuple(x), tuple(y))
705 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000706
707 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000708 x = MyList([1, 2, 3])
709 x.foo = 42
710 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000711 for proto in protocols:
712 s = self.dumps(x, proto)
713 y = self.loads(s)
714 self.assertEqual(list(x), list(y))
715 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000716
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000717 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +0000718 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000719 for C in myclasses:
720 B = C.__base__
721 x = C(C.sample)
722 x.foo = 42
723 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000724 y = self.loads(s)
725 detail = (proto, C, B, x, y, type(y))
726 self.assertEqual(B(x), B(y), detail)
727 self.assertEqual(x.__dict__, y.__dict__, detail)
728
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000729 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +0000730 # an object of that type. Check that the resulting pickle uses opcode
731 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +0000732
Tim Peters22e71712003-02-03 22:27:38 +0000733 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +0000734 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000735 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000736 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000737 x = MyList([1, 2, 3])
738 x.foo = 42
739 x.bar = "hello"
740
Tim Peters22e71712003-02-03 22:27:38 +0000741 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000742 s1 = self.dumps(x, 1)
Guido van Rossum39478e82007-08-27 17:23:59 +0000743 self.assert_(__name__.encode("utf-8") in s1)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000744 self.assert_(b"MyList" in s1)
Tim Peters3e667d52003-02-04 21:47:44 +0000745 self.assertEqual(opcode_in_pickle(opcode, s1), False)
746
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000747 y = self.loads(s1)
748 self.assertEqual(list(x), list(y))
749 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000750
Tim Peters22e71712003-02-03 22:27:38 +0000751 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000752 s2 = self.dumps(x, 2)
Guido van Rossum39478e82007-08-27 17:23:59 +0000753 self.assert_(__name__.encode("utf-8") not in s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000754 self.assert_(b"MyList" not in s2)
755 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +0000756
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000757 y = self.loads(s2)
758 self.assertEqual(list(x), list(y))
759 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000760
761 finally:
Tim Peters3e667d52003-02-04 21:47:44 +0000762 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +0000763
764 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000765 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
766 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000767
768 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000769 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
770 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
771 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000772
773 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000774 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
775 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
776 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
777
Tim Peters8d2613a2003-02-11 16:40:16 +0000778 def test_list_chunking(self):
779 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +0000780 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000781 for proto in protocols:
782 s = self.dumps(x, proto)
783 y = self.loads(s)
784 self.assertEqual(x, y)
785 num_appends = count_opcode(pickle.APPENDS, s)
786 self.assertEqual(num_appends, proto > 0)
787
788 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +0000789 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000790 for proto in protocols:
791 s = self.dumps(x, proto)
792 y = self.loads(s)
793 self.assertEqual(x, y)
794 num_appends = count_opcode(pickle.APPENDS, s)
795 if proto == 0:
796 self.assertEqual(num_appends, 0)
797 else:
798 self.failUnless(num_appends >= 2)
799
800 def test_dict_chunking(self):
801 n = 10 # too small to chunk
802 x = dict.fromkeys(range(n))
803 for proto in protocols:
804 s = self.dumps(x, proto)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000805 assert isinstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +0000806 y = self.loads(s)
807 self.assertEqual(x, y)
808 num_setitems = count_opcode(pickle.SETITEMS, s)
809 self.assertEqual(num_setitems, proto > 0)
810
811 n = 2500 # expect at least two chunks when proto > 0
812 x = dict.fromkeys(range(n))
813 for proto in protocols:
814 s = self.dumps(x, proto)
815 y = self.loads(s)
816 self.assertEqual(x, y)
817 num_setitems = count_opcode(pickle.SETITEMS, s)
818 if proto == 0:
819 self.assertEqual(num_setitems, 0)
820 else:
821 self.failUnless(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000822
Tim Peterse9ef2032003-02-13 18:42:00 +0000823 def test_simple_newobj(self):
824 x = object.__new__(SimpleNewObj) # avoid __init__
825 x.abc = 666
826 for proto in protocols:
827 s = self.dumps(x, proto)
828 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
829 y = self.loads(s) # will raise TypeError if __init__ called
830 self.assertEqual(y.abc, 666)
831 self.assertEqual(x.__dict__, y.__dict__)
832
Tim Peters42f08ac2003-02-11 22:43:24 +0000833 def test_newobj_list_slots(self):
834 x = SlotList([1, 2, 3])
835 x.foo = 42
836 x.bar = "hello"
837 s = self.dumps(x, 2)
838 y = self.loads(s)
839 self.assertEqual(list(x), list(y))
840 self.assertEqual(x.__dict__, y.__dict__)
841 self.assertEqual(x.foo, y.foo)
842 self.assertEqual(x.bar, y.bar)
843
Guido van Rossum2a30b212003-02-18 22:41:24 +0000844 def test_reduce_overrides_default_reduce_ex(self):
845 for proto in 0, 1, 2:
846 x = REX_one()
847 self.assertEqual(x._reduce_called, 0)
848 s = self.dumps(x, proto)
849 self.assertEqual(x._reduce_called, 1)
850 y = self.loads(s)
851 self.assertEqual(y._reduce_called, 0)
852
853 def test_reduce_ex_called(self):
854 for proto in 0, 1, 2:
855 x = REX_two()
856 self.assertEqual(x._proto, None)
857 s = self.dumps(x, proto)
858 self.assertEqual(x._proto, proto)
859 y = self.loads(s)
860 self.assertEqual(y._proto, None)
861
862 def test_reduce_ex_overrides_reduce(self):
863 for proto in 0, 1, 2:
864 x = REX_three()
865 self.assertEqual(x._proto, None)
866 s = self.dumps(x, proto)
867 self.assertEqual(x._proto, proto)
868 y = self.loads(s)
869 self.assertEqual(y._proto, None)
870
Guido van Rossumd8faa362007-04-27 19:54:29 +0000871 def test_reduce_ex_calls_base(self):
872 for proto in 0, 1, 2:
873 x = REX_four()
874 self.assertEqual(x._proto, None)
875 s = self.dumps(x, proto)
876 self.assertEqual(x._proto, proto)
877 y = self.loads(s)
878 self.assertEqual(y._proto, proto)
879
880 def test_reduce_calls_base(self):
881 for proto in 0, 1, 2:
882 x = REX_five()
883 self.assertEqual(x._reduce_called, 0)
884 s = self.dumps(x, proto)
885 self.assertEqual(x._reduce_called, 1)
886 y = self.loads(s)
887 self.assertEqual(y._reduce_called, 1)
888
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +0000889 def test_bad_getattr(self):
890 x = BadGetattr()
891 for proto in 0, 1:
892 self.assertRaises(RuntimeError, self.dumps, x, proto)
893 # protocol 2 don't raise a RuntimeError.
894 d = self.dumps(x, 2)
895 self.assertRaises(RuntimeError, self.loads, d)
896
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +0000897 def test_reduce_bad_iterator(self):
898 # Issue4176: crash when 4th and 5th items of __reduce__()
899 # are not iterators
900 class C(object):
901 def __reduce__(self):
902 # 4th item is not an iterator
903 return list, (), None, [], None
904 class D(object):
905 def __reduce__(self):
906 # 5th item is not an iterator
907 return dict, (), None, None, []
908
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +0000909 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +0000910 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +0000911 try:
912 self.dumps(C(), proto)
913 except (pickle.PickleError):
914 pass
915 try:
916 self.dumps(D(), proto)
917 except (pickle.PickleError):
918 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +0000919
Guido van Rossum2a30b212003-02-18 22:41:24 +0000920# Test classes for reduce_ex
921
922class REX_one(object):
923 _reduce_called = 0
924 def __reduce__(self):
925 self._reduce_called = 1
926 return REX_one, ()
927 # No __reduce_ex__ here, but inheriting it from object
928
929class REX_two(object):
930 _proto = None
931 def __reduce_ex__(self, proto):
932 self._proto = proto
933 return REX_two, ()
934 # No __reduce__ here, but inheriting it from object
935
936class REX_three(object):
937 _proto = None
938 def __reduce_ex__(self, proto):
939 self._proto = proto
940 return REX_two, ()
941 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +0000942 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +0000943
Guido van Rossumd8faa362007-04-27 19:54:29 +0000944class REX_four(object):
945 _proto = None
946 def __reduce_ex__(self, proto):
947 self._proto = proto
948 return object.__reduce_ex__(self, proto)
949 # Calling base class method should succeed
950
951class REX_five(object):
952 _reduce_called = 0
953 def __reduce__(self):
954 self._reduce_called = 1
955 return object.__reduce__(self)
956 # This one used to fail with infinite recursion
957
Guido van Rossum2a30b212003-02-18 22:41:24 +0000958# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +0000959
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000960class MyInt(int):
961 sample = 1
962
Guido van Rossume2a383d2007-01-15 16:59:06 +0000963class MyLong(int):
964 sample = 1
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000965
966class MyFloat(float):
967 sample = 1.0
968
969class MyComplex(complex):
970 sample = 1.0 + 0.0j
971
972class MyStr(str):
973 sample = "hello"
974
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000975class MyUnicode(str):
976 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000977
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000978class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000979 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000980
981class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000982 sample = [1, 2, 3]
983
984class MyDict(dict):
985 sample = {"a": 1, "b": 2}
986
987myclasses = [MyInt, MyLong, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +0000988 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000989 MyStr, MyUnicode,
990 MyTuple, MyList, MyDict]
991
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000992
Guido van Rossumc8d6ef52003-01-28 22:02:31 +0000993class SlotList(MyList):
994 __slots__ = ["foo"]
995
Tim Peterse9ef2032003-02-13 18:42:00 +0000996class SimpleNewObj(object):
997 def __init__(self, a, b, c):
998 # raise an error, to make sure this isn't called
999 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1000
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001001class BadGetattr:
1002 def __getattr__(self, key):
1003 self.foo
1004
Jeremy Hylton66426532001-10-15 21:38:56 +00001005class AbstractPickleModuleTests(unittest.TestCase):
1006
1007 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001008 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001009 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001010 try:
1011 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001012 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001013 finally:
1014 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001015
1016 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001017 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001018 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001019 try:
1020 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001021 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001022 finally:
1023 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001024
Tim Petersc0c93702003-02-13 19:30:57 +00001025 def test_highest_protocol(self):
1026 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001027 self.assertEqual(pickle.HIGHEST_PROTOCOL, 3)
Tim Petersc0c93702003-02-13 19:30:57 +00001028
Martin v. Löwis544f1192004-07-27 05:22:33 +00001029 def test_callapi(self):
Guido van Rossum34d19282007-08-09 01:03:29 +00001030 from io import BytesIO
1031 f = BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001032 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001033 pickle.dump(123, f, -1)
1034 pickle.dump(123, file=f, protocol=-1)
1035 pickle.dumps(123, -1)
1036 pickle.dumps(123, protocol=-1)
1037 pickle.Pickler(f, -1)
1038 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001039
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001040 def test_bad_init(self):
1041 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
1042 from io import BytesIO
1043 # Override initialization without calling __init__() of the superclass.
1044 class BadPickler(pickle.Pickler):
1045 def __init__(self): pass
1046
1047 class BadUnpickler(pickle.Unpickler):
1048 def __init__(self): pass
1049
1050 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1051 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1052
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001053 def test_bad_input(self):
1054 # Test issue4298
1055 s = bytes([0x58, 0, 0, 0, 0x54])
1056 self.assertRaises(EOFError, pickle.loads, s)
1057
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001058
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001059class AbstractPersistentPicklerTests(unittest.TestCase):
1060
1061 # This class defines persistent_id() and persistent_load()
1062 # functions that should be used by the pickler. All even integers
1063 # are pickled using persistent ids.
1064
1065 def persistent_id(self, object):
1066 if isinstance(object, int) and object % 2 == 0:
1067 self.id_count += 1
1068 return str(object)
1069 else:
1070 return None
1071
1072 def persistent_load(self, oid):
1073 self.load_count += 1
1074 object = int(oid)
1075 assert object % 2 == 0
1076 return object
1077
1078 def test_persistence(self):
1079 self.id_count = 0
1080 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001081 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001082 self.assertEqual(self.loads(self.dumps(L)), L)
1083 self.assertEqual(self.id_count, 5)
1084 self.assertEqual(self.load_count, 5)
1085
1086 def test_bin_persistence(self):
1087 self.id_count = 0
1088 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001089 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001090 self.assertEqual(self.loads(self.dumps(L, 1)), L)
1091 self.assertEqual(self.id_count, 5)
1092 self.assertEqual(self.load_count, 5)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001093
1094if __name__ == "__main__":
1095 # Print some stuff that can be used to rewrite DATA{0,1,2}
1096 from pickletools import dis
1097 x = create_data()
1098 for i in range(3):
1099 p = pickle.dumps(x, i)
1100 print("DATA{0} = (".format(i))
1101 for j in range(0, len(p), 20):
1102 b = bytes(p[j:j+20])
1103 print(" {0!r}".format(b))
1104 print(")")
1105 print()
1106 print("# Disassembly of DATA{0}".format(i))
1107 print("DATA{0}_DIS = \"\"\"\\".format(i))
1108 dis(p)
1109 print("\"\"\"")
1110 print()