blob: 7922b54f03e77fd52897308bebfa5ce9e65f5fd5 [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):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001818 x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__
Tim Peterse9ef2032003-02-13 18:42:00 +00001819 x.abc = 666
1820 for proto in protocols:
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001821 with self.subTest(proto=proto):
1822 s = self.dumps(x, proto)
1823 if proto < 1:
1824 self.assertIn(b'\nL64206', s) # LONG
1825 else:
1826 self.assertIn(b'M\xce\xfa', s) # BININT2
1827 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1828 2 <= proto)
1829 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1830 y = self.loads(s) # will raise TypeError if __init__ called
1831 self.assert_is_copy(x, y)
1832
1833 def test_complex_newobj(self):
1834 x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__
1835 x.abc = 666
1836 for proto in protocols:
1837 with self.subTest(proto=proto):
1838 s = self.dumps(x, proto)
1839 if proto < 1:
1840 self.assertIn(b'\nL64206', s) # LONG
1841 elif proto < 2:
1842 self.assertIn(b'M\xce\xfa', s) # BININT2
1843 elif proto < 4:
1844 self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
1845 else:
1846 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1847 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1848 2 <= proto)
1849 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1850 y = self.loads(s) # will raise TypeError if __init__ called
1851 self.assert_is_copy(x, y)
1852
1853 def test_complex_newobj_ex(self):
1854 x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__
1855 x.abc = 666
1856 for proto in protocols:
1857 with self.subTest(proto=proto):
1858 if 2 <= proto < 4:
1859 self.assertRaises(ValueError, self.dumps, x, proto)
1860 continue
1861 s = self.dumps(x, proto)
1862 if proto < 1:
1863 self.assertIn(b'\nL64206', s) # LONG
1864 elif proto < 2:
1865 self.assertIn(b'M\xce\xfa', s) # BININT2
1866 else:
1867 assert proto >= 4
1868 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1869 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s))
1870 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1871 4 <= proto)
1872 y = self.loads(s) # will raise TypeError if __init__ called
1873 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001874
Tim Peters42f08ac2003-02-11 22:43:24 +00001875 def test_newobj_list_slots(self):
1876 x = SlotList([1, 2, 3])
1877 x.foo = 42
1878 x.bar = "hello"
1879 s = self.dumps(x, 2)
1880 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001881 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001882
Guido van Rossum2a30b212003-02-18 22:41:24 +00001883 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001884 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001885 x = REX_one()
1886 self.assertEqual(x._reduce_called, 0)
1887 s = self.dumps(x, proto)
1888 self.assertEqual(x._reduce_called, 1)
1889 y = self.loads(s)
1890 self.assertEqual(y._reduce_called, 0)
1891
1892 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001893 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001894 x = REX_two()
1895 self.assertEqual(x._proto, None)
1896 s = self.dumps(x, proto)
1897 self.assertEqual(x._proto, proto)
1898 y = self.loads(s)
1899 self.assertEqual(y._proto, None)
1900
1901 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001902 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001903 x = REX_three()
1904 self.assertEqual(x._proto, None)
1905 s = self.dumps(x, proto)
1906 self.assertEqual(x._proto, proto)
1907 y = self.loads(s)
1908 self.assertEqual(y._proto, None)
1909
Guido van Rossumd8faa362007-04-27 19:54:29 +00001910 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001911 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001912 x = REX_four()
1913 self.assertEqual(x._proto, None)
1914 s = self.dumps(x, proto)
1915 self.assertEqual(x._proto, proto)
1916 y = self.loads(s)
1917 self.assertEqual(y._proto, proto)
1918
1919 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001920 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001921 x = REX_five()
1922 self.assertEqual(x._reduce_called, 0)
1923 s = self.dumps(x, proto)
1924 self.assertEqual(x._reduce_called, 1)
1925 y = self.loads(s)
1926 self.assertEqual(y._reduce_called, 1)
1927
Brett Cannon31f59292011-02-21 19:29:56 +00001928 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001929 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001930 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001931 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001932 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001933 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001934
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001935 def test_reduce_bad_iterator(self):
1936 # Issue4176: crash when 4th and 5th items of __reduce__()
1937 # are not iterators
1938 class C(object):
1939 def __reduce__(self):
1940 # 4th item is not an iterator
1941 return list, (), None, [], None
1942 class D(object):
1943 def __reduce__(self):
1944 # 5th item is not an iterator
1945 return dict, (), None, None, []
1946
Serhiy Storchakabeb652c2015-12-30 21:00:08 +02001947 # Python implementation is less strict and also accepts iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001948 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001949 try:
1950 self.dumps(C(), proto)
Serhiy Storchakabeb652c2015-12-30 21:00:08 +02001951 except pickle.PicklingError:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001952 pass
1953 try:
1954 self.dumps(D(), proto)
Serhiy Storchakabeb652c2015-12-30 21:00:08 +02001955 except pickle.PicklingError:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001956 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001957
Collin Winter771d8342009-04-16 03:18:06 +00001958 def test_many_puts_and_gets(self):
1959 # Test that internal data structures correctly deal with lots of
1960 # puts/gets.
1961 keys = ("aaa" + str(i) for i in range(100))
1962 large_dict = dict((k, [4, 5, 6]) for k in keys)
1963 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1964
1965 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001966 with self.subTest(proto=proto):
1967 dumped = self.dumps(obj, proto)
1968 loaded = self.loads(dumped)
1969 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00001970
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001971 def test_attribute_name_interning(self):
1972 # Test that attribute names of pickled objects are interned when
1973 # unpickling.
1974 for proto in protocols:
1975 x = C()
1976 x.foo = 42
1977 x.bar = "hello"
1978 s = self.dumps(x, proto)
1979 y = self.loads(s)
1980 x_keys = sorted(x.__dict__)
1981 y_keys = sorted(y.__dict__)
1982 for x_key, y_key in zip(x_keys, y_keys):
1983 self.assertIs(x_key, y_key)
1984
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001985 def test_pickle_to_2x(self):
1986 # Pickle non-trivial data with protocol 2, expecting that it yields
1987 # the same result as Python 2.x did.
1988 # NOTE: this test is a bit too strong since we can produce different
1989 # bytecode that 2.x will still understand.
1990 dumped = self.dumps(range(5), 2)
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001991 self.assertEqual(dumped, DATA_XRANGE)
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001992 dumped = self.dumps(set([3]), 2)
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001993 self.assertEqual(dumped, DATA_SET2)
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001994
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001995 def test_large_pickles(self):
1996 # Test the correctness of internal buffering routines when handling
1997 # large data.
1998 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001999 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00002000 dumped = self.dumps(data, proto)
2001 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002002 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00002003 self.assertEqual(loaded, data)
2004
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002005 def test_int_pickling_efficiency(self):
2006 # Test compacity of int representation (see issue #12744)
2007 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002008 with self.subTest(proto=proto):
2009 pickles = [self.dumps(2**n, proto) for n in range(70)]
2010 sizes = list(map(len, pickles))
2011 # the size function is monotonic
2012 self.assertEqual(sorted(sizes), sizes)
2013 if proto >= 2:
2014 for p in pickles:
2015 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002016
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002017 def _check_pickling_with_opcode(self, obj, opcode, proto):
2018 pickled = self.dumps(obj, proto)
2019 self.assertTrue(opcode_in_pickle(opcode, pickled))
2020 unpickled = self.loads(pickled)
2021 self.assertEqual(obj, unpickled)
2022
2023 def test_appends_on_non_lists(self):
2024 # Issue #17720
2025 obj = REX_six([1, 2, 3])
2026 for proto in protocols:
2027 if proto == 0:
2028 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
2029 else:
2030 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
2031
2032 def test_setitems_on_non_dicts(self):
2033 obj = REX_seven({1: -1, 2: -2, 3: -3})
2034 for proto in protocols:
2035 if proto == 0:
2036 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
2037 else:
2038 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
2039
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002040 # Exercise framing (proto >= 4) for significant workloads
2041
2042 FRAME_SIZE_TARGET = 64 * 1024
2043
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002044 def check_frame_opcodes(self, pickled):
2045 """
2046 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
2047 """
2048 frame_opcode_size = 9
2049 last_arg = last_pos = None
2050 for op, arg, pos in pickletools.genops(pickled):
2051 if op.name != 'FRAME':
2052 continue
2053 if last_pos is not None:
2054 # The previous frame's size should be equal to the number
2055 # of bytes up to the current frame.
2056 frame_size = pos - last_pos - frame_opcode_size
2057 self.assertEqual(frame_size, last_arg)
2058 last_arg, last_pos = arg, pos
2059 # The last frame's size should be equal to the number of bytes up
2060 # to the pickle's end.
2061 frame_size = len(pickled) - last_pos - frame_opcode_size
2062 self.assertEqual(frame_size, last_arg)
2063
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002064 def test_framing_many_objects(self):
2065 obj = list(range(10**5))
2066 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2067 with self.subTest(proto=proto):
2068 pickled = self.dumps(obj, proto)
2069 unpickled = self.loads(pickled)
2070 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01002071 bytes_per_frame = (len(pickled) /
2072 count_opcode(pickle.FRAME, pickled))
2073 self.assertGreater(bytes_per_frame,
2074 self.FRAME_SIZE_TARGET / 2)
2075 self.assertLessEqual(bytes_per_frame,
2076 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002077 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002078
2079 def test_framing_large_objects(self):
2080 N = 1024 * 1024
2081 obj = [b'x' * N, b'y' * N, b'z' * N]
2082 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2083 with self.subTest(proto=proto):
2084 pickled = self.dumps(obj, proto)
2085 unpickled = self.loads(pickled)
2086 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01002087 n_frames = count_opcode(pickle.FRAME, pickled)
Alexandre Vassalotti28d271e2013-12-01 16:27:46 -08002088 self.assertGreaterEqual(n_frames, len(obj))
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002089 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002090
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002091 def test_optional_frames(self):
2092 if pickle.HIGHEST_PROTOCOL < 4:
2093 return
2094
2095 def remove_frames(pickled, keep_frame=None):
2096 """Remove frame opcodes from the given pickle."""
2097 frame_starts = []
2098 # 1 byte for the opcode and 8 for the argument
2099 frame_opcode_size = 9
2100 for opcode, _, pos in pickletools.genops(pickled):
2101 if opcode.name == 'FRAME':
2102 frame_starts.append(pos)
2103
2104 newpickle = bytearray()
2105 last_frame_end = 0
2106 for i, pos in enumerate(frame_starts):
2107 if keep_frame and keep_frame(i):
2108 continue
2109 newpickle += pickled[last_frame_end:pos]
2110 last_frame_end = pos + frame_opcode_size
2111 newpickle += pickled[last_frame_end:]
2112 return newpickle
2113
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08002114 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002115 num_frames = 20
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08002116 obj = [bytes([i]) * frame_size for i in range(num_frames)]
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002117
2118 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2119 pickled = self.dumps(obj, proto)
2120
2121 frameless_pickle = remove_frames(pickled)
2122 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
2123 self.assertEqual(obj, self.loads(frameless_pickle))
2124
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08002125 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002126 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
2127 count_opcode(pickle.FRAME, pickled))
2128 self.assertEqual(obj, self.loads(some_frames_pickle))
2129
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002130 def test_nested_names(self):
2131 global Nested
2132 class Nested:
2133 class A:
2134 class B:
2135 class C:
2136 pass
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002137 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002138 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
2139 with self.subTest(proto=proto, obj=obj):
2140 unpickled = self.loads(self.dumps(obj, proto))
2141 self.assertIs(obj, unpickled)
2142
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002143 def test_recursive_nested_names(self):
2144 global Recursive
2145 class Recursive:
2146 pass
2147 Recursive.mod = sys.modules[Recursive.__module__]
2148 Recursive.__qualname__ = 'Recursive.mod.Recursive'
2149 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2150 with self.subTest(proto=proto):
2151 unpickled = self.loads(self.dumps(Recursive, proto))
2152 self.assertIs(unpickled, Recursive)
2153 del Recursive.mod # break reference loop
2154
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002155 def test_py_methods(self):
2156 global PyMethodsTest
2157 class PyMethodsTest:
2158 @staticmethod
2159 def cheese():
2160 return "cheese"
2161 @classmethod
2162 def wine(cls):
2163 assert cls is PyMethodsTest
2164 return "wine"
2165 def biscuits(self):
2166 assert isinstance(self, PyMethodsTest)
2167 return "biscuits"
2168 class Nested:
2169 "Nested class"
2170 @staticmethod
2171 def ketchup():
2172 return "ketchup"
2173 @classmethod
2174 def maple(cls):
2175 assert cls is PyMethodsTest.Nested
2176 return "maple"
2177 def pie(self):
2178 assert isinstance(self, PyMethodsTest.Nested)
2179 return "pie"
2180
2181 py_methods = (
2182 PyMethodsTest.cheese,
2183 PyMethodsTest.wine,
2184 PyMethodsTest().biscuits,
2185 PyMethodsTest.Nested.ketchup,
2186 PyMethodsTest.Nested.maple,
2187 PyMethodsTest.Nested().pie
2188 )
2189 py_unbound_methods = (
2190 (PyMethodsTest.biscuits, PyMethodsTest),
2191 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
2192 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002193 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002194 for method in py_methods:
2195 with self.subTest(proto=proto, method=method):
2196 unpickled = self.loads(self.dumps(method, proto))
2197 self.assertEqual(method(), unpickled())
2198 for method, cls in py_unbound_methods:
2199 obj = cls()
2200 with self.subTest(proto=proto, method=method):
2201 unpickled = self.loads(self.dumps(method, proto))
2202 self.assertEqual(method(obj), unpickled(obj))
2203
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002204 def test_c_methods(self):
2205 global Subclass
2206 class Subclass(tuple):
2207 class Nested(str):
2208 pass
2209
2210 c_methods = (
2211 # bound built-in method
2212 ("abcd".index, ("c",)),
2213 # unbound built-in method
2214 (str.index, ("abcd", "c")),
2215 # bound "slot" method
2216 ([1, 2, 3].__len__, ()),
2217 # unbound "slot" method
2218 (list.__len__, ([1, 2, 3],)),
2219 # bound "coexist" method
2220 ({1, 2}.__contains__, (2,)),
2221 # unbound "coexist" method
2222 (set.__contains__, ({1, 2}, 2)),
2223 # built-in class method
2224 (dict.fromkeys, (("a", 1), ("b", 2))),
2225 # built-in static method
2226 (bytearray.maketrans, (b"abc", b"xyz")),
2227 # subclass methods
2228 (Subclass([1,2,2]).count, (2,)),
2229 (Subclass.count, (Subclass([1,2,2]), 2)),
2230 (Subclass.Nested("sweet").count, ("e",)),
2231 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
2232 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002233 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002234 for method, args in c_methods:
2235 with self.subTest(proto=proto, method=method):
2236 unpickled = self.loads(self.dumps(method, proto))
2237 self.assertEqual(method(*args), unpickled(*args))
2238
Serhiy Storchakabfe18242015-03-31 13:12:37 +03002239 def test_compat_pickle(self):
2240 tests = [
2241 (range(1, 7), '__builtin__', 'xrange'),
2242 (map(int, '123'), 'itertools', 'imap'),
2243 (functools.reduce, '__builtin__', 'reduce'),
2244 (dbm.whichdb, 'whichdb', 'whichdb'),
2245 (Exception(), 'exceptions', 'Exception'),
2246 (collections.UserDict(), 'UserDict', 'IterableUserDict'),
2247 (collections.UserList(), 'UserList', 'UserList'),
2248 (collections.defaultdict(), 'collections', 'defaultdict'),
2249 ]
2250 for val, mod, name in tests:
2251 for proto in range(3):
2252 with self.subTest(type=type(val), proto=proto):
2253 pickled = self.dumps(val, proto)
2254 self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled)
2255 self.assertIs(type(self.loads(pickled)), type(val))
2256
Antoine Pitrou6cd5eda2014-12-02 00:20:03 +01002257 def test_local_lookup_error(self):
2258 # Test that whichmodule() errors out cleanly when looking up
2259 # an assumed globally-reachable object fails.
2260 def f():
2261 pass
2262 # Since the function is local, lookup will fail
2263 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2264 with self.assertRaises((AttributeError, pickle.PicklingError)):
2265 pickletools.dis(self.dumps(f, proto))
2266 # Same without a __module__ attribute (exercises a different path
2267 # in _pickle.c).
2268 del f.__module__
2269 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2270 with self.assertRaises((AttributeError, pickle.PicklingError)):
2271 pickletools.dis(self.dumps(f, proto))
2272 # Yet a different path.
2273 f.__name__ = f.__qualname__
2274 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2275 with self.assertRaises((AttributeError, pickle.PicklingError)):
2276 pickletools.dis(self.dumps(f, proto))
2277
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002278
2279class BigmemPickleTests(unittest.TestCase):
2280
2281 # Binary protocols can serialize longs of up to 2GB-1
2282
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002283 @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002284 def test_huge_long_32b(self, size):
2285 data = 1 << (8 * size)
2286 try:
2287 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002288 if proto < 2:
2289 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002290 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002291 with self.assertRaises((ValueError, OverflowError)):
2292 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002293 finally:
2294 data = None
2295
2296 # Protocol 3 can serialize up to 4GB-1 as a bytes object
2297 # (older protocols don't have a dedicated opcode for bytes and are
2298 # too inefficient)
2299
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002300 @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002301 def test_huge_bytes_32b(self, size):
2302 data = b"abcd" * (size // 4)
2303 try:
2304 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002305 if proto < 3:
2306 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002307 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002308 try:
2309 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002310 header = (pickle.BINBYTES +
2311 struct.pack("<I", len(data)))
2312 data_start = pickled.index(data)
2313 self.assertEqual(
2314 header,
2315 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002316 finally:
2317 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002318 finally:
2319 data = None
2320
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002321 @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002322 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002323 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002324 try:
2325 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002326 if proto < 3:
2327 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002328 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002329 if proto == 3:
2330 # Protocol 3 does not support large bytes objects.
2331 # Verify that we do not crash when processing one.
2332 with self.assertRaises((ValueError, OverflowError)):
2333 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002334 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002335 try:
2336 pickled = self.dumps(data, protocol=proto)
2337 header = (pickle.BINBYTES8 +
2338 struct.pack("<Q", len(data)))
2339 data_start = pickled.index(data)
2340 self.assertEqual(
2341 header,
2342 pickled[data_start-len(header):data_start])
2343 finally:
2344 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002345 finally:
2346 data = None
2347
2348 # All protocols use 1-byte per printable ASCII character; we add another
2349 # byte because the encoded form has to be copied into the internal buffer.
2350
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002351 @bigmemtest(size=_2G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002352 def test_huge_str_32b(self, size):
2353 data = "abcd" * (size // 4)
2354 try:
2355 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002356 if proto == 0:
2357 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002358 with self.subTest(proto=proto):
2359 try:
2360 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002361 header = (pickle.BINUNICODE +
2362 struct.pack("<I", len(data)))
2363 data_start = pickled.index(b'abcd')
2364 self.assertEqual(
2365 header,
2366 pickled[data_start-len(header):data_start])
2367 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2368 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002369 finally:
2370 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002371 finally:
2372 data = None
2373
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002374 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
2375 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
2376 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02002377
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002378 @bigmemtest(size=_4G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002379 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002380 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002381 try:
2382 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002383 if proto == 0:
2384 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002385 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002386 if proto < 4:
2387 with self.assertRaises((ValueError, OverflowError)):
2388 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002389 continue
2390 try:
2391 pickled = self.dumps(data, protocol=proto)
2392 header = (pickle.BINUNICODE8 +
2393 struct.pack("<Q", len(data)))
2394 data_start = pickled.index(b'abcd')
2395 self.assertEqual(
2396 header,
2397 pickled[data_start-len(header):data_start])
2398 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2399 pickled.index(b"abcd")), len(data))
2400 finally:
2401 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002402 finally:
2403 data = None
2404
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002405
Guido van Rossum2a30b212003-02-18 22:41:24 +00002406# Test classes for reduce_ex
2407
2408class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002409 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00002410 _reduce_called = 0
2411 def __reduce__(self):
2412 self._reduce_called = 1
2413 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00002414
2415class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002416 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00002417 _proto = None
2418 def __reduce_ex__(self, proto):
2419 self._proto = proto
2420 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00002421
2422class REX_three(object):
2423 _proto = None
2424 def __reduce_ex__(self, proto):
2425 self._proto = proto
2426 return REX_two, ()
2427 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00002428 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00002429
Guido van Rossumd8faa362007-04-27 19:54:29 +00002430class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002431 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00002432 _proto = None
2433 def __reduce_ex__(self, proto):
2434 self._proto = proto
2435 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002436
2437class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002438 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00002439 _reduce_called = 0
2440 def __reduce__(self):
2441 self._reduce_called = 1
2442 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002443
2444class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002445 """This class is used to check the 4th argument (list iterator) of
2446 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002447 """
2448 def __init__(self, items=None):
2449 self.items = items if items is not None else []
2450 def __eq__(self, other):
Serhiy Storchakabe700022016-03-04 09:39:47 +02002451 return type(self) is type(other) and self.items == other.items
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002452 def append(self, item):
2453 self.items.append(item)
2454 def __reduce__(self):
2455 return type(self), (), None, iter(self.items), None
2456
2457class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002458 """This class is used to check the 5th argument (dict iterator) of
2459 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002460 """
2461 def __init__(self, table=None):
2462 self.table = table if table is not None else {}
2463 def __eq__(self, other):
Serhiy Storchakabe700022016-03-04 09:39:47 +02002464 return type(self) is type(other) and self.table == other.table
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002465 def __setitem__(self, key, value):
2466 self.table[key] = value
2467 def __reduce__(self):
2468 return type(self), (), None, None, iter(self.table.items())
2469
Guido van Rossumd8faa362007-04-27 19:54:29 +00002470
Guido van Rossum2a30b212003-02-18 22:41:24 +00002471# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00002472
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002473class MyInt(int):
2474 sample = 1
2475
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002476class MyFloat(float):
2477 sample = 1.0
2478
2479class MyComplex(complex):
2480 sample = 1.0 + 0.0j
2481
2482class MyStr(str):
2483 sample = "hello"
2484
Guido van Rossumef87d6e2007-05-02 19:09:54 +00002485class MyUnicode(str):
2486 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002487
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002488class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002489 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002490
2491class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002492 sample = [1, 2, 3]
2493
2494class MyDict(dict):
2495 sample = {"a": 1, "b": 2}
2496
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002497class MySet(set):
2498 sample = {"a", "b"}
2499
2500class MyFrozenSet(frozenset):
2501 sample = frozenset({"a", "b"})
2502
Mark Dickinson5c2db372009-12-05 20:28:34 +00002503myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00002504 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002505 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002506 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002507
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002508
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00002509class SlotList(MyList):
2510 __slots__ = ["foo"]
2511
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002512class SimpleNewObj(int):
2513 def __init__(self, *args, **kwargs):
Tim Peterse9ef2032003-02-13 18:42:00 +00002514 # raise an error, to make sure this isn't called
2515 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002516 def __eq__(self, other):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002517 return int(self) == int(other) and self.__dict__ == other.__dict__
2518
2519class ComplexNewObj(SimpleNewObj):
2520 def __getnewargs__(self):
2521 return ('%X' % self, 16)
2522
2523class ComplexNewObjEx(SimpleNewObj):
2524 def __getnewargs_ex__(self):
2525 return ('%X' % self,), {'base': 16}
Tim Peterse9ef2032003-02-13 18:42:00 +00002526
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002527class BadGetattr:
2528 def __getattr__(self, key):
2529 self.foo
2530
Collin Winter771d8342009-04-16 03:18:06 +00002531
Jeremy Hylton66426532001-10-15 21:38:56 +00002532class AbstractPickleModuleTests(unittest.TestCase):
2533
2534 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002535 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00002536 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002537 try:
2538 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002539 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002540 finally:
2541 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00002542
2543 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002544 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00002545 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002546 try:
2547 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002548 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002549 finally:
2550 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002551
Collin Winter771d8342009-04-16 03:18:06 +00002552 def test_load_from_and_dump_to_file(self):
2553 stream = io.BytesIO()
2554 data = [123, {}, 124]
2555 pickle.dump(data, stream)
2556 stream.seek(0)
2557 unpickled = pickle.load(stream)
2558 self.assertEqual(unpickled, data)
2559
Tim Petersc0c93702003-02-13 19:30:57 +00002560 def test_highest_protocol(self):
2561 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002562 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00002563
Martin v. Löwis544f1192004-07-27 05:22:33 +00002564 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00002565 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00002566 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002567 pickle.dump(123, f, -1)
2568 pickle.dump(123, file=f, protocol=-1)
2569 pickle.dumps(123, -1)
2570 pickle.dumps(123, protocol=-1)
2571 pickle.Pickler(f, -1)
2572 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00002573
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002574 def test_bad_init(self):
2575 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002576 # Override initialization without calling __init__() of the superclass.
2577 class BadPickler(pickle.Pickler):
2578 def __init__(self): pass
2579
2580 class BadUnpickler(pickle.Unpickler):
2581 def __init__(self): pass
2582
2583 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
2584 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
2585
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00002586 def test_bad_input(self):
2587 # Test issue4298
2588 s = bytes([0x58, 0, 0, 0, 0x54])
2589 self.assertRaises(EOFError, pickle.loads, s)
2590
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002591
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002592class AbstractPersistentPicklerTests(unittest.TestCase):
2593
2594 # This class defines persistent_id() and persistent_load()
2595 # functions that should be used by the pickler. All even integers
2596 # are pickled using persistent ids.
2597
2598 def persistent_id(self, object):
2599 if isinstance(object, int) and object % 2 == 0:
2600 self.id_count += 1
2601 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002602 elif object == "test_false_value":
2603 self.false_count += 1
2604 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002605 else:
2606 return None
2607
2608 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002609 if not oid:
2610 self.load_false_count += 1
2611 return "test_false_value"
2612 else:
2613 self.load_count += 1
2614 object = int(oid)
2615 assert object % 2 == 0
2616 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002617
2618 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002619 L = list(range(10)) + ["test_false_value"]
2620 for proto in protocols:
2621 self.id_count = 0
2622 self.false_count = 0
2623 self.load_false_count = 0
2624 self.load_count = 0
2625 self.assertEqual(self.loads(self.dumps(L, proto)), L)
2626 self.assertEqual(self.id_count, 5)
2627 self.assertEqual(self.false_count, 1)
2628 self.assertEqual(self.load_count, 5)
2629 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00002630
Collin Winter771d8342009-04-16 03:18:06 +00002631
Serhiy Storchakadec25af2016-07-17 11:24:17 +03002632class AbstractIdentityPersistentPicklerTests(unittest.TestCase):
2633
2634 def persistent_id(self, obj):
2635 return obj
2636
2637 def persistent_load(self, pid):
2638 return pid
2639
2640 def _check_return_correct_type(self, obj, proto):
2641 unpickled = self.loads(self.dumps(obj, proto))
2642 self.assertIsInstance(unpickled, type(obj))
2643 self.assertEqual(unpickled, obj)
2644
2645 def test_return_correct_type(self):
2646 for proto in protocols:
2647 # Protocol 0 supports only ASCII strings.
2648 if proto == 0:
2649 self._check_return_correct_type("abc", 0)
2650 else:
2651 for obj in [b"abc\n", "abc\n", -1, -1.1 * 0.1, str]:
2652 self._check_return_correct_type(obj, proto)
2653
2654 def test_protocol0_is_ascii_only(self):
2655 non_ascii_str = "\N{EMPTY SET}"
2656 self.assertRaises(pickle.PicklingError, self.dumps, non_ascii_str, 0)
2657 pickled = pickle.PERSID + non_ascii_str.encode('utf-8') + b'\n.'
2658 self.assertRaises(pickle.UnpicklingError, self.loads, pickled)
2659
2660
Collin Winter771d8342009-04-16 03:18:06 +00002661class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
2662
2663 pickler_class = None
2664 unpickler_class = None
2665
2666 def setUp(self):
2667 assert self.pickler_class
2668 assert self.unpickler_class
2669
2670 def test_clear_pickler_memo(self):
2671 # To test whether clear_memo() has any effect, we pickle an object,
2672 # then pickle it again without clearing the memo; the two serialized
2673 # forms should be different. If we clear_memo() and then pickle the
2674 # object again, the third serialized form should be identical to the
2675 # first one we obtained.
2676 data = ["abcdefg", "abcdefg", 44]
2677 f = io.BytesIO()
2678 pickler = self.pickler_class(f)
2679
2680 pickler.dump(data)
2681 first_pickled = f.getvalue()
2682
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002683 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00002684 f.seek(0)
2685 f.truncate()
2686
2687 pickler.dump(data)
2688 second_pickled = f.getvalue()
2689
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002690 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00002691 pickler.clear_memo()
2692 f.seek(0)
2693 f.truncate()
2694
2695 pickler.dump(data)
2696 third_pickled = f.getvalue()
2697
2698 self.assertNotEqual(first_pickled, second_pickled)
2699 self.assertEqual(first_pickled, third_pickled)
2700
2701 def test_priming_pickler_memo(self):
2702 # Verify that we can set the Pickler's memo attribute.
2703 data = ["abcdefg", "abcdefg", 44]
2704 f = io.BytesIO()
2705 pickler = self.pickler_class(f)
2706
2707 pickler.dump(data)
2708 first_pickled = f.getvalue()
2709
2710 f = io.BytesIO()
2711 primed = self.pickler_class(f)
2712 primed.memo = pickler.memo
2713
2714 primed.dump(data)
2715 primed_pickled = f.getvalue()
2716
2717 self.assertNotEqual(first_pickled, primed_pickled)
2718
2719 def test_priming_unpickler_memo(self):
2720 # Verify that we can set the Unpickler's memo attribute.
2721 data = ["abcdefg", "abcdefg", 44]
2722 f = io.BytesIO()
2723 pickler = self.pickler_class(f)
2724
2725 pickler.dump(data)
2726 first_pickled = f.getvalue()
2727
2728 f = io.BytesIO()
2729 primed = self.pickler_class(f)
2730 primed.memo = pickler.memo
2731
2732 primed.dump(data)
2733 primed_pickled = f.getvalue()
2734
2735 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2736 unpickled_data1 = unpickler.load()
2737
2738 self.assertEqual(unpickled_data1, data)
2739
2740 primed = self.unpickler_class(io.BytesIO(primed_pickled))
2741 primed.memo = unpickler.memo
2742 unpickled_data2 = primed.load()
2743
2744 primed.memo.clear()
2745
2746 self.assertEqual(unpickled_data2, data)
2747 self.assertTrue(unpickled_data2 is unpickled_data1)
2748
2749 def test_reusing_unpickler_objects(self):
2750 data1 = ["abcdefg", "abcdefg", 44]
2751 f = io.BytesIO()
2752 pickler = self.pickler_class(f)
2753 pickler.dump(data1)
2754 pickled1 = f.getvalue()
2755
2756 data2 = ["abcdefg", 44, 44]
2757 f = io.BytesIO()
2758 pickler = self.pickler_class(f)
2759 pickler.dump(data2)
2760 pickled2 = f.getvalue()
2761
2762 f = io.BytesIO()
2763 f.write(pickled1)
2764 f.seek(0)
2765 unpickler = self.unpickler_class(f)
2766 self.assertEqual(unpickler.load(), data1)
2767
2768 f.seek(0)
2769 f.truncate()
2770 f.write(pickled2)
2771 f.seek(0)
2772 self.assertEqual(unpickler.load(), data2)
2773
Antoine Pitrou04248a82010-10-12 20:51:21 +00002774 def _check_multiple_unpicklings(self, ioclass):
2775 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002776 with self.subTest(proto=proto):
2777 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2778 f = ioclass()
2779 pickler = self.pickler_class(f, protocol=proto)
2780 pickler.dump(data1)
2781 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002782
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002783 N = 5
2784 f = ioclass(pickled * N)
2785 unpickler = self.unpickler_class(f)
2786 for i in range(N):
2787 if f.seekable():
2788 pos = f.tell()
2789 self.assertEqual(unpickler.load(), data1)
2790 if f.seekable():
2791 self.assertEqual(f.tell(), pos + len(pickled))
2792 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002793
2794 def test_multiple_unpicklings_seekable(self):
2795 self._check_multiple_unpicklings(io.BytesIO)
2796
2797 def test_multiple_unpicklings_unseekable(self):
2798 self._check_multiple_unpicklings(UnseekableIO)
2799
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002800 def test_unpickling_buffering_readline(self):
2801 # Issue #12687: the unpickler's buffering logic could fail with
2802 # text mode opcodes.
2803 data = list(range(10))
2804 for proto in protocols:
2805 for buf_size in range(1, 11):
2806 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2807 pickler = self.pickler_class(f, protocol=proto)
2808 pickler.dump(data)
2809 f.seek(0)
2810 unpickler = self.unpickler_class(f)
2811 self.assertEqual(unpickler.load(), data)
2812
Collin Winter771d8342009-04-16 03:18:06 +00002813
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002814# Tests for dispatch_table attribute
2815
2816REDUCE_A = 'reduce_A'
2817
2818class AAA(object):
2819 def __reduce__(self):
2820 return str, (REDUCE_A,)
2821
2822class BBB(object):
2823 pass
2824
2825class AbstractDispatchTableTests(unittest.TestCase):
2826
2827 def test_default_dispatch_table(self):
2828 # No dispatch_table attribute by default
2829 f = io.BytesIO()
2830 p = self.pickler_class(f, 0)
2831 with self.assertRaises(AttributeError):
2832 p.dispatch_table
2833 self.assertFalse(hasattr(p, 'dispatch_table'))
2834
2835 def test_class_dispatch_table(self):
2836 # A dispatch_table attribute can be specified class-wide
2837 dt = self.get_dispatch_table()
2838
2839 class MyPickler(self.pickler_class):
2840 dispatch_table = dt
2841
2842 def dumps(obj, protocol=None):
2843 f = io.BytesIO()
2844 p = MyPickler(f, protocol)
2845 self.assertEqual(p.dispatch_table, dt)
2846 p.dump(obj)
2847 return f.getvalue()
2848
2849 self._test_dispatch_table(dumps, dt)
2850
2851 def test_instance_dispatch_table(self):
2852 # A dispatch_table attribute can also be specified instance-wide
2853 dt = self.get_dispatch_table()
2854
2855 def dumps(obj, protocol=None):
2856 f = io.BytesIO()
2857 p = self.pickler_class(f, protocol)
2858 p.dispatch_table = dt
2859 self.assertEqual(p.dispatch_table, dt)
2860 p.dump(obj)
2861 return f.getvalue()
2862
2863 self._test_dispatch_table(dumps, dt)
2864
2865 def _test_dispatch_table(self, dumps, dispatch_table):
2866 def custom_load_dump(obj):
2867 return pickle.loads(dumps(obj, 0))
2868
2869 def default_load_dump(obj):
2870 return pickle.loads(pickle.dumps(obj, 0))
2871
2872 # pickling complex numbers using protocol 0 relies on copyreg
2873 # so check pickling a complex number still works
2874 z = 1 + 2j
2875 self.assertEqual(custom_load_dump(z), z)
2876 self.assertEqual(default_load_dump(z), z)
2877
2878 # modify pickling of complex
2879 REDUCE_1 = 'reduce_1'
2880 def reduce_1(obj):
2881 return str, (REDUCE_1,)
2882 dispatch_table[complex] = reduce_1
2883 self.assertEqual(custom_load_dump(z), REDUCE_1)
2884 self.assertEqual(default_load_dump(z), z)
2885
2886 # check picklability of AAA and BBB
2887 a = AAA()
2888 b = BBB()
2889 self.assertEqual(custom_load_dump(a), REDUCE_A)
2890 self.assertIsInstance(custom_load_dump(b), BBB)
2891 self.assertEqual(default_load_dump(a), REDUCE_A)
2892 self.assertIsInstance(default_load_dump(b), BBB)
2893
2894 # modify pickling of BBB
2895 dispatch_table[BBB] = reduce_1
2896 self.assertEqual(custom_load_dump(a), REDUCE_A)
2897 self.assertEqual(custom_load_dump(b), REDUCE_1)
2898 self.assertEqual(default_load_dump(a), REDUCE_A)
2899 self.assertIsInstance(default_load_dump(b), BBB)
2900
2901 # revert pickling of BBB and modify pickling of AAA
2902 REDUCE_2 = 'reduce_2'
2903 def reduce_2(obj):
2904 return str, (REDUCE_2,)
2905 dispatch_table[AAA] = reduce_2
2906 del dispatch_table[BBB]
2907 self.assertEqual(custom_load_dump(a), REDUCE_2)
2908 self.assertIsInstance(custom_load_dump(b), BBB)
2909 self.assertEqual(default_load_dump(a), REDUCE_A)
2910 self.assertIsInstance(default_load_dump(b), BBB)
2911
2912
Guido van Rossum98297ee2007-11-06 21:34:58 +00002913if __name__ == "__main__":
2914 # Print some stuff that can be used to rewrite DATA{0,1,2}
2915 from pickletools import dis
2916 x = create_data()
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03002917 for i in range(pickle.HIGHEST_PROTOCOL+1):
Guido van Rossum98297ee2007-11-06 21:34:58 +00002918 p = pickle.dumps(x, i)
2919 print("DATA{0} = (".format(i))
2920 for j in range(0, len(p), 20):
2921 b = bytes(p[j:j+20])
2922 print(" {0!r}".format(b))
2923 print(")")
2924 print()
2925 print("# Disassembly of DATA{0}".format(i))
2926 print("DATA{0}_DIS = \"\"\"\\".format(i))
2927 dis(p)
2928 print("\"\"\"")
2929 print()