blob: 58ce3b5cf96c8b1605748e2eb9a206acf6e4987e [file] [log] [blame]
Collin Winter771d8342009-04-16 03:18:06 +00001import io
Jeremy Hylton66426532001-10-15 21:38:56 +00002import unittest
Tim Peters4190fb82003-02-02 16:09:05 +00003import pickle
Tim Peters31f119e2003-02-03 16:20:13 +00004import pickletools
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00005import copyreg
Tim Peters4190fb82003-02-02 16:09:05 +00006
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test.support import TestFailed, TESTFN, run_with_locale
Tim Peterse089c682001-04-10 03:41:41 +00008
Guido van Rossum98297ee2007-11-06 21:34:58 +00009from pickle import bytes_types
10
Tim Petersee1a53c2003-02-02 02:57:53 +000011# Tests that try a number of pickle protocols should have a
12# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000013# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000014protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000015
Tim Peters22e71712003-02-03 22:27:38 +000016
17# Return True if opcode code appears in the pickle, else False.
18def opcode_in_pickle(code, pickle):
19 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000020 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000021 return True
22 return False
23
Tim Peters8d2613a2003-02-11 16:40:16 +000024# Return the number of times opcode code appears in pickle.
25def count_opcode(code, pickle):
26 n = 0
27 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000028 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000029 n += 1
30 return n
31
Tim Peters3e667d52003-02-04 21:47:44 +000032# We can't very well test the extension registry without putting known stuff
33# in it, but we have to be careful to restore its original state. Code
34# should do this:
35#
36# e = ExtensionSaver(extension_code)
37# try:
38# fiddle w/ the extension registry's stuff for extension_code
39# finally:
40# e.restore()
41
42class ExtensionSaver:
43 # Remember current registration for code (if any), and remove it (if
44 # there is one).
45 def __init__(self, code):
46 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000047 if code in copyreg._inverted_registry:
48 self.pair = copyreg._inverted_registry[code]
49 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000050 else:
51 self.pair = None
52
53 # Restore previous registration for code.
54 def restore(self):
55 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000056 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000057 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000058 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000059 pair = self.pair
60 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000061 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000062
Jeremy Hylton66426532001-10-15 21:38:56 +000063class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000064 def __eq__(self, other):
65 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000066
67import __main__
68__main__.C = C
69C.__module__ = "__main__"
70
71class myint(int):
72 def __init__(self, x):
73 self.str = str(x)
74
75class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +000076
Jeremy Hylton66426532001-10-15 21:38:56 +000077 def __init__(self, a, b):
78 self.a = a
79 self.b = b
80
81 def __getinitargs__(self):
82 return self.a, self.b
83
Guido van Rossum04a86612001-12-19 16:58:54 +000084class metaclass(type):
85 pass
86
Guido van Rossum52cc1d82007-03-18 15:41:51 +000087class use_metaclass(object, metaclass=metaclass):
88 pass
Guido van Rossum04a86612001-12-19 16:58:54 +000089
Tim Peters70b02d72003-02-02 17:26:40 +000090# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
91# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +000092
Guido van Rossum98297ee2007-11-06 21:34:58 +000093DATA0 = (
Mark Dickinson8dd05142009-01-20 20:43:58 +000094 b'(lp0\nL0L\naL1L\naF2.0\nac'
Georg Brandl1a3284e2007-12-02 09:40:06 +000095 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +000096 b'p1\n(F3.0\nF0.0\ntp2\nRp'
Mark Dickinson8dd05142009-01-20 20:43:58 +000097 b'3\naL1L\naL-1L\naL255L\naL-'
98 b'255L\naL-256L\naL65535L\na'
99 b'L-65535L\naL-65536L\naL2'
100 b'147483647L\naL-2147483'
101 b'647L\naL-2147483648L\na('
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000102 b'Vabc\np4\ng4\nccopyreg'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000103 b'\n_reconstructor\np5\n('
Georg Brandl1a3284e2007-12-02 09:40:06 +0000104 b'c__main__\nC\np6\ncbu'
105 b'iltins\nobject\np7\nNt'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000106 b'p8\nRp9\n(dp10\nVfoo\np1'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000107 b'1\nL1L\nsVbar\np12\nL2L\nsb'
108 b'g9\ntp13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000109)
Tim Peterse9358162001-01-22 22:05:20 +0000110
Guido van Rossum98297ee2007-11-06 21:34:58 +0000111# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000112DATA0_DIS = """\
113 0: ( MARK
114 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000115 2: p PUT 0
116 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000117 9: a APPEND
118 10: L LONG 1
119 14: a APPEND
120 15: F FLOAT 2.0
121 20: a APPEND
122 21: c GLOBAL 'builtins complex'
123 39: p PUT 1
124 42: ( MARK
125 43: F FLOAT 3.0
126 48: F FLOAT 0.0
127 53: t TUPLE (MARK at 42)
128 54: p PUT 2
129 57: R REDUCE
130 58: p PUT 3
131 61: a APPEND
132 62: L LONG 1
133 66: a APPEND
134 67: L LONG -1
135 72: a APPEND
136 73: L LONG 255
137 79: a APPEND
138 80: L LONG -255
139 87: a APPEND
140 88: L LONG -256
141 95: a APPEND
142 96: L LONG 65535
143 104: a APPEND
144 105: L LONG -65535
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000145 114: a APPEND
Mark Dickinson8dd05142009-01-20 20:43:58 +0000146 115: L LONG -65536
147 124: a APPEND
148 125: L LONG 2147483647
149 138: a APPEND
150 139: L LONG -2147483647
151 153: a APPEND
152 154: L LONG -2147483648
153 168: a APPEND
154 169: ( MARK
155 170: V UNICODE 'abc'
156 175: p PUT 4
157 178: g GET 4
158 181: c GLOBAL 'copyreg _reconstructor'
159 205: p PUT 5
160 208: ( MARK
161 209: c GLOBAL '__main__ C'
162 221: p PUT 6
163 224: c GLOBAL 'builtins object'
164 241: p PUT 7
165 244: N NONE
166 245: t TUPLE (MARK at 208)
167 246: p PUT 8
168 249: R REDUCE
169 250: p PUT 9
170 253: ( MARK
171 254: d DICT (MARK at 253)
172 255: p PUT 10
173 259: V UNICODE 'foo'
174 264: p PUT 11
175 268: L LONG 1
176 272: s SETITEM
177 273: V UNICODE 'bar'
178 278: p PUT 12
179 282: L LONG 2
180 286: s SETITEM
181 287: b BUILD
182 288: g GET 9
183 291: t TUPLE (MARK at 169)
184 292: p PUT 13
185 296: a APPEND
186 297: g GET 13
187 301: a APPEND
188 302: L LONG 5
189 306: a APPEND
190 307: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000191highest protocol among opcodes = 0
192"""
193
Guido van Rossum98297ee2007-11-06 21:34:58 +0000194DATA1 = (
Georg Brandl1a3284e2007-12-02 09:40:06 +0000195 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
196 b'builtins\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000197 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
198 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
199 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
200 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000201 b'cq\x04h\x04ccopyreg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000202 b'nstructor\nq\x05(c__main'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000203 b'__\nC\nq\x06cbuiltins\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000204 b'object\nq\x07Ntq\x08Rq\t}q\n('
205 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
206 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
207)
Tim Peters70b02d72003-02-02 17:26:40 +0000208
Guido van Rossum98297ee2007-11-06 21:34:58 +0000209# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000210DATA1_DIS = """\
211 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000212 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000213 3: ( MARK
214 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000215 6: K BININT1 1
216 8: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000217 17: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000218 35: q BINPUT 1
219 37: ( MARK
220 38: G BINFLOAT 3.0
221 47: G BINFLOAT 0.0
222 56: t TUPLE (MARK at 37)
223 57: q BINPUT 2
224 59: R REDUCE
225 60: q BINPUT 3
226 62: K BININT1 1
227 64: J BININT -1
228 69: K BININT1 255
229 71: J BININT -255
230 76: J BININT -256
231 81: M BININT2 65535
232 84: J BININT -65535
233 89: J BININT -65536
234 94: J BININT 2147483647
235 99: J BININT -2147483647
236 104: J BININT -2147483648
237 109: ( MARK
238 110: X BINUNICODE 'abc'
239 118: q BINPUT 4
240 120: h BINGET 4
241 122: c GLOBAL 'copyreg _reconstructor'
242 146: q BINPUT 5
243 148: ( MARK
244 149: c GLOBAL '__main__ C'
245 161: q BINPUT 6
246 163: c GLOBAL 'builtins object'
247 180: q BINPUT 7
248 182: N NONE
249 183: t TUPLE (MARK at 148)
250 184: q BINPUT 8
251 186: R REDUCE
252 187: q BINPUT 9
253 189: } EMPTY_DICT
254 190: q BINPUT 10
255 192: ( MARK
256 193: X BINUNICODE 'foo'
257 201: q BINPUT 11
258 203: K BININT1 1
259 205: X BINUNICODE 'bar'
260 213: q BINPUT 12
261 215: K BININT1 2
262 217: u SETITEMS (MARK at 192)
263 218: b BUILD
264 219: h BINGET 9
265 221: t TUPLE (MARK at 109)
266 222: q BINPUT 13
267 224: h BINGET 13
268 226: K BININT1 5
269 228: e APPENDS (MARK at 3)
270 229: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000271highest protocol among opcodes = 1
272"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000273
Guido van Rossum98297ee2007-11-06 21:34:58 +0000274DATA2 = (
275 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000276 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000277 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
278 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
279 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
280 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
281 b'bcq\x04h\x04c__main__\nC\nq\x05'
282 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
283 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
284 b'\nK\x05e.'
285)
Tim Petersfc273752003-03-02 04:54:24 +0000286
Guido van Rossum98297ee2007-11-06 21:34:58 +0000287# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000288DATA2_DIS = """\
289 0: \x80 PROTO 2
290 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000291 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000292 5: ( MARK
293 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000294 8: K BININT1 1
295 10: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000296 19: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000297 37: q BINPUT 1
298 39: G BINFLOAT 3.0
299 48: G BINFLOAT 0.0
300 57: \x86 TUPLE2
301 58: q BINPUT 2
302 60: R REDUCE
303 61: q BINPUT 3
304 63: K BININT1 1
305 65: J BININT -1
306 70: K BININT1 255
307 72: J BININT -255
308 77: J BININT -256
309 82: M BININT2 65535
310 85: J BININT -65535
311 90: J BININT -65536
312 95: J BININT 2147483647
313 100: J BININT -2147483647
314 105: J BININT -2147483648
315 110: ( MARK
316 111: X BINUNICODE 'abc'
317 119: q BINPUT 4
318 121: h BINGET 4
319 123: c GLOBAL '__main__ C'
320 135: q BINPUT 5
321 137: ) EMPTY_TUPLE
322 138: \x81 NEWOBJ
323 139: q BINPUT 6
324 141: } EMPTY_DICT
325 142: q BINPUT 7
326 144: ( MARK
327 145: X BINUNICODE 'foo'
328 153: q BINPUT 8
329 155: K BININT1 1
330 157: X BINUNICODE 'bar'
331 165: q BINPUT 9
332 167: K BININT1 2
333 169: u SETITEMS (MARK at 144)
334 170: b BUILD
335 171: h BINGET 6
336 173: t TUPLE (MARK at 110)
337 174: q BINPUT 10
338 176: h BINGET 10
339 178: K BININT1 5
340 180: e APPENDS (MARK at 5)
341 181: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000342highest protocol among opcodes = 2
343"""
344
Jeremy Hylton66426532001-10-15 21:38:56 +0000345def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000346 c = C()
347 c.foo = 1
348 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000349 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000350 # Append some integer test cases at cPickle.c's internal size
351 # cutoffs.
352 uint1max = 0xff
353 uint2max = 0xffff
354 int4max = 0x7fffffff
355 x.extend([1, -1,
356 uint1max, -uint1max, -uint1max-1,
357 uint2max, -uint2max, -uint2max-1,
358 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000359 y = ('abc', 'abc', c, c)
360 x.append(y)
361 x.append(y)
362 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000363 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000364
Jeremy Hylton66426532001-10-15 21:38:56 +0000365class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000366 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000367
Jeremy Hylton66426532001-10-15 21:38:56 +0000368 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000369
Jeremy Hylton66426532001-10-15 21:38:56 +0000370 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000371 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000372
Jeremy Hylton66426532001-10-15 21:38:56 +0000373 def test_misc(self):
374 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000375 for proto in protocols:
376 x = myint(4)
377 s = self.dumps(x, proto)
378 y = self.loads(s)
379 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000380
Tim Peters70b02d72003-02-02 17:26:40 +0000381 x = (1, ())
382 s = self.dumps(x, proto)
383 y = self.loads(s)
384 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000385
Tim Peters70b02d72003-02-02 17:26:40 +0000386 x = initarg(1, x)
387 s = self.dumps(x, proto)
388 y = self.loads(s)
389 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000390
Jeremy Hylton66426532001-10-15 21:38:56 +0000391 # XXX test __reduce__ protocol?
392
Tim Peters70b02d72003-02-02 17:26:40 +0000393 def test_roundtrip_equality(self):
394 expected = self._testdata
395 for proto in protocols:
396 s = self.dumps(expected, proto)
397 got = self.loads(s)
398 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000399
Guido van Rossum98297ee2007-11-06 21:34:58 +0000400 def test_load_from_data0(self):
401 self.assertEqual(self._testdata, self.loads(DATA0))
402
403 def test_load_from_data1(self):
404 self.assertEqual(self._testdata, self.loads(DATA1))
405
406 def test_load_from_data2(self):
407 self.assertEqual(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000408
Tim Peters70b02d72003-02-02 17:26:40 +0000409 # There are gratuitous differences between pickles produced by
410 # pickle and cPickle, largely because cPickle starts PUT indices at
411 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
412 # there's a comment with an exclamation point there whose meaning
413 # is a mystery. cPickle also suppresses PUT for objects with a refcount
414 # of 1.
415 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000416 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000417 from pickletools import dis
418
419 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
420 s = self.dumps(self._testdata, proto)
421 filelike = StringIO()
422 dis(s, out=filelike)
423 got = filelike.getvalue()
424 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000425
426 def test_recursive_list(self):
427 l = []
428 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000429 for proto in protocols:
430 s = self.dumps(l, proto)
431 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000432 self.assertEqual(len(x), 1)
433 self.assert_(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000434
Collin Winter8ca69de2009-05-26 16:53:41 +0000435 def test_recursive_tuple(self):
436 t = ([],)
437 t[0].append(t)
438 for proto in protocols:
439 s = self.dumps(t, proto)
440 x = self.loads(s)
441 self.assertEqual(len(x), 1)
442 self.assertEqual(len(x[0]), 1)
443 self.assert_(x is x[0][0])
444
Jeremy Hylton66426532001-10-15 21:38:56 +0000445 def test_recursive_dict(self):
446 d = {}
447 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000448 for proto in protocols:
449 s = self.dumps(d, proto)
450 x = self.loads(s)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000451 self.assertEqual(list(x.keys()), [1])
Armin Rigo2b3eb402003-10-28 12:05:48 +0000452 self.assert_(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000453
454 def test_recursive_inst(self):
455 i = C()
456 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000457 for proto in protocols:
458 s = self.dumps(i, 2)
459 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000460 self.assertEqual(dir(x), dir(i))
461 self.assert_(x.attr is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000462
463 def test_recursive_multi(self):
464 l = []
465 d = {1:l}
466 i = C()
467 i.attr = d
468 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000469 for proto in protocols:
470 s = self.dumps(l, proto)
471 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000472 self.assertEqual(len(x), 1)
473 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000474 self.assertEqual(list(x[0].attr.keys()), [1])
Armin Rigo2b3eb402003-10-28 12:05:48 +0000475 self.assert_(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000476
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000477 def test_get(self):
478 self.assertRaises(KeyError, self.loads, b'g0\np0')
479 self.assertEquals(self.loads(b'((Kdtp0\nh\x00l.))'), [(100,), (100,)])
Jeremy Hylton66426532001-10-15 21:38:56 +0000480
481 def test_insecure_strings(self):
Guido van Rossum39478e82007-08-27 17:23:59 +0000482 # XXX Some of these tests are temporarily disabled
483 insecure = [b"abc", b"2 + 2", # not quoted
484 ## b"'abc' + 'def'", # not a single quoted string
485 b"'abc", # quote is not closed
486 b"'abc\"", # open quote and close quote don't match
487 b"'abc' ?", # junk after close quote
488 b"'\\'", # trailing backslash
Jeremy Hylton66426532001-10-15 21:38:56 +0000489 # some tests of the quoting rules
Guido van Rossum39478e82007-08-27 17:23:59 +0000490 ## b"'abc\"\''",
491 ## b"'\\\\a\'\'\'\\\'\\\\\''",
Jeremy Hylton66426532001-10-15 21:38:56 +0000492 ]
Guido van Rossum39478e82007-08-27 17:23:59 +0000493 for b in insecure:
494 buf = b"S" + b + b"\012p0\012."
Jeremy Hylton66426532001-10-15 21:38:56 +0000495 self.assertRaises(ValueError, self.loads, buf)
496
Walter Dörwald9b775532007-06-08 14:30:53 +0000497 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000498 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
499 '<\\>', '<\\\U00012345>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000500 for proto in protocols:
501 for u in endcases:
502 p = self.dumps(u, proto)
503 u2 = self.loads(p)
504 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000505
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000506 def test_unicode_high_plane(self):
507 t = '\U00012345'
508 for proto in protocols:
509 p = self.dumps(t, proto)
510 t2 = self.loads(p)
511 self.assertEqual(t2, t)
512
Guido van Rossumf4169812008-03-17 22:56:06 +0000513 def test_bytes(self):
514 for proto in protocols:
515 for u in b'', b'xyz', b'xyz'*100:
516 p = self.dumps(u)
517 self.assertEqual(self.loads(p), u)
518
Jeremy Hylton66426532001-10-15 21:38:56 +0000519 def test_ints(self):
520 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000521 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000522 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000523 while n:
524 for expected in (-n, n):
525 s = self.dumps(expected, proto)
526 n2 = self.loads(s)
527 self.assertEqual(expected, n2)
528 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000529
Jeremy Hylton66426532001-10-15 21:38:56 +0000530 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000531 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000532 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000533 got = self.loads(data)
534 self.assertEqual(got, maxint64)
535
536 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000537 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000538 self.assertRaises(ValueError, self.loads, data)
539
Tim Petersee1a53c2003-02-02 02:57:53 +0000540 def test_long(self):
541 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000542 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000543 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000544 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000545 for npos in nbase-1, nbase, nbase+1:
546 for n in npos, -npos:
547 pickle = self.dumps(n, proto)
548 got = self.loads(pickle)
549 self.assertEqual(n, got)
550 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
551 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000552 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000553 nbase += nbase << 1000000
554 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000555 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000556 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000557 self.assertEqual(n, got)
558
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000559 def test_float(self):
560 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
561 3.14, 263.44582062374053, 6.022e23, 1e30]
562 test_values = test_values + [-x for x in test_values]
563 for proto in protocols:
564 for value in test_values:
565 pickle = self.dumps(value, proto)
566 got = self.loads(pickle)
567 self.assertEqual(value, got)
568
Thomas Wouters477c8d52006-05-27 19:21:47 +0000569 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
570 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000571 # make sure that floats are formatted locale independent with proto 0
572 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000573
Jeremy Hylton66426532001-10-15 21:38:56 +0000574 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000575 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000576
577 def test_getinitargs(self):
578 pass
579
Guido van Rossum04a86612001-12-19 16:58:54 +0000580 def test_metaclass(self):
581 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000582 for proto in protocols:
583 s = self.dumps(a, proto)
584 b = self.loads(s)
585 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000586
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000587 def test_structseq(self):
588 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000589 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000590
591 t = time.localtime()
592 for proto in protocols:
593 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000594 u = self.loads(s)
595 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000596 if hasattr(os, "stat"):
597 t = os.stat(os.curdir)
598 s = self.dumps(t, proto)
599 u = self.loads(s)
600 self.assertEqual(t, u)
601 if hasattr(os, "statvfs"):
602 t = os.statvfs(os.curdir)
603 s = self.dumps(t, proto)
604 u = self.loads(s)
605 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000606
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000607 # Tests for protocol 2
608
Tim Peters4190fb82003-02-02 16:09:05 +0000609 def test_proto(self):
610 build_none = pickle.NONE + pickle.STOP
611 for proto in protocols:
612 expected = build_none
613 if proto >= 2:
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000614 expected = pickle.PROTO + bytes([proto]) + expected
Tim Peters4190fb82003-02-02 16:09:05 +0000615 p = self.dumps(None, proto)
616 self.assertEqual(p, expected)
617
618 oob = protocols[-1] + 1 # a future protocol
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000619 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000620 try:
621 self.loads(badpickle)
Guido van Rossumb940e112007-01-10 16:19:56 +0000622 except ValueError as detail:
Tim Peters4190fb82003-02-02 16:09:05 +0000623 self.failUnless(str(detail).startswith(
624 "unsupported pickle protocol"))
625 else:
626 self.fail("expected bad protocol number to raise ValueError")
627
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000628 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000629 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000630 for proto in protocols:
631 s = self.dumps(x, proto)
632 y = self.loads(s)
633 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000634 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000635
636 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000637 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000638 for proto in protocols:
639 s = self.dumps(x, proto)
640 y = self.loads(s)
641 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000642 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000643
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000644 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000645 # Map (proto, len(tuple)) to expected opcode.
646 expected_opcode = {(0, 0): pickle.TUPLE,
647 (0, 1): pickle.TUPLE,
648 (0, 2): pickle.TUPLE,
649 (0, 3): pickle.TUPLE,
650 (0, 4): pickle.TUPLE,
651
652 (1, 0): pickle.EMPTY_TUPLE,
653 (1, 1): pickle.TUPLE,
654 (1, 2): pickle.TUPLE,
655 (1, 3): pickle.TUPLE,
656 (1, 4): pickle.TUPLE,
657
658 (2, 0): pickle.EMPTY_TUPLE,
659 (2, 1): pickle.TUPLE1,
660 (2, 2): pickle.TUPLE2,
661 (2, 3): pickle.TUPLE3,
662 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000663
664 (3, 0): pickle.EMPTY_TUPLE,
665 (3, 1): pickle.TUPLE1,
666 (3, 2): pickle.TUPLE2,
667 (3, 3): pickle.TUPLE3,
668 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000669 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000670 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000671 b = (1,)
672 c = (1, 2)
673 d = (1, 2, 3)
674 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000675 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000676 for x in a, b, c, d, e:
677 s = self.dumps(x, proto)
678 y = self.loads(s)
679 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000680 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +0000681 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +0000682
Guido van Rossum7d97d312003-01-28 04:25:27 +0000683 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000684 # Map (proto, singleton) to expected opcode.
685 expected_opcode = {(0, None): pickle.NONE,
686 (1, None): pickle.NONE,
687 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000688 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000689
690 (0, True): pickle.INT,
691 (1, True): pickle.INT,
692 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000693 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000694
695 (0, False): pickle.INT,
696 (1, False): pickle.INT,
697 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000698 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000699 }
Tim Peters4190fb82003-02-02 16:09:05 +0000700 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000701 for x in None, False, True:
702 s = self.dumps(x, proto)
703 y = self.loads(s)
704 self.assert_(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +0000705 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +0000706 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +0000707
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000708 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000709 x = MyTuple([1, 2, 3])
710 x.foo = 42
711 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000712 for proto in protocols:
713 s = self.dumps(x, proto)
714 y = self.loads(s)
715 self.assertEqual(tuple(x), tuple(y))
716 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000717
718 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000719 x = MyList([1, 2, 3])
720 x.foo = 42
721 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000722 for proto in protocols:
723 s = self.dumps(x, proto)
724 y = self.loads(s)
725 self.assertEqual(list(x), list(y))
726 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000727
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000728 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +0000729 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000730 for C in myclasses:
731 B = C.__base__
732 x = C(C.sample)
733 x.foo = 42
734 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000735 y = self.loads(s)
736 detail = (proto, C, B, x, y, type(y))
737 self.assertEqual(B(x), B(y), detail)
738 self.assertEqual(x.__dict__, y.__dict__, detail)
739
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000740 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +0000741 # an object of that type. Check that the resulting pickle uses opcode
742 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +0000743
Tim Peters22e71712003-02-03 22:27:38 +0000744 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +0000745 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000746 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000747 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000748 x = MyList([1, 2, 3])
749 x.foo = 42
750 x.bar = "hello"
751
Tim Peters22e71712003-02-03 22:27:38 +0000752 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000753 s1 = self.dumps(x, 1)
Guido van Rossum39478e82007-08-27 17:23:59 +0000754 self.assert_(__name__.encode("utf-8") in s1)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000755 self.assert_(b"MyList" in s1)
Tim Peters3e667d52003-02-04 21:47:44 +0000756 self.assertEqual(opcode_in_pickle(opcode, s1), False)
757
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000758 y = self.loads(s1)
759 self.assertEqual(list(x), list(y))
760 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000761
Tim Peters22e71712003-02-03 22:27:38 +0000762 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000763 s2 = self.dumps(x, 2)
Guido van Rossum39478e82007-08-27 17:23:59 +0000764 self.assert_(__name__.encode("utf-8") not in s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000765 self.assert_(b"MyList" not in s2)
766 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +0000767
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000768 y = self.loads(s2)
769 self.assertEqual(list(x), list(y))
770 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000771
772 finally:
Tim Peters3e667d52003-02-04 21:47:44 +0000773 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +0000774
775 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000776 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
777 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000778
779 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000780 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
781 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
782 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000783
784 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000785 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
786 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
787 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
788
Tim Peters8d2613a2003-02-11 16:40:16 +0000789 def test_list_chunking(self):
790 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +0000791 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000792 for proto in protocols:
793 s = self.dumps(x, proto)
794 y = self.loads(s)
795 self.assertEqual(x, y)
796 num_appends = count_opcode(pickle.APPENDS, s)
797 self.assertEqual(num_appends, proto > 0)
798
799 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +0000800 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000801 for proto in protocols:
802 s = self.dumps(x, proto)
803 y = self.loads(s)
804 self.assertEqual(x, y)
805 num_appends = count_opcode(pickle.APPENDS, s)
806 if proto == 0:
807 self.assertEqual(num_appends, 0)
808 else:
809 self.failUnless(num_appends >= 2)
810
811 def test_dict_chunking(self):
812 n = 10 # too small to chunk
813 x = dict.fromkeys(range(n))
814 for proto in protocols:
815 s = self.dumps(x, proto)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000816 assert isinstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +0000817 y = self.loads(s)
818 self.assertEqual(x, y)
819 num_setitems = count_opcode(pickle.SETITEMS, s)
820 self.assertEqual(num_setitems, proto > 0)
821
822 n = 2500 # expect at least two chunks when proto > 0
823 x = dict.fromkeys(range(n))
824 for proto in protocols:
825 s = self.dumps(x, proto)
826 y = self.loads(s)
827 self.assertEqual(x, y)
828 num_setitems = count_opcode(pickle.SETITEMS, s)
829 if proto == 0:
830 self.assertEqual(num_setitems, 0)
831 else:
832 self.failUnless(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000833
Tim Peterse9ef2032003-02-13 18:42:00 +0000834 def test_simple_newobj(self):
835 x = object.__new__(SimpleNewObj) # avoid __init__
836 x.abc = 666
837 for proto in protocols:
838 s = self.dumps(x, proto)
839 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
840 y = self.loads(s) # will raise TypeError if __init__ called
841 self.assertEqual(y.abc, 666)
842 self.assertEqual(x.__dict__, y.__dict__)
843
Tim Peters42f08ac2003-02-11 22:43:24 +0000844 def test_newobj_list_slots(self):
845 x = SlotList([1, 2, 3])
846 x.foo = 42
847 x.bar = "hello"
848 s = self.dumps(x, 2)
849 y = self.loads(s)
850 self.assertEqual(list(x), list(y))
851 self.assertEqual(x.__dict__, y.__dict__)
852 self.assertEqual(x.foo, y.foo)
853 self.assertEqual(x.bar, y.bar)
854
Guido van Rossum2a30b212003-02-18 22:41:24 +0000855 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +0000856 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000857 x = REX_one()
858 self.assertEqual(x._reduce_called, 0)
859 s = self.dumps(x, proto)
860 self.assertEqual(x._reduce_called, 1)
861 y = self.loads(s)
862 self.assertEqual(y._reduce_called, 0)
863
864 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +0000865 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000866 x = REX_two()
867 self.assertEqual(x._proto, None)
868 s = self.dumps(x, proto)
869 self.assertEqual(x._proto, proto)
870 y = self.loads(s)
871 self.assertEqual(y._proto, None)
872
873 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +0000874 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000875 x = REX_three()
876 self.assertEqual(x._proto, None)
877 s = self.dumps(x, proto)
878 self.assertEqual(x._proto, proto)
879 y = self.loads(s)
880 self.assertEqual(y._proto, None)
881
Guido van Rossumd8faa362007-04-27 19:54:29 +0000882 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +0000883 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000884 x = REX_four()
885 self.assertEqual(x._proto, None)
886 s = self.dumps(x, proto)
887 self.assertEqual(x._proto, proto)
888 y = self.loads(s)
889 self.assertEqual(y._proto, proto)
890
891 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +0000892 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000893 x = REX_five()
894 self.assertEqual(x._reduce_called, 0)
895 s = self.dumps(x, proto)
896 self.assertEqual(x._reduce_called, 1)
897 y = self.loads(s)
898 self.assertEqual(y._reduce_called, 1)
899
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +0000900 def test_bad_getattr(self):
901 x = BadGetattr()
902 for proto in 0, 1:
903 self.assertRaises(RuntimeError, self.dumps, x, proto)
904 # protocol 2 don't raise a RuntimeError.
905 d = self.dumps(x, 2)
906 self.assertRaises(RuntimeError, self.loads, d)
907
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +0000908 def test_reduce_bad_iterator(self):
909 # Issue4176: crash when 4th and 5th items of __reduce__()
910 # are not iterators
911 class C(object):
912 def __reduce__(self):
913 # 4th item is not an iterator
914 return list, (), None, [], None
915 class D(object):
916 def __reduce__(self):
917 # 5th item is not an iterator
918 return dict, (), None, None, []
919
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +0000920 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +0000921 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +0000922 try:
923 self.dumps(C(), proto)
924 except (pickle.PickleError):
925 pass
926 try:
927 self.dumps(D(), proto)
928 except (pickle.PickleError):
929 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +0000930
Collin Winter771d8342009-04-16 03:18:06 +0000931 def test_many_puts_and_gets(self):
932 # Test that internal data structures correctly deal with lots of
933 # puts/gets.
934 keys = ("aaa" + str(i) for i in range(100))
935 large_dict = dict((k, [4, 5, 6]) for k in keys)
936 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
937
938 for proto in protocols:
939 dumped = self.dumps(obj, proto)
940 loaded = self.loads(dumped)
941 self.assertEqual(loaded, obj,
942 "Failed protocol %d: %r != %r"
943 % (proto, obj, loaded))
944
Antoine Pitroua9f48a02009-05-02 21:41:14 +0000945 def test_attribute_name_interning(self):
946 # Test that attribute names of pickled objects are interned when
947 # unpickling.
948 for proto in protocols:
949 x = C()
950 x.foo = 42
951 x.bar = "hello"
952 s = self.dumps(x, proto)
953 y = self.loads(s)
954 x_keys = sorted(x.__dict__)
955 y_keys = sorted(y.__dict__)
956 for x_key, y_key in zip(x_keys, y_keys):
957 self.assertIs(x_key, y_key)
958
Guido van Rossum2a30b212003-02-18 22:41:24 +0000959# Test classes for reduce_ex
960
961class REX_one(object):
962 _reduce_called = 0
963 def __reduce__(self):
964 self._reduce_called = 1
965 return REX_one, ()
966 # No __reduce_ex__ here, but inheriting it from object
967
968class REX_two(object):
969 _proto = None
970 def __reduce_ex__(self, proto):
971 self._proto = proto
972 return REX_two, ()
973 # No __reduce__ here, but inheriting it from object
974
975class REX_three(object):
976 _proto = None
977 def __reduce_ex__(self, proto):
978 self._proto = proto
979 return REX_two, ()
980 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +0000981 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +0000982
Guido van Rossumd8faa362007-04-27 19:54:29 +0000983class REX_four(object):
984 _proto = None
985 def __reduce_ex__(self, proto):
986 self._proto = proto
987 return object.__reduce_ex__(self, proto)
988 # Calling base class method should succeed
989
990class REX_five(object):
991 _reduce_called = 0
992 def __reduce__(self):
993 self._reduce_called = 1
994 return object.__reduce__(self)
995 # This one used to fail with infinite recursion
996
Guido van Rossum2a30b212003-02-18 22:41:24 +0000997# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +0000998
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000999class MyInt(int):
1000 sample = 1
1001
Guido van Rossume2a383d2007-01-15 16:59:06 +00001002class MyLong(int):
1003 sample = 1
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001004
1005class MyFloat(float):
1006 sample = 1.0
1007
1008class MyComplex(complex):
1009 sample = 1.0 + 0.0j
1010
1011class MyStr(str):
1012 sample = "hello"
1013
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001014class MyUnicode(str):
1015 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001016
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001017class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001018 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001019
1020class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001021 sample = [1, 2, 3]
1022
1023class MyDict(dict):
1024 sample = {"a": 1, "b": 2}
1025
1026myclasses = [MyInt, MyLong, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001027 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001028 MyStr, MyUnicode,
1029 MyTuple, MyList, MyDict]
1030
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001031
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001032class SlotList(MyList):
1033 __slots__ = ["foo"]
1034
Tim Peterse9ef2032003-02-13 18:42:00 +00001035class SimpleNewObj(object):
1036 def __init__(self, a, b, c):
1037 # raise an error, to make sure this isn't called
1038 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1039
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001040class BadGetattr:
1041 def __getattr__(self, key):
1042 self.foo
1043
Collin Winter771d8342009-04-16 03:18:06 +00001044
Jeremy Hylton66426532001-10-15 21:38:56 +00001045class AbstractPickleModuleTests(unittest.TestCase):
1046
1047 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001048 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001049 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001050 try:
1051 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001052 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001053 finally:
1054 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001055
1056 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001057 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001058 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001059 try:
1060 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001061 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001062 finally:
1063 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001064
Collin Winter771d8342009-04-16 03:18:06 +00001065 def test_load_from_and_dump_to_file(self):
1066 stream = io.BytesIO()
1067 data = [123, {}, 124]
1068 pickle.dump(data, stream)
1069 stream.seek(0)
1070 unpickled = pickle.load(stream)
1071 self.assertEqual(unpickled, data)
1072
Tim Petersc0c93702003-02-13 19:30:57 +00001073 def test_highest_protocol(self):
1074 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001075 self.assertEqual(pickle.HIGHEST_PROTOCOL, 3)
Tim Petersc0c93702003-02-13 19:30:57 +00001076
Martin v. Löwis544f1192004-07-27 05:22:33 +00001077 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001078 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001079 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001080 pickle.dump(123, f, -1)
1081 pickle.dump(123, file=f, protocol=-1)
1082 pickle.dumps(123, -1)
1083 pickle.dumps(123, protocol=-1)
1084 pickle.Pickler(f, -1)
1085 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001086
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001087 def test_bad_init(self):
1088 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001089 # Override initialization without calling __init__() of the superclass.
1090 class BadPickler(pickle.Pickler):
1091 def __init__(self): pass
1092
1093 class BadUnpickler(pickle.Unpickler):
1094 def __init__(self): pass
1095
1096 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1097 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1098
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001099 def test_bad_input(self):
1100 # Test issue4298
1101 s = bytes([0x58, 0, 0, 0, 0x54])
1102 self.assertRaises(EOFError, pickle.loads, s)
1103
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001104
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001105class AbstractPersistentPicklerTests(unittest.TestCase):
1106
1107 # This class defines persistent_id() and persistent_load()
1108 # functions that should be used by the pickler. All even integers
1109 # are pickled using persistent ids.
1110
1111 def persistent_id(self, object):
1112 if isinstance(object, int) and object % 2 == 0:
1113 self.id_count += 1
1114 return str(object)
1115 else:
1116 return None
1117
1118 def persistent_load(self, oid):
1119 self.load_count += 1
1120 object = int(oid)
1121 assert object % 2 == 0
1122 return object
1123
1124 def test_persistence(self):
1125 self.id_count = 0
1126 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001127 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001128 self.assertEqual(self.loads(self.dumps(L)), L)
1129 self.assertEqual(self.id_count, 5)
1130 self.assertEqual(self.load_count, 5)
1131
1132 def test_bin_persistence(self):
1133 self.id_count = 0
1134 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001135 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001136 self.assertEqual(self.loads(self.dumps(L, 1)), L)
1137 self.assertEqual(self.id_count, 5)
1138 self.assertEqual(self.load_count, 5)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001139
Collin Winter771d8342009-04-16 03:18:06 +00001140
1141class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1142
1143 pickler_class = None
1144 unpickler_class = None
1145
1146 def setUp(self):
1147 assert self.pickler_class
1148 assert self.unpickler_class
1149
1150 def test_clear_pickler_memo(self):
1151 # To test whether clear_memo() has any effect, we pickle an object,
1152 # then pickle it again without clearing the memo; the two serialized
1153 # forms should be different. If we clear_memo() and then pickle the
1154 # object again, the third serialized form should be identical to the
1155 # first one we obtained.
1156 data = ["abcdefg", "abcdefg", 44]
1157 f = io.BytesIO()
1158 pickler = self.pickler_class(f)
1159
1160 pickler.dump(data)
1161 first_pickled = f.getvalue()
1162
1163 # Reset StringIO object.
1164 f.seek(0)
1165 f.truncate()
1166
1167 pickler.dump(data)
1168 second_pickled = f.getvalue()
1169
1170 # Reset the Pickler and StringIO objects.
1171 pickler.clear_memo()
1172 f.seek(0)
1173 f.truncate()
1174
1175 pickler.dump(data)
1176 third_pickled = f.getvalue()
1177
1178 self.assertNotEqual(first_pickled, second_pickled)
1179 self.assertEqual(first_pickled, third_pickled)
1180
1181 def test_priming_pickler_memo(self):
1182 # Verify that we can set the Pickler's memo attribute.
1183 data = ["abcdefg", "abcdefg", 44]
1184 f = io.BytesIO()
1185 pickler = self.pickler_class(f)
1186
1187 pickler.dump(data)
1188 first_pickled = f.getvalue()
1189
1190 f = io.BytesIO()
1191 primed = self.pickler_class(f)
1192 primed.memo = pickler.memo
1193
1194 primed.dump(data)
1195 primed_pickled = f.getvalue()
1196
1197 self.assertNotEqual(first_pickled, primed_pickled)
1198
1199 def test_priming_unpickler_memo(self):
1200 # Verify that we can set the Unpickler's memo attribute.
1201 data = ["abcdefg", "abcdefg", 44]
1202 f = io.BytesIO()
1203 pickler = self.pickler_class(f)
1204
1205 pickler.dump(data)
1206 first_pickled = f.getvalue()
1207
1208 f = io.BytesIO()
1209 primed = self.pickler_class(f)
1210 primed.memo = pickler.memo
1211
1212 primed.dump(data)
1213 primed_pickled = f.getvalue()
1214
1215 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
1216 unpickled_data1 = unpickler.load()
1217
1218 self.assertEqual(unpickled_data1, data)
1219
1220 primed = self.unpickler_class(io.BytesIO(primed_pickled))
1221 primed.memo = unpickler.memo
1222 unpickled_data2 = primed.load()
1223
1224 primed.memo.clear()
1225
1226 self.assertEqual(unpickled_data2, data)
1227 self.assertTrue(unpickled_data2 is unpickled_data1)
1228
1229 def test_reusing_unpickler_objects(self):
1230 data1 = ["abcdefg", "abcdefg", 44]
1231 f = io.BytesIO()
1232 pickler = self.pickler_class(f)
1233 pickler.dump(data1)
1234 pickled1 = f.getvalue()
1235
1236 data2 = ["abcdefg", 44, 44]
1237 f = io.BytesIO()
1238 pickler = self.pickler_class(f)
1239 pickler.dump(data2)
1240 pickled2 = f.getvalue()
1241
1242 f = io.BytesIO()
1243 f.write(pickled1)
1244 f.seek(0)
1245 unpickler = self.unpickler_class(f)
1246 self.assertEqual(unpickler.load(), data1)
1247
1248 f.seek(0)
1249 f.truncate()
1250 f.write(pickled2)
1251 f.seek(0)
1252 self.assertEqual(unpickler.load(), data2)
1253
1254
Guido van Rossum98297ee2007-11-06 21:34:58 +00001255if __name__ == "__main__":
1256 # Print some stuff that can be used to rewrite DATA{0,1,2}
1257 from pickletools import dis
1258 x = create_data()
1259 for i in range(3):
1260 p = pickle.dumps(x, i)
1261 print("DATA{0} = (".format(i))
1262 for j in range(0, len(p), 20):
1263 b = bytes(p[j:j+20])
1264 print(" {0!r}".format(b))
1265 print(")")
1266 print()
1267 print("# Disassembly of DATA{0}".format(i))
1268 print("DATA{0}_DIS = \"\"\"\\".format(i))
1269 dis(p)
1270 print("\"\"\"")
1271 print()