blob: b948c55407356fde5d213af47fb7f7059ff63492 [file] [log] [blame]
Serhiy Storchakabfe18242015-03-31 13:12:37 +03001import collections
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002import copyreg
Serhiy Storchakabfe18242015-03-31 13:12:37 +03003import dbm
Collin Winter771d8342009-04-16 03:18:06 +00004import io
Serhiy Storchakabfe18242015-03-31 13:12:37 +03005import functools
Tim Peters4190fb82003-02-02 16:09:05 +00006import pickle
Tim Peters31f119e2003-02-03 16:20:13 +00007import pickletools
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08008import struct
Antoine Pitrou82be19f2011-08-29 23:09:33 +02009import sys
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +010010import unittest
Antoine Pitrou16c4ce12011-03-11 21:30:43 +010011import weakref
Antoine Pitroud9dfaa92009-06-04 20:32:06 +000012from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +000013
Serhiy Storchaka7279bef2015-11-29 13:12:10 +020014from test import support
Antoine Pitrou82be19f2011-08-29 23:09:33 +020015from test.support import (
Serhiy Storchaka7279bef2015-11-29 13:12:10 +020016 TestFailed, TESTFN, run_with_locale, no_tracing,
Antoine Pitrou94190bb2011-10-04 10:22:36 +020017 _2G, _4G, bigmemtest,
Antoine Pitrou82be19f2011-08-29 23:09:33 +020018 )
Tim Peterse089c682001-04-10 03:41:41 +000019
Guido van Rossum98297ee2007-11-06 21:34:58 +000020from pickle import bytes_types
21
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030022requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
23 "test is only meaningful on 32-bit builds")
24
Tim Petersee1a53c2003-02-02 02:57:53 +000025# Tests that try a number of pickle protocols should have a
26# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000027# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000028protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000029
Tim Peters22e71712003-02-03 22:27:38 +000030
31# Return True if opcode code appears in the pickle, else False.
32def opcode_in_pickle(code, pickle):
33 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000034 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000035 return True
36 return False
37
Tim Peters8d2613a2003-02-11 16:40:16 +000038# Return the number of times opcode code appears in pickle.
39def count_opcode(code, pickle):
40 n = 0
41 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000042 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000043 n += 1
44 return n
45
Antoine Pitrou04248a82010-10-12 20:51:21 +000046
47class UnseekableIO(io.BytesIO):
48 def peek(self, *args):
49 raise NotImplementedError
50
51 def seekable(self):
52 return False
53
54 def seek(self, *args):
55 raise io.UnsupportedOperation
56
57 def tell(self):
58 raise io.UnsupportedOperation
59
60
Tim Peters3e667d52003-02-04 21:47:44 +000061# We can't very well test the extension registry without putting known stuff
62# in it, but we have to be careful to restore its original state. Code
63# should do this:
64#
65# e = ExtensionSaver(extension_code)
66# try:
67# fiddle w/ the extension registry's stuff for extension_code
68# finally:
69# e.restore()
70
71class ExtensionSaver:
72 # Remember current registration for code (if any), and remove it (if
73 # there is one).
74 def __init__(self, code):
75 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000076 if code in copyreg._inverted_registry:
77 self.pair = copyreg._inverted_registry[code]
78 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000079 else:
80 self.pair = None
81
82 # Restore previous registration for code.
83 def restore(self):
84 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000085 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000086 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000087 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000088 pair = self.pair
89 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000090 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000091
Jeremy Hylton66426532001-10-15 21:38:56 +000092class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000093 def __eq__(self, other):
94 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000095
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000096class D(C):
97 def __init__(self, arg):
98 pass
99
100class E(C):
101 def __getinitargs__(self):
102 return ()
103
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100104class H(object):
105 pass
106
Serhiy Storchaka608c2132015-11-07 11:16:10 +0200107# Hashable mutable key
108class K(object):
109 def __init__(self, value):
110 self.value = value
111
112 def __reduce__(self):
113 # Shouldn't support the recursion itself
114 return K, (self.value,)
115
Jeremy Hylton66426532001-10-15 21:38:56 +0000116import __main__
117__main__.C = C
118C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000119__main__.D = D
120D.__module__ = "__main__"
121__main__.E = E
122E.__module__ = "__main__"
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100123__main__.H = H
124H.__module__ = "__main__"
Serhiy Storchaka608c2132015-11-07 11:16:10 +0200125__main__.K = K
126K.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000127
128class myint(int):
129 def __init__(self, x):
130 self.str = str(x)
131
132class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000133
Jeremy Hylton66426532001-10-15 21:38:56 +0000134 def __init__(self, a, b):
135 self.a = a
136 self.b = b
137
138 def __getinitargs__(self):
139 return self.a, self.b
140
Guido van Rossum04a86612001-12-19 16:58:54 +0000141class metaclass(type):
142 pass
143
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000144class use_metaclass(object, metaclass=metaclass):
145 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000146
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200147class pickling_metaclass(type):
148 def __eq__(self, other):
149 return (type(self) == type(other) and
150 self.reduce_args == other.reduce_args)
151
152 def __reduce__(self):
153 return (create_dynamic_class, self.reduce_args)
154
155def create_dynamic_class(name, bases):
156 result = pickling_metaclass(name, bases, dict())
157 result.reduce_args = (name, bases)
158 return result
159
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300160# DATA0 .. DATA4 are the pickles we expect under the various protocols, for
Tim Peters70b02d72003-02-02 17:26:40 +0000161# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000162
Guido van Rossum98297ee2007-11-06 21:34:58 +0000163DATA0 = (
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200164 b'(lp0\nL0L\naL1L\naF2.0\n'
165 b'ac__builtin__\ncomple'
166 b'x\np1\n(F3.0\nF0.0\ntp2\n'
167 b'Rp3\naL1L\naL-1L\naL255'
168 b'L\naL-255L\naL-256L\naL'
169 b'65535L\naL-65535L\naL-'
170 b'65536L\naL2147483647L'
171 b'\naL-2147483647L\naL-2'
172 b'147483648L\na(Vabc\np4'
173 b'\ng4\nccopy_reg\n_recon'
174 b'structor\np5\n(c__main'
175 b'__\nC\np6\nc__builtin__'
176 b'\nobject\np7\nNtp8\nRp9\n'
177 b'(dp10\nVfoo\np11\nL1L\ns'
178 b'Vbar\np12\nL2L\nsbg9\ntp'
179 b'13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000180)
Tim Peterse9358162001-01-22 22:05:20 +0000181
Guido van Rossum98297ee2007-11-06 21:34:58 +0000182# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000183DATA0_DIS = """\
184 0: ( MARK
185 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000186 2: p PUT 0
187 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000188 9: a APPEND
189 10: L LONG 1
190 14: a APPEND
191 15: F FLOAT 2.0
192 20: a APPEND
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200193 21: c GLOBAL '__builtin__ complex'
194 42: p PUT 1
195 45: ( MARK
196 46: F FLOAT 3.0
197 51: F FLOAT 0.0
198 56: t TUPLE (MARK at 45)
199 57: p PUT 2
200 60: R REDUCE
201 61: p PUT 3
202 64: a APPEND
203 65: L LONG 1
204 69: a APPEND
205 70: L LONG -1
206 75: a APPEND
207 76: L LONG 255
208 82: a APPEND
209 83: L LONG -255
210 90: a APPEND
211 91: L LONG -256
212 98: a APPEND
213 99: L LONG 65535
214 107: a APPEND
215 108: L LONG -65535
216 117: a APPEND
217 118: L LONG -65536
218 127: a APPEND
219 128: L LONG 2147483647
220 141: a APPEND
221 142: L LONG -2147483647
222 156: a APPEND
223 157: L LONG -2147483648
224 171: a APPEND
225 172: ( MARK
226 173: V UNICODE 'abc'
227 178: p PUT 4
228 181: g GET 4
229 184: c GLOBAL 'copy_reg _reconstructor'
230 209: p PUT 5
231 212: ( MARK
232 213: c GLOBAL '__main__ C'
233 225: p PUT 6
234 228: c GLOBAL '__builtin__ object'
235 248: p PUT 7
236 251: N NONE
237 252: t TUPLE (MARK at 212)
238 253: p PUT 8
239 256: R REDUCE
240 257: p PUT 9
241 260: ( MARK
242 261: d DICT (MARK at 260)
243 262: p PUT 10
244 266: V UNICODE 'foo'
245 271: p PUT 11
246 275: L LONG 1
247 279: s SETITEM
248 280: V UNICODE 'bar'
249 285: p PUT 12
250 289: L LONG 2
251 293: s SETITEM
252 294: b BUILD
253 295: g GET 9
254 298: t TUPLE (MARK at 172)
255 299: p PUT 13
256 303: a APPEND
257 304: g GET 13
258 308: a APPEND
259 309: L LONG 5
260 313: a APPEND
261 314: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000262highest protocol among opcodes = 0
263"""
264
Guido van Rossum98297ee2007-11-06 21:34:58 +0000265DATA1 = (
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200266 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c__'
267 b'builtin__\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000268 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
269 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
270 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
271 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200272 b'cq\x04h\x04ccopy_reg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000273 b'nstructor\nq\x05(c__main'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200274 b'__\nC\nq\x06c__builtin__\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000275 b'object\nq\x07Ntq\x08Rq\t}q\n('
276 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
277 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
278)
Tim Peters70b02d72003-02-02 17:26:40 +0000279
Guido van Rossum98297ee2007-11-06 21:34:58 +0000280# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000281DATA1_DIS = """\
282 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000283 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000284 3: ( MARK
285 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000286 6: K BININT1 1
287 8: G BINFLOAT 2.0
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200288 17: c GLOBAL '__builtin__ complex'
289 38: q BINPUT 1
290 40: ( MARK
291 41: G BINFLOAT 3.0
292 50: G BINFLOAT 0.0
293 59: t TUPLE (MARK at 40)
294 60: q BINPUT 2
295 62: R REDUCE
296 63: q BINPUT 3
297 65: K BININT1 1
298 67: J BININT -1
299 72: K BININT1 255
300 74: J BININT -255
301 79: J BININT -256
302 84: M BININT2 65535
303 87: J BININT -65535
304 92: J BININT -65536
305 97: J BININT 2147483647
306 102: J BININT -2147483647
307 107: J BININT -2147483648
308 112: ( MARK
309 113: X BINUNICODE 'abc'
310 121: q BINPUT 4
311 123: h BINGET 4
312 125: c GLOBAL 'copy_reg _reconstructor'
313 150: q BINPUT 5
314 152: ( MARK
315 153: c GLOBAL '__main__ C'
316 165: q BINPUT 6
317 167: c GLOBAL '__builtin__ object'
318 187: q BINPUT 7
319 189: N NONE
320 190: t TUPLE (MARK at 152)
321 191: q BINPUT 8
322 193: R REDUCE
323 194: q BINPUT 9
324 196: } EMPTY_DICT
325 197: q BINPUT 10
326 199: ( MARK
327 200: X BINUNICODE 'foo'
328 208: q BINPUT 11
329 210: K BININT1 1
330 212: X BINUNICODE 'bar'
331 220: q BINPUT 12
332 222: K BININT1 2
333 224: u SETITEMS (MARK at 199)
334 225: b BUILD
335 226: h BINGET 9
336 228: t TUPLE (MARK at 112)
337 229: q BINPUT 13
338 231: h BINGET 13
339 233: K BININT1 5
340 235: e APPENDS (MARK at 3)
341 236: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000342highest protocol among opcodes = 1
343"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000344
Guido van Rossum98297ee2007-11-06 21:34:58 +0000345DATA2 = (
346 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200347 b'__builtin__\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000348 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
349 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
350 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
351 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
352 b'bcq\x04h\x04c__main__\nC\nq\x05'
353 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
354 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
355 b'\nK\x05e.'
356)
Tim Petersfc273752003-03-02 04:54:24 +0000357
Guido van Rossum98297ee2007-11-06 21:34:58 +0000358# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000359DATA2_DIS = """\
360 0: \x80 PROTO 2
361 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000362 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000363 5: ( MARK
364 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000365 8: K BININT1 1
366 10: G BINFLOAT 2.0
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200367 19: c GLOBAL '__builtin__ complex'
368 40: q BINPUT 1
369 42: G BINFLOAT 3.0
370 51: G BINFLOAT 0.0
371 60: \x86 TUPLE2
372 61: q BINPUT 2
373 63: R REDUCE
374 64: q BINPUT 3
375 66: K BININT1 1
376 68: J BININT -1
377 73: K BININT1 255
378 75: J BININT -255
379 80: J BININT -256
380 85: M BININT2 65535
381 88: J BININT -65535
382 93: J BININT -65536
383 98: J BININT 2147483647
384 103: J BININT -2147483647
385 108: J BININT -2147483648
386 113: ( MARK
387 114: X BINUNICODE 'abc'
388 122: q BINPUT 4
389 124: h BINGET 4
390 126: c GLOBAL '__main__ C'
391 138: q BINPUT 5
392 140: ) EMPTY_TUPLE
393 141: \x81 NEWOBJ
394 142: q BINPUT 6
395 144: } EMPTY_DICT
396 145: q BINPUT 7
397 147: ( MARK
398 148: X BINUNICODE 'foo'
399 156: q BINPUT 8
400 158: K BININT1 1
401 160: X BINUNICODE 'bar'
402 168: q BINPUT 9
403 170: K BININT1 2
404 172: u SETITEMS (MARK at 147)
405 173: b BUILD
406 174: h BINGET 6
407 176: t TUPLE (MARK at 113)
408 177: q BINPUT 10
409 179: h BINGET 10
410 181: K BININT1 5
411 183: e APPENDS (MARK at 5)
412 184: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000413highest protocol among opcodes = 2
414"""
415
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300416DATA3 = (
417 b'\x80\x03]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
418 b'builtins\ncomplex\nq\x01G'
419 b'@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00\x86q\x02'
420 b'Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff'
421 b'\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7f'
422 b'J\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00abcq'
423 b'\x04h\x04c__main__\nC\nq\x05)\x81q'
424 b'\x06}q\x07(X\x03\x00\x00\x00barq\x08K\x02X\x03\x00'
425 b'\x00\x00fooq\tK\x01ubh\x06tq\nh\nK\x05'
426 b'e.'
427)
428
429# Disassembly of DATA3
430DATA3_DIS = """\
431 0: \x80 PROTO 3
432 2: ] EMPTY_LIST
433 3: q BINPUT 0
434 5: ( MARK
435 6: K BININT1 0
436 8: K BININT1 1
437 10: G BINFLOAT 2.0
438 19: c GLOBAL 'builtins complex'
439 37: q BINPUT 1
440 39: G BINFLOAT 3.0
441 48: G BINFLOAT 0.0
442 57: \x86 TUPLE2
443 58: q BINPUT 2
444 60: R REDUCE
445 61: q BINPUT 3
446 63: K BININT1 1
447 65: J BININT -1
448 70: K BININT1 255
449 72: J BININT -255
450 77: J BININT -256
451 82: M BININT2 65535
452 85: J BININT -65535
453 90: J BININT -65536
454 95: J BININT 2147483647
455 100: J BININT -2147483647
456 105: J BININT -2147483648
457 110: ( MARK
458 111: X BINUNICODE 'abc'
459 119: q BINPUT 4
460 121: h BINGET 4
461 123: c GLOBAL '__main__ C'
462 135: q BINPUT 5
463 137: ) EMPTY_TUPLE
464 138: \x81 NEWOBJ
465 139: q BINPUT 6
466 141: } EMPTY_DICT
467 142: q BINPUT 7
468 144: ( MARK
469 145: X BINUNICODE 'bar'
470 153: q BINPUT 8
471 155: K BININT1 2
472 157: X BINUNICODE 'foo'
473 165: q BINPUT 9
474 167: K BININT1 1
475 169: u SETITEMS (MARK at 144)
476 170: b BUILD
477 171: h BINGET 6
478 173: t TUPLE (MARK at 110)
479 174: q BINPUT 10
480 176: h BINGET 10
481 178: K BININT1 5
482 180: e APPENDS (MARK at 5)
483 181: . STOP
484highest protocol among opcodes = 2
485"""
486
487DATA4 = (
488 b'\x80\x04\x95\xa8\x00\x00\x00\x00\x00\x00\x00]\x94(K\x00K\x01G@'
489 b'\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x07'
490 b'complex\x94\x93\x94G@\x08\x00\x00\x00\x00\x00\x00G'
491 b'\x00\x00\x00\x00\x00\x00\x00\x00\x86\x94R\x94K\x01J\xff\xff\xff\xffK'
492 b'\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ'
493 b'\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80('
494 b'\x8c\x03abc\x94h\x06\x8c\x08__main__\x94\x8c'
495 b'\x01C\x94\x93\x94)\x81\x94}\x94(\x8c\x03bar\x94K\x02\x8c'
496 b'\x03foo\x94K\x01ubh\nt\x94h\x0eK\x05e.'
497)
498
499# Disassembly of DATA4
500DATA4_DIS = """\
501 0: \x80 PROTO 4
502 2: \x95 FRAME 168
503 11: ] EMPTY_LIST
504 12: \x94 MEMOIZE
505 13: ( MARK
506 14: K BININT1 0
507 16: K BININT1 1
508 18: G BINFLOAT 2.0
509 27: \x8c SHORT_BINUNICODE 'builtins'
510 37: \x94 MEMOIZE
511 38: \x8c SHORT_BINUNICODE 'complex'
512 47: \x94 MEMOIZE
513 48: \x93 STACK_GLOBAL
514 49: \x94 MEMOIZE
515 50: G BINFLOAT 3.0
516 59: G BINFLOAT 0.0
517 68: \x86 TUPLE2
518 69: \x94 MEMOIZE
519 70: R REDUCE
520 71: \x94 MEMOIZE
521 72: K BININT1 1
522 74: J BININT -1
523 79: K BININT1 255
524 81: J BININT -255
525 86: J BININT -256
526 91: M BININT2 65535
527 94: J BININT -65535
528 99: J BININT -65536
529 104: J BININT 2147483647
530 109: J BININT -2147483647
531 114: J BININT -2147483648
532 119: ( MARK
533 120: \x8c SHORT_BINUNICODE 'abc'
534 125: \x94 MEMOIZE
535 126: h BINGET 6
536 128: \x8c SHORT_BINUNICODE '__main__'
537 138: \x94 MEMOIZE
538 139: \x8c SHORT_BINUNICODE 'C'
539 142: \x94 MEMOIZE
540 143: \x93 STACK_GLOBAL
541 144: \x94 MEMOIZE
542 145: ) EMPTY_TUPLE
543 146: \x81 NEWOBJ
544 147: \x94 MEMOIZE
545 148: } EMPTY_DICT
546 149: \x94 MEMOIZE
547 150: ( MARK
548 151: \x8c SHORT_BINUNICODE 'bar'
549 156: \x94 MEMOIZE
550 157: K BININT1 2
551 159: \x8c SHORT_BINUNICODE 'foo'
552 164: \x94 MEMOIZE
553 165: K BININT1 1
554 167: u SETITEMS (MARK at 150)
555 168: b BUILD
556 169: h BINGET 10
557 171: t TUPLE (MARK at 119)
558 172: \x94 MEMOIZE
559 173: h BINGET 14
560 175: K BININT1 5
561 177: e APPENDS (MARK at 13)
562 178: . STOP
563highest protocol among opcodes = 4
564"""
565
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000566# set([1,2]) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300567DATA_SET = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000568
569# xrange(5) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300570DATA_XRANGE = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000571
572# a SimpleCookie() object pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300573DATA_COOKIE = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
574 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
575 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
576 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
577 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
578 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000579
580# set([3]) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300581DATA_SET2 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000582
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100583python2_exceptions_without_args = (
584 ArithmeticError,
585 AssertionError,
586 AttributeError,
587 BaseException,
588 BufferError,
589 BytesWarning,
590 DeprecationWarning,
591 EOFError,
592 EnvironmentError,
593 Exception,
594 FloatingPointError,
595 FutureWarning,
596 GeneratorExit,
597 IOError,
598 ImportError,
599 ImportWarning,
600 IndentationError,
601 IndexError,
602 KeyError,
603 KeyboardInterrupt,
604 LookupError,
605 MemoryError,
606 NameError,
607 NotImplementedError,
608 OSError,
609 OverflowError,
610 PendingDeprecationWarning,
611 ReferenceError,
612 RuntimeError,
613 RuntimeWarning,
614 # StandardError is gone in Python 3, we map it to Exception
615 StopIteration,
616 SyntaxError,
617 SyntaxWarning,
618 SystemError,
619 SystemExit,
620 TabError,
621 TypeError,
622 UnboundLocalError,
623 UnicodeError,
624 UnicodeWarning,
625 UserWarning,
626 ValueError,
627 Warning,
628 ZeroDivisionError,
629)
630
631exception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.'
632
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100633# UnicodeEncodeError object pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300634DATA_UEERR = (b'\x80\x02cexceptions\nUnicodeEncodeError\n'
635 b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01'
636 b'U\x03badq\x03tq\x04Rq\x05.')
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100637
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000638
Jeremy Hylton66426532001-10-15 21:38:56 +0000639def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000640 c = C()
641 c.foo = 1
642 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000643 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000644 # Append some integer test cases at cPickle.c's internal size
645 # cutoffs.
646 uint1max = 0xff
647 uint2max = 0xffff
648 int4max = 0x7fffffff
649 x.extend([1, -1,
650 uint1max, -uint1max, -uint1max-1,
651 uint2max, -uint2max, -uint2max-1,
652 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000653 y = ('abc', 'abc', c, c)
654 x.append(y)
655 x.append(y)
656 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000657 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000658
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100659
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300660class AbstractUnpickleTests(unittest.TestCase):
661 # Subclass must define self.loads.
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +0100662
Jeremy Hylton66426532001-10-15 21:38:56 +0000663 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000664
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100665 def assert_is_copy(self, obj, objcopy, msg=None):
666 """Utility method to verify if two objects are copies of each others.
667 """
668 if msg is None:
669 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
670 self.assertEqual(obj, objcopy, msg=msg)
671 self.assertIs(type(obj), type(objcopy), msg=msg)
672 if hasattr(obj, '__dict__'):
673 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
674 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
675 if hasattr(obj, '__slots__'):
676 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
677 for slot in obj.__slots__:
678 self.assertEqual(
679 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
680 self.assertEqual(getattr(obj, slot, None),
681 getattr(objcopy, slot, None), msg=msg)
682
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200683 def check_unpickling_error(self, errors, data):
684 with self.subTest(data=data), \
685 self.assertRaises(errors):
686 try:
687 self.loads(data)
688 except BaseException as exc:
689 if support.verbose > 1:
690 print('%-32r - %s: %s' %
691 (data, exc.__class__.__name__, exc))
692 raise
693
Guido van Rossum98297ee2007-11-06 21:34:58 +0000694 def test_load_from_data0(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100695 self.assert_is_copy(self._testdata, self.loads(DATA0))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000696
697 def test_load_from_data1(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100698 self.assert_is_copy(self._testdata, self.loads(DATA1))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000699
700 def test_load_from_data2(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100701 self.assert_is_copy(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000702
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300703 def test_load_from_data3(self):
704 self.assert_is_copy(self._testdata, self.loads(DATA3))
705
706 def test_load_from_data4(self):
707 self.assert_is_copy(self._testdata, self.loads(DATA4))
708
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000709 def test_load_classic_instance(self):
710 # See issue5180. Test loading 2.x pickles that
711 # contain an instance of old style class.
712 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
713 xname = X.__name__.encode('ascii')
714 # Protocol 0 (text mode pickle):
715 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200716 0: ( MARK
717 1: i INST '__main__ X' (MARK at 0)
718 13: p PUT 0
719 16: ( MARK
720 17: d DICT (MARK at 16)
721 18: p PUT 1
722 21: b BUILD
723 22: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000724 """
725 pickle0 = (b"(i__main__\n"
726 b"X\n"
727 b"p0\n"
728 b"(dp1\nb.").replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100729 self.assert_is_copy(X(*args), self.loads(pickle0))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000730
731 # Protocol 1 (binary mode pickle)
732 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200733 0: ( MARK
734 1: c GLOBAL '__main__ X'
735 13: q BINPUT 0
736 15: o OBJ (MARK at 0)
737 16: q BINPUT 1
738 18: } EMPTY_DICT
739 19: q BINPUT 2
740 21: b BUILD
741 22: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000742 """
743 pickle1 = (b'(c__main__\n'
744 b'X\n'
745 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100746 self.assert_is_copy(X(*args), self.loads(pickle1))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000747
748 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
749 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200750 0: \x80 PROTO 2
751 2: ( MARK
752 3: c GLOBAL '__main__ X'
753 15: q BINPUT 0
754 17: o OBJ (MARK at 2)
755 18: q BINPUT 1
756 20: } EMPTY_DICT
757 21: q BINPUT 2
758 23: b BUILD
759 24: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000760 """
761 pickle2 = (b'\x80\x02(c__main__\n'
762 b'X\n'
763 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100764 self.assert_is_copy(X(*args), self.loads(pickle2))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000765
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300766 def test_maxint64(self):
767 maxint64 = (1 << 63) - 1
768 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
769 got = self.loads(data)
770 self.assert_is_copy(maxint64, got)
771
772 # Try too with a bogus literal.
773 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200774 self.check_unpickling_error(ValueError, data)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300775
776 def test_unpickle_from_2x(self):
777 # Unpickle non-trivial data from Python 2.x.
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300778 loaded = self.loads(DATA_SET)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300779 self.assertEqual(loaded, set([1, 2]))
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300780 loaded = self.loads(DATA_XRANGE)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300781 self.assertEqual(type(loaded), type(range(0)))
782 self.assertEqual(list(loaded), list(range(5)))
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300783 loaded = self.loads(DATA_COOKIE)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300784 self.assertEqual(type(loaded), SimpleCookie)
785 self.assertEqual(list(loaded.keys()), ["key"])
786 self.assertEqual(loaded["key"].value, "value")
787
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300788 # Exception objects without arguments pickled from 2.x with protocol 2
789 for exc in python2_exceptions_without_args:
790 data = exception_pickle.replace(b'?', exc.__name__.encode("ascii"))
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300791 loaded = self.loads(data)
792 self.assertIs(type(loaded), exc)
793
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300794 # StandardError is mapped to Exception, test that separately
795 loaded = self.loads(exception_pickle.replace(b'?', b'StandardError'))
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300796 self.assertIs(type(loaded), Exception)
797
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300798 loaded = self.loads(DATA_UEERR)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300799 self.assertIs(type(loaded), UnicodeEncodeError)
800 self.assertEqual(loaded.object, "foo")
801 self.assertEqual(loaded.encoding, "ascii")
802 self.assertEqual(loaded.start, 0)
803 self.assertEqual(loaded.end, 1)
804 self.assertEqual(loaded.reason, "bad")
805
806 def test_load_python2_str_as_bytes(self):
807 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
808 self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
809 encoding="bytes"), b'a\x00\xa0')
810 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
811 self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
812 encoding="bytes"), b'a\x00\xa0')
813 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
814 self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
815 encoding="bytes"), b'a\x00\xa0')
816
817 def test_load_python2_unicode_as_str(self):
818 # From Python 2: pickle.dumps(u'π', protocol=0)
819 self.assertEqual(self.loads(b'V\\u03c0\n.',
820 encoding='bytes'), 'π')
821 # From Python 2: pickle.dumps(u'π', protocol=1)
822 self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
823 encoding="bytes"), 'π')
824 # From Python 2: pickle.dumps(u'π', protocol=2)
825 self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
826 encoding="bytes"), 'π')
827
828 def test_load_long_python2_str_as_bytes(self):
829 # From Python 2: pickle.dumps('x' * 300, protocol=1)
830 self.assertEqual(self.loads(pickle.BINSTRING +
831 struct.pack("<I", 300) +
832 b'x' * 300 + pickle.STOP,
833 encoding='bytes'), b'x' * 300)
834
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300835 def test_constants(self):
836 self.assertIsNone(self.loads(b'N.'))
837 self.assertIs(self.loads(b'\x88.'), True)
838 self.assertIs(self.loads(b'\x89.'), False)
839 self.assertIs(self.loads(b'I01\n.'), True)
840 self.assertIs(self.loads(b'I00\n.'), False)
841
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300842 def test_empty_bytestring(self):
843 # issue 11286
844 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
845 self.assertEqual(empty, '')
846
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300847 def test_short_binbytes(self):
848 dumped = b'\x80\x03C\x04\xe2\x82\xac\x00.'
849 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
850
851 def test_binbytes(self):
852 dumped = b'\x80\x03B\x04\x00\x00\x00\xe2\x82\xac\x00.'
853 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
854
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300855 @requires_32b
856 def test_negative_32b_binbytes(self):
857 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
858 dumped = b'\x80\x03B\xff\xff\xff\xffxyzq\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200859 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
860 dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300861
862 @requires_32b
863 def test_negative_32b_binunicode(self):
864 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
865 dumped = b'\x80\x03X\xff\xff\xff\xffxyzq\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200866 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
867 dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300868
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300869 def test_short_binunicode(self):
870 dumped = b'\x80\x04\x8c\x04\xe2\x82\xac\x00.'
871 self.assertEqual(self.loads(dumped), '\u20ac\x00')
872
873 def test_misc_get(self):
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200874 self.check_unpickling_error(KeyError, b'g0\np0')
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300875 self.assert_is_copy([(100,), (100,)],
876 self.loads(b'((Kdtp0\nh\x00l.))'))
877
Serhiy Storchakae0606192015-09-29 22:10:07 +0300878 def test_binbytes8(self):
879 dumped = b'\x80\x04\x8e\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
880 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
881
882 def test_binunicode8(self):
883 dumped = b'\x80\x04\x8d\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
884 self.assertEqual(self.loads(dumped), '\u20ac\x00')
885
886 @requires_32b
887 def test_large_32b_binbytes8(self):
888 dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200889 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
890 dumped)
Serhiy Storchakae0606192015-09-29 22:10:07 +0300891
892 @requires_32b
893 def test_large_32b_binunicode8(self):
894 dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200895 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
896 dumped)
Serhiy Storchakae0606192015-09-29 22:10:07 +0300897
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300898 def test_get(self):
899 pickled = b'((lp100000\ng100000\nt.'
900 unpickled = self.loads(pickled)
901 self.assertEqual(unpickled, ([],)*2)
902 self.assertIs(unpickled[0], unpickled[1])
903
904 def test_binget(self):
905 pickled = b'(]q\xffh\xfft.'
906 unpickled = self.loads(pickled)
907 self.assertEqual(unpickled, ([],)*2)
908 self.assertIs(unpickled[0], unpickled[1])
909
910 def test_long_binget(self):
911 pickled = b'(]r\x00\x00\x01\x00j\x00\x00\x01\x00t.'
912 unpickled = self.loads(pickled)
913 self.assertEqual(unpickled, ([],)*2)
914 self.assertIs(unpickled[0], unpickled[1])
915
916 def test_dup(self):
917 pickled = b'((l2t.'
918 unpickled = self.loads(pickled)
919 self.assertEqual(unpickled, ([],)*2)
920 self.assertIs(unpickled[0], unpickled[1])
921
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300922 def test_negative_put(self):
923 # Issue #12847
924 dumped = b'Va\np-1\n.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200925 self.check_unpickling_error(ValueError, dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300926
927 @requires_32b
928 def test_negative_32b_binput(self):
929 # Issue #12847
930 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200931 self.check_unpickling_error(ValueError, dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300932
933 def test_badly_escaped_string(self):
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200934 self.check_unpickling_error(ValueError, b"S'\\'\n.")
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300935
936 def test_badly_quoted_string(self):
937 # Issue #17710
938 badpickles = [b"S'\n.",
939 b'S"\n.',
940 b'S\' \n.',
941 b'S" \n.',
942 b'S\'"\n.',
943 b'S"\'\n.',
944 b"S' ' \n.",
945 b'S" " \n.',
946 b"S ''\n.",
947 b'S ""\n.',
948 b'S \n.',
949 b'S\n.',
950 b'S.']
951 for p in badpickles:
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200952 self.check_unpickling_error(pickle.UnpicklingError, p)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300953
954 def test_correctly_quoted_string(self):
955 goodpickles = [(b"S''\n.", ''),
956 (b'S""\n.', ''),
957 (b'S"\\n"\n.', '\n'),
958 (b"S'\\n'\n.", '\n')]
959 for p, expected in goodpickles:
960 self.assertEqual(self.loads(p), expected)
961
962 def test_frame_readline(self):
963 pickled = b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00I42\n.'
964 # 0: \x80 PROTO 4
965 # 2: \x95 FRAME 5
966 # 11: I INT 42
967 # 15: . STOP
968 self.assertEqual(self.loads(pickled), 42)
969
970 def test_compat_unpickle(self):
971 # xrange(1, 7)
972 pickled = b'\x80\x02c__builtin__\nxrange\nK\x01K\x07K\x01\x87R.'
973 unpickled = self.loads(pickled)
974 self.assertIs(type(unpickled), range)
975 self.assertEqual(unpickled, range(1, 7))
976 self.assertEqual(list(unpickled), [1, 2, 3, 4, 5, 6])
977 # reduce
978 pickled = b'\x80\x02c__builtin__\nreduce\n.'
979 self.assertIs(self.loads(pickled), functools.reduce)
980 # whichdb.whichdb
981 pickled = b'\x80\x02cwhichdb\nwhichdb\n.'
982 self.assertIs(self.loads(pickled), dbm.whichdb)
983 # Exception(), StandardError()
984 for name in (b'Exception', b'StandardError'):
985 pickled = (b'\x80\x02cexceptions\n' + name + b'\nU\x03ugh\x85R.')
986 unpickled = self.loads(pickled)
987 self.assertIs(type(unpickled), Exception)
988 self.assertEqual(str(unpickled), 'ugh')
989 # UserDict.UserDict({1: 2}), UserDict.IterableUserDict({1: 2})
990 for name in (b'UserDict', b'IterableUserDict'):
991 pickled = (b'\x80\x02(cUserDict\n' + name +
992 b'\no}U\x04data}K\x01K\x02ssb.')
993 unpickled = self.loads(pickled)
994 self.assertIs(type(unpickled), collections.UserDict)
995 self.assertEqual(unpickled, collections.UserDict({1: 2}))
996
Serhiy Storchakae9b30742015-11-23 15:17:43 +0200997 def test_bad_stack(self):
998 badpickles = [
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200999 b'.', # STOP
1000 b'0', # POP
1001 b'1', # POP_MARK
1002 b'2', # DUP
1003 # b'(2', # PyUnpickler doesn't raise
1004 b'R', # REDUCE
1005 b')R',
1006 b'a', # APPEND
1007 b'Na',
1008 b'b', # BUILD
1009 b'Nb',
1010 b'd', # DICT
1011 b'e', # APPENDS
1012 # b'(e', # PyUnpickler raises AttributeError
1013 b'ibuiltins\nlist\n', # INST
1014 b'l', # LIST
1015 b'o', # OBJ
1016 b'(o',
1017 b'p1\n', # PUT
1018 b'q\x00', # BINPUT
1019 b'r\x00\x00\x00\x00', # LONG_BINPUT
1020 b's', # SETITEM
1021 b'Ns',
1022 b'NNs',
1023 b't', # TUPLE
1024 b'u', # SETITEMS
1025 # b'(u', # PyUnpickler doesn't raise
1026 b'}(Nu',
1027 b'\x81', # NEWOBJ
1028 b')\x81',
1029 b'\x85', # TUPLE1
1030 b'\x86', # TUPLE2
1031 b'N\x86',
1032 b'\x87', # TUPLE3
1033 b'N\x87',
1034 b'NN\x87',
1035 b'\x90', # ADDITEMS
1036 # b'(\x90', # PyUnpickler raises AttributeError
1037 b'\x91', # FROZENSET
1038 b'\x92', # NEWOBJ_EX
1039 b')}\x92',
1040 b'\x93', # STACK_GLOBAL
1041 b'Vlist\n\x93',
1042 b'\x94', # MEMOIZE
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001043 ]
1044 for p in badpickles:
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001045 self.check_unpickling_error(self.bad_stack_errors, p)
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001046
1047 def test_bad_mark(self):
1048 badpickles = [
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001049 # b'N(.', # STOP
1050 b'N(2', # DUP
1051 b'cbuiltins\nlist\n)(R', # REDUCE
1052 b'cbuiltins\nlist\n()R',
1053 b']N(a', # APPEND
1054 # BUILD
1055 b'cbuiltins\nValueError\n)R}(b',
1056 b'cbuiltins\nValueError\n)R(}b',
1057 b'(Nd', # DICT
1058 b'N(p1\n', # PUT
1059 b'N(q\x00', # BINPUT
1060 b'N(r\x00\x00\x00\x00', # LONG_BINPUT
1061 b'}NN(s', # SETITEM
1062 b'}N(Ns',
1063 b'}(NNs',
1064 b'}((u', # SETITEMS
1065 b'cbuiltins\nlist\n)(\x81', # NEWOBJ
1066 b'cbuiltins\nlist\n()\x81',
1067 b'N(\x85', # TUPLE1
1068 b'NN(\x86', # TUPLE2
1069 b'N(N\x86',
1070 b'NNN(\x87', # TUPLE3
1071 b'NN(N\x87',
1072 b'N(NN\x87',
1073 b']((\x90', # ADDITEMS
1074 # NEWOBJ_EX
1075 b'cbuiltins\nlist\n)}(\x92',
1076 b'cbuiltins\nlist\n)(}\x92',
1077 b'cbuiltins\nlist\n()}\x92',
1078 # STACK_GLOBAL
1079 b'Vbuiltins\n(Vlist\n\x93',
1080 b'Vbuiltins\nVlist\n(\x93',
1081 b'N(\x94', # MEMOIZE
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001082 ]
1083 for p in badpickles:
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001084 self.check_unpickling_error(self.bad_mark_errors, p)
1085
1086 def test_truncated_data(self):
1087 self.check_unpickling_error(EOFError, b'')
1088 self.check_unpickling_error(EOFError, b'N')
1089 badpickles = [
1090 b'B', # BINBYTES
1091 b'B\x03\x00\x00',
1092 b'B\x03\x00\x00\x00',
1093 b'B\x03\x00\x00\x00ab',
1094 b'C', # SHORT_BINBYTES
1095 b'C\x03',
1096 b'C\x03ab',
1097 b'F', # FLOAT
1098 b'F0.0',
1099 b'F0.00',
1100 b'G', # BINFLOAT
1101 b'G\x00\x00\x00\x00\x00\x00\x00',
1102 b'I', # INT
1103 b'I0',
1104 b'J', # BININT
1105 b'J\x00\x00\x00',
1106 b'K', # BININT1
1107 b'L', # LONG
1108 b'L0',
1109 b'L10',
1110 b'L0L',
1111 b'L10L',
1112 b'M', # BININT2
1113 b'M\x00',
1114 # b'P', # PERSID
1115 # b'Pabc',
1116 b'S', # STRING
1117 b"S'abc'",
1118 b'T', # BINSTRING
1119 b'T\x03\x00\x00',
1120 b'T\x03\x00\x00\x00',
1121 b'T\x03\x00\x00\x00ab',
1122 b'U', # SHORT_BINSTRING
1123 b'U\x03',
1124 b'U\x03ab',
1125 b'V', # UNICODE
1126 b'Vabc',
1127 b'X', # BINUNICODE
1128 b'X\x03\x00\x00',
1129 b'X\x03\x00\x00\x00',
1130 b'X\x03\x00\x00\x00ab',
1131 b'(c', # GLOBAL
1132 b'(cbuiltins',
1133 b'(cbuiltins\n',
1134 b'(cbuiltins\nlist',
1135 b'Ng', # GET
1136 b'Ng0',
1137 b'(i', # INST
1138 b'(ibuiltins',
1139 b'(ibuiltins\n',
1140 b'(ibuiltins\nlist',
1141 b'Nh', # BINGET
1142 b'Nj', # LONG_BINGET
1143 b'Nj\x00\x00\x00',
1144 b'Np', # PUT
1145 b'Np0',
1146 b'Nq', # BINPUT
1147 b'Nr', # LONG_BINPUT
1148 b'Nr\x00\x00\x00',
1149 b'\x80', # PROTO
1150 b'\x82', # EXT1
1151 b'\x83', # EXT2
1152 b'\x84\x01',
1153 b'\x84', # EXT4
1154 b'\x84\x01\x00\x00',
1155 b'\x8a', # LONG1
1156 b'\x8b', # LONG4
1157 b'\x8b\x00\x00\x00',
1158 b'\x8c', # SHORT_BINUNICODE
1159 b'\x8c\x03',
1160 b'\x8c\x03ab',
1161 b'\x8d', # BINUNICODE8
1162 b'\x8d\x03\x00\x00\x00\x00\x00\x00',
1163 b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00',
1164 b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00ab',
1165 b'\x8e', # BINBYTES8
1166 b'\x8e\x03\x00\x00\x00\x00\x00\x00',
1167 b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00',
1168 b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00ab',
1169 b'\x95', # FRAME
1170 b'\x95\x02\x00\x00\x00\x00\x00\x00',
1171 b'\x95\x02\x00\x00\x00\x00\x00\x00\x00',
1172 b'\x95\x02\x00\x00\x00\x00\x00\x00\x00N',
1173 ]
1174 for p in badpickles:
1175 self.check_unpickling_error(self.truncated_errors, p)
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001176
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001177
1178class AbstractPickleTests(unittest.TestCase):
1179 # Subclass must define self.dumps, self.loads.
1180
1181 optimized = False
1182
1183 _testdata = AbstractUnpickleTests._testdata
1184
1185 def setUp(self):
1186 pass
1187
1188 assert_is_copy = AbstractUnpickleTests.assert_is_copy
1189
1190 def test_misc(self):
1191 # test various datatypes not tested by testdata
1192 for proto in protocols:
1193 x = myint(4)
1194 s = self.dumps(x, proto)
1195 y = self.loads(s)
1196 self.assert_is_copy(x, y)
1197
1198 x = (1, ())
1199 s = self.dumps(x, proto)
1200 y = self.loads(s)
1201 self.assert_is_copy(x, y)
1202
1203 x = initarg(1, x)
1204 s = self.dumps(x, proto)
1205 y = self.loads(s)
1206 self.assert_is_copy(x, y)
1207
1208 # XXX test __reduce__ protocol?
1209
1210 def test_roundtrip_equality(self):
1211 expected = self._testdata
1212 for proto in protocols:
1213 s = self.dumps(expected, proto)
1214 got = self.loads(s)
1215 self.assert_is_copy(expected, got)
1216
Tim Peters70b02d72003-02-02 17:26:40 +00001217 # There are gratuitous differences between pickles produced by
1218 # pickle and cPickle, largely because cPickle starts PUT indices at
1219 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
1220 # there's a comment with an exclamation point there whose meaning
1221 # is a mystery. cPickle also suppresses PUT for objects with a refcount
1222 # of 1.
1223 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +00001224 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +00001225 from pickletools import dis
1226
1227 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
1228 s = self.dumps(self._testdata, proto)
1229 filelike = StringIO()
1230 dis(s, out=filelike)
1231 got = filelike.getvalue()
1232 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +00001233
1234 def test_recursive_list(self):
1235 l = []
1236 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +00001237 for proto in protocols:
1238 s = self.dumps(l, proto)
1239 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001240 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001241 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001242 self.assertIs(x[0], x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001243
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001244 def test_recursive_tuple_and_list(self):
Collin Winter8ca69de2009-05-26 16:53:41 +00001245 t = ([],)
1246 t[0].append(t)
1247 for proto in protocols:
1248 s = self.dumps(t, proto)
1249 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001250 self.assertIsInstance(x, tuple)
Collin Winter8ca69de2009-05-26 16:53:41 +00001251 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001252 self.assertIsInstance(x[0], list)
Collin Winter8ca69de2009-05-26 16:53:41 +00001253 self.assertEqual(len(x[0]), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001254 self.assertIs(x[0][0], x)
Collin Winter8ca69de2009-05-26 16:53:41 +00001255
Jeremy Hylton66426532001-10-15 21:38:56 +00001256 def test_recursive_dict(self):
1257 d = {}
1258 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +00001259 for proto in protocols:
1260 s = self.dumps(d, proto)
1261 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001262 self.assertIsInstance(x, dict)
Guido van Rossumcc2b0162007-02-11 06:12:03 +00001263 self.assertEqual(list(x.keys()), [1])
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001264 self.assertIs(x[1], x)
1265
1266 def test_recursive_dict_key(self):
1267 d = {}
1268 k = K(d)
1269 d[k] = 1
1270 for proto in protocols:
1271 s = self.dumps(d, proto)
1272 x = self.loads(s)
1273 self.assertIsInstance(x, dict)
1274 self.assertEqual(len(x.keys()), 1)
1275 self.assertIsInstance(list(x.keys())[0], K)
1276 self.assertIs(list(x.keys())[0].value, x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001277
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001278 def test_recursive_set(self):
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001279 y = set()
1280 k = K(y)
1281 y.add(k)
1282 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001283 s = self.dumps(y, proto)
1284 x = self.loads(s)
1285 self.assertIsInstance(x, set)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001286 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001287 self.assertIsInstance(list(x)[0], K)
1288 self.assertIs(list(x)[0].value, x)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001289
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001290 def test_recursive_list_subclass(self):
1291 y = MyList()
1292 y.append(y)
1293 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001294 s = self.dumps(y, proto)
1295 x = self.loads(s)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001296 self.assertIsInstance(x, MyList)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001297 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001298 self.assertIs(x[0], x)
1299
1300 def test_recursive_dict_subclass(self):
1301 d = MyDict()
1302 d[1] = d
1303 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1304 s = self.dumps(d, proto)
1305 x = self.loads(s)
1306 self.assertIsInstance(x, MyDict)
1307 self.assertEqual(list(x.keys()), [1])
1308 self.assertIs(x[1], x)
1309
1310 def test_recursive_dict_subclass_key(self):
1311 d = MyDict()
1312 k = K(d)
1313 d[k] = 1
1314 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1315 s = self.dumps(d, proto)
1316 x = self.loads(s)
1317 self.assertIsInstance(x, MyDict)
1318 self.assertEqual(len(list(x.keys())), 1)
1319 self.assertIsInstance(list(x.keys())[0], K)
1320 self.assertIs(list(x.keys())[0].value, x)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001321
Jeremy Hylton66426532001-10-15 21:38:56 +00001322 def test_recursive_inst(self):
1323 i = C()
1324 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +00001325 for proto in protocols:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001326 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +00001327 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001328 self.assertIsInstance(x, C)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001329 self.assertEqual(dir(x), dir(i))
Ezio Melottiaaef3442013-03-04 15:17:56 +02001330 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001331
1332 def test_recursive_multi(self):
1333 l = []
1334 d = {1:l}
1335 i = C()
1336 i.attr = d
1337 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +00001338 for proto in protocols:
1339 s = self.dumps(l, proto)
1340 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001341 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001342 self.assertEqual(len(x), 1)
1343 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +00001344 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001345 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001346
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001347 def check_recursive_collection_and_inst(self, factory):
1348 h = H()
1349 y = factory([h])
1350 h.attr = y
1351 for proto in protocols:
1352 s = self.dumps(y, proto)
1353 x = self.loads(s)
1354 self.assertIsInstance(x, type(y))
1355 self.assertEqual(len(x), 1)
1356 self.assertIsInstance(list(x)[0], H)
1357 self.assertIs(list(x)[0].attr, x)
1358
1359 def test_recursive_list_and_inst(self):
1360 self.check_recursive_collection_and_inst(list)
1361
1362 def test_recursive_tuple_and_inst(self):
1363 self.check_recursive_collection_and_inst(tuple)
1364
1365 def test_recursive_dict_and_inst(self):
1366 self.check_recursive_collection_and_inst(dict.fromkeys)
1367
1368 def test_recursive_set_and_inst(self):
1369 self.check_recursive_collection_and_inst(set)
1370
1371 def test_recursive_frozenset_and_inst(self):
1372 self.check_recursive_collection_and_inst(frozenset)
1373
1374 def test_recursive_list_subclass_and_inst(self):
1375 self.check_recursive_collection_and_inst(MyList)
1376
1377 def test_recursive_tuple_subclass_and_inst(self):
1378 self.check_recursive_collection_and_inst(MyTuple)
1379
1380 def test_recursive_dict_subclass_and_inst(self):
1381 self.check_recursive_collection_and_inst(MyDict.fromkeys)
1382
1383 def test_recursive_set_subclass_and_inst(self):
1384 self.check_recursive_collection_and_inst(MySet)
1385
1386 def test_recursive_frozenset_subclass_and_inst(self):
1387 self.check_recursive_collection_and_inst(MyFrozenSet)
1388
Walter Dörwald9b775532007-06-08 14:30:53 +00001389 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +00001390 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +00001391 '<\\>', '<\\\U00012345>',
1392 # surrogates
1393 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +00001394 for proto in protocols:
1395 for u in endcases:
1396 p = self.dumps(u, proto)
1397 u2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001398 self.assert_is_copy(u, u2)
Tim Peterse089c682001-04-10 03:41:41 +00001399
Alexandre Vassalotti554d8782008-12-27 07:32:41 +00001400 def test_unicode_high_plane(self):
1401 t = '\U00012345'
1402 for proto in protocols:
1403 p = self.dumps(t, proto)
1404 t2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001405 self.assert_is_copy(t, t2)
Alexandre Vassalotti554d8782008-12-27 07:32:41 +00001406
Guido van Rossumf4169812008-03-17 22:56:06 +00001407 def test_bytes(self):
1408 for proto in protocols:
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001409 for s in b'', b'xyz', b'xyz'*100:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001410 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001411 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001412 for s in [bytes([i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001413 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001414 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001415 for s in [bytes([i, i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001416 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001417 self.assert_is_copy(s, self.loads(p))
Guido van Rossumf4169812008-03-17 22:56:06 +00001418
Jeremy Hylton66426532001-10-15 21:38:56 +00001419 def test_ints(self):
Tim Petersee1a53c2003-02-02 02:57:53 +00001420 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +00001421 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +00001422 while n:
1423 for expected in (-n, n):
1424 s = self.dumps(expected, proto)
1425 n2 = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001426 self.assert_is_copy(expected, n2)
Tim Petersee1a53c2003-02-02 02:57:53 +00001427 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +00001428
Tim Petersee1a53c2003-02-02 02:57:53 +00001429 def test_long(self):
1430 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +00001431 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +00001432 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +00001433 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +00001434 for npos in nbase-1, nbase, nbase+1:
1435 for n in npos, -npos:
1436 pickle = self.dumps(n, proto)
1437 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001438 self.assert_is_copy(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +00001439 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
1440 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +00001441 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +00001442 nbase += nbase << 1000000
1443 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +00001444 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +00001445 got = self.loads(p)
Antoine Pitroud5df1942013-11-23 21:20:49 +01001446 # assert_is_copy is very expensive here as it precomputes
1447 # a failure message by computing the repr() of n and got,
1448 # we just do the check ourselves.
1449 self.assertIs(type(got), int)
1450 self.assertEqual(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +00001451
Mark Dickinsoncddcf442009-01-24 21:46:33 +00001452 def test_float(self):
1453 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
1454 3.14, 263.44582062374053, 6.022e23, 1e30]
1455 test_values = test_values + [-x for x in test_values]
1456 for proto in protocols:
1457 for value in test_values:
1458 pickle = self.dumps(value, proto)
1459 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001460 self.assert_is_copy(value, got)
Mark Dickinsoncddcf442009-01-24 21:46:33 +00001461
Thomas Wouters477c8d52006-05-27 19:21:47 +00001462 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
1463 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +00001464 # make sure that floats are formatted locale independent with proto 0
1465 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001466
Jeremy Hylton66426532001-10-15 21:38:56 +00001467 def test_reduce(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +01001468 for proto in protocols:
1469 inst = AAA()
1470 dumped = self.dumps(inst, proto)
1471 loaded = self.loads(dumped)
1472 self.assertEqual(loaded, REDUCE_A)
Jeremy Hylton66426532001-10-15 21:38:56 +00001473
1474 def test_getinitargs(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +01001475 for proto in protocols:
1476 inst = initarg(1, 2)
1477 dumped = self.dumps(inst, proto)
1478 loaded = self.loads(dumped)
1479 self.assert_is_copy(inst, loaded)
Jeremy Hylton66426532001-10-15 21:38:56 +00001480
Guido van Rossum04a86612001-12-19 16:58:54 +00001481 def test_metaclass(self):
1482 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +00001483 for proto in protocols:
1484 s = self.dumps(a, proto)
1485 b = self.loads(s)
1486 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +00001487
Antoine Pitrouffd41d92011-10-04 09:23:04 +02001488 def test_dynamic_class(self):
1489 a = create_dynamic_class("my_dynamic_class", (object,))
1490 copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
1491 for proto in protocols:
1492 s = self.dumps(a, proto)
1493 b = self.loads(s)
1494 self.assertEqual(a, b)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001495 self.assertIs(type(a), type(b))
Antoine Pitrouffd41d92011-10-04 09:23:04 +02001496
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001497 def test_structseq(self):
1498 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +00001499 import os
Tim Peters70b02d72003-02-02 17:26:40 +00001500
1501 t = time.localtime()
1502 for proto in protocols:
1503 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +00001504 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001505 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +00001506 if hasattr(os, "stat"):
1507 t = os.stat(os.curdir)
1508 s = self.dumps(t, proto)
1509 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001510 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +00001511 if hasattr(os, "statvfs"):
1512 t = os.statvfs(os.curdir)
1513 s = self.dumps(t, proto)
1514 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001515 self.assert_is_copy(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001516
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001517 def test_ellipsis(self):
1518 for proto in protocols:
1519 s = self.dumps(..., proto)
1520 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001521 self.assertIs(..., u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001522
1523 def test_notimplemented(self):
1524 for proto in protocols:
1525 s = self.dumps(NotImplemented, proto)
1526 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001527 self.assertIs(NotImplemented, u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001528
Alexandre Vassalotti19b6fa62013-11-30 16:06:39 -08001529 def test_singleton_types(self):
1530 # Issue #6477: Test that types of built-in singletons can be pickled.
1531 singletons = [None, ..., NotImplemented]
1532 for singleton in singletons:
1533 for proto in protocols:
1534 s = self.dumps(type(singleton), proto)
1535 u = self.loads(s)
1536 self.assertIs(type(singleton), u)
1537
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001538 # Tests for protocol 2
1539
Tim Peters4190fb82003-02-02 16:09:05 +00001540 def test_proto(self):
Tim Peters4190fb82003-02-02 16:09:05 +00001541 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001542 pickled = self.dumps(None, proto)
Tim Peters4190fb82003-02-02 16:09:05 +00001543 if proto >= 2:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001544 proto_header = pickle.PROTO + bytes([proto])
1545 self.assertTrue(pickled.startswith(proto_header))
1546 else:
1547 self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)
Tim Peters4190fb82003-02-02 16:09:05 +00001548
1549 oob = protocols[-1] + 1 # a future protocol
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001550 build_none = pickle.NONE + pickle.STOP
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001551 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +00001552 try:
1553 self.loads(badpickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001554 except ValueError as err:
1555 self.assertIn("unsupported pickle protocol", str(err))
Tim Peters4190fb82003-02-02 16:09:05 +00001556 else:
1557 self.fail("expected bad protocol number to raise ValueError")
1558
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001559 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +00001560 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +00001561 for proto in protocols:
1562 s = self.dumps(x, proto)
1563 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001564 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001565 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001566
1567 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +00001568 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +00001569 for proto in protocols:
1570 s = self.dumps(x, proto)
1571 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001572 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001573 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001574
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001575 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +00001576 # Map (proto, len(tuple)) to expected opcode.
1577 expected_opcode = {(0, 0): pickle.TUPLE,
1578 (0, 1): pickle.TUPLE,
1579 (0, 2): pickle.TUPLE,
1580 (0, 3): pickle.TUPLE,
1581 (0, 4): pickle.TUPLE,
1582
1583 (1, 0): pickle.EMPTY_TUPLE,
1584 (1, 1): pickle.TUPLE,
1585 (1, 2): pickle.TUPLE,
1586 (1, 3): pickle.TUPLE,
1587 (1, 4): pickle.TUPLE,
1588
1589 (2, 0): pickle.EMPTY_TUPLE,
1590 (2, 1): pickle.TUPLE1,
1591 (2, 2): pickle.TUPLE2,
1592 (2, 3): pickle.TUPLE3,
1593 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001594
1595 (3, 0): pickle.EMPTY_TUPLE,
1596 (3, 1): pickle.TUPLE1,
1597 (3, 2): pickle.TUPLE2,
1598 (3, 3): pickle.TUPLE3,
1599 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +00001600 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001601 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +00001602 b = (1,)
1603 c = (1, 2)
1604 d = (1, 2, 3)
1605 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +00001606 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001607 for x in a, b, c, d, e:
1608 s = self.dumps(x, proto)
1609 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001610 self.assert_is_copy(x, y)
1611 expected = expected_opcode[min(proto, 3), len(x)]
1612 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters1d63c9f2003-02-02 20:29:39 +00001613
Guido van Rossum7d97d312003-01-28 04:25:27 +00001614 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +00001615 # Map (proto, singleton) to expected opcode.
1616 expected_opcode = {(0, None): pickle.NONE,
1617 (1, None): pickle.NONE,
1618 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001619 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +00001620
1621 (0, True): pickle.INT,
1622 (1, True): pickle.INT,
1623 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001624 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +00001625
1626 (0, False): pickle.INT,
1627 (1, False): pickle.INT,
1628 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001629 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +00001630 }
Tim Peters4190fb82003-02-02 16:09:05 +00001631 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +00001632 for x in None, False, True:
1633 s = self.dumps(x, proto)
1634 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001635 self.assertTrue(x is y, (proto, x, s, y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001636 expected = expected_opcode[min(proto, 3), x]
1637 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters3c67d792003-02-02 17:59:11 +00001638
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001639 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001640 x = MyTuple([1, 2, 3])
1641 x.foo = 42
1642 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001643 for proto in protocols:
1644 s = self.dumps(x, proto)
1645 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001646 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001647
1648 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001649 x = MyList([1, 2, 3])
1650 x.foo = 42
1651 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001652 for proto in protocols:
1653 s = self.dumps(x, proto)
1654 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001655 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001656
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001657 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001658 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001659 for C in myclasses:
1660 B = C.__base__
1661 x = C(C.sample)
1662 x.foo = 42
1663 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001664 y = self.loads(s)
1665 detail = (proto, C, B, x, y, type(y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001666 self.assert_is_copy(x, y) # XXX revisit
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001667 self.assertEqual(B(x), B(y), detail)
1668 self.assertEqual(x.__dict__, y.__dict__, detail)
1669
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01001670 def test_newobj_proxies(self):
1671 # NEWOBJ should use the __class__ rather than the raw type
1672 classes = myclasses[:]
1673 # Cannot create weakproxies to these classes
1674 for c in (MyInt, MyTuple):
1675 classes.remove(c)
1676 for proto in protocols:
1677 for C in classes:
1678 B = C.__base__
1679 x = C(C.sample)
1680 x.foo = 42
1681 p = weakref.proxy(x)
1682 s = self.dumps(p, proto)
1683 y = self.loads(s)
1684 self.assertEqual(type(y), type(x)) # rather than type(p)
1685 detail = (proto, C, B, x, y, type(y))
1686 self.assertEqual(B(x), B(y), detail)
1687 self.assertEqual(x.__dict__, y.__dict__, detail)
1688
Benjamin Peterson80f78a32015-07-02 16:18:38 -05001689 def test_newobj_not_class(self):
1690 # Issue 24552
1691 global SimpleNewObj
1692 save = SimpleNewObj
Benjamin Petersond3a2a952015-07-02 16:58:22 -05001693 o = SimpleNewObj.__new__(SimpleNewObj)
Benjamin Peterson80f78a32015-07-02 16:18:38 -05001694 b = self.dumps(o, 4)
1695 try:
1696 SimpleNewObj = 42
1697 self.assertRaises((TypeError, pickle.UnpicklingError), self.loads, b)
1698 finally:
1699 SimpleNewObj = save
1700
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001701 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001702 # an object of that type. Check that the resulting pickle uses opcode
1703 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001704
Tim Peters22e71712003-02-03 22:27:38 +00001705 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001706 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001707 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001708 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001709 x = MyList([1, 2, 3])
1710 x.foo = 42
1711 x.bar = "hello"
1712
Tim Peters22e71712003-02-03 22:27:38 +00001713 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001714 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001715 self.assertIn(__name__.encode("utf-8"), s1)
1716 self.assertIn(b"MyList", s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001717 self.assertFalse(opcode_in_pickle(opcode, s1))
Tim Peters3e667d52003-02-04 21:47:44 +00001718
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001719 y = self.loads(s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001720 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001721
Tim Peters22e71712003-02-03 22:27:38 +00001722 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001723 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001724 self.assertNotIn(__name__.encode("utf-8"), s2)
1725 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001726 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +00001727
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001728 y = self.loads(s2)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001729 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001730 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001731 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001732
1733 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001734 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1735 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001736
1737 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001738 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1739 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1740 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001741
1742 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001743 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1744 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1745 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1746
Tim Peters8d2613a2003-02-11 16:40:16 +00001747 def test_list_chunking(self):
1748 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +00001749 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001750 for proto in protocols:
1751 s = self.dumps(x, proto)
1752 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001753 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001754 num_appends = count_opcode(pickle.APPENDS, s)
1755 self.assertEqual(num_appends, proto > 0)
1756
1757 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001758 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001759 for proto in protocols:
1760 s = self.dumps(x, proto)
1761 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001762 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001763 num_appends = count_opcode(pickle.APPENDS, s)
1764 if proto == 0:
1765 self.assertEqual(num_appends, 0)
1766 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001767 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001768
1769 def test_dict_chunking(self):
1770 n = 10 # too small to chunk
1771 x = dict.fromkeys(range(n))
1772 for proto in protocols:
1773 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +00001774 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00001775 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001776 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001777 num_setitems = count_opcode(pickle.SETITEMS, s)
1778 self.assertEqual(num_setitems, proto > 0)
1779
1780 n = 2500 # expect at least two chunks when proto > 0
1781 x = dict.fromkeys(range(n))
1782 for proto in protocols:
1783 s = self.dumps(x, proto)
1784 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001785 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001786 num_setitems = count_opcode(pickle.SETITEMS, s)
1787 if proto == 0:
1788 self.assertEqual(num_setitems, 0)
1789 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001790 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001791
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001792 def test_set_chunking(self):
1793 n = 10 # too small to chunk
1794 x = set(range(n))
1795 for proto in protocols:
1796 s = self.dumps(x, proto)
1797 y = self.loads(s)
1798 self.assert_is_copy(x, y)
1799 num_additems = count_opcode(pickle.ADDITEMS, s)
1800 if proto < 4:
1801 self.assertEqual(num_additems, 0)
1802 else:
1803 self.assertEqual(num_additems, 1)
1804
1805 n = 2500 # expect at least two chunks when proto >= 4
1806 x = set(range(n))
1807 for proto in protocols:
1808 s = self.dumps(x, proto)
1809 y = self.loads(s)
1810 self.assert_is_copy(x, y)
1811 num_additems = count_opcode(pickle.ADDITEMS, s)
1812 if proto < 4:
1813 self.assertEqual(num_additems, 0)
1814 else:
1815 self.assertGreaterEqual(num_additems, 2)
1816
Tim Peterse9ef2032003-02-13 18:42:00 +00001817 def test_simple_newobj(self):
1818 x = object.__new__(SimpleNewObj) # avoid __init__
1819 x.abc = 666
1820 for proto in protocols:
1821 s = self.dumps(x, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001822 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1823 2 <= proto < 4)
1824 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1825 proto >= 4)
Tim Peterse9ef2032003-02-13 18:42:00 +00001826 y = self.loads(s) # will raise TypeError if __init__ called
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001827 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001828
Tim Peters42f08ac2003-02-11 22:43:24 +00001829 def test_newobj_list_slots(self):
1830 x = SlotList([1, 2, 3])
1831 x.foo = 42
1832 x.bar = "hello"
1833 s = self.dumps(x, 2)
1834 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001835 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001836
Guido van Rossum2a30b212003-02-18 22:41:24 +00001837 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001838 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001839 x = REX_one()
1840 self.assertEqual(x._reduce_called, 0)
1841 s = self.dumps(x, proto)
1842 self.assertEqual(x._reduce_called, 1)
1843 y = self.loads(s)
1844 self.assertEqual(y._reduce_called, 0)
1845
1846 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001847 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001848 x = REX_two()
1849 self.assertEqual(x._proto, None)
1850 s = self.dumps(x, proto)
1851 self.assertEqual(x._proto, proto)
1852 y = self.loads(s)
1853 self.assertEqual(y._proto, None)
1854
1855 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001856 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001857 x = REX_three()
1858 self.assertEqual(x._proto, None)
1859 s = self.dumps(x, proto)
1860 self.assertEqual(x._proto, proto)
1861 y = self.loads(s)
1862 self.assertEqual(y._proto, None)
1863
Guido van Rossumd8faa362007-04-27 19:54:29 +00001864 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001865 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001866 x = REX_four()
1867 self.assertEqual(x._proto, None)
1868 s = self.dumps(x, proto)
1869 self.assertEqual(x._proto, proto)
1870 y = self.loads(s)
1871 self.assertEqual(y._proto, proto)
1872
1873 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001874 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001875 x = REX_five()
1876 self.assertEqual(x._reduce_called, 0)
1877 s = self.dumps(x, proto)
1878 self.assertEqual(x._reduce_called, 1)
1879 y = self.loads(s)
1880 self.assertEqual(y._reduce_called, 1)
1881
Brett Cannon31f59292011-02-21 19:29:56 +00001882 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001883 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001884 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001885 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001886 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001887 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001888
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001889 def test_reduce_bad_iterator(self):
1890 # Issue4176: crash when 4th and 5th items of __reduce__()
1891 # are not iterators
1892 class C(object):
1893 def __reduce__(self):
1894 # 4th item is not an iterator
1895 return list, (), None, [], None
1896 class D(object):
1897 def __reduce__(self):
1898 # 5th item is not an iterator
1899 return dict, (), None, None, []
1900
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001901 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001902 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001903 try:
1904 self.dumps(C(), proto)
1905 except (pickle.PickleError):
1906 pass
1907 try:
1908 self.dumps(D(), proto)
1909 except (pickle.PickleError):
1910 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001911
Collin Winter771d8342009-04-16 03:18:06 +00001912 def test_many_puts_and_gets(self):
1913 # Test that internal data structures correctly deal with lots of
1914 # puts/gets.
1915 keys = ("aaa" + str(i) for i in range(100))
1916 large_dict = dict((k, [4, 5, 6]) for k in keys)
1917 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1918
1919 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001920 with self.subTest(proto=proto):
1921 dumped = self.dumps(obj, proto)
1922 loaded = self.loads(dumped)
1923 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00001924
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001925 def test_attribute_name_interning(self):
1926 # Test that attribute names of pickled objects are interned when
1927 # unpickling.
1928 for proto in protocols:
1929 x = C()
1930 x.foo = 42
1931 x.bar = "hello"
1932 s = self.dumps(x, proto)
1933 y = self.loads(s)
1934 x_keys = sorted(x.__dict__)
1935 y_keys = sorted(y.__dict__)
1936 for x_key, y_key in zip(x_keys, y_keys):
1937 self.assertIs(x_key, y_key)
1938
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001939 def test_pickle_to_2x(self):
1940 # Pickle non-trivial data with protocol 2, expecting that it yields
1941 # the same result as Python 2.x did.
1942 # NOTE: this test is a bit too strong since we can produce different
1943 # bytecode that 2.x will still understand.
1944 dumped = self.dumps(range(5), 2)
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001945 self.assertEqual(dumped, DATA_XRANGE)
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001946 dumped = self.dumps(set([3]), 2)
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001947 self.assertEqual(dumped, DATA_SET2)
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001948
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001949 def test_large_pickles(self):
1950 # Test the correctness of internal buffering routines when handling
1951 # large data.
1952 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001953 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001954 dumped = self.dumps(data, proto)
1955 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001956 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001957 self.assertEqual(loaded, data)
1958
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001959 def test_int_pickling_efficiency(self):
1960 # Test compacity of int representation (see issue #12744)
1961 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001962 with self.subTest(proto=proto):
1963 pickles = [self.dumps(2**n, proto) for n in range(70)]
1964 sizes = list(map(len, pickles))
1965 # the size function is monotonic
1966 self.assertEqual(sorted(sizes), sizes)
1967 if proto >= 2:
1968 for p in pickles:
1969 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001970
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001971 def _check_pickling_with_opcode(self, obj, opcode, proto):
1972 pickled = self.dumps(obj, proto)
1973 self.assertTrue(opcode_in_pickle(opcode, pickled))
1974 unpickled = self.loads(pickled)
1975 self.assertEqual(obj, unpickled)
1976
1977 def test_appends_on_non_lists(self):
1978 # Issue #17720
1979 obj = REX_six([1, 2, 3])
1980 for proto in protocols:
1981 if proto == 0:
1982 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1983 else:
1984 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1985
1986 def test_setitems_on_non_dicts(self):
1987 obj = REX_seven({1: -1, 2: -2, 3: -3})
1988 for proto in protocols:
1989 if proto == 0:
1990 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1991 else:
1992 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1993
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001994 # Exercise framing (proto >= 4) for significant workloads
1995
1996 FRAME_SIZE_TARGET = 64 * 1024
1997
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001998 def check_frame_opcodes(self, pickled):
1999 """
2000 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
2001 """
2002 frame_opcode_size = 9
2003 last_arg = last_pos = None
2004 for op, arg, pos in pickletools.genops(pickled):
2005 if op.name != 'FRAME':
2006 continue
2007 if last_pos is not None:
2008 # The previous frame's size should be equal to the number
2009 # of bytes up to the current frame.
2010 frame_size = pos - last_pos - frame_opcode_size
2011 self.assertEqual(frame_size, last_arg)
2012 last_arg, last_pos = arg, pos
2013 # The last frame's size should be equal to the number of bytes up
2014 # to the pickle's end.
2015 frame_size = len(pickled) - last_pos - frame_opcode_size
2016 self.assertEqual(frame_size, last_arg)
2017
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002018 def test_framing_many_objects(self):
2019 obj = list(range(10**5))
2020 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2021 with self.subTest(proto=proto):
2022 pickled = self.dumps(obj, proto)
2023 unpickled = self.loads(pickled)
2024 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01002025 bytes_per_frame = (len(pickled) /
2026 count_opcode(pickle.FRAME, pickled))
2027 self.assertGreater(bytes_per_frame,
2028 self.FRAME_SIZE_TARGET / 2)
2029 self.assertLessEqual(bytes_per_frame,
2030 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002031 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002032
2033 def test_framing_large_objects(self):
2034 N = 1024 * 1024
2035 obj = [b'x' * N, b'y' * N, b'z' * N]
2036 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2037 with self.subTest(proto=proto):
2038 pickled = self.dumps(obj, proto)
2039 unpickled = self.loads(pickled)
2040 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01002041 n_frames = count_opcode(pickle.FRAME, pickled)
Alexandre Vassalotti28d271e2013-12-01 16:27:46 -08002042 self.assertGreaterEqual(n_frames, len(obj))
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002043 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002044
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002045 def test_optional_frames(self):
2046 if pickle.HIGHEST_PROTOCOL < 4:
2047 return
2048
2049 def remove_frames(pickled, keep_frame=None):
2050 """Remove frame opcodes from the given pickle."""
2051 frame_starts = []
2052 # 1 byte for the opcode and 8 for the argument
2053 frame_opcode_size = 9
2054 for opcode, _, pos in pickletools.genops(pickled):
2055 if opcode.name == 'FRAME':
2056 frame_starts.append(pos)
2057
2058 newpickle = bytearray()
2059 last_frame_end = 0
2060 for i, pos in enumerate(frame_starts):
2061 if keep_frame and keep_frame(i):
2062 continue
2063 newpickle += pickled[last_frame_end:pos]
2064 last_frame_end = pos + frame_opcode_size
2065 newpickle += pickled[last_frame_end:]
2066 return newpickle
2067
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08002068 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002069 num_frames = 20
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08002070 obj = [bytes([i]) * frame_size for i in range(num_frames)]
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002071
2072 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2073 pickled = self.dumps(obj, proto)
2074
2075 frameless_pickle = remove_frames(pickled)
2076 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
2077 self.assertEqual(obj, self.loads(frameless_pickle))
2078
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08002079 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002080 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
2081 count_opcode(pickle.FRAME, pickled))
2082 self.assertEqual(obj, self.loads(some_frames_pickle))
2083
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002084 def test_nested_names(self):
2085 global Nested
2086 class Nested:
2087 class A:
2088 class B:
2089 class C:
2090 pass
2091
2092 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2093 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
2094 with self.subTest(proto=proto, obj=obj):
2095 unpickled = self.loads(self.dumps(obj, proto))
2096 self.assertIs(obj, unpickled)
2097
2098 def test_py_methods(self):
2099 global PyMethodsTest
2100 class PyMethodsTest:
2101 @staticmethod
2102 def cheese():
2103 return "cheese"
2104 @classmethod
2105 def wine(cls):
2106 assert cls is PyMethodsTest
2107 return "wine"
2108 def biscuits(self):
2109 assert isinstance(self, PyMethodsTest)
2110 return "biscuits"
2111 class Nested:
2112 "Nested class"
2113 @staticmethod
2114 def ketchup():
2115 return "ketchup"
2116 @classmethod
2117 def maple(cls):
2118 assert cls is PyMethodsTest.Nested
2119 return "maple"
2120 def pie(self):
2121 assert isinstance(self, PyMethodsTest.Nested)
2122 return "pie"
2123
2124 py_methods = (
2125 PyMethodsTest.cheese,
2126 PyMethodsTest.wine,
2127 PyMethodsTest().biscuits,
2128 PyMethodsTest.Nested.ketchup,
2129 PyMethodsTest.Nested.maple,
2130 PyMethodsTest.Nested().pie
2131 )
2132 py_unbound_methods = (
2133 (PyMethodsTest.biscuits, PyMethodsTest),
2134 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
2135 )
2136 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2137 for method in py_methods:
2138 with self.subTest(proto=proto, method=method):
2139 unpickled = self.loads(self.dumps(method, proto))
2140 self.assertEqual(method(), unpickled())
2141 for method, cls in py_unbound_methods:
2142 obj = cls()
2143 with self.subTest(proto=proto, method=method):
2144 unpickled = self.loads(self.dumps(method, proto))
2145 self.assertEqual(method(obj), unpickled(obj))
2146
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002147 def test_c_methods(self):
2148 global Subclass
2149 class Subclass(tuple):
2150 class Nested(str):
2151 pass
2152
2153 c_methods = (
2154 # bound built-in method
2155 ("abcd".index, ("c",)),
2156 # unbound built-in method
2157 (str.index, ("abcd", "c")),
2158 # bound "slot" method
2159 ([1, 2, 3].__len__, ()),
2160 # unbound "slot" method
2161 (list.__len__, ([1, 2, 3],)),
2162 # bound "coexist" method
2163 ({1, 2}.__contains__, (2,)),
2164 # unbound "coexist" method
2165 (set.__contains__, ({1, 2}, 2)),
2166 # built-in class method
2167 (dict.fromkeys, (("a", 1), ("b", 2))),
2168 # built-in static method
2169 (bytearray.maketrans, (b"abc", b"xyz")),
2170 # subclass methods
2171 (Subclass([1,2,2]).count, (2,)),
2172 (Subclass.count, (Subclass([1,2,2]), 2)),
2173 (Subclass.Nested("sweet").count, ("e",)),
2174 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
2175 )
2176 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2177 for method, args in c_methods:
2178 with self.subTest(proto=proto, method=method):
2179 unpickled = self.loads(self.dumps(method, proto))
2180 self.assertEqual(method(*args), unpickled(*args))
2181
Serhiy Storchakabfe18242015-03-31 13:12:37 +03002182 def test_compat_pickle(self):
2183 tests = [
2184 (range(1, 7), '__builtin__', 'xrange'),
2185 (map(int, '123'), 'itertools', 'imap'),
2186 (functools.reduce, '__builtin__', 'reduce'),
2187 (dbm.whichdb, 'whichdb', 'whichdb'),
2188 (Exception(), 'exceptions', 'Exception'),
2189 (collections.UserDict(), 'UserDict', 'IterableUserDict'),
2190 (collections.UserList(), 'UserList', 'UserList'),
2191 (collections.defaultdict(), 'collections', 'defaultdict'),
2192 ]
2193 for val, mod, name in tests:
2194 for proto in range(3):
2195 with self.subTest(type=type(val), proto=proto):
2196 pickled = self.dumps(val, proto)
2197 self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled)
2198 self.assertIs(type(self.loads(pickled)), type(val))
2199
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002200
2201class BigmemPickleTests(unittest.TestCase):
2202
2203 # Binary protocols can serialize longs of up to 2GB-1
2204
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002205 @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002206 def test_huge_long_32b(self, size):
2207 data = 1 << (8 * size)
2208 try:
2209 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002210 if proto < 2:
2211 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002212 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002213 with self.assertRaises((ValueError, OverflowError)):
2214 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002215 finally:
2216 data = None
2217
2218 # Protocol 3 can serialize up to 4GB-1 as a bytes object
2219 # (older protocols don't have a dedicated opcode for bytes and are
2220 # too inefficient)
2221
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002222 @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002223 def test_huge_bytes_32b(self, size):
2224 data = b"abcd" * (size // 4)
2225 try:
2226 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002227 if proto < 3:
2228 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002229 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002230 try:
2231 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002232 header = (pickle.BINBYTES +
2233 struct.pack("<I", len(data)))
2234 data_start = pickled.index(data)
2235 self.assertEqual(
2236 header,
2237 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002238 finally:
2239 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002240 finally:
2241 data = None
2242
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002243 @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002244 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002245 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002246 try:
2247 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002248 if proto < 3:
2249 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002250 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002251 if proto == 3:
2252 # Protocol 3 does not support large bytes objects.
2253 # Verify that we do not crash when processing one.
2254 with self.assertRaises((ValueError, OverflowError)):
2255 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002256 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002257 try:
2258 pickled = self.dumps(data, protocol=proto)
2259 header = (pickle.BINBYTES8 +
2260 struct.pack("<Q", len(data)))
2261 data_start = pickled.index(data)
2262 self.assertEqual(
2263 header,
2264 pickled[data_start-len(header):data_start])
2265 finally:
2266 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002267 finally:
2268 data = None
2269
2270 # All protocols use 1-byte per printable ASCII character; we add another
2271 # byte because the encoded form has to be copied into the internal buffer.
2272
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002273 @bigmemtest(size=_2G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002274 def test_huge_str_32b(self, size):
2275 data = "abcd" * (size // 4)
2276 try:
2277 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002278 if proto == 0:
2279 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002280 with self.subTest(proto=proto):
2281 try:
2282 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002283 header = (pickle.BINUNICODE +
2284 struct.pack("<I", len(data)))
2285 data_start = pickled.index(b'abcd')
2286 self.assertEqual(
2287 header,
2288 pickled[data_start-len(header):data_start])
2289 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2290 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002291 finally:
2292 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002293 finally:
2294 data = None
2295
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002296 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
2297 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
2298 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02002299
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002300 @bigmemtest(size=_4G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002301 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002302 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002303 try:
2304 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002305 if proto == 0:
2306 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002307 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002308 if proto < 4:
2309 with self.assertRaises((ValueError, OverflowError)):
2310 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002311 continue
2312 try:
2313 pickled = self.dumps(data, protocol=proto)
2314 header = (pickle.BINUNICODE8 +
2315 struct.pack("<Q", len(data)))
2316 data_start = pickled.index(b'abcd')
2317 self.assertEqual(
2318 header,
2319 pickled[data_start-len(header):data_start])
2320 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2321 pickled.index(b"abcd")), len(data))
2322 finally:
2323 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002324 finally:
2325 data = None
2326
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002327
Guido van Rossum2a30b212003-02-18 22:41:24 +00002328# Test classes for reduce_ex
2329
2330class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002331 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00002332 _reduce_called = 0
2333 def __reduce__(self):
2334 self._reduce_called = 1
2335 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00002336
2337class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002338 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00002339 _proto = None
2340 def __reduce_ex__(self, proto):
2341 self._proto = proto
2342 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00002343
2344class REX_three(object):
2345 _proto = None
2346 def __reduce_ex__(self, proto):
2347 self._proto = proto
2348 return REX_two, ()
2349 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00002350 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00002351
Guido van Rossumd8faa362007-04-27 19:54:29 +00002352class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002353 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00002354 _proto = None
2355 def __reduce_ex__(self, proto):
2356 self._proto = proto
2357 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002358
2359class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002360 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00002361 _reduce_called = 0
2362 def __reduce__(self):
2363 self._reduce_called = 1
2364 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002365
2366class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002367 """This class is used to check the 4th argument (list iterator) of
2368 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002369 """
2370 def __init__(self, items=None):
2371 self.items = items if items is not None else []
2372 def __eq__(self, other):
2373 return type(self) is type(other) and self.items == self.items
2374 def append(self, item):
2375 self.items.append(item)
2376 def __reduce__(self):
2377 return type(self), (), None, iter(self.items), None
2378
2379class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002380 """This class is used to check the 5th argument (dict iterator) of
2381 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002382 """
2383 def __init__(self, table=None):
2384 self.table = table if table is not None else {}
2385 def __eq__(self, other):
2386 return type(self) is type(other) and self.table == self.table
2387 def __setitem__(self, key, value):
2388 self.table[key] = value
2389 def __reduce__(self):
2390 return type(self), (), None, None, iter(self.table.items())
2391
Guido van Rossumd8faa362007-04-27 19:54:29 +00002392
Guido van Rossum2a30b212003-02-18 22:41:24 +00002393# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00002394
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002395class MyInt(int):
2396 sample = 1
2397
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002398class MyFloat(float):
2399 sample = 1.0
2400
2401class MyComplex(complex):
2402 sample = 1.0 + 0.0j
2403
2404class MyStr(str):
2405 sample = "hello"
2406
Guido van Rossumef87d6e2007-05-02 19:09:54 +00002407class MyUnicode(str):
2408 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002409
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002410class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002411 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002412
2413class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002414 sample = [1, 2, 3]
2415
2416class MyDict(dict):
2417 sample = {"a": 1, "b": 2}
2418
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002419class MySet(set):
2420 sample = {"a", "b"}
2421
2422class MyFrozenSet(frozenset):
2423 sample = frozenset({"a", "b"})
2424
Mark Dickinson5c2db372009-12-05 20:28:34 +00002425myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00002426 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002427 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002428 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002429
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002430
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00002431class SlotList(MyList):
2432 __slots__ = ["foo"]
2433
Tim Peterse9ef2032003-02-13 18:42:00 +00002434class SimpleNewObj(object):
2435 def __init__(self, a, b, c):
2436 # raise an error, to make sure this isn't called
2437 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002438 def __eq__(self, other):
2439 return self.__dict__ == other.__dict__
Tim Peterse9ef2032003-02-13 18:42:00 +00002440
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002441class BadGetattr:
2442 def __getattr__(self, key):
2443 self.foo
2444
Collin Winter771d8342009-04-16 03:18:06 +00002445
Jeremy Hylton66426532001-10-15 21:38:56 +00002446class AbstractPickleModuleTests(unittest.TestCase):
2447
2448 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002449 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00002450 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002451 try:
2452 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002453 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002454 finally:
2455 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00002456
2457 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002458 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00002459 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002460 try:
2461 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002462 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002463 finally:
2464 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002465
Collin Winter771d8342009-04-16 03:18:06 +00002466 def test_load_from_and_dump_to_file(self):
2467 stream = io.BytesIO()
2468 data = [123, {}, 124]
2469 pickle.dump(data, stream)
2470 stream.seek(0)
2471 unpickled = pickle.load(stream)
2472 self.assertEqual(unpickled, data)
2473
Tim Petersc0c93702003-02-13 19:30:57 +00002474 def test_highest_protocol(self):
2475 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002476 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00002477
Martin v. Löwis544f1192004-07-27 05:22:33 +00002478 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00002479 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00002480 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002481 pickle.dump(123, f, -1)
2482 pickle.dump(123, file=f, protocol=-1)
2483 pickle.dumps(123, -1)
2484 pickle.dumps(123, protocol=-1)
2485 pickle.Pickler(f, -1)
2486 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00002487
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002488 def test_bad_init(self):
2489 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002490 # Override initialization without calling __init__() of the superclass.
2491 class BadPickler(pickle.Pickler):
2492 def __init__(self): pass
2493
2494 class BadUnpickler(pickle.Unpickler):
2495 def __init__(self): pass
2496
2497 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
2498 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
2499
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00002500 def test_bad_input(self):
2501 # Test issue4298
2502 s = bytes([0x58, 0, 0, 0, 0x54])
2503 self.assertRaises(EOFError, pickle.loads, s)
2504
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002505
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002506class AbstractPersistentPicklerTests(unittest.TestCase):
2507
2508 # This class defines persistent_id() and persistent_load()
2509 # functions that should be used by the pickler. All even integers
2510 # are pickled using persistent ids.
2511
2512 def persistent_id(self, object):
2513 if isinstance(object, int) and object % 2 == 0:
2514 self.id_count += 1
2515 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002516 elif object == "test_false_value":
2517 self.false_count += 1
2518 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002519 else:
2520 return None
2521
2522 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002523 if not oid:
2524 self.load_false_count += 1
2525 return "test_false_value"
2526 else:
2527 self.load_count += 1
2528 object = int(oid)
2529 assert object % 2 == 0
2530 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002531
2532 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002533 L = list(range(10)) + ["test_false_value"]
2534 for proto in protocols:
2535 self.id_count = 0
2536 self.false_count = 0
2537 self.load_false_count = 0
2538 self.load_count = 0
2539 self.assertEqual(self.loads(self.dumps(L, proto)), L)
2540 self.assertEqual(self.id_count, 5)
2541 self.assertEqual(self.false_count, 1)
2542 self.assertEqual(self.load_count, 5)
2543 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00002544
Collin Winter771d8342009-04-16 03:18:06 +00002545
2546class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
2547
2548 pickler_class = None
2549 unpickler_class = None
2550
2551 def setUp(self):
2552 assert self.pickler_class
2553 assert self.unpickler_class
2554
2555 def test_clear_pickler_memo(self):
2556 # To test whether clear_memo() has any effect, we pickle an object,
2557 # then pickle it again without clearing the memo; the two serialized
2558 # forms should be different. If we clear_memo() and then pickle the
2559 # object again, the third serialized form should be identical to the
2560 # first one we obtained.
2561 data = ["abcdefg", "abcdefg", 44]
2562 f = io.BytesIO()
2563 pickler = self.pickler_class(f)
2564
2565 pickler.dump(data)
2566 first_pickled = f.getvalue()
2567
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002568 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00002569 f.seek(0)
2570 f.truncate()
2571
2572 pickler.dump(data)
2573 second_pickled = f.getvalue()
2574
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002575 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00002576 pickler.clear_memo()
2577 f.seek(0)
2578 f.truncate()
2579
2580 pickler.dump(data)
2581 third_pickled = f.getvalue()
2582
2583 self.assertNotEqual(first_pickled, second_pickled)
2584 self.assertEqual(first_pickled, third_pickled)
2585
2586 def test_priming_pickler_memo(self):
2587 # Verify that we can set the Pickler's memo attribute.
2588 data = ["abcdefg", "abcdefg", 44]
2589 f = io.BytesIO()
2590 pickler = self.pickler_class(f)
2591
2592 pickler.dump(data)
2593 first_pickled = f.getvalue()
2594
2595 f = io.BytesIO()
2596 primed = self.pickler_class(f)
2597 primed.memo = pickler.memo
2598
2599 primed.dump(data)
2600 primed_pickled = f.getvalue()
2601
2602 self.assertNotEqual(first_pickled, primed_pickled)
2603
2604 def test_priming_unpickler_memo(self):
2605 # Verify that we can set the Unpickler's memo attribute.
2606 data = ["abcdefg", "abcdefg", 44]
2607 f = io.BytesIO()
2608 pickler = self.pickler_class(f)
2609
2610 pickler.dump(data)
2611 first_pickled = f.getvalue()
2612
2613 f = io.BytesIO()
2614 primed = self.pickler_class(f)
2615 primed.memo = pickler.memo
2616
2617 primed.dump(data)
2618 primed_pickled = f.getvalue()
2619
2620 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2621 unpickled_data1 = unpickler.load()
2622
2623 self.assertEqual(unpickled_data1, data)
2624
2625 primed = self.unpickler_class(io.BytesIO(primed_pickled))
2626 primed.memo = unpickler.memo
2627 unpickled_data2 = primed.load()
2628
2629 primed.memo.clear()
2630
2631 self.assertEqual(unpickled_data2, data)
2632 self.assertTrue(unpickled_data2 is unpickled_data1)
2633
2634 def test_reusing_unpickler_objects(self):
2635 data1 = ["abcdefg", "abcdefg", 44]
2636 f = io.BytesIO()
2637 pickler = self.pickler_class(f)
2638 pickler.dump(data1)
2639 pickled1 = f.getvalue()
2640
2641 data2 = ["abcdefg", 44, 44]
2642 f = io.BytesIO()
2643 pickler = self.pickler_class(f)
2644 pickler.dump(data2)
2645 pickled2 = f.getvalue()
2646
2647 f = io.BytesIO()
2648 f.write(pickled1)
2649 f.seek(0)
2650 unpickler = self.unpickler_class(f)
2651 self.assertEqual(unpickler.load(), data1)
2652
2653 f.seek(0)
2654 f.truncate()
2655 f.write(pickled2)
2656 f.seek(0)
2657 self.assertEqual(unpickler.load(), data2)
2658
Antoine Pitrou04248a82010-10-12 20:51:21 +00002659 def _check_multiple_unpicklings(self, ioclass):
2660 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002661 with self.subTest(proto=proto):
2662 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2663 f = ioclass()
2664 pickler = self.pickler_class(f, protocol=proto)
2665 pickler.dump(data1)
2666 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002667
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002668 N = 5
2669 f = ioclass(pickled * N)
2670 unpickler = self.unpickler_class(f)
2671 for i in range(N):
2672 if f.seekable():
2673 pos = f.tell()
2674 self.assertEqual(unpickler.load(), data1)
2675 if f.seekable():
2676 self.assertEqual(f.tell(), pos + len(pickled))
2677 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002678
2679 def test_multiple_unpicklings_seekable(self):
2680 self._check_multiple_unpicklings(io.BytesIO)
2681
2682 def test_multiple_unpicklings_unseekable(self):
2683 self._check_multiple_unpicklings(UnseekableIO)
2684
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002685 def test_unpickling_buffering_readline(self):
2686 # Issue #12687: the unpickler's buffering logic could fail with
2687 # text mode opcodes.
2688 data = list(range(10))
2689 for proto in protocols:
2690 for buf_size in range(1, 11):
2691 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2692 pickler = self.pickler_class(f, protocol=proto)
2693 pickler.dump(data)
2694 f.seek(0)
2695 unpickler = self.unpickler_class(f)
2696 self.assertEqual(unpickler.load(), data)
2697
Collin Winter771d8342009-04-16 03:18:06 +00002698
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002699# Tests for dispatch_table attribute
2700
2701REDUCE_A = 'reduce_A'
2702
2703class AAA(object):
2704 def __reduce__(self):
2705 return str, (REDUCE_A,)
2706
2707class BBB(object):
2708 pass
2709
2710class AbstractDispatchTableTests(unittest.TestCase):
2711
2712 def test_default_dispatch_table(self):
2713 # No dispatch_table attribute by default
2714 f = io.BytesIO()
2715 p = self.pickler_class(f, 0)
2716 with self.assertRaises(AttributeError):
2717 p.dispatch_table
2718 self.assertFalse(hasattr(p, 'dispatch_table'))
2719
2720 def test_class_dispatch_table(self):
2721 # A dispatch_table attribute can be specified class-wide
2722 dt = self.get_dispatch_table()
2723
2724 class MyPickler(self.pickler_class):
2725 dispatch_table = dt
2726
2727 def dumps(obj, protocol=None):
2728 f = io.BytesIO()
2729 p = MyPickler(f, protocol)
2730 self.assertEqual(p.dispatch_table, dt)
2731 p.dump(obj)
2732 return f.getvalue()
2733
2734 self._test_dispatch_table(dumps, dt)
2735
2736 def test_instance_dispatch_table(self):
2737 # A dispatch_table attribute can also be specified instance-wide
2738 dt = self.get_dispatch_table()
2739
2740 def dumps(obj, protocol=None):
2741 f = io.BytesIO()
2742 p = self.pickler_class(f, protocol)
2743 p.dispatch_table = dt
2744 self.assertEqual(p.dispatch_table, dt)
2745 p.dump(obj)
2746 return f.getvalue()
2747
2748 self._test_dispatch_table(dumps, dt)
2749
2750 def _test_dispatch_table(self, dumps, dispatch_table):
2751 def custom_load_dump(obj):
2752 return pickle.loads(dumps(obj, 0))
2753
2754 def default_load_dump(obj):
2755 return pickle.loads(pickle.dumps(obj, 0))
2756
2757 # pickling complex numbers using protocol 0 relies on copyreg
2758 # so check pickling a complex number still works
2759 z = 1 + 2j
2760 self.assertEqual(custom_load_dump(z), z)
2761 self.assertEqual(default_load_dump(z), z)
2762
2763 # modify pickling of complex
2764 REDUCE_1 = 'reduce_1'
2765 def reduce_1(obj):
2766 return str, (REDUCE_1,)
2767 dispatch_table[complex] = reduce_1
2768 self.assertEqual(custom_load_dump(z), REDUCE_1)
2769 self.assertEqual(default_load_dump(z), z)
2770
2771 # check picklability of AAA and BBB
2772 a = AAA()
2773 b = BBB()
2774 self.assertEqual(custom_load_dump(a), REDUCE_A)
2775 self.assertIsInstance(custom_load_dump(b), BBB)
2776 self.assertEqual(default_load_dump(a), REDUCE_A)
2777 self.assertIsInstance(default_load_dump(b), BBB)
2778
2779 # modify pickling of BBB
2780 dispatch_table[BBB] = reduce_1
2781 self.assertEqual(custom_load_dump(a), REDUCE_A)
2782 self.assertEqual(custom_load_dump(b), REDUCE_1)
2783 self.assertEqual(default_load_dump(a), REDUCE_A)
2784 self.assertIsInstance(default_load_dump(b), BBB)
2785
2786 # revert pickling of BBB and modify pickling of AAA
2787 REDUCE_2 = 'reduce_2'
2788 def reduce_2(obj):
2789 return str, (REDUCE_2,)
2790 dispatch_table[AAA] = reduce_2
2791 del dispatch_table[BBB]
2792 self.assertEqual(custom_load_dump(a), REDUCE_2)
2793 self.assertIsInstance(custom_load_dump(b), BBB)
2794 self.assertEqual(default_load_dump(a), REDUCE_A)
2795 self.assertIsInstance(default_load_dump(b), BBB)
2796
2797
Guido van Rossum98297ee2007-11-06 21:34:58 +00002798if __name__ == "__main__":
2799 # Print some stuff that can be used to rewrite DATA{0,1,2}
2800 from pickletools import dis
2801 x = create_data()
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03002802 for i in range(pickle.HIGHEST_PROTOCOL+1):
Guido van Rossum98297ee2007-11-06 21:34:58 +00002803 p = pickle.dumps(x, i)
2804 print("DATA{0} = (".format(i))
2805 for j in range(0, len(p), 20):
2806 b = bytes(p[j:j+20])
2807 print(" {0!r}".format(b))
2808 print(")")
2809 print()
2810 print("# Disassembly of DATA{0}".format(i))
2811 print("DATA{0}_DIS = \"\"\"\\".format(i))
2812 dis(p)
2813 print("\"\"\"")
2814 print()