blob: ae288f5d01250a8349e411b91d6e839ecec6e0c7 [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
tjb9004371c0a2019-02-18 23:30:51 +08006import os
Pierre Glaser289f1f82019-05-08 23:08:25 +02007import math
Tim Peters4190fb82003-02-02 16:09:05 +00008import pickle
Tim Peters31f119e2003-02-03 16:20:13 +00009import pickletools
tjb9004371c0a2019-02-18 23:30:51 +080010import shutil
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -080011import struct
Antoine Pitrou82be19f2011-08-29 23:09:33 +020012import sys
tjb9004371c0a2019-02-18 23:30:51 +080013import threading
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +010014import unittest
Antoine Pitrou16c4ce12011-03-11 21:30:43 +010015import weakref
tjb9004371c0a2019-02-18 23:30:51 +080016from textwrap import dedent
Antoine Pitroud9dfaa92009-06-04 20:32:06 +000017from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +000018
Antoine Pitrou91f43802019-05-26 17:10:09 +020019try:
20 import _testbuffer
21except ImportError:
22 _testbuffer = None
23
Serhiy Storchaka7279bef2015-11-29 13:12:10 +020024from test import support
Hai Shi883bc632020-07-06 17:12:49 +080025from test.support import os_helper
Antoine Pitrou82be19f2011-08-29 23:09:33 +020026from test.support import (
Hai Shi883bc632020-07-06 17:12:49 +080027 TestFailed, run_with_locale, no_tracing,
28 _2G, _4G, bigmemtest
Antoine Pitrou82be19f2011-08-29 23:09:33 +020029 )
Hai Shi883bc632020-07-06 17:12:49 +080030from test.support.import_helper import forget
31from test.support.os_helper import TESTFN
Hai Shie80697d2020-05-28 06:10:27 +080032from test.support import threading_helper
Victor Stinner83628932020-06-17 18:07:13 +020033from test.support.warnings_helper import save_restore_warnings_filters
Tim Peterse089c682001-04-10 03:41:41 +000034
Guido van Rossum98297ee2007-11-06 21:34:58 +000035from pickle import bytes_types
36
Victor Stinner83628932020-06-17 18:07:13 +020037
38# bpo-41003: Save/restore warnings filters to leave them unchanged.
39# Ignore filters installed by numpy.
40try:
41 with save_restore_warnings_filters():
42 import numpy as np
43except ImportError:
44 np = None
45
46
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030047requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
48 "test is only meaningful on 32-bit builds")
49
Tim Petersee1a53c2003-02-02 02:57:53 +000050# Tests that try a number of pickle protocols should have a
51# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000052# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000053protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000054
Tim Peters22e71712003-02-03 22:27:38 +000055
56# Return True if opcode code appears in the pickle, else False.
57def opcode_in_pickle(code, pickle):
58 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000059 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000060 return True
61 return False
62
Tim Peters8d2613a2003-02-11 16:40:16 +000063# Return the number of times opcode code appears in pickle.
64def count_opcode(code, pickle):
65 n = 0
66 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000067 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000068 n += 1
69 return n
70
Antoine Pitrou04248a82010-10-12 20:51:21 +000071
72class UnseekableIO(io.BytesIO):
73 def peek(self, *args):
74 raise NotImplementedError
75
76 def seekable(self):
77 return False
78
79 def seek(self, *args):
80 raise io.UnsupportedOperation
81
82 def tell(self):
83 raise io.UnsupportedOperation
84
85
Antoine Pitrou9f378722020-02-23 23:33:53 +010086class MinimalIO(object):
87 """
88 A file-like object that doesn't support readinto().
89 """
90 def __init__(self, *args):
91 self._bio = io.BytesIO(*args)
92 self.getvalue = self._bio.getvalue
93 self.read = self._bio.read
94 self.readline = self._bio.readline
95 self.write = self._bio.write
96
97
Tim Peters3e667d52003-02-04 21:47:44 +000098# We can't very well test the extension registry without putting known stuff
99# in it, but we have to be careful to restore its original state. Code
100# should do this:
101#
102# e = ExtensionSaver(extension_code)
103# try:
104# fiddle w/ the extension registry's stuff for extension_code
105# finally:
106# e.restore()
107
108class ExtensionSaver:
109 # Remember current registration for code (if any), and remove it (if
110 # there is one).
111 def __init__(self, code):
112 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000113 if code in copyreg._inverted_registry:
114 self.pair = copyreg._inverted_registry[code]
115 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000116 else:
117 self.pair = None
118
119 # Restore previous registration for code.
120 def restore(self):
121 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000122 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +0000123 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000124 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000125 pair = self.pair
126 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000127 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000128
Jeremy Hylton66426532001-10-15 21:38:56 +0000129class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000130 def __eq__(self, other):
131 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +0000132
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000133class D(C):
134 def __init__(self, arg):
135 pass
136
137class E(C):
138 def __getinitargs__(self):
139 return ()
140
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100141class H(object):
142 pass
143
Serhiy Storchaka608c2132015-11-07 11:16:10 +0200144# Hashable mutable key
145class K(object):
146 def __init__(self, value):
147 self.value = value
148
149 def __reduce__(self):
150 # Shouldn't support the recursion itself
151 return K, (self.value,)
152
Jeremy Hylton66426532001-10-15 21:38:56 +0000153import __main__
154__main__.C = C
155C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000156__main__.D = D
157D.__module__ = "__main__"
158__main__.E = E
159E.__module__ = "__main__"
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100160__main__.H = H
161H.__module__ = "__main__"
Serhiy Storchaka608c2132015-11-07 11:16:10 +0200162__main__.K = K
163K.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000164
165class myint(int):
166 def __init__(self, x):
167 self.str = str(x)
168
169class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000170
Jeremy Hylton66426532001-10-15 21:38:56 +0000171 def __init__(self, a, b):
172 self.a = a
173 self.b = b
174
175 def __getinitargs__(self):
176 return self.a, self.b
177
Guido van Rossum04a86612001-12-19 16:58:54 +0000178class metaclass(type):
179 pass
180
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000181class use_metaclass(object, metaclass=metaclass):
182 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000183
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200184class pickling_metaclass(type):
185 def __eq__(self, other):
186 return (type(self) == type(other) and
187 self.reduce_args == other.reduce_args)
188
189 def __reduce__(self):
190 return (create_dynamic_class, self.reduce_args)
191
192def create_dynamic_class(name, bases):
193 result = pickling_metaclass(name, bases, dict())
194 result.reduce_args = (name, bases)
195 return result
196
Antoine Pitrou91f43802019-05-26 17:10:09 +0200197
198class ZeroCopyBytes(bytes):
199 readonly = True
200 c_contiguous = True
201 f_contiguous = True
202 zero_copy_reconstruct = True
203
204 def __reduce_ex__(self, protocol):
205 if protocol >= 5:
206 return type(self)._reconstruct, (pickle.PickleBuffer(self),), None
207 else:
208 return type(self)._reconstruct, (bytes(self),)
209
210 def __repr__(self):
211 return "{}({!r})".format(self.__class__.__name__, bytes(self))
212
213 __str__ = __repr__
214
215 @classmethod
216 def _reconstruct(cls, obj):
217 with memoryview(obj) as m:
218 obj = m.obj
219 if type(obj) is cls:
220 # Zero-copy
221 return obj
222 else:
223 return cls(obj)
224
225
226class ZeroCopyBytearray(bytearray):
227 readonly = False
228 c_contiguous = True
229 f_contiguous = True
230 zero_copy_reconstruct = True
231
232 def __reduce_ex__(self, protocol):
233 if protocol >= 5:
234 return type(self)._reconstruct, (pickle.PickleBuffer(self),), None
235 else:
236 return type(self)._reconstruct, (bytes(self),)
237
238 def __repr__(self):
239 return "{}({!r})".format(self.__class__.__name__, bytes(self))
240
241 __str__ = __repr__
242
243 @classmethod
244 def _reconstruct(cls, obj):
245 with memoryview(obj) as m:
246 obj = m.obj
247 if type(obj) is cls:
248 # Zero-copy
249 return obj
250 else:
251 return cls(obj)
252
253
254if _testbuffer is not None:
255
256 class PicklableNDArray:
257 # A not-really-zero-copy picklable ndarray, as the ndarray()
258 # constructor doesn't allow for it
259
260 zero_copy_reconstruct = False
261
262 def __init__(self, *args, **kwargs):
263 self.array = _testbuffer.ndarray(*args, **kwargs)
264
265 def __getitem__(self, idx):
266 cls = type(self)
267 new = cls.__new__(cls)
268 new.array = self.array[idx]
269 return new
270
271 @property
272 def readonly(self):
273 return self.array.readonly
274
275 @property
276 def c_contiguous(self):
277 return self.array.c_contiguous
278
279 @property
280 def f_contiguous(self):
281 return self.array.f_contiguous
282
283 def __eq__(self, other):
284 if not isinstance(other, PicklableNDArray):
285 return NotImplemented
286 return (other.array.format == self.array.format and
287 other.array.shape == self.array.shape and
288 other.array.strides == self.array.strides and
289 other.array.readonly == self.array.readonly and
290 other.array.tobytes() == self.array.tobytes())
291
292 def __ne__(self, other):
293 if not isinstance(other, PicklableNDArray):
294 return NotImplemented
295 return not (self == other)
296
297 def __repr__(self):
298 return (f"{type(self)}(shape={self.array.shape},"
299 f"strides={self.array.strides}, "
300 f"bytes={self.array.tobytes()})")
301
302 def __reduce_ex__(self, protocol):
303 if not self.array.contiguous:
304 raise NotImplementedError("Reconstructing a non-contiguous "
305 "ndarray does not seem possible")
306 ndarray_kwargs = {"shape": self.array.shape,
307 "strides": self.array.strides,
308 "format": self.array.format,
309 "flags": (0 if self.readonly
310 else _testbuffer.ND_WRITABLE)}
311 pb = pickle.PickleBuffer(self.array)
312 if protocol >= 5:
313 return (type(self)._reconstruct,
314 (pb, ndarray_kwargs))
315 else:
316 # Need to serialize the bytes in physical order
317 with pb.raw() as m:
318 return (type(self)._reconstruct,
319 (m.tobytes(), ndarray_kwargs))
320
321 @classmethod
322 def _reconstruct(cls, obj, kwargs):
323 with memoryview(obj) as m:
324 # For some reason, ndarray() wants a list of integers...
325 # XXX This only works if format == 'B'
326 items = list(m.tobytes())
327 return cls(items, **kwargs)
328
329
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300330# DATA0 .. DATA4 are the pickles we expect under the various protocols, for
Tim Peters70b02d72003-02-02 17:26:40 +0000331# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000332
Guido van Rossum98297ee2007-11-06 21:34:58 +0000333DATA0 = (
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200334 b'(lp0\nL0L\naL1L\naF2.0\n'
335 b'ac__builtin__\ncomple'
336 b'x\np1\n(F3.0\nF0.0\ntp2\n'
337 b'Rp3\naL1L\naL-1L\naL255'
338 b'L\naL-255L\naL-256L\naL'
339 b'65535L\naL-65535L\naL-'
340 b'65536L\naL2147483647L'
341 b'\naL-2147483647L\naL-2'
342 b'147483648L\na(Vabc\np4'
343 b'\ng4\nccopy_reg\n_recon'
344 b'structor\np5\n(c__main'
345 b'__\nC\np6\nc__builtin__'
346 b'\nobject\np7\nNtp8\nRp9\n'
347 b'(dp10\nVfoo\np11\nL1L\ns'
348 b'Vbar\np12\nL2L\nsbg9\ntp'
349 b'13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000350)
Tim Peterse9358162001-01-22 22:05:20 +0000351
Guido van Rossum98297ee2007-11-06 21:34:58 +0000352# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000353DATA0_DIS = """\
354 0: ( MARK
355 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000356 2: p PUT 0
357 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000358 9: a APPEND
359 10: L LONG 1
360 14: a APPEND
361 15: F FLOAT 2.0
362 20: a APPEND
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200363 21: c GLOBAL '__builtin__ complex'
364 42: p PUT 1
365 45: ( MARK
366 46: F FLOAT 3.0
367 51: F FLOAT 0.0
368 56: t TUPLE (MARK at 45)
369 57: p PUT 2
370 60: R REDUCE
371 61: p PUT 3
372 64: a APPEND
373 65: L LONG 1
374 69: a APPEND
375 70: L LONG -1
376 75: a APPEND
377 76: L LONG 255
378 82: a APPEND
379 83: L LONG -255
380 90: a APPEND
381 91: L LONG -256
382 98: a APPEND
383 99: L LONG 65535
384 107: a APPEND
385 108: L LONG -65535
386 117: a APPEND
387 118: L LONG -65536
388 127: a APPEND
389 128: L LONG 2147483647
390 141: a APPEND
391 142: L LONG -2147483647
392 156: a APPEND
393 157: L LONG -2147483648
394 171: a APPEND
395 172: ( MARK
396 173: V UNICODE 'abc'
397 178: p PUT 4
398 181: g GET 4
399 184: c GLOBAL 'copy_reg _reconstructor'
400 209: p PUT 5
401 212: ( MARK
402 213: c GLOBAL '__main__ C'
403 225: p PUT 6
404 228: c GLOBAL '__builtin__ object'
405 248: p PUT 7
406 251: N NONE
407 252: t TUPLE (MARK at 212)
408 253: p PUT 8
409 256: R REDUCE
410 257: p PUT 9
411 260: ( MARK
412 261: d DICT (MARK at 260)
413 262: p PUT 10
414 266: V UNICODE 'foo'
415 271: p PUT 11
416 275: L LONG 1
417 279: s SETITEM
418 280: V UNICODE 'bar'
419 285: p PUT 12
420 289: L LONG 2
421 293: s SETITEM
422 294: b BUILD
423 295: g GET 9
424 298: t TUPLE (MARK at 172)
425 299: p PUT 13
426 303: a APPEND
427 304: g GET 13
428 308: a APPEND
429 309: L LONG 5
430 313: a APPEND
431 314: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000432highest protocol among opcodes = 0
433"""
434
Guido van Rossum98297ee2007-11-06 21:34:58 +0000435DATA1 = (
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200436 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c__'
437 b'builtin__\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000438 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
439 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
440 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
441 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200442 b'cq\x04h\x04ccopy_reg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000443 b'nstructor\nq\x05(c__main'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200444 b'__\nC\nq\x06c__builtin__\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000445 b'object\nq\x07Ntq\x08Rq\t}q\n('
446 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
447 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
448)
Tim Peters70b02d72003-02-02 17:26:40 +0000449
Guido van Rossum98297ee2007-11-06 21:34:58 +0000450# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000451DATA1_DIS = """\
452 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000453 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000454 3: ( MARK
455 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000456 6: K BININT1 1
457 8: G BINFLOAT 2.0
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200458 17: c GLOBAL '__builtin__ complex'
459 38: q BINPUT 1
460 40: ( MARK
461 41: G BINFLOAT 3.0
462 50: G BINFLOAT 0.0
463 59: t TUPLE (MARK at 40)
464 60: q BINPUT 2
465 62: R REDUCE
466 63: q BINPUT 3
467 65: K BININT1 1
468 67: J BININT -1
469 72: K BININT1 255
470 74: J BININT -255
471 79: J BININT -256
472 84: M BININT2 65535
473 87: J BININT -65535
474 92: J BININT -65536
475 97: J BININT 2147483647
476 102: J BININT -2147483647
477 107: J BININT -2147483648
478 112: ( MARK
479 113: X BINUNICODE 'abc'
480 121: q BINPUT 4
481 123: h BINGET 4
482 125: c GLOBAL 'copy_reg _reconstructor'
483 150: q BINPUT 5
484 152: ( MARK
485 153: c GLOBAL '__main__ C'
486 165: q BINPUT 6
487 167: c GLOBAL '__builtin__ object'
488 187: q BINPUT 7
489 189: N NONE
490 190: t TUPLE (MARK at 152)
491 191: q BINPUT 8
492 193: R REDUCE
493 194: q BINPUT 9
494 196: } EMPTY_DICT
495 197: q BINPUT 10
496 199: ( MARK
497 200: X BINUNICODE 'foo'
498 208: q BINPUT 11
499 210: K BININT1 1
500 212: X BINUNICODE 'bar'
501 220: q BINPUT 12
502 222: K BININT1 2
503 224: u SETITEMS (MARK at 199)
504 225: b BUILD
505 226: h BINGET 9
506 228: t TUPLE (MARK at 112)
507 229: q BINPUT 13
508 231: h BINGET 13
509 233: K BININT1 5
510 235: e APPENDS (MARK at 3)
511 236: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000512highest protocol among opcodes = 1
513"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000514
Guido van Rossum98297ee2007-11-06 21:34:58 +0000515DATA2 = (
516 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200517 b'__builtin__\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000518 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
519 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
520 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
521 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
522 b'bcq\x04h\x04c__main__\nC\nq\x05'
523 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
524 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
525 b'\nK\x05e.'
526)
Tim Petersfc273752003-03-02 04:54:24 +0000527
Guido van Rossum98297ee2007-11-06 21:34:58 +0000528# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000529DATA2_DIS = """\
530 0: \x80 PROTO 2
531 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000532 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000533 5: ( MARK
534 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000535 8: K BININT1 1
536 10: G BINFLOAT 2.0
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200537 19: c GLOBAL '__builtin__ complex'
538 40: q BINPUT 1
539 42: G BINFLOAT 3.0
540 51: G BINFLOAT 0.0
541 60: \x86 TUPLE2
542 61: q BINPUT 2
543 63: R REDUCE
544 64: q BINPUT 3
545 66: K BININT1 1
546 68: J BININT -1
547 73: K BININT1 255
548 75: J BININT -255
549 80: J BININT -256
550 85: M BININT2 65535
551 88: J BININT -65535
552 93: J BININT -65536
553 98: J BININT 2147483647
554 103: J BININT -2147483647
555 108: J BININT -2147483648
556 113: ( MARK
557 114: X BINUNICODE 'abc'
558 122: q BINPUT 4
559 124: h BINGET 4
560 126: c GLOBAL '__main__ C'
561 138: q BINPUT 5
562 140: ) EMPTY_TUPLE
563 141: \x81 NEWOBJ
564 142: q BINPUT 6
565 144: } EMPTY_DICT
566 145: q BINPUT 7
567 147: ( MARK
568 148: X BINUNICODE 'foo'
569 156: q BINPUT 8
570 158: K BININT1 1
571 160: X BINUNICODE 'bar'
572 168: q BINPUT 9
573 170: K BININT1 2
574 172: u SETITEMS (MARK at 147)
575 173: b BUILD
576 174: h BINGET 6
577 176: t TUPLE (MARK at 113)
578 177: q BINPUT 10
579 179: h BINGET 10
580 181: K BININT1 5
581 183: e APPENDS (MARK at 5)
582 184: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000583highest protocol among opcodes = 2
584"""
585
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300586DATA3 = (
587 b'\x80\x03]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
588 b'builtins\ncomplex\nq\x01G'
589 b'@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00\x86q\x02'
590 b'Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff'
591 b'\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7f'
592 b'J\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00abcq'
593 b'\x04h\x04c__main__\nC\nq\x05)\x81q'
594 b'\x06}q\x07(X\x03\x00\x00\x00barq\x08K\x02X\x03\x00'
595 b'\x00\x00fooq\tK\x01ubh\x06tq\nh\nK\x05'
596 b'e.'
597)
598
599# Disassembly of DATA3
600DATA3_DIS = """\
601 0: \x80 PROTO 3
602 2: ] EMPTY_LIST
603 3: q BINPUT 0
604 5: ( MARK
605 6: K BININT1 0
606 8: K BININT1 1
607 10: G BINFLOAT 2.0
608 19: c GLOBAL 'builtins complex'
609 37: q BINPUT 1
610 39: G BINFLOAT 3.0
611 48: G BINFLOAT 0.0
612 57: \x86 TUPLE2
613 58: q BINPUT 2
614 60: R REDUCE
615 61: q BINPUT 3
616 63: K BININT1 1
617 65: J BININT -1
618 70: K BININT1 255
619 72: J BININT -255
620 77: J BININT -256
621 82: M BININT2 65535
622 85: J BININT -65535
623 90: J BININT -65536
624 95: J BININT 2147483647
625 100: J BININT -2147483647
626 105: J BININT -2147483648
627 110: ( MARK
628 111: X BINUNICODE 'abc'
629 119: q BINPUT 4
630 121: h BINGET 4
631 123: c GLOBAL '__main__ C'
632 135: q BINPUT 5
633 137: ) EMPTY_TUPLE
634 138: \x81 NEWOBJ
635 139: q BINPUT 6
636 141: } EMPTY_DICT
637 142: q BINPUT 7
638 144: ( MARK
639 145: X BINUNICODE 'bar'
640 153: q BINPUT 8
641 155: K BININT1 2
642 157: X BINUNICODE 'foo'
643 165: q BINPUT 9
644 167: K BININT1 1
645 169: u SETITEMS (MARK at 144)
646 170: b BUILD
647 171: h BINGET 6
648 173: t TUPLE (MARK at 110)
649 174: q BINPUT 10
650 176: h BINGET 10
651 178: K BININT1 5
652 180: e APPENDS (MARK at 5)
653 181: . STOP
654highest protocol among opcodes = 2
655"""
656
657DATA4 = (
658 b'\x80\x04\x95\xa8\x00\x00\x00\x00\x00\x00\x00]\x94(K\x00K\x01G@'
659 b'\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x07'
660 b'complex\x94\x93\x94G@\x08\x00\x00\x00\x00\x00\x00G'
661 b'\x00\x00\x00\x00\x00\x00\x00\x00\x86\x94R\x94K\x01J\xff\xff\xff\xffK'
662 b'\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ'
663 b'\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80('
664 b'\x8c\x03abc\x94h\x06\x8c\x08__main__\x94\x8c'
665 b'\x01C\x94\x93\x94)\x81\x94}\x94(\x8c\x03bar\x94K\x02\x8c'
666 b'\x03foo\x94K\x01ubh\nt\x94h\x0eK\x05e.'
667)
668
669# Disassembly of DATA4
670DATA4_DIS = """\
671 0: \x80 PROTO 4
672 2: \x95 FRAME 168
673 11: ] EMPTY_LIST
674 12: \x94 MEMOIZE
675 13: ( MARK
676 14: K BININT1 0
677 16: K BININT1 1
678 18: G BINFLOAT 2.0
679 27: \x8c SHORT_BINUNICODE 'builtins'
680 37: \x94 MEMOIZE
681 38: \x8c SHORT_BINUNICODE 'complex'
682 47: \x94 MEMOIZE
683 48: \x93 STACK_GLOBAL
684 49: \x94 MEMOIZE
685 50: G BINFLOAT 3.0
686 59: G BINFLOAT 0.0
687 68: \x86 TUPLE2
688 69: \x94 MEMOIZE
689 70: R REDUCE
690 71: \x94 MEMOIZE
691 72: K BININT1 1
692 74: J BININT -1
693 79: K BININT1 255
694 81: J BININT -255
695 86: J BININT -256
696 91: M BININT2 65535
697 94: J BININT -65535
698 99: J BININT -65536
699 104: J BININT 2147483647
700 109: J BININT -2147483647
701 114: J BININT -2147483648
702 119: ( MARK
703 120: \x8c SHORT_BINUNICODE 'abc'
704 125: \x94 MEMOIZE
705 126: h BINGET 6
706 128: \x8c SHORT_BINUNICODE '__main__'
707 138: \x94 MEMOIZE
708 139: \x8c SHORT_BINUNICODE 'C'
709 142: \x94 MEMOIZE
710 143: \x93 STACK_GLOBAL
711 144: \x94 MEMOIZE
712 145: ) EMPTY_TUPLE
713 146: \x81 NEWOBJ
714 147: \x94 MEMOIZE
715 148: } EMPTY_DICT
716 149: \x94 MEMOIZE
717 150: ( MARK
718 151: \x8c SHORT_BINUNICODE 'bar'
719 156: \x94 MEMOIZE
720 157: K BININT1 2
721 159: \x8c SHORT_BINUNICODE 'foo'
722 164: \x94 MEMOIZE
723 165: K BININT1 1
724 167: u SETITEMS (MARK at 150)
725 168: b BUILD
726 169: h BINGET 10
727 171: t TUPLE (MARK at 119)
728 172: \x94 MEMOIZE
729 173: h BINGET 14
730 175: K BININT1 5
731 177: e APPENDS (MARK at 13)
732 178: . STOP
733highest protocol among opcodes = 4
734"""
735
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000736# set([1,2]) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300737DATA_SET = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000738
739# xrange(5) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300740DATA_XRANGE = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000741
742# a SimpleCookie() object pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300743DATA_COOKIE = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
744 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
745 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
746 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
747 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
748 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000749
750# set([3]) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300751DATA_SET2 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000752
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100753python2_exceptions_without_args = (
754 ArithmeticError,
755 AssertionError,
756 AttributeError,
757 BaseException,
758 BufferError,
759 BytesWarning,
760 DeprecationWarning,
761 EOFError,
762 EnvironmentError,
763 Exception,
764 FloatingPointError,
765 FutureWarning,
766 GeneratorExit,
767 IOError,
768 ImportError,
769 ImportWarning,
770 IndentationError,
771 IndexError,
772 KeyError,
773 KeyboardInterrupt,
774 LookupError,
775 MemoryError,
776 NameError,
777 NotImplementedError,
778 OSError,
779 OverflowError,
780 PendingDeprecationWarning,
781 ReferenceError,
782 RuntimeError,
783 RuntimeWarning,
784 # StandardError is gone in Python 3, we map it to Exception
785 StopIteration,
786 SyntaxError,
787 SyntaxWarning,
788 SystemError,
789 SystemExit,
790 TabError,
791 TypeError,
792 UnboundLocalError,
793 UnicodeError,
794 UnicodeWarning,
795 UserWarning,
796 ValueError,
797 Warning,
798 ZeroDivisionError,
799)
800
801exception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.'
802
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100803# UnicodeEncodeError object pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300804DATA_UEERR = (b'\x80\x02cexceptions\nUnicodeEncodeError\n'
805 b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01'
806 b'U\x03badq\x03tq\x04Rq\x05.')
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100807
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000808
Jeremy Hylton66426532001-10-15 21:38:56 +0000809def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000810 c = C()
811 c.foo = 1
812 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000813 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000814 # Append some integer test cases at cPickle.c's internal size
815 # cutoffs.
816 uint1max = 0xff
817 uint2max = 0xffff
818 int4max = 0x7fffffff
819 x.extend([1, -1,
820 uint1max, -uint1max, -uint1max-1,
821 uint2max, -uint2max, -uint2max-1,
822 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000823 y = ('abc', 'abc', c, c)
824 x.append(y)
825 x.append(y)
826 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000827 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000828
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100829
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300830class AbstractUnpickleTests(unittest.TestCase):
831 # Subclass must define self.loads.
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +0100832
Jeremy Hylton66426532001-10-15 21:38:56 +0000833 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000834
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100835 def assert_is_copy(self, obj, objcopy, msg=None):
836 """Utility method to verify if two objects are copies of each others.
837 """
838 if msg is None:
839 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
840 self.assertEqual(obj, objcopy, msg=msg)
841 self.assertIs(type(obj), type(objcopy), msg=msg)
842 if hasattr(obj, '__dict__'):
843 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
844 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
845 if hasattr(obj, '__slots__'):
846 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
847 for slot in obj.__slots__:
848 self.assertEqual(
849 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
850 self.assertEqual(getattr(obj, slot, None),
851 getattr(objcopy, slot, None), msg=msg)
852
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200853 def check_unpickling_error(self, errors, data):
854 with self.subTest(data=data), \
855 self.assertRaises(errors):
856 try:
857 self.loads(data)
858 except BaseException as exc:
859 if support.verbose > 1:
860 print('%-32r - %s: %s' %
861 (data, exc.__class__.__name__, exc))
862 raise
863
Guido van Rossum98297ee2007-11-06 21:34:58 +0000864 def test_load_from_data0(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100865 self.assert_is_copy(self._testdata, self.loads(DATA0))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000866
867 def test_load_from_data1(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100868 self.assert_is_copy(self._testdata, self.loads(DATA1))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000869
870 def test_load_from_data2(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100871 self.assert_is_copy(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000872
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300873 def test_load_from_data3(self):
874 self.assert_is_copy(self._testdata, self.loads(DATA3))
875
876 def test_load_from_data4(self):
877 self.assert_is_copy(self._testdata, self.loads(DATA4))
878
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000879 def test_load_classic_instance(self):
880 # See issue5180. Test loading 2.x pickles that
881 # contain an instance of old style class.
882 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
883 xname = X.__name__.encode('ascii')
884 # Protocol 0 (text mode pickle):
885 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200886 0: ( MARK
887 1: i INST '__main__ X' (MARK at 0)
888 13: p PUT 0
889 16: ( MARK
890 17: d DICT (MARK at 16)
891 18: p PUT 1
892 21: b BUILD
893 22: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000894 """
895 pickle0 = (b"(i__main__\n"
896 b"X\n"
897 b"p0\n"
898 b"(dp1\nb.").replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100899 self.assert_is_copy(X(*args), self.loads(pickle0))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000900
901 # Protocol 1 (binary mode pickle)
902 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200903 0: ( MARK
904 1: c GLOBAL '__main__ X'
905 13: q BINPUT 0
906 15: o OBJ (MARK at 0)
907 16: q BINPUT 1
908 18: } EMPTY_DICT
909 19: q BINPUT 2
910 21: b BUILD
911 22: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000912 """
913 pickle1 = (b'(c__main__\n'
914 b'X\n'
915 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100916 self.assert_is_copy(X(*args), self.loads(pickle1))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000917
918 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
919 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200920 0: \x80 PROTO 2
921 2: ( MARK
922 3: c GLOBAL '__main__ X'
923 15: q BINPUT 0
924 17: o OBJ (MARK at 2)
925 18: q BINPUT 1
926 20: } EMPTY_DICT
927 21: q BINPUT 2
928 23: b BUILD
929 24: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000930 """
931 pickle2 = (b'\x80\x02(c__main__\n'
932 b'X\n'
933 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100934 self.assert_is_copy(X(*args), self.loads(pickle2))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000935
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300936 def test_maxint64(self):
937 maxint64 = (1 << 63) - 1
938 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
939 got = self.loads(data)
940 self.assert_is_copy(maxint64, got)
941
942 # Try too with a bogus literal.
943 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200944 self.check_unpickling_error(ValueError, data)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300945
946 def test_unpickle_from_2x(self):
947 # Unpickle non-trivial data from Python 2.x.
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300948 loaded = self.loads(DATA_SET)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300949 self.assertEqual(loaded, set([1, 2]))
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300950 loaded = self.loads(DATA_XRANGE)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300951 self.assertEqual(type(loaded), type(range(0)))
952 self.assertEqual(list(loaded), list(range(5)))
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300953 loaded = self.loads(DATA_COOKIE)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300954 self.assertEqual(type(loaded), SimpleCookie)
955 self.assertEqual(list(loaded.keys()), ["key"])
956 self.assertEqual(loaded["key"].value, "value")
957
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300958 # Exception objects without arguments pickled from 2.x with protocol 2
959 for exc in python2_exceptions_without_args:
960 data = exception_pickle.replace(b'?', exc.__name__.encode("ascii"))
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300961 loaded = self.loads(data)
962 self.assertIs(type(loaded), exc)
963
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300964 # StandardError is mapped to Exception, test that separately
965 loaded = self.loads(exception_pickle.replace(b'?', b'StandardError'))
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300966 self.assertIs(type(loaded), Exception)
967
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300968 loaded = self.loads(DATA_UEERR)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300969 self.assertIs(type(loaded), UnicodeEncodeError)
970 self.assertEqual(loaded.object, "foo")
971 self.assertEqual(loaded.encoding, "ascii")
972 self.assertEqual(loaded.start, 0)
973 self.assertEqual(loaded.end, 1)
974 self.assertEqual(loaded.reason, "bad")
975
976 def test_load_python2_str_as_bytes(self):
977 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
978 self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
979 encoding="bytes"), b'a\x00\xa0')
980 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
981 self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
982 encoding="bytes"), b'a\x00\xa0')
983 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
984 self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
985 encoding="bytes"), b'a\x00\xa0')
986
987 def test_load_python2_unicode_as_str(self):
988 # From Python 2: pickle.dumps(u'π', protocol=0)
989 self.assertEqual(self.loads(b'V\\u03c0\n.',
990 encoding='bytes'), 'π')
991 # From Python 2: pickle.dumps(u'π', protocol=1)
992 self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
993 encoding="bytes"), 'π')
994 # From Python 2: pickle.dumps(u'π', protocol=2)
995 self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
996 encoding="bytes"), 'π')
997
998 def test_load_long_python2_str_as_bytes(self):
999 # From Python 2: pickle.dumps('x' * 300, protocol=1)
1000 self.assertEqual(self.loads(pickle.BINSTRING +
1001 struct.pack("<I", 300) +
1002 b'x' * 300 + pickle.STOP,
1003 encoding='bytes'), b'x' * 300)
1004
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001005 def test_constants(self):
1006 self.assertIsNone(self.loads(b'N.'))
1007 self.assertIs(self.loads(b'\x88.'), True)
1008 self.assertIs(self.loads(b'\x89.'), False)
1009 self.assertIs(self.loads(b'I01\n.'), True)
1010 self.assertIs(self.loads(b'I00\n.'), False)
1011
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001012 def test_empty_bytestring(self):
1013 # issue 11286
1014 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1015 self.assertEqual(empty, '')
1016
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001017 def test_short_binbytes(self):
1018 dumped = b'\x80\x03C\x04\xe2\x82\xac\x00.'
1019 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
1020
1021 def test_binbytes(self):
1022 dumped = b'\x80\x03B\x04\x00\x00\x00\xe2\x82\xac\x00.'
1023 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
1024
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001025 @requires_32b
1026 def test_negative_32b_binbytes(self):
1027 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1028 dumped = b'\x80\x03B\xff\xff\xff\xffxyzq\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001029 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
1030 dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001031
1032 @requires_32b
1033 def test_negative_32b_binunicode(self):
1034 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1035 dumped = b'\x80\x03X\xff\xff\xff\xffxyzq\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001036 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
1037 dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001038
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001039 def test_short_binunicode(self):
1040 dumped = b'\x80\x04\x8c\x04\xe2\x82\xac\x00.'
1041 self.assertEqual(self.loads(dumped), '\u20ac\x00')
1042
1043 def test_misc_get(self):
Claudiu Popa6f03b232019-11-24 20:15:08 +01001044 self.check_unpickling_error(pickle.UnpicklingError, b'g0\np0')
1045 self.check_unpickling_error(pickle.UnpicklingError, b'jens:')
1046 self.check_unpickling_error(pickle.UnpicklingError, b'hens:')
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001047 self.assert_is_copy([(100,), (100,)],
1048 self.loads(b'((Kdtp0\nh\x00l.))'))
1049
Serhiy Storchakae0606192015-09-29 22:10:07 +03001050 def test_binbytes8(self):
1051 dumped = b'\x80\x04\x8e\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
1052 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
1053
1054 def test_binunicode8(self):
1055 dumped = b'\x80\x04\x8d\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
1056 self.assertEqual(self.loads(dumped), '\u20ac\x00')
1057
Antoine Pitrou91f43802019-05-26 17:10:09 +02001058 def test_bytearray8(self):
1059 dumped = b'\x80\x05\x96\x03\x00\x00\x00\x00\x00\x00\x00xxx.'
1060 self.assertEqual(self.loads(dumped), bytearray(b'xxx'))
1061
Serhiy Storchakae0606192015-09-29 22:10:07 +03001062 @requires_32b
1063 def test_large_32b_binbytes8(self):
1064 dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001065 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
1066 dumped)
Serhiy Storchakae0606192015-09-29 22:10:07 +03001067
1068 @requires_32b
Antoine Pitrou91f43802019-05-26 17:10:09 +02001069 def test_large_32b_bytearray8(self):
1070 dumped = b'\x80\x05\x96\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
1071 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
1072 dumped)
1073
1074 @requires_32b
Serhiy Storchakae0606192015-09-29 22:10:07 +03001075 def test_large_32b_binunicode8(self):
1076 dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001077 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
1078 dumped)
Serhiy Storchakae0606192015-09-29 22:10:07 +03001079
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001080 def test_get(self):
1081 pickled = b'((lp100000\ng100000\nt.'
1082 unpickled = self.loads(pickled)
1083 self.assertEqual(unpickled, ([],)*2)
1084 self.assertIs(unpickled[0], unpickled[1])
1085
1086 def test_binget(self):
1087 pickled = b'(]q\xffh\xfft.'
1088 unpickled = self.loads(pickled)
1089 self.assertEqual(unpickled, ([],)*2)
1090 self.assertIs(unpickled[0], unpickled[1])
1091
1092 def test_long_binget(self):
1093 pickled = b'(]r\x00\x00\x01\x00j\x00\x00\x01\x00t.'
1094 unpickled = self.loads(pickled)
1095 self.assertEqual(unpickled, ([],)*2)
1096 self.assertIs(unpickled[0], unpickled[1])
1097
1098 def test_dup(self):
1099 pickled = b'((l2t.'
1100 unpickled = self.loads(pickled)
1101 self.assertEqual(unpickled, ([],)*2)
1102 self.assertIs(unpickled[0], unpickled[1])
1103
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001104 def test_negative_put(self):
1105 # Issue #12847
1106 dumped = b'Va\np-1\n.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001107 self.check_unpickling_error(ValueError, dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001108
1109 @requires_32b
1110 def test_negative_32b_binput(self):
1111 # Issue #12847
1112 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001113 self.check_unpickling_error(ValueError, dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001114
1115 def test_badly_escaped_string(self):
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001116 self.check_unpickling_error(ValueError, b"S'\\'\n.")
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001117
1118 def test_badly_quoted_string(self):
1119 # Issue #17710
1120 badpickles = [b"S'\n.",
1121 b'S"\n.',
1122 b'S\' \n.',
1123 b'S" \n.',
1124 b'S\'"\n.',
1125 b'S"\'\n.',
1126 b"S' ' \n.",
1127 b'S" " \n.',
1128 b"S ''\n.",
1129 b'S ""\n.',
1130 b'S \n.',
1131 b'S\n.',
1132 b'S.']
1133 for p in badpickles:
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001134 self.check_unpickling_error(pickle.UnpicklingError, p)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001135
1136 def test_correctly_quoted_string(self):
1137 goodpickles = [(b"S''\n.", ''),
1138 (b'S""\n.', ''),
1139 (b'S"\\n"\n.', '\n'),
1140 (b"S'\\n'\n.", '\n')]
1141 for p, expected in goodpickles:
1142 self.assertEqual(self.loads(p), expected)
1143
1144 def test_frame_readline(self):
1145 pickled = b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00I42\n.'
1146 # 0: \x80 PROTO 4
1147 # 2: \x95 FRAME 5
1148 # 11: I INT 42
1149 # 15: . STOP
1150 self.assertEqual(self.loads(pickled), 42)
1151
1152 def test_compat_unpickle(self):
1153 # xrange(1, 7)
1154 pickled = b'\x80\x02c__builtin__\nxrange\nK\x01K\x07K\x01\x87R.'
1155 unpickled = self.loads(pickled)
1156 self.assertIs(type(unpickled), range)
1157 self.assertEqual(unpickled, range(1, 7))
1158 self.assertEqual(list(unpickled), [1, 2, 3, 4, 5, 6])
1159 # reduce
1160 pickled = b'\x80\x02c__builtin__\nreduce\n.'
1161 self.assertIs(self.loads(pickled), functools.reduce)
1162 # whichdb.whichdb
1163 pickled = b'\x80\x02cwhichdb\nwhichdb\n.'
1164 self.assertIs(self.loads(pickled), dbm.whichdb)
1165 # Exception(), StandardError()
1166 for name in (b'Exception', b'StandardError'):
1167 pickled = (b'\x80\x02cexceptions\n' + name + b'\nU\x03ugh\x85R.')
1168 unpickled = self.loads(pickled)
1169 self.assertIs(type(unpickled), Exception)
1170 self.assertEqual(str(unpickled), 'ugh')
1171 # UserDict.UserDict({1: 2}), UserDict.IterableUserDict({1: 2})
1172 for name in (b'UserDict', b'IterableUserDict'):
1173 pickled = (b'\x80\x02(cUserDict\n' + name +
1174 b'\no}U\x04data}K\x01K\x02ssb.')
1175 unpickled = self.loads(pickled)
1176 self.assertIs(type(unpickled), collections.UserDict)
1177 self.assertEqual(unpickled, collections.UserDict({1: 2}))
1178
Serhiy Storchaka4f309ab2020-07-13 15:49:26 +03001179 def test_bad_reduce(self):
1180 self.assertEqual(self.loads(b'cbuiltins\nint\n)R.'), 0)
1181 self.check_unpickling_error(TypeError, b'N)R.')
1182 self.check_unpickling_error(TypeError, b'cbuiltins\nint\nNR.')
1183
1184 def test_bad_newobj(self):
1185 error = (pickle.UnpicklingError, TypeError)
1186 self.assertEqual(self.loads(b'cbuiltins\nint\n)\x81.'), 0)
1187 self.check_unpickling_error(error, b'cbuiltins\nlen\n)\x81.')
1188 self.check_unpickling_error(error, b'cbuiltins\nint\nN\x81.')
1189
1190 def test_bad_newobj_ex(self):
1191 error = (pickle.UnpicklingError, TypeError)
1192 self.assertEqual(self.loads(b'cbuiltins\nint\n)}\x92.'), 0)
1193 self.check_unpickling_error(error, b'cbuiltins\nlen\n)}\x92.')
1194 self.check_unpickling_error(error, b'cbuiltins\nint\nN}\x92.')
1195 self.check_unpickling_error(error, b'cbuiltins\nint\n)N\x92.')
1196
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001197 def test_bad_stack(self):
1198 badpickles = [
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001199 b'.', # STOP
1200 b'0', # POP
1201 b'1', # POP_MARK
1202 b'2', # DUP
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001203 b'(2',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001204 b'R', # REDUCE
1205 b')R',
1206 b'a', # APPEND
1207 b'Na',
1208 b'b', # BUILD
1209 b'Nb',
1210 b'd', # DICT
1211 b'e', # APPENDS
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001212 b'(e',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001213 b'ibuiltins\nlist\n', # INST
1214 b'l', # LIST
1215 b'o', # OBJ
1216 b'(o',
1217 b'p1\n', # PUT
1218 b'q\x00', # BINPUT
1219 b'r\x00\x00\x00\x00', # LONG_BINPUT
1220 b's', # SETITEM
1221 b'Ns',
1222 b'NNs',
1223 b't', # TUPLE
1224 b'u', # SETITEMS
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001225 b'(u',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001226 b'}(Nu',
1227 b'\x81', # NEWOBJ
1228 b')\x81',
1229 b'\x85', # TUPLE1
1230 b'\x86', # TUPLE2
1231 b'N\x86',
1232 b'\x87', # TUPLE3
1233 b'N\x87',
1234 b'NN\x87',
1235 b'\x90', # ADDITEMS
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001236 b'(\x90',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001237 b'\x91', # FROZENSET
1238 b'\x92', # NEWOBJ_EX
1239 b')}\x92',
1240 b'\x93', # STACK_GLOBAL
1241 b'Vlist\n\x93',
1242 b'\x94', # MEMOIZE
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001243 ]
1244 for p in badpickles:
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001245 self.check_unpickling_error(self.bad_stack_errors, p)
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001246
1247 def test_bad_mark(self):
1248 badpickles = [
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001249 b'N(.', # STOP
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001250 b'N(2', # DUP
1251 b'cbuiltins\nlist\n)(R', # REDUCE
1252 b'cbuiltins\nlist\n()R',
1253 b']N(a', # APPEND
1254 # BUILD
1255 b'cbuiltins\nValueError\n)R}(b',
1256 b'cbuiltins\nValueError\n)R(}b',
1257 b'(Nd', # DICT
1258 b'N(p1\n', # PUT
1259 b'N(q\x00', # BINPUT
1260 b'N(r\x00\x00\x00\x00', # LONG_BINPUT
1261 b'}NN(s', # SETITEM
1262 b'}N(Ns',
1263 b'}(NNs',
1264 b'}((u', # SETITEMS
1265 b'cbuiltins\nlist\n)(\x81', # NEWOBJ
1266 b'cbuiltins\nlist\n()\x81',
1267 b'N(\x85', # TUPLE1
1268 b'NN(\x86', # TUPLE2
1269 b'N(N\x86',
1270 b'NNN(\x87', # TUPLE3
1271 b'NN(N\x87',
1272 b'N(NN\x87',
1273 b']((\x90', # ADDITEMS
1274 # NEWOBJ_EX
1275 b'cbuiltins\nlist\n)}(\x92',
1276 b'cbuiltins\nlist\n)(}\x92',
1277 b'cbuiltins\nlist\n()}\x92',
1278 # STACK_GLOBAL
1279 b'Vbuiltins\n(Vlist\n\x93',
1280 b'Vbuiltins\nVlist\n(\x93',
1281 b'N(\x94', # MEMOIZE
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001282 ]
1283 for p in badpickles:
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001284 self.check_unpickling_error(self.bad_stack_errors, p)
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001285
1286 def test_truncated_data(self):
1287 self.check_unpickling_error(EOFError, b'')
1288 self.check_unpickling_error(EOFError, b'N')
1289 badpickles = [
1290 b'B', # BINBYTES
1291 b'B\x03\x00\x00',
1292 b'B\x03\x00\x00\x00',
1293 b'B\x03\x00\x00\x00ab',
1294 b'C', # SHORT_BINBYTES
1295 b'C\x03',
1296 b'C\x03ab',
1297 b'F', # FLOAT
1298 b'F0.0',
1299 b'F0.00',
1300 b'G', # BINFLOAT
1301 b'G\x00\x00\x00\x00\x00\x00\x00',
1302 b'I', # INT
1303 b'I0',
1304 b'J', # BININT
1305 b'J\x00\x00\x00',
1306 b'K', # BININT1
1307 b'L', # LONG
1308 b'L0',
1309 b'L10',
1310 b'L0L',
1311 b'L10L',
1312 b'M', # BININT2
1313 b'M\x00',
1314 # b'P', # PERSID
1315 # b'Pabc',
1316 b'S', # STRING
1317 b"S'abc'",
1318 b'T', # BINSTRING
1319 b'T\x03\x00\x00',
1320 b'T\x03\x00\x00\x00',
1321 b'T\x03\x00\x00\x00ab',
1322 b'U', # SHORT_BINSTRING
1323 b'U\x03',
1324 b'U\x03ab',
1325 b'V', # UNICODE
1326 b'Vabc',
1327 b'X', # BINUNICODE
1328 b'X\x03\x00\x00',
1329 b'X\x03\x00\x00\x00',
1330 b'X\x03\x00\x00\x00ab',
1331 b'(c', # GLOBAL
1332 b'(cbuiltins',
1333 b'(cbuiltins\n',
1334 b'(cbuiltins\nlist',
1335 b'Ng', # GET
1336 b'Ng0',
1337 b'(i', # INST
1338 b'(ibuiltins',
1339 b'(ibuiltins\n',
1340 b'(ibuiltins\nlist',
1341 b'Nh', # BINGET
1342 b'Nj', # LONG_BINGET
1343 b'Nj\x00\x00\x00',
1344 b'Np', # PUT
1345 b'Np0',
1346 b'Nq', # BINPUT
1347 b'Nr', # LONG_BINPUT
1348 b'Nr\x00\x00\x00',
1349 b'\x80', # PROTO
1350 b'\x82', # EXT1
1351 b'\x83', # EXT2
1352 b'\x84\x01',
1353 b'\x84', # EXT4
1354 b'\x84\x01\x00\x00',
1355 b'\x8a', # LONG1
1356 b'\x8b', # LONG4
1357 b'\x8b\x00\x00\x00',
1358 b'\x8c', # SHORT_BINUNICODE
1359 b'\x8c\x03',
1360 b'\x8c\x03ab',
1361 b'\x8d', # BINUNICODE8
1362 b'\x8d\x03\x00\x00\x00\x00\x00\x00',
1363 b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00',
1364 b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00ab',
1365 b'\x8e', # BINBYTES8
1366 b'\x8e\x03\x00\x00\x00\x00\x00\x00',
1367 b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00',
1368 b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00ab',
Antoine Pitrou91f43802019-05-26 17:10:09 +02001369 b'\x96', # BYTEARRAY8
1370 b'\x96\x03\x00\x00\x00\x00\x00\x00',
1371 b'\x96\x03\x00\x00\x00\x00\x00\x00\x00',
1372 b'\x96\x03\x00\x00\x00\x00\x00\x00\x00ab',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001373 b'\x95', # FRAME
1374 b'\x95\x02\x00\x00\x00\x00\x00\x00',
1375 b'\x95\x02\x00\x00\x00\x00\x00\x00\x00',
1376 b'\x95\x02\x00\x00\x00\x00\x00\x00\x00N',
1377 ]
1378 for p in badpickles:
1379 self.check_unpickling_error(self.truncated_errors, p)
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001380
Hai Shie80697d2020-05-28 06:10:27 +08001381 @threading_helper.reap_threads
tjb9004371c0a2019-02-18 23:30:51 +08001382 def test_unpickle_module_race(self):
1383 # https://bugs.python.org/issue34572
1384 locker_module = dedent("""
1385 import threading
1386 barrier = threading.Barrier(2)
1387 """)
1388 locking_import_module = dedent("""
1389 import locker
1390 locker.barrier.wait()
1391 class ToBeUnpickled(object):
1392 pass
1393 """)
1394
1395 os.mkdir(TESTFN)
1396 self.addCleanup(shutil.rmtree, TESTFN)
1397 sys.path.insert(0, TESTFN)
1398 self.addCleanup(sys.path.remove, TESTFN)
1399 with open(os.path.join(TESTFN, "locker.py"), "wb") as f:
1400 f.write(locker_module.encode('utf-8'))
1401 with open(os.path.join(TESTFN, "locking_import.py"), "wb") as f:
1402 f.write(locking_import_module.encode('utf-8'))
1403 self.addCleanup(forget, "locker")
1404 self.addCleanup(forget, "locking_import")
1405
1406 import locker
1407
1408 pickle_bytes = (
1409 b'\x80\x03clocking_import\nToBeUnpickled\nq\x00)\x81q\x01.')
1410
1411 # Then try to unpickle two of these simultaneously
1412 # One of them will cause the module import, and we want it to block
1413 # until the other one either:
1414 # - fails (before the patch for this issue)
1415 # - blocks on the import lock for the module, as it should
1416 results = []
1417 barrier = threading.Barrier(3)
1418 def t():
1419 # This ensures the threads have all started
1420 # presumably barrier release is faster than thread startup
1421 barrier.wait()
1422 results.append(pickle.loads(pickle_bytes))
1423
1424 t1 = threading.Thread(target=t)
1425 t2 = threading.Thread(target=t)
1426 t1.start()
1427 t2.start()
1428
1429 barrier.wait()
1430 # could have delay here
1431 locker.barrier.wait()
1432
1433 t1.join()
1434 t2.join()
1435
1436 from locking_import import ToBeUnpickled
1437 self.assertEqual(
1438 [type(x) for x in results],
1439 [ToBeUnpickled] * 2)
1440
1441
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001442
1443class AbstractPickleTests(unittest.TestCase):
1444 # Subclass must define self.dumps, self.loads.
1445
1446 optimized = False
1447
1448 _testdata = AbstractUnpickleTests._testdata
1449
1450 def setUp(self):
1451 pass
1452
1453 assert_is_copy = AbstractUnpickleTests.assert_is_copy
1454
1455 def test_misc(self):
1456 # test various datatypes not tested by testdata
1457 for proto in protocols:
1458 x = myint(4)
1459 s = self.dumps(x, proto)
1460 y = self.loads(s)
1461 self.assert_is_copy(x, y)
1462
1463 x = (1, ())
1464 s = self.dumps(x, proto)
1465 y = self.loads(s)
1466 self.assert_is_copy(x, y)
1467
1468 x = initarg(1, x)
1469 s = self.dumps(x, proto)
1470 y = self.loads(s)
1471 self.assert_is_copy(x, y)
1472
1473 # XXX test __reduce__ protocol?
1474
1475 def test_roundtrip_equality(self):
1476 expected = self._testdata
1477 for proto in protocols:
1478 s = self.dumps(expected, proto)
1479 got = self.loads(s)
1480 self.assert_is_copy(expected, got)
1481
Tim Peters70b02d72003-02-02 17:26:40 +00001482 # There are gratuitous differences between pickles produced by
1483 # pickle and cPickle, largely because cPickle starts PUT indices at
1484 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
1485 # there's a comment with an exclamation point there whose meaning
1486 # is a mystery. cPickle also suppresses PUT for objects with a refcount
1487 # of 1.
1488 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +00001489 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +00001490 from pickletools import dis
1491
1492 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
1493 s = self.dumps(self._testdata, proto)
1494 filelike = StringIO()
1495 dis(s, out=filelike)
1496 got = filelike.getvalue()
1497 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +00001498
1499 def test_recursive_list(self):
1500 l = []
1501 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +00001502 for proto in protocols:
1503 s = self.dumps(l, proto)
1504 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001505 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001506 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001507 self.assertIs(x[0], x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001508
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001509 def test_recursive_tuple_and_list(self):
Collin Winter8ca69de2009-05-26 16:53:41 +00001510 t = ([],)
1511 t[0].append(t)
1512 for proto in protocols:
1513 s = self.dumps(t, proto)
1514 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001515 self.assertIsInstance(x, tuple)
Collin Winter8ca69de2009-05-26 16:53:41 +00001516 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001517 self.assertIsInstance(x[0], list)
Collin Winter8ca69de2009-05-26 16:53:41 +00001518 self.assertEqual(len(x[0]), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001519 self.assertIs(x[0][0], x)
Collin Winter8ca69de2009-05-26 16:53:41 +00001520
Jeremy Hylton66426532001-10-15 21:38:56 +00001521 def test_recursive_dict(self):
1522 d = {}
1523 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +00001524 for proto in protocols:
1525 s = self.dumps(d, proto)
1526 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001527 self.assertIsInstance(x, dict)
Guido van Rossumcc2b0162007-02-11 06:12:03 +00001528 self.assertEqual(list(x.keys()), [1])
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001529 self.assertIs(x[1], x)
1530
1531 def test_recursive_dict_key(self):
1532 d = {}
1533 k = K(d)
1534 d[k] = 1
1535 for proto in protocols:
1536 s = self.dumps(d, proto)
1537 x = self.loads(s)
1538 self.assertIsInstance(x, dict)
1539 self.assertEqual(len(x.keys()), 1)
1540 self.assertIsInstance(list(x.keys())[0], K)
1541 self.assertIs(list(x.keys())[0].value, x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001542
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001543 def test_recursive_set(self):
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001544 y = set()
1545 k = K(y)
1546 y.add(k)
1547 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001548 s = self.dumps(y, proto)
1549 x = self.loads(s)
1550 self.assertIsInstance(x, set)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001551 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001552 self.assertIsInstance(list(x)[0], K)
1553 self.assertIs(list(x)[0].value, x)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001554
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001555 def test_recursive_list_subclass(self):
1556 y = MyList()
1557 y.append(y)
1558 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001559 s = self.dumps(y, proto)
1560 x = self.loads(s)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001561 self.assertIsInstance(x, MyList)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001562 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001563 self.assertIs(x[0], x)
1564
1565 def test_recursive_dict_subclass(self):
1566 d = MyDict()
1567 d[1] = d
1568 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1569 s = self.dumps(d, proto)
1570 x = self.loads(s)
1571 self.assertIsInstance(x, MyDict)
1572 self.assertEqual(list(x.keys()), [1])
1573 self.assertIs(x[1], x)
1574
1575 def test_recursive_dict_subclass_key(self):
1576 d = MyDict()
1577 k = K(d)
1578 d[k] = 1
1579 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1580 s = self.dumps(d, proto)
1581 x = self.loads(s)
1582 self.assertIsInstance(x, MyDict)
1583 self.assertEqual(len(list(x.keys())), 1)
1584 self.assertIsInstance(list(x.keys())[0], K)
1585 self.assertIs(list(x.keys())[0].value, x)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001586
Jeremy Hylton66426532001-10-15 21:38:56 +00001587 def test_recursive_inst(self):
1588 i = C()
1589 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +00001590 for proto in protocols:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001591 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +00001592 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001593 self.assertIsInstance(x, C)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001594 self.assertEqual(dir(x), dir(i))
Ezio Melottiaaef3442013-03-04 15:17:56 +02001595 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001596
1597 def test_recursive_multi(self):
1598 l = []
1599 d = {1:l}
1600 i = C()
1601 i.attr = d
1602 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +00001603 for proto in protocols:
1604 s = self.dumps(l, proto)
1605 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001606 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001607 self.assertEqual(len(x), 1)
1608 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +00001609 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001610 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001611
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001612 def check_recursive_collection_and_inst(self, factory):
1613 h = H()
1614 y = factory([h])
1615 h.attr = y
1616 for proto in protocols:
1617 s = self.dumps(y, proto)
1618 x = self.loads(s)
1619 self.assertIsInstance(x, type(y))
1620 self.assertEqual(len(x), 1)
1621 self.assertIsInstance(list(x)[0], H)
1622 self.assertIs(list(x)[0].attr, x)
1623
1624 def test_recursive_list_and_inst(self):
1625 self.check_recursive_collection_and_inst(list)
1626
1627 def test_recursive_tuple_and_inst(self):
1628 self.check_recursive_collection_and_inst(tuple)
1629
1630 def test_recursive_dict_and_inst(self):
1631 self.check_recursive_collection_and_inst(dict.fromkeys)
1632
1633 def test_recursive_set_and_inst(self):
1634 self.check_recursive_collection_and_inst(set)
1635
1636 def test_recursive_frozenset_and_inst(self):
1637 self.check_recursive_collection_and_inst(frozenset)
1638
1639 def test_recursive_list_subclass_and_inst(self):
1640 self.check_recursive_collection_and_inst(MyList)
1641
1642 def test_recursive_tuple_subclass_and_inst(self):
1643 self.check_recursive_collection_and_inst(MyTuple)
1644
1645 def test_recursive_dict_subclass_and_inst(self):
1646 self.check_recursive_collection_and_inst(MyDict.fromkeys)
1647
1648 def test_recursive_set_subclass_and_inst(self):
1649 self.check_recursive_collection_and_inst(MySet)
1650
1651 def test_recursive_frozenset_subclass_and_inst(self):
1652 self.check_recursive_collection_and_inst(MyFrozenSet)
1653
Walter Dörwald9b775532007-06-08 14:30:53 +00001654 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +00001655 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +00001656 '<\\>', '<\\\U00012345>',
1657 # surrogates
1658 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +00001659 for proto in protocols:
1660 for u in endcases:
1661 p = self.dumps(u, proto)
1662 u2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001663 self.assert_is_copy(u, u2)
Tim Peterse089c682001-04-10 03:41:41 +00001664
Alexandre Vassalotti554d8782008-12-27 07:32:41 +00001665 def test_unicode_high_plane(self):
1666 t = '\U00012345'
1667 for proto in protocols:
1668 p = self.dumps(t, proto)
1669 t2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001670 self.assert_is_copy(t, t2)
Alexandre Vassalotti554d8782008-12-27 07:32:41 +00001671
Guido van Rossumf4169812008-03-17 22:56:06 +00001672 def test_bytes(self):
1673 for proto in protocols:
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001674 for s in b'', b'xyz', b'xyz'*100:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001675 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001676 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001677 for s in [bytes([i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001678 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001679 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001680 for s in [bytes([i, i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001681 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001682 self.assert_is_copy(s, self.loads(p))
Guido van Rossumf4169812008-03-17 22:56:06 +00001683
Antoine Pitrou91f43802019-05-26 17:10:09 +02001684 def test_bytearray(self):
1685 for proto in protocols:
1686 for s in b'', b'xyz', b'xyz'*100:
1687 b = bytearray(s)
1688 p = self.dumps(b, proto)
1689 bb = self.loads(p)
1690 self.assertIsNot(bb, b)
1691 self.assert_is_copy(b, bb)
1692 if proto <= 3:
1693 # bytearray is serialized using a global reference
1694 self.assertIn(b'bytearray', p)
1695 self.assertTrue(opcode_in_pickle(pickle.GLOBAL, p))
1696 elif proto == 4:
1697 self.assertIn(b'bytearray', p)
1698 self.assertTrue(opcode_in_pickle(pickle.STACK_GLOBAL, p))
1699 elif proto == 5:
1700 self.assertNotIn(b'bytearray', p)
1701 self.assertTrue(opcode_in_pickle(pickle.BYTEARRAY8, p))
1702
Jeremy Hylton66426532001-10-15 21:38:56 +00001703 def test_ints(self):
Tim Petersee1a53c2003-02-02 02:57:53 +00001704 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +00001705 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +00001706 while n:
1707 for expected in (-n, n):
1708 s = self.dumps(expected, proto)
1709 n2 = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001710 self.assert_is_copy(expected, n2)
Tim Petersee1a53c2003-02-02 02:57:53 +00001711 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +00001712
Tim Petersee1a53c2003-02-02 02:57:53 +00001713 def test_long(self):
1714 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +00001715 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +00001716 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +00001717 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +00001718 for npos in nbase-1, nbase, nbase+1:
1719 for n in npos, -npos:
1720 pickle = self.dumps(n, proto)
1721 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001722 self.assert_is_copy(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +00001723 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
1724 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +00001725 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +00001726 nbase += nbase << 1000000
1727 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +00001728 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +00001729 got = self.loads(p)
Antoine Pitroud5df1942013-11-23 21:20:49 +01001730 # assert_is_copy is very expensive here as it precomputes
1731 # a failure message by computing the repr() of n and got,
1732 # we just do the check ourselves.
1733 self.assertIs(type(got), int)
1734 self.assertEqual(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +00001735
Mark Dickinsoncddcf442009-01-24 21:46:33 +00001736 def test_float(self):
1737 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
1738 3.14, 263.44582062374053, 6.022e23, 1e30]
1739 test_values = test_values + [-x for x in test_values]
1740 for proto in protocols:
1741 for value in test_values:
1742 pickle = self.dumps(value, proto)
1743 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001744 self.assert_is_copy(value, got)
Mark Dickinsoncddcf442009-01-24 21:46:33 +00001745
Thomas Wouters477c8d52006-05-27 19:21:47 +00001746 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
1747 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +00001748 # make sure that floats are formatted locale independent with proto 0
1749 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001750
Jeremy Hylton66426532001-10-15 21:38:56 +00001751 def test_reduce(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +01001752 for proto in protocols:
1753 inst = AAA()
1754 dumped = self.dumps(inst, proto)
1755 loaded = self.loads(dumped)
1756 self.assertEqual(loaded, REDUCE_A)
Jeremy Hylton66426532001-10-15 21:38:56 +00001757
1758 def test_getinitargs(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +01001759 for proto in protocols:
1760 inst = initarg(1, 2)
1761 dumped = self.dumps(inst, proto)
1762 loaded = self.loads(dumped)
1763 self.assert_is_copy(inst, loaded)
Jeremy Hylton66426532001-10-15 21:38:56 +00001764
Guido van Rossum04a86612001-12-19 16:58:54 +00001765 def test_metaclass(self):
1766 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +00001767 for proto in protocols:
1768 s = self.dumps(a, proto)
1769 b = self.loads(s)
1770 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +00001771
Antoine Pitrouffd41d92011-10-04 09:23:04 +02001772 def test_dynamic_class(self):
1773 a = create_dynamic_class("my_dynamic_class", (object,))
1774 copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
1775 for proto in protocols:
1776 s = self.dumps(a, proto)
1777 b = self.loads(s)
1778 self.assertEqual(a, b)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001779 self.assertIs(type(a), type(b))
Antoine Pitrouffd41d92011-10-04 09:23:04 +02001780
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001781 def test_structseq(self):
1782 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +00001783 import os
Tim Peters70b02d72003-02-02 17:26:40 +00001784
1785 t = time.localtime()
1786 for proto in protocols:
1787 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +00001788 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001789 self.assert_is_copy(t, u)
Anthony Sottile8377cd42019-02-25 14:32:27 -08001790 t = os.stat(os.curdir)
1791 s = self.dumps(t, proto)
1792 u = self.loads(s)
1793 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +00001794 if hasattr(os, "statvfs"):
1795 t = os.statvfs(os.curdir)
1796 s = self.dumps(t, proto)
1797 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001798 self.assert_is_copy(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001799
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001800 def test_ellipsis(self):
1801 for proto in protocols:
1802 s = self.dumps(..., proto)
1803 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001804 self.assertIs(..., u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001805
1806 def test_notimplemented(self):
1807 for proto in protocols:
1808 s = self.dumps(NotImplemented, proto)
1809 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001810 self.assertIs(NotImplemented, u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001811
Alexandre Vassalotti19b6fa62013-11-30 16:06:39 -08001812 def test_singleton_types(self):
1813 # Issue #6477: Test that types of built-in singletons can be pickled.
1814 singletons = [None, ..., NotImplemented]
1815 for singleton in singletons:
1816 for proto in protocols:
1817 s = self.dumps(type(singleton), proto)
1818 u = self.loads(s)
1819 self.assertIs(type(singleton), u)
1820
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001821 # Tests for protocol 2
1822
Tim Peters4190fb82003-02-02 16:09:05 +00001823 def test_proto(self):
Tim Peters4190fb82003-02-02 16:09:05 +00001824 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001825 pickled = self.dumps(None, proto)
Tim Peters4190fb82003-02-02 16:09:05 +00001826 if proto >= 2:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001827 proto_header = pickle.PROTO + bytes([proto])
1828 self.assertTrue(pickled.startswith(proto_header))
1829 else:
1830 self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)
Tim Peters4190fb82003-02-02 16:09:05 +00001831
1832 oob = protocols[-1] + 1 # a future protocol
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001833 build_none = pickle.NONE + pickle.STOP
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001834 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +00001835 try:
1836 self.loads(badpickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001837 except ValueError as err:
1838 self.assertIn("unsupported pickle protocol", str(err))
Tim Peters4190fb82003-02-02 16:09:05 +00001839 else:
1840 self.fail("expected bad protocol number to raise ValueError")
1841
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001842 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +00001843 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +00001844 for proto in protocols:
1845 s = self.dumps(x, proto)
1846 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001847 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001848 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001849
1850 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +00001851 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +00001852 for proto in protocols:
1853 s = self.dumps(x, proto)
1854 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001855 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001856 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001857
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001858 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +00001859 # Map (proto, len(tuple)) to expected opcode.
1860 expected_opcode = {(0, 0): pickle.TUPLE,
1861 (0, 1): pickle.TUPLE,
1862 (0, 2): pickle.TUPLE,
1863 (0, 3): pickle.TUPLE,
1864 (0, 4): pickle.TUPLE,
1865
1866 (1, 0): pickle.EMPTY_TUPLE,
1867 (1, 1): pickle.TUPLE,
1868 (1, 2): pickle.TUPLE,
1869 (1, 3): pickle.TUPLE,
1870 (1, 4): pickle.TUPLE,
1871
1872 (2, 0): pickle.EMPTY_TUPLE,
1873 (2, 1): pickle.TUPLE1,
1874 (2, 2): pickle.TUPLE2,
1875 (2, 3): pickle.TUPLE3,
1876 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001877
1878 (3, 0): pickle.EMPTY_TUPLE,
1879 (3, 1): pickle.TUPLE1,
1880 (3, 2): pickle.TUPLE2,
1881 (3, 3): pickle.TUPLE3,
1882 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +00001883 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001884 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +00001885 b = (1,)
1886 c = (1, 2)
1887 d = (1, 2, 3)
1888 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +00001889 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001890 for x in a, b, c, d, e:
1891 s = self.dumps(x, proto)
1892 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001893 self.assert_is_copy(x, y)
1894 expected = expected_opcode[min(proto, 3), len(x)]
1895 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters1d63c9f2003-02-02 20:29:39 +00001896
Guido van Rossum7d97d312003-01-28 04:25:27 +00001897 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +00001898 # Map (proto, singleton) to expected opcode.
1899 expected_opcode = {(0, None): pickle.NONE,
1900 (1, None): pickle.NONE,
1901 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001902 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +00001903
1904 (0, True): pickle.INT,
1905 (1, True): pickle.INT,
1906 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001907 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +00001908
1909 (0, False): pickle.INT,
1910 (1, False): pickle.INT,
1911 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001912 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +00001913 }
Tim Peters4190fb82003-02-02 16:09:05 +00001914 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +00001915 for x in None, False, True:
1916 s = self.dumps(x, proto)
1917 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001918 self.assertTrue(x is y, (proto, x, s, y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001919 expected = expected_opcode[min(proto, 3), x]
1920 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters3c67d792003-02-02 17:59:11 +00001921
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001922 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001923 x = MyTuple([1, 2, 3])
1924 x.foo = 42
1925 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001926 for proto in protocols:
1927 s = self.dumps(x, proto)
1928 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001929 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001930
1931 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001932 x = MyList([1, 2, 3])
1933 x.foo = 42
1934 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001935 for proto in protocols:
1936 s = self.dumps(x, proto)
1937 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001938 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001939
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001940 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001941 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001942 for C in myclasses:
1943 B = C.__base__
1944 x = C(C.sample)
1945 x.foo = 42
1946 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001947 y = self.loads(s)
1948 detail = (proto, C, B, x, y, type(y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001949 self.assert_is_copy(x, y) # XXX revisit
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001950 self.assertEqual(B(x), B(y), detail)
1951 self.assertEqual(x.__dict__, y.__dict__, detail)
1952
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01001953 def test_newobj_proxies(self):
1954 # NEWOBJ should use the __class__ rather than the raw type
1955 classes = myclasses[:]
1956 # Cannot create weakproxies to these classes
1957 for c in (MyInt, MyTuple):
1958 classes.remove(c)
1959 for proto in protocols:
1960 for C in classes:
1961 B = C.__base__
1962 x = C(C.sample)
1963 x.foo = 42
1964 p = weakref.proxy(x)
1965 s = self.dumps(p, proto)
1966 y = self.loads(s)
1967 self.assertEqual(type(y), type(x)) # rather than type(p)
1968 detail = (proto, C, B, x, y, type(y))
1969 self.assertEqual(B(x), B(y), detail)
1970 self.assertEqual(x.__dict__, y.__dict__, detail)
1971
Serhiy Storchaka8cd1dba2020-10-24 21:14:23 +03001972 def test_newobj_overridden_new(self):
1973 # Test that Python class with C implemented __new__ is pickleable
1974 for proto in protocols:
1975 x = MyIntWithNew2(1)
1976 x.foo = 42
1977 s = self.dumps(x, proto)
1978 y = self.loads(s)
1979 self.assertIs(type(y), MyIntWithNew2)
1980 self.assertEqual(int(y), 1)
1981 self.assertEqual(y.foo, 42)
1982
Benjamin Peterson80f78a32015-07-02 16:18:38 -05001983 def test_newobj_not_class(self):
1984 # Issue 24552
1985 global SimpleNewObj
1986 save = SimpleNewObj
Benjamin Petersond3a2a952015-07-02 16:58:22 -05001987 o = SimpleNewObj.__new__(SimpleNewObj)
Benjamin Peterson80f78a32015-07-02 16:18:38 -05001988 b = self.dumps(o, 4)
1989 try:
1990 SimpleNewObj = 42
1991 self.assertRaises((TypeError, pickle.UnpicklingError), self.loads, b)
1992 finally:
1993 SimpleNewObj = save
1994
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001995 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001996 # an object of that type. Check that the resulting pickle uses opcode
1997 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001998
Tim Peters22e71712003-02-03 22:27:38 +00001999 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00002000 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002001 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00002002 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002003 x = MyList([1, 2, 3])
2004 x.foo = 42
2005 x.bar = "hello"
2006
Tim Peters22e71712003-02-03 22:27:38 +00002007 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002008 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00002009 self.assertIn(__name__.encode("utf-8"), s1)
2010 self.assertIn(b"MyList", s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002011 self.assertFalse(opcode_in_pickle(opcode, s1))
Tim Peters3e667d52003-02-04 21:47:44 +00002012
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002013 y = self.loads(s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002014 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002015
Tim Peters22e71712003-02-03 22:27:38 +00002016 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002017 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00002018 self.assertNotIn(__name__.encode("utf-8"), s2)
2019 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +00002020 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +00002021
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002022 y = self.loads(s2)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002023 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002024 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00002025 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00002026
2027 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00002028 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
2029 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002030
2031 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00002032 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
2033 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
2034 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002035
2036 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00002037 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
2038 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
2039 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
2040
Tim Peters8d2613a2003-02-11 16:40:16 +00002041 def test_list_chunking(self):
2042 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +00002043 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00002044 for proto in protocols:
2045 s = self.dumps(x, proto)
2046 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002047 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00002048 num_appends = count_opcode(pickle.APPENDS, s)
2049 self.assertEqual(num_appends, proto > 0)
2050
2051 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +00002052 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00002053 for proto in protocols:
2054 s = self.dumps(x, proto)
2055 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002056 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00002057 num_appends = count_opcode(pickle.APPENDS, s)
2058 if proto == 0:
2059 self.assertEqual(num_appends, 0)
2060 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00002061 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00002062
2063 def test_dict_chunking(self):
2064 n = 10 # too small to chunk
2065 x = dict.fromkeys(range(n))
2066 for proto in protocols:
2067 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +00002068 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00002069 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002070 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00002071 num_setitems = count_opcode(pickle.SETITEMS, s)
2072 self.assertEqual(num_setitems, proto > 0)
2073
2074 n = 2500 # expect at least two chunks when proto > 0
2075 x = dict.fromkeys(range(n))
2076 for proto in protocols:
2077 s = self.dumps(x, proto)
2078 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002079 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00002080 num_setitems = count_opcode(pickle.SETITEMS, s)
2081 if proto == 0:
2082 self.assertEqual(num_setitems, 0)
2083 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00002084 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002085
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002086 def test_set_chunking(self):
2087 n = 10 # too small to chunk
2088 x = set(range(n))
2089 for proto in protocols:
2090 s = self.dumps(x, proto)
2091 y = self.loads(s)
2092 self.assert_is_copy(x, y)
2093 num_additems = count_opcode(pickle.ADDITEMS, s)
2094 if proto < 4:
2095 self.assertEqual(num_additems, 0)
2096 else:
2097 self.assertEqual(num_additems, 1)
2098
2099 n = 2500 # expect at least two chunks when proto >= 4
2100 x = set(range(n))
2101 for proto in protocols:
2102 s = self.dumps(x, proto)
2103 y = self.loads(s)
2104 self.assert_is_copy(x, y)
2105 num_additems = count_opcode(pickle.ADDITEMS, s)
2106 if proto < 4:
2107 self.assertEqual(num_additems, 0)
2108 else:
2109 self.assertGreaterEqual(num_additems, 2)
2110
Tim Peterse9ef2032003-02-13 18:42:00 +00002111 def test_simple_newobj(self):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002112 x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__
Tim Peterse9ef2032003-02-13 18:42:00 +00002113 x.abc = 666
2114 for proto in protocols:
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002115 with self.subTest(proto=proto):
2116 s = self.dumps(x, proto)
2117 if proto < 1:
Serhiy Storchaka3daaafb2017-11-16 09:44:43 +02002118 self.assertIn(b'\nI64206', s) # INT
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002119 else:
2120 self.assertIn(b'M\xce\xfa', s) # BININT2
2121 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
2122 2 <= proto)
2123 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
2124 y = self.loads(s) # will raise TypeError if __init__ called
2125 self.assert_is_copy(x, y)
2126
2127 def test_complex_newobj(self):
2128 x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__
2129 x.abc = 666
2130 for proto in protocols:
2131 with self.subTest(proto=proto):
2132 s = self.dumps(x, proto)
2133 if proto < 1:
Serhiy Storchaka3daaafb2017-11-16 09:44:43 +02002134 self.assertIn(b'\nI64206', s) # INT
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002135 elif proto < 2:
2136 self.assertIn(b'M\xce\xfa', s) # BININT2
2137 elif proto < 4:
2138 self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
2139 else:
2140 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
2141 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
2142 2 <= proto)
2143 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
2144 y = self.loads(s) # will raise TypeError if __init__ called
2145 self.assert_is_copy(x, y)
2146
2147 def test_complex_newobj_ex(self):
2148 x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__
2149 x.abc = 666
2150 for proto in protocols:
2151 with self.subTest(proto=proto):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002152 s = self.dumps(x, proto)
2153 if proto < 1:
Serhiy Storchaka3daaafb2017-11-16 09:44:43 +02002154 self.assertIn(b'\nI64206', s) # INT
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002155 elif proto < 2:
2156 self.assertIn(b'M\xce\xfa', s) # BININT2
Serhiy Storchaka0d554d72015-10-10 22:42:18 +03002157 elif proto < 4:
2158 self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002159 else:
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002160 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
2161 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s))
2162 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
2163 4 <= proto)
2164 y = self.loads(s) # will raise TypeError if __init__ called
2165 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00002166
Tim Peters42f08ac2003-02-11 22:43:24 +00002167 def test_newobj_list_slots(self):
2168 x = SlotList([1, 2, 3])
2169 x.foo = 42
2170 x.bar = "hello"
2171 s = self.dumps(x, 2)
2172 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002173 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00002174
Guido van Rossum2a30b212003-02-18 22:41:24 +00002175 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00002176 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00002177 x = REX_one()
2178 self.assertEqual(x._reduce_called, 0)
2179 s = self.dumps(x, proto)
2180 self.assertEqual(x._reduce_called, 1)
2181 y = self.loads(s)
2182 self.assertEqual(y._reduce_called, 0)
2183
2184 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00002185 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00002186 x = REX_two()
2187 self.assertEqual(x._proto, None)
2188 s = self.dumps(x, proto)
2189 self.assertEqual(x._proto, proto)
2190 y = self.loads(s)
2191 self.assertEqual(y._proto, None)
2192
2193 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00002194 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00002195 x = REX_three()
2196 self.assertEqual(x._proto, None)
2197 s = self.dumps(x, proto)
2198 self.assertEqual(x._proto, proto)
2199 y = self.loads(s)
2200 self.assertEqual(y._proto, None)
2201
Guido van Rossumd8faa362007-04-27 19:54:29 +00002202 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00002203 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002204 x = REX_four()
2205 self.assertEqual(x._proto, None)
2206 s = self.dumps(x, proto)
2207 self.assertEqual(x._proto, proto)
2208 y = self.loads(s)
2209 self.assertEqual(y._proto, proto)
2210
2211 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00002212 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002213 x = REX_five()
2214 self.assertEqual(x._reduce_called, 0)
2215 s = self.dumps(x, proto)
2216 self.assertEqual(x._reduce_called, 1)
2217 y = self.loads(s)
2218 self.assertEqual(y._reduce_called, 1)
2219
Brett Cannon31f59292011-02-21 19:29:56 +00002220 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002221 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002222 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002223 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002224 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002225 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002226
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00002227 def test_reduce_bad_iterator(self):
2228 # Issue4176: crash when 4th and 5th items of __reduce__()
2229 # are not iterators
2230 class C(object):
2231 def __reduce__(self):
2232 # 4th item is not an iterator
2233 return list, (), None, [], None
2234 class D(object):
2235 def __reduce__(self):
2236 # 5th item is not an iterator
2237 return dict, (), None, None, []
2238
Serhiy Storchakabeb652c2015-12-30 21:00:08 +02002239 # Python implementation is less strict and also accepts iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00002240 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00002241 try:
2242 self.dumps(C(), proto)
Serhiy Storchakabeb652c2015-12-30 21:00:08 +02002243 except pickle.PicklingError:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00002244 pass
2245 try:
2246 self.dumps(D(), proto)
Serhiy Storchakabeb652c2015-12-30 21:00:08 +02002247 except pickle.PicklingError:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00002248 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00002249
Collin Winter771d8342009-04-16 03:18:06 +00002250 def test_many_puts_and_gets(self):
2251 # Test that internal data structures correctly deal with lots of
2252 # puts/gets.
2253 keys = ("aaa" + str(i) for i in range(100))
2254 large_dict = dict((k, [4, 5, 6]) for k in keys)
2255 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
2256
2257 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002258 with self.subTest(proto=proto):
2259 dumped = self.dumps(obj, proto)
2260 loaded = self.loads(dumped)
2261 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00002262
Antoine Pitroua9f48a02009-05-02 21:41:14 +00002263 def test_attribute_name_interning(self):
2264 # Test that attribute names of pickled objects are interned when
2265 # unpickling.
2266 for proto in protocols:
2267 x = C()
2268 x.foo = 42
2269 x.bar = "hello"
2270 s = self.dumps(x, proto)
2271 y = self.loads(s)
2272 x_keys = sorted(x.__dict__)
2273 y_keys = sorted(y.__dict__)
2274 for x_key, y_key in zip(x_keys, y_keys):
2275 self.assertIs(x_key, y_key)
2276
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00002277 def test_pickle_to_2x(self):
2278 # Pickle non-trivial data with protocol 2, expecting that it yields
2279 # the same result as Python 2.x did.
2280 # NOTE: this test is a bit too strong since we can produce different
2281 # bytecode that 2.x will still understand.
2282 dumped = self.dumps(range(5), 2)
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03002283 self.assertEqual(dumped, DATA_XRANGE)
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00002284 dumped = self.dumps(set([3]), 2)
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03002285 self.assertEqual(dumped, DATA_SET2)
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00002286
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00002287 def test_large_pickles(self):
2288 # Test the correctness of internal buffering routines when handling
2289 # large data.
2290 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00002291 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00002292 dumped = self.dumps(data, proto)
2293 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002294 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00002295 self.assertEqual(loaded, data)
2296
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002297 def test_int_pickling_efficiency(self):
2298 # Test compacity of int representation (see issue #12744)
2299 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002300 with self.subTest(proto=proto):
2301 pickles = [self.dumps(2**n, proto) for n in range(70)]
2302 sizes = list(map(len, pickles))
2303 # the size function is monotonic
2304 self.assertEqual(sorted(sizes), sizes)
2305 if proto >= 2:
2306 for p in pickles:
2307 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002308
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002309 def _check_pickling_with_opcode(self, obj, opcode, proto):
2310 pickled = self.dumps(obj, proto)
2311 self.assertTrue(opcode_in_pickle(opcode, pickled))
2312 unpickled = self.loads(pickled)
2313 self.assertEqual(obj, unpickled)
2314
2315 def test_appends_on_non_lists(self):
2316 # Issue #17720
2317 obj = REX_six([1, 2, 3])
2318 for proto in protocols:
2319 if proto == 0:
2320 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
2321 else:
2322 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
2323
2324 def test_setitems_on_non_dicts(self):
2325 obj = REX_seven({1: -1, 2: -2, 3: -3})
2326 for proto in protocols:
2327 if proto == 0:
2328 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
2329 else:
2330 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
2331
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002332 # Exercise framing (proto >= 4) for significant workloads
2333
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002334 FRAME_SIZE_MIN = 4
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002335 FRAME_SIZE_TARGET = 64 * 1024
2336
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002337 def check_frame_opcodes(self, pickled):
2338 """
2339 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002340
2341 Note that binary objects that are larger than FRAME_SIZE_TARGET are not
2342 framed by default and are therefore considered a frame by themselves in
2343 the following consistency check.
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002344 """
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002345 frame_end = frameless_start = None
Antoine Pitrou91f43802019-05-26 17:10:09 +02002346 frameless_opcodes = {'BINBYTES', 'BINUNICODE', 'BINBYTES8',
2347 'BINUNICODE8', 'BYTEARRAY8'}
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002348 for op, arg, pos in pickletools.genops(pickled):
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002349 if frame_end is not None:
2350 self.assertLessEqual(pos, frame_end)
2351 if pos == frame_end:
2352 frame_end = None
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002353
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002354 if frame_end is not None: # framed
2355 self.assertNotEqual(op.name, 'FRAME')
2356 if op.name in frameless_opcodes:
2357 # Only short bytes and str objects should be written
2358 # in a frame
2359 self.assertLessEqual(len(arg), self.FRAME_SIZE_TARGET)
2360
2361 else: # not framed
2362 if (op.name == 'FRAME' or
2363 (op.name in frameless_opcodes and
2364 len(arg) > self.FRAME_SIZE_TARGET)):
2365 # Frame or large bytes or str object
2366 if frameless_start is not None:
2367 # Only short data should be written outside of a frame
2368 self.assertLess(pos - frameless_start,
2369 self.FRAME_SIZE_MIN)
2370 frameless_start = None
2371 elif frameless_start is None and op.name != 'PROTO':
2372 frameless_start = pos
2373
2374 if op.name == 'FRAME':
2375 self.assertGreaterEqual(arg, self.FRAME_SIZE_MIN)
2376 frame_end = pos + 9 + arg
2377
2378 pos = len(pickled)
2379 if frame_end is not None:
2380 self.assertEqual(frame_end, pos)
2381 elif frameless_start is not None:
2382 self.assertLess(pos - frameless_start, self.FRAME_SIZE_MIN)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002383
Neil Schemenauer52a48e62019-07-30 11:08:18 -07002384 @support.skip_if_pgo_task
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002385 def test_framing_many_objects(self):
2386 obj = list(range(10**5))
2387 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2388 with self.subTest(proto=proto):
2389 pickled = self.dumps(obj, proto)
2390 unpickled = self.loads(pickled)
2391 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01002392 bytes_per_frame = (len(pickled) /
2393 count_opcode(pickle.FRAME, pickled))
2394 self.assertGreater(bytes_per_frame,
2395 self.FRAME_SIZE_TARGET / 2)
2396 self.assertLessEqual(bytes_per_frame,
2397 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002398 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002399
2400 def test_framing_large_objects(self):
2401 N = 1024 * 1024
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002402 small_items = [[i] for i in range(10)]
2403 obj = [b'x' * N, *small_items, b'y' * N, 'z' * N]
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002404 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
Serhiy Storchaka0a2da502018-01-11 13:03:20 +02002405 for fast in [False, True]:
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002406 with self.subTest(proto=proto, fast=fast):
Serhiy Storchaka0a2da502018-01-11 13:03:20 +02002407 if not fast:
2408 # fast=False by default.
2409 # This covers in-memory pickling with pickle.dumps().
2410 pickled = self.dumps(obj, proto)
2411 else:
2412 # Pickler is required when fast=True.
2413 if not hasattr(self, 'pickler'):
2414 continue
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002415 buf = io.BytesIO()
2416 pickler = self.pickler(buf, protocol=proto)
2417 pickler.fast = fast
2418 pickler.dump(obj)
2419 pickled = buf.getvalue()
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002420 unpickled = self.loads(pickled)
2421 # More informative error message in case of failure.
2422 self.assertEqual([len(x) for x in obj],
2423 [len(x) for x in unpickled])
2424 # Perform full equality check if the lengths match.
2425 self.assertEqual(obj, unpickled)
2426 n_frames = count_opcode(pickle.FRAME, pickled)
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002427 # A single frame for small objects between
2428 # first two large objects.
2429 self.assertEqual(n_frames, 1)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002430 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002431
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002432 def test_optional_frames(self):
2433 if pickle.HIGHEST_PROTOCOL < 4:
2434 return
2435
2436 def remove_frames(pickled, keep_frame=None):
2437 """Remove frame opcodes from the given pickle."""
2438 frame_starts = []
2439 # 1 byte for the opcode and 8 for the argument
2440 frame_opcode_size = 9
2441 for opcode, _, pos in pickletools.genops(pickled):
2442 if opcode.name == 'FRAME':
2443 frame_starts.append(pos)
2444
2445 newpickle = bytearray()
2446 last_frame_end = 0
2447 for i, pos in enumerate(frame_starts):
2448 if keep_frame and keep_frame(i):
2449 continue
2450 newpickle += pickled[last_frame_end:pos]
2451 last_frame_end = pos + frame_opcode_size
2452 newpickle += pickled[last_frame_end:]
2453 return newpickle
2454
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08002455 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002456 num_frames = 20
penguindustin96466302019-05-06 14:57:17 -04002457 # Large byte objects (dict values) intermittent with small objects
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002458 # (dict keys)
Antoine Pitrou91f43802019-05-26 17:10:09 +02002459 for bytes_type in (bytes, bytearray):
2460 obj = {i: bytes_type([i]) * frame_size for i in range(num_frames)}
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002461
Antoine Pitrou91f43802019-05-26 17:10:09 +02002462 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2463 pickled = self.dumps(obj, proto)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002464
Antoine Pitrou91f43802019-05-26 17:10:09 +02002465 frameless_pickle = remove_frames(pickled)
2466 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
2467 self.assertEqual(obj, self.loads(frameless_pickle))
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002468
Antoine Pitrou91f43802019-05-26 17:10:09 +02002469 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
2470 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
2471 count_opcode(pickle.FRAME, pickled))
2472 self.assertEqual(obj, self.loads(some_frames_pickle))
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002473
Neil Schemenauer52a48e62019-07-30 11:08:18 -07002474 @support.skip_if_pgo_task
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002475 def test_framed_write_sizes_with_delayed_writer(self):
2476 class ChunkAccumulator:
2477 """Accumulate pickler output in a list of raw chunks."""
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002478 def __init__(self):
2479 self.chunks = []
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002480 def write(self, chunk):
2481 self.chunks.append(chunk)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002482 def concatenate_chunks(self):
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002483 return b"".join(self.chunks)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002484
2485 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002486 objects = [(str(i).encode('ascii'), i % 42, {'i': str(i)})
2487 for i in range(int(1e4))]
2488 # Add a large unique ASCII string
2489 objects.append('0123456789abcdef' *
2490 (self.FRAME_SIZE_TARGET // 16 + 1))
2491
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002492 # Protocol 4 packs groups of small objects into frames and issues
2493 # calls to write only once or twice per frame:
2494 # The C pickler issues one call to write per-frame (header and
2495 # contents) while Python pickler issues two calls to write: one for
2496 # the frame header and one for the frame binary contents.
2497 writer = ChunkAccumulator()
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002498 self.pickler(writer, proto).dump(objects)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002499
2500 # Actually read the binary content of the chunks after the end
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002501 # of the call to dump: any memoryview passed to write should not
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002502 # be released otherwise this delayed access would not be possible.
2503 pickled = writer.concatenate_chunks()
2504 reconstructed = self.loads(pickled)
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002505 self.assertEqual(reconstructed, objects)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002506 self.assertGreater(len(writer.chunks), 1)
2507
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002508 # memoryviews should own the memory.
2509 del objects
2510 support.gc_collect()
2511 self.assertEqual(writer.concatenate_chunks(), pickled)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002512
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002513 n_frames = (len(pickled) - 1) // self.FRAME_SIZE_TARGET + 1
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002514 # There should be at least one call to write per frame
2515 self.assertGreaterEqual(len(writer.chunks), n_frames)
2516
2517 # but not too many either: there can be one for the proto,
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002518 # one per-frame header, one per frame for the actual contents,
2519 # and two for the header.
2520 self.assertLessEqual(len(writer.chunks), 2 * n_frames + 3)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002521
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002522 chunk_sizes = [len(c) for c in writer.chunks]
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002523 large_sizes = [s for s in chunk_sizes
2524 if s >= self.FRAME_SIZE_TARGET]
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002525 medium_sizes = [s for s in chunk_sizes
2526 if 9 < s < self.FRAME_SIZE_TARGET]
2527 small_sizes = [s for s in chunk_sizes if s <= 9]
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002528
2529 # Large chunks should not be too large:
2530 for chunk_size in large_sizes:
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002531 self.assertLess(chunk_size, 2 * self.FRAME_SIZE_TARGET,
2532 chunk_sizes)
2533 # There shouldn't bee too many small chunks: the protocol header,
2534 # the frame headers and the large string headers are written
2535 # in small chunks.
2536 self.assertLessEqual(len(small_sizes),
2537 len(large_sizes) + len(medium_sizes) + 3,
2538 chunk_sizes)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002539
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002540 def test_nested_names(self):
2541 global Nested
2542 class Nested:
2543 class A:
2544 class B:
2545 class C:
2546 pass
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002547 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002548 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
2549 with self.subTest(proto=proto, obj=obj):
2550 unpickled = self.loads(self.dumps(obj, proto))
2551 self.assertIs(obj, unpickled)
2552
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002553 def test_recursive_nested_names(self):
2554 global Recursive
2555 class Recursive:
2556 pass
2557 Recursive.mod = sys.modules[Recursive.__module__]
2558 Recursive.__qualname__ = 'Recursive.mod.Recursive'
2559 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2560 with self.subTest(proto=proto):
2561 unpickled = self.loads(self.dumps(Recursive, proto))
2562 self.assertIs(unpickled, Recursive)
2563 del Recursive.mod # break reference loop
2564
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002565 def test_py_methods(self):
2566 global PyMethodsTest
2567 class PyMethodsTest:
2568 @staticmethod
2569 def cheese():
2570 return "cheese"
2571 @classmethod
2572 def wine(cls):
2573 assert cls is PyMethodsTest
2574 return "wine"
2575 def biscuits(self):
2576 assert isinstance(self, PyMethodsTest)
2577 return "biscuits"
2578 class Nested:
2579 "Nested class"
2580 @staticmethod
2581 def ketchup():
2582 return "ketchup"
2583 @classmethod
2584 def maple(cls):
2585 assert cls is PyMethodsTest.Nested
2586 return "maple"
2587 def pie(self):
2588 assert isinstance(self, PyMethodsTest.Nested)
2589 return "pie"
2590
2591 py_methods = (
2592 PyMethodsTest.cheese,
2593 PyMethodsTest.wine,
2594 PyMethodsTest().biscuits,
2595 PyMethodsTest.Nested.ketchup,
2596 PyMethodsTest.Nested.maple,
2597 PyMethodsTest.Nested().pie
2598 )
2599 py_unbound_methods = (
2600 (PyMethodsTest.biscuits, PyMethodsTest),
2601 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
2602 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002603 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002604 for method in py_methods:
2605 with self.subTest(proto=proto, method=method):
2606 unpickled = self.loads(self.dumps(method, proto))
2607 self.assertEqual(method(), unpickled())
2608 for method, cls in py_unbound_methods:
2609 obj = cls()
2610 with self.subTest(proto=proto, method=method):
2611 unpickled = self.loads(self.dumps(method, proto))
2612 self.assertEqual(method(obj), unpickled(obj))
2613
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002614 def test_c_methods(self):
2615 global Subclass
2616 class Subclass(tuple):
2617 class Nested(str):
2618 pass
2619
2620 c_methods = (
2621 # bound built-in method
2622 ("abcd".index, ("c",)),
2623 # unbound built-in method
2624 (str.index, ("abcd", "c")),
2625 # bound "slot" method
2626 ([1, 2, 3].__len__, ()),
2627 # unbound "slot" method
2628 (list.__len__, ([1, 2, 3],)),
2629 # bound "coexist" method
2630 ({1, 2}.__contains__, (2,)),
2631 # unbound "coexist" method
2632 (set.__contains__, ({1, 2}, 2)),
2633 # built-in class method
2634 (dict.fromkeys, (("a", 1), ("b", 2))),
2635 # built-in static method
2636 (bytearray.maketrans, (b"abc", b"xyz")),
2637 # subclass methods
2638 (Subclass([1,2,2]).count, (2,)),
2639 (Subclass.count, (Subclass([1,2,2]), 2)),
2640 (Subclass.Nested("sweet").count, ("e",)),
2641 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
2642 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002643 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002644 for method, args in c_methods:
2645 with self.subTest(proto=proto, method=method):
2646 unpickled = self.loads(self.dumps(method, proto))
2647 self.assertEqual(method(*args), unpickled(*args))
2648
Serhiy Storchakabfe18242015-03-31 13:12:37 +03002649 def test_compat_pickle(self):
2650 tests = [
2651 (range(1, 7), '__builtin__', 'xrange'),
2652 (map(int, '123'), 'itertools', 'imap'),
2653 (functools.reduce, '__builtin__', 'reduce'),
2654 (dbm.whichdb, 'whichdb', 'whichdb'),
2655 (Exception(), 'exceptions', 'Exception'),
2656 (collections.UserDict(), 'UserDict', 'IterableUserDict'),
2657 (collections.UserList(), 'UserList', 'UserList'),
2658 (collections.defaultdict(), 'collections', 'defaultdict'),
2659 ]
2660 for val, mod, name in tests:
2661 for proto in range(3):
2662 with self.subTest(type=type(val), proto=proto):
2663 pickled = self.dumps(val, proto)
2664 self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled)
2665 self.assertIs(type(self.loads(pickled)), type(val))
2666
Antoine Pitrou6cd5eda2014-12-02 00:20:03 +01002667 def test_local_lookup_error(self):
2668 # Test that whichmodule() errors out cleanly when looking up
2669 # an assumed globally-reachable object fails.
2670 def f():
2671 pass
2672 # Since the function is local, lookup will fail
2673 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2674 with self.assertRaises((AttributeError, pickle.PicklingError)):
2675 pickletools.dis(self.dumps(f, proto))
2676 # Same without a __module__ attribute (exercises a different path
2677 # in _pickle.c).
2678 del f.__module__
2679 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2680 with self.assertRaises((AttributeError, pickle.PicklingError)):
2681 pickletools.dis(self.dumps(f, proto))
2682 # Yet a different path.
2683 f.__name__ = f.__qualname__
2684 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2685 with self.assertRaises((AttributeError, pickle.PicklingError)):
2686 pickletools.dis(self.dumps(f, proto))
2687
Antoine Pitrou91f43802019-05-26 17:10:09 +02002688 #
2689 # PEP 574 tests below
2690 #
2691
2692 def buffer_like_objects(self):
2693 # Yield buffer-like objects with the bytestring "abcdef" in them
2694 bytestring = b"abcdefgh"
2695 yield ZeroCopyBytes(bytestring)
2696 yield ZeroCopyBytearray(bytestring)
2697 if _testbuffer is not None:
2698 items = list(bytestring)
2699 value = int.from_bytes(bytestring, byteorder='little')
2700 for flags in (0, _testbuffer.ND_WRITABLE):
2701 # 1-D, contiguous
2702 yield PicklableNDArray(items, format='B', shape=(8,),
2703 flags=flags)
2704 # 2-D, C-contiguous
2705 yield PicklableNDArray(items, format='B', shape=(4, 2),
2706 strides=(2, 1), flags=flags)
2707 # 2-D, Fortran-contiguous
2708 yield PicklableNDArray(items, format='B',
2709 shape=(4, 2), strides=(1, 4),
2710 flags=flags)
2711
2712 def test_in_band_buffers(self):
2713 # Test in-band buffers (PEP 574)
2714 for obj in self.buffer_like_objects():
2715 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2716 data = self.dumps(obj, proto)
2717 if obj.c_contiguous and proto >= 5:
2718 # The raw memory bytes are serialized in physical order
2719 self.assertIn(b"abcdefgh", data)
2720 self.assertEqual(count_opcode(pickle.NEXT_BUFFER, data), 0)
2721 if proto >= 5:
2722 self.assertEqual(count_opcode(pickle.SHORT_BINBYTES, data),
2723 1 if obj.readonly else 0)
2724 self.assertEqual(count_opcode(pickle.BYTEARRAY8, data),
2725 0 if obj.readonly else 1)
2726 # Return a true value from buffer_callback should have
2727 # the same effect
2728 def buffer_callback(obj):
2729 return True
2730 data2 = self.dumps(obj, proto,
2731 buffer_callback=buffer_callback)
2732 self.assertEqual(data2, data)
2733
2734 new = self.loads(data)
2735 # It's a copy
2736 self.assertIsNot(new, obj)
2737 self.assertIs(type(new), type(obj))
2738 self.assertEqual(new, obj)
2739
2740 # XXX Unfortunately cannot test non-contiguous array
2741 # (see comment in PicklableNDArray.__reduce_ex__)
2742
2743 def test_oob_buffers(self):
2744 # Test out-of-band buffers (PEP 574)
2745 for obj in self.buffer_like_objects():
2746 for proto in range(0, 5):
2747 # Need protocol >= 5 for buffer_callback
2748 with self.assertRaises(ValueError):
2749 self.dumps(obj, proto,
2750 buffer_callback=[].append)
2751 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
2752 buffers = []
2753 buffer_callback = lambda pb: buffers.append(pb.raw())
2754 data = self.dumps(obj, proto,
2755 buffer_callback=buffer_callback)
2756 self.assertNotIn(b"abcdefgh", data)
2757 self.assertEqual(count_opcode(pickle.SHORT_BINBYTES, data), 0)
2758 self.assertEqual(count_opcode(pickle.BYTEARRAY8, data), 0)
2759 self.assertEqual(count_opcode(pickle.NEXT_BUFFER, data), 1)
2760 self.assertEqual(count_opcode(pickle.READONLY_BUFFER, data),
2761 1 if obj.readonly else 0)
2762
2763 if obj.c_contiguous:
2764 self.assertEqual(bytes(buffers[0]), b"abcdefgh")
2765 # Need buffers argument to unpickle properly
2766 with self.assertRaises(pickle.UnpicklingError):
2767 self.loads(data)
2768
2769 new = self.loads(data, buffers=buffers)
2770 if obj.zero_copy_reconstruct:
2771 # Zero-copy achieved
2772 self.assertIs(new, obj)
2773 else:
2774 self.assertIs(type(new), type(obj))
2775 self.assertEqual(new, obj)
2776 # Non-sequence buffers accepted too
2777 new = self.loads(data, buffers=iter(buffers))
2778 if obj.zero_copy_reconstruct:
2779 # Zero-copy achieved
2780 self.assertIs(new, obj)
2781 else:
2782 self.assertIs(type(new), type(obj))
2783 self.assertEqual(new, obj)
2784
2785 def test_oob_buffers_writable_to_readonly(self):
2786 # Test reconstructing readonly object from writable buffer
2787 obj = ZeroCopyBytes(b"foobar")
2788 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
2789 buffers = []
2790 buffer_callback = buffers.append
2791 data = self.dumps(obj, proto, buffer_callback=buffer_callback)
2792
2793 buffers = map(bytearray, buffers)
2794 new = self.loads(data, buffers=buffers)
2795 self.assertIs(type(new), type(obj))
2796 self.assertEqual(new, obj)
2797
2798 def test_picklebuffer_error(self):
2799 # PickleBuffer forbidden with protocol < 5
2800 pb = pickle.PickleBuffer(b"foobar")
2801 for proto in range(0, 5):
2802 with self.assertRaises(pickle.PickleError):
2803 self.dumps(pb, proto)
2804
2805 def test_buffer_callback_error(self):
2806 def buffer_callback(buffers):
2807 1/0
2808 pb = pickle.PickleBuffer(b"foobar")
2809 with self.assertRaises(ZeroDivisionError):
2810 self.dumps(pb, 5, buffer_callback=buffer_callback)
2811
2812 def test_buffers_error(self):
2813 pb = pickle.PickleBuffer(b"foobar")
2814 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
2815 data = self.dumps(pb, proto, buffer_callback=[].append)
2816 # Non iterable buffers
2817 with self.assertRaises(TypeError):
2818 self.loads(data, buffers=object())
2819 # Buffer iterable exhausts too early
2820 with self.assertRaises(pickle.UnpicklingError):
2821 self.loads(data, buffers=[])
2822
Markus Mohrhard898318b2019-07-26 00:00:34 +08002823 def test_inband_accept_default_buffers_argument(self):
2824 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
2825 data_pickled = self.dumps(1, proto, buffer_callback=None)
2826 data = self.loads(data_pickled, buffers=None)
2827
Antoine Pitrou91f43802019-05-26 17:10:09 +02002828 @unittest.skipIf(np is None, "Test needs Numpy")
2829 def test_buffers_numpy(self):
2830 def check_no_copy(x, y):
2831 np.testing.assert_equal(x, y)
2832 self.assertEqual(x.ctypes.data, y.ctypes.data)
2833
2834 def check_copy(x, y):
2835 np.testing.assert_equal(x, y)
2836 self.assertNotEqual(x.ctypes.data, y.ctypes.data)
2837
2838 def check_array(arr):
2839 # In-band
2840 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2841 data = self.dumps(arr, proto)
2842 new = self.loads(data)
2843 check_copy(arr, new)
2844 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
2845 buffer_callback = lambda _: True
2846 data = self.dumps(arr, proto, buffer_callback=buffer_callback)
2847 new = self.loads(data)
2848 check_copy(arr, new)
2849 # Out-of-band
2850 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
2851 buffers = []
2852 buffer_callback = buffers.append
2853 data = self.dumps(arr, proto, buffer_callback=buffer_callback)
2854 new = self.loads(data, buffers=buffers)
2855 if arr.flags.c_contiguous or arr.flags.f_contiguous:
2856 check_no_copy(arr, new)
2857 else:
2858 check_copy(arr, new)
2859
2860 # 1-D
2861 arr = np.arange(6)
2862 check_array(arr)
2863 # 1-D, non-contiguous
2864 check_array(arr[::2])
2865 # 2-D, C-contiguous
2866 arr = np.arange(12).reshape((3, 4))
2867 check_array(arr)
2868 # 2-D, F-contiguous
2869 check_array(arr.T)
2870 # 2-D, non-contiguous
2871 check_array(arr[::2])
2872
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002873
2874class BigmemPickleTests(unittest.TestCase):
2875
Victor Stinner8c663fd2017-11-08 14:44:44 -08002876 # Binary protocols can serialize longs of up to 2 GiB-1
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002877
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002878 @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002879 def test_huge_long_32b(self, size):
2880 data = 1 << (8 * size)
2881 try:
2882 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002883 if proto < 2:
2884 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002885 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002886 with self.assertRaises((ValueError, OverflowError)):
2887 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002888 finally:
2889 data = None
2890
Victor Stinner8c663fd2017-11-08 14:44:44 -08002891 # Protocol 3 can serialize up to 4 GiB-1 as a bytes object
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002892 # (older protocols don't have a dedicated opcode for bytes and are
2893 # too inefficient)
2894
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002895 @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002896 def test_huge_bytes_32b(self, size):
2897 data = b"abcd" * (size // 4)
2898 try:
2899 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002900 if proto < 3:
2901 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002902 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002903 try:
2904 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002905 header = (pickle.BINBYTES +
2906 struct.pack("<I", len(data)))
2907 data_start = pickled.index(data)
2908 self.assertEqual(
2909 header,
2910 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002911 finally:
2912 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002913 finally:
2914 data = None
2915
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002916 @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002917 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002918 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002919 try:
2920 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002921 if proto < 3:
2922 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002923 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002924 if proto == 3:
2925 # Protocol 3 does not support large bytes objects.
2926 # Verify that we do not crash when processing one.
2927 with self.assertRaises((ValueError, OverflowError)):
2928 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002929 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002930 try:
2931 pickled = self.dumps(data, protocol=proto)
2932 header = (pickle.BINBYTES8 +
2933 struct.pack("<Q", len(data)))
2934 data_start = pickled.index(data)
2935 self.assertEqual(
2936 header,
2937 pickled[data_start-len(header):data_start])
2938 finally:
2939 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002940 finally:
2941 data = None
2942
2943 # All protocols use 1-byte per printable ASCII character; we add another
2944 # byte because the encoded form has to be copied into the internal buffer.
2945
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002946 @bigmemtest(size=_2G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002947 def test_huge_str_32b(self, size):
2948 data = "abcd" * (size // 4)
2949 try:
2950 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002951 if proto == 0:
2952 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002953 with self.subTest(proto=proto):
2954 try:
2955 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002956 header = (pickle.BINUNICODE +
2957 struct.pack("<I", len(data)))
2958 data_start = pickled.index(b'abcd')
2959 self.assertEqual(
2960 header,
2961 pickled[data_start-len(header):data_start])
2962 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2963 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002964 finally:
2965 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002966 finally:
2967 data = None
2968
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002969 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
2970 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
2971 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02002972
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002973 @bigmemtest(size=_4G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002974 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002975 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002976 try:
2977 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002978 if proto == 0:
2979 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002980 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002981 if proto < 4:
2982 with self.assertRaises((ValueError, OverflowError)):
2983 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002984 continue
2985 try:
2986 pickled = self.dumps(data, protocol=proto)
2987 header = (pickle.BINUNICODE8 +
2988 struct.pack("<Q", len(data)))
2989 data_start = pickled.index(b'abcd')
2990 self.assertEqual(
2991 header,
2992 pickled[data_start-len(header):data_start])
2993 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2994 pickled.index(b"abcd")), len(data))
2995 finally:
2996 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002997 finally:
2998 data = None
2999
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02003000
Guido van Rossum2a30b212003-02-18 22:41:24 +00003001# Test classes for reduce_ex
3002
3003class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003004 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00003005 _reduce_called = 0
3006 def __reduce__(self):
3007 self._reduce_called = 1
3008 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00003009
3010class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003011 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00003012 _proto = None
3013 def __reduce_ex__(self, proto):
3014 self._proto = proto
3015 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00003016
3017class REX_three(object):
3018 _proto = None
3019 def __reduce_ex__(self, proto):
3020 self._proto = proto
3021 return REX_two, ()
3022 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00003023 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00003024
Guido van Rossumd8faa362007-04-27 19:54:29 +00003025class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003026 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00003027 _proto = None
3028 def __reduce_ex__(self, proto):
3029 self._proto = proto
3030 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00003031
3032class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003033 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00003034 _reduce_called = 0
3035 def __reduce__(self):
3036 self._reduce_called = 1
3037 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003038
3039class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003040 """This class is used to check the 4th argument (list iterator) of
3041 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003042 """
3043 def __init__(self, items=None):
3044 self.items = items if items is not None else []
3045 def __eq__(self, other):
Serhiy Storchakabe700022016-03-04 09:39:47 +02003046 return type(self) is type(other) and self.items == other.items
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003047 def append(self, item):
3048 self.items.append(item)
3049 def __reduce__(self):
3050 return type(self), (), None, iter(self.items), None
3051
3052class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003053 """This class is used to check the 5th argument (dict iterator) of
3054 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003055 """
3056 def __init__(self, table=None):
3057 self.table = table if table is not None else {}
3058 def __eq__(self, other):
Serhiy Storchakabe700022016-03-04 09:39:47 +02003059 return type(self) is type(other) and self.table == other.table
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003060 def __setitem__(self, key, value):
3061 self.table[key] = value
3062 def __reduce__(self):
3063 return type(self), (), None, None, iter(self.table.items())
3064
Guido van Rossumd8faa362007-04-27 19:54:29 +00003065
Guido van Rossum2a30b212003-02-18 22:41:24 +00003066# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00003067
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003068class MyInt(int):
3069 sample = 1
3070
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003071class MyFloat(float):
3072 sample = 1.0
3073
3074class MyComplex(complex):
3075 sample = 1.0 + 0.0j
3076
3077class MyStr(str):
3078 sample = "hello"
3079
Guido van Rossumef87d6e2007-05-02 19:09:54 +00003080class MyUnicode(str):
3081 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003082
Guido van Rossum533dbcf2003-01-28 17:55:05 +00003083class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003084 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00003085
3086class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003087 sample = [1, 2, 3]
3088
3089class MyDict(dict):
3090 sample = {"a": 1, "b": 2}
3091
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003092class MySet(set):
3093 sample = {"a", "b"}
3094
3095class MyFrozenSet(frozenset):
3096 sample = frozenset({"a", "b"})
3097
Mark Dickinson5c2db372009-12-05 20:28:34 +00003098myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00003099 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003100 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003101 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003102
Serhiy Storchaka8cd1dba2020-10-24 21:14:23 +03003103class MyIntWithNew(int):
3104 def __new__(cls, value):
3105 raise AssertionError
3106
3107class MyIntWithNew2(MyIntWithNew):
3108 __new__ = int.__new__
3109
Guido van Rossum533dbcf2003-01-28 17:55:05 +00003110
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00003111class SlotList(MyList):
3112 __slots__ = ["foo"]
3113
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02003114class SimpleNewObj(int):
3115 def __init__(self, *args, **kwargs):
Tim Peterse9ef2032003-02-13 18:42:00 +00003116 # raise an error, to make sure this isn't called
3117 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003118 def __eq__(self, other):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02003119 return int(self) == int(other) and self.__dict__ == other.__dict__
3120
3121class ComplexNewObj(SimpleNewObj):
3122 def __getnewargs__(self):
3123 return ('%X' % self, 16)
3124
3125class ComplexNewObjEx(SimpleNewObj):
3126 def __getnewargs_ex__(self):
3127 return ('%X' % self,), {'base': 16}
Tim Peterse9ef2032003-02-13 18:42:00 +00003128
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00003129class BadGetattr:
3130 def __getattr__(self, key):
3131 self.foo
3132
Collin Winter771d8342009-04-16 03:18:06 +00003133
Jeremy Hylton66426532001-10-15 21:38:56 +00003134class AbstractPickleModuleTests(unittest.TestCase):
3135
3136 def test_dump_closed_file(self):
Walter Dörwald11b41f62007-06-20 12:46:31 +00003137 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00003138 try:
3139 f.close()
Serhiy Storchaka65452562017-11-15 14:01:08 +02003140 self.assertRaises(ValueError, self.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00003141 finally:
Hai Shi883bc632020-07-06 17:12:49 +08003142 os_helper.unlink(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00003143
3144 def test_load_closed_file(self):
Walter Dörwald11b41f62007-06-20 12:46:31 +00003145 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00003146 try:
3147 f.close()
Serhiy Storchaka65452562017-11-15 14:01:08 +02003148 self.assertRaises(ValueError, self.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00003149 finally:
Hai Shi883bc632020-07-06 17:12:49 +08003150 os_helper.unlink(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00003151
Collin Winter771d8342009-04-16 03:18:06 +00003152 def test_load_from_and_dump_to_file(self):
3153 stream = io.BytesIO()
3154 data = [123, {}, 124]
Serhiy Storchaka65452562017-11-15 14:01:08 +02003155 self.dump(data, stream)
Collin Winter771d8342009-04-16 03:18:06 +00003156 stream.seek(0)
Serhiy Storchaka65452562017-11-15 14:01:08 +02003157 unpickled = self.load(stream)
Collin Winter771d8342009-04-16 03:18:06 +00003158 self.assertEqual(unpickled, data)
3159
Tim Petersc0c93702003-02-13 19:30:57 +00003160 def test_highest_protocol(self):
3161 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrou91f43802019-05-26 17:10:09 +02003162 self.assertEqual(pickle.HIGHEST_PROTOCOL, 5)
Tim Petersc0c93702003-02-13 19:30:57 +00003163
Martin v. Löwis544f1192004-07-27 05:22:33 +00003164 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00003165 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00003166 # With and without keyword arguments
Serhiy Storchaka65452562017-11-15 14:01:08 +02003167 self.dump(123, f, -1)
3168 self.dump(123, file=f, protocol=-1)
3169 self.dumps(123, -1)
3170 self.dumps(123, protocol=-1)
3171 self.Pickler(f, -1)
3172 self.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00003173
Serhiy Storchaka38ab7d42019-05-31 11:29:39 +03003174 def test_dump_text_file(self):
3175 f = open(TESTFN, "w")
3176 try:
3177 for proto in protocols:
3178 self.assertRaises(TypeError, self.dump, 123, f, proto)
3179 finally:
3180 f.close()
Hai Shi883bc632020-07-06 17:12:49 +08003181 os_helper.unlink(TESTFN)
Serhiy Storchaka38ab7d42019-05-31 11:29:39 +03003182
3183 def test_incomplete_input(self):
3184 s = io.BytesIO(b"X''.")
3185 self.assertRaises((EOFError, struct.error, pickle.UnpicklingError), self.load, s)
3186
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00003187 def test_bad_init(self):
3188 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00003189 # Override initialization without calling __init__() of the superclass.
Serhiy Storchaka65452562017-11-15 14:01:08 +02003190 class BadPickler(self.Pickler):
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00003191 def __init__(self): pass
3192
Serhiy Storchaka65452562017-11-15 14:01:08 +02003193 class BadUnpickler(self.Unpickler):
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00003194 def __init__(self): pass
3195
3196 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
3197 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
3198
Antoine Pitrou91f43802019-05-26 17:10:09 +02003199 def check_dumps_loads_oob_buffers(self, dumps, loads):
3200 # No need to do the full gamut of tests here, just enough to
3201 # check that dumps() and loads() redirect their arguments
3202 # to the underlying Pickler and Unpickler, respectively.
3203 obj = ZeroCopyBytes(b"foo")
3204
3205 for proto in range(0, 5):
3206 # Need protocol >= 5 for buffer_callback
3207 with self.assertRaises(ValueError):
3208 dumps(obj, protocol=proto,
3209 buffer_callback=[].append)
3210 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
3211 buffers = []
3212 buffer_callback = buffers.append
3213 data = dumps(obj, protocol=proto,
3214 buffer_callback=buffer_callback)
3215 self.assertNotIn(b"foo", data)
3216 self.assertEqual(bytes(buffers[0]), b"foo")
3217 # Need buffers argument to unpickle properly
3218 with self.assertRaises(pickle.UnpicklingError):
3219 loads(data)
3220 new = loads(data, buffers=buffers)
3221 self.assertIs(new, obj)
3222
3223 def test_dumps_loads_oob_buffers(self):
3224 # Test out-of-band buffers (PEP 574) with top-level dumps() and loads()
3225 self.check_dumps_loads_oob_buffers(self.dumps, self.loads)
3226
3227 def test_dump_load_oob_buffers(self):
3228 # Test out-of-band buffers (PEP 574) with top-level dump() and load()
3229 def dumps(obj, **kwargs):
3230 f = io.BytesIO()
3231 self.dump(obj, f, **kwargs)
3232 return f.getvalue()
3233
3234 def loads(data, **kwargs):
3235 f = io.BytesIO(data)
3236 return self.load(f, **kwargs)
3237
3238 self.check_dumps_loads_oob_buffers(dumps, loads)
3239
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00003240
Jeremy Hylton4c8be852002-11-13 22:10:47 +00003241class AbstractPersistentPicklerTests(unittest.TestCase):
3242
3243 # This class defines persistent_id() and persistent_load()
3244 # functions that should be used by the pickler. All even integers
3245 # are pickled using persistent ids.
3246
3247 def persistent_id(self, object):
3248 if isinstance(object, int) and object % 2 == 0:
3249 self.id_count += 1
3250 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08003251 elif object == "test_false_value":
3252 self.false_count += 1
3253 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00003254 else:
3255 return None
3256
3257 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08003258 if not oid:
3259 self.load_false_count += 1
3260 return "test_false_value"
3261 else:
3262 self.load_count += 1
3263 object = int(oid)
3264 assert object % 2 == 0
3265 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00003266
3267 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08003268 L = list(range(10)) + ["test_false_value"]
3269 for proto in protocols:
3270 self.id_count = 0
3271 self.false_count = 0
3272 self.load_false_count = 0
3273 self.load_count = 0
3274 self.assertEqual(self.loads(self.dumps(L, proto)), L)
3275 self.assertEqual(self.id_count, 5)
3276 self.assertEqual(self.false_count, 1)
3277 self.assertEqual(self.load_count, 5)
3278 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00003279
Collin Winter771d8342009-04-16 03:18:06 +00003280
Serhiy Storchakadec25af2016-07-17 11:24:17 +03003281class AbstractIdentityPersistentPicklerTests(unittest.TestCase):
3282
3283 def persistent_id(self, obj):
3284 return obj
3285
3286 def persistent_load(self, pid):
3287 return pid
3288
3289 def _check_return_correct_type(self, obj, proto):
3290 unpickled = self.loads(self.dumps(obj, proto))
3291 self.assertIsInstance(unpickled, type(obj))
3292 self.assertEqual(unpickled, obj)
3293
3294 def test_return_correct_type(self):
3295 for proto in protocols:
3296 # Protocol 0 supports only ASCII strings.
3297 if proto == 0:
3298 self._check_return_correct_type("abc", 0)
3299 else:
3300 for obj in [b"abc\n", "abc\n", -1, -1.1 * 0.1, str]:
3301 self._check_return_correct_type(obj, proto)
3302
3303 def test_protocol0_is_ascii_only(self):
3304 non_ascii_str = "\N{EMPTY SET}"
3305 self.assertRaises(pickle.PicklingError, self.dumps, non_ascii_str, 0)
3306 pickled = pickle.PERSID + non_ascii_str.encode('utf-8') + b'\n.'
3307 self.assertRaises(pickle.UnpicklingError, self.loads, pickled)
3308
3309
Collin Winter771d8342009-04-16 03:18:06 +00003310class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
3311
3312 pickler_class = None
3313 unpickler_class = None
3314
3315 def setUp(self):
3316 assert self.pickler_class
3317 assert self.unpickler_class
3318
3319 def test_clear_pickler_memo(self):
3320 # To test whether clear_memo() has any effect, we pickle an object,
3321 # then pickle it again without clearing the memo; the two serialized
3322 # forms should be different. If we clear_memo() and then pickle the
3323 # object again, the third serialized form should be identical to the
3324 # first one we obtained.
3325 data = ["abcdefg", "abcdefg", 44]
Serhiy Storchakac8695292018-04-04 00:11:27 +03003326 for proto in protocols:
3327 f = io.BytesIO()
3328 pickler = self.pickler_class(f, proto)
Collin Winter771d8342009-04-16 03:18:06 +00003329
Serhiy Storchakac8695292018-04-04 00:11:27 +03003330 pickler.dump(data)
3331 first_pickled = f.getvalue()
Collin Winter771d8342009-04-16 03:18:06 +00003332
Serhiy Storchakac8695292018-04-04 00:11:27 +03003333 # Reset BytesIO object.
3334 f.seek(0)
3335 f.truncate()
Collin Winter771d8342009-04-16 03:18:06 +00003336
Serhiy Storchakac8695292018-04-04 00:11:27 +03003337 pickler.dump(data)
3338 second_pickled = f.getvalue()
Collin Winter771d8342009-04-16 03:18:06 +00003339
Serhiy Storchakac8695292018-04-04 00:11:27 +03003340 # Reset the Pickler and BytesIO objects.
3341 pickler.clear_memo()
3342 f.seek(0)
3343 f.truncate()
Collin Winter771d8342009-04-16 03:18:06 +00003344
Serhiy Storchakac8695292018-04-04 00:11:27 +03003345 pickler.dump(data)
3346 third_pickled = f.getvalue()
Collin Winter771d8342009-04-16 03:18:06 +00003347
Serhiy Storchakac8695292018-04-04 00:11:27 +03003348 self.assertNotEqual(first_pickled, second_pickled)
3349 self.assertEqual(first_pickled, third_pickled)
Collin Winter771d8342009-04-16 03:18:06 +00003350
3351 def test_priming_pickler_memo(self):
3352 # Verify that we can set the Pickler's memo attribute.
3353 data = ["abcdefg", "abcdefg", 44]
3354 f = io.BytesIO()
3355 pickler = self.pickler_class(f)
3356
3357 pickler.dump(data)
3358 first_pickled = f.getvalue()
3359
3360 f = io.BytesIO()
3361 primed = self.pickler_class(f)
3362 primed.memo = pickler.memo
3363
3364 primed.dump(data)
3365 primed_pickled = f.getvalue()
3366
3367 self.assertNotEqual(first_pickled, primed_pickled)
3368
3369 def test_priming_unpickler_memo(self):
3370 # Verify that we can set the Unpickler's memo attribute.
3371 data = ["abcdefg", "abcdefg", 44]
3372 f = io.BytesIO()
3373 pickler = self.pickler_class(f)
3374
3375 pickler.dump(data)
3376 first_pickled = f.getvalue()
3377
3378 f = io.BytesIO()
3379 primed = self.pickler_class(f)
3380 primed.memo = pickler.memo
3381
3382 primed.dump(data)
3383 primed_pickled = f.getvalue()
3384
3385 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
3386 unpickled_data1 = unpickler.load()
3387
3388 self.assertEqual(unpickled_data1, data)
3389
3390 primed = self.unpickler_class(io.BytesIO(primed_pickled))
3391 primed.memo = unpickler.memo
3392 unpickled_data2 = primed.load()
3393
3394 primed.memo.clear()
3395
3396 self.assertEqual(unpickled_data2, data)
3397 self.assertTrue(unpickled_data2 is unpickled_data1)
3398
3399 def test_reusing_unpickler_objects(self):
3400 data1 = ["abcdefg", "abcdefg", 44]
3401 f = io.BytesIO()
3402 pickler = self.pickler_class(f)
3403 pickler.dump(data1)
3404 pickled1 = f.getvalue()
3405
3406 data2 = ["abcdefg", 44, 44]
3407 f = io.BytesIO()
3408 pickler = self.pickler_class(f)
3409 pickler.dump(data2)
3410 pickled2 = f.getvalue()
3411
3412 f = io.BytesIO()
3413 f.write(pickled1)
3414 f.seek(0)
3415 unpickler = self.unpickler_class(f)
3416 self.assertEqual(unpickler.load(), data1)
3417
3418 f.seek(0)
3419 f.truncate()
3420 f.write(pickled2)
3421 f.seek(0)
3422 self.assertEqual(unpickler.load(), data2)
3423
Antoine Pitrou9f378722020-02-23 23:33:53 +01003424 def _check_multiple_unpicklings(self, ioclass, *, seekable=True):
Antoine Pitrou04248a82010-10-12 20:51:21 +00003425 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003426 with self.subTest(proto=proto):
3427 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
3428 f = ioclass()
3429 pickler = self.pickler_class(f, protocol=proto)
3430 pickler.dump(data1)
3431 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00003432
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003433 N = 5
3434 f = ioclass(pickled * N)
3435 unpickler = self.unpickler_class(f)
3436 for i in range(N):
Antoine Pitrou9f378722020-02-23 23:33:53 +01003437 if seekable:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003438 pos = f.tell()
3439 self.assertEqual(unpickler.load(), data1)
Antoine Pitrou9f378722020-02-23 23:33:53 +01003440 if seekable:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003441 self.assertEqual(f.tell(), pos + len(pickled))
3442 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00003443
3444 def test_multiple_unpicklings_seekable(self):
3445 self._check_multiple_unpicklings(io.BytesIO)
3446
3447 def test_multiple_unpicklings_unseekable(self):
Antoine Pitrou9f378722020-02-23 23:33:53 +01003448 self._check_multiple_unpicklings(UnseekableIO, seekable=False)
3449
3450 def test_multiple_unpicklings_minimal(self):
3451 # File-like object that doesn't support peek() and readinto()
3452 # (bpo-39681)
3453 self._check_multiple_unpicklings(MinimalIO, seekable=False)
Antoine Pitrou04248a82010-10-12 20:51:21 +00003454
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02003455 def test_unpickling_buffering_readline(self):
3456 # Issue #12687: the unpickler's buffering logic could fail with
3457 # text mode opcodes.
3458 data = list(range(10))
3459 for proto in protocols:
3460 for buf_size in range(1, 11):
3461 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
3462 pickler = self.pickler_class(f, protocol=proto)
3463 pickler.dump(data)
3464 f.seek(0)
3465 unpickler = self.unpickler_class(f)
3466 self.assertEqual(unpickler.load(), data)
3467
Collin Winter771d8342009-04-16 03:18:06 +00003468
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01003469# Tests for dispatch_table attribute
3470
3471REDUCE_A = 'reduce_A'
3472
3473class AAA(object):
3474 def __reduce__(self):
3475 return str, (REDUCE_A,)
3476
3477class BBB(object):
Pierre Glaser65d98d02019-05-08 21:40:25 +02003478 def __init__(self):
3479 # Add an instance attribute to enable state-saving routines at pickling
3480 # time.
3481 self.a = "some attribute"
3482
3483 def __setstate__(self, state):
3484 self.a = "BBB.__setstate__"
3485
3486
3487def setstate_bbb(obj, state):
3488 """Custom state setter for BBB objects
3489
3490 Such callable may be created by other persons than the ones who created the
3491 BBB class. If passed as the state_setter item of a custom reducer, this
3492 allows for custom state setting behavior of BBB objects. One can think of
3493 it as the analogous of list_setitems or dict_setitems but for foreign
3494 classes/functions.
3495 """
3496 obj.a = "custom state_setter"
3497
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01003498
Pierre Glaser289f1f82019-05-08 23:08:25 +02003499
3500class AbstractCustomPicklerClass:
3501 """Pickler implementing a reducing hook using reducer_override."""
3502 def reducer_override(self, obj):
3503 obj_name = getattr(obj, "__name__", None)
3504
3505 if obj_name == 'f':
3506 # asking the pickler to save f as 5
3507 return int, (5, )
3508
3509 if obj_name == 'MyClass':
3510 return str, ('some str',)
3511
3512 elif obj_name == 'g':
3513 # in this case, the callback returns an invalid result (not a 2-5
3514 # tuple or a string), the pickler should raise a proper error.
3515 return False
3516
3517 elif obj_name == 'h':
3518 # Simulate a case when the reducer fails. The error should
3519 # be propagated to the original ``dump`` call.
3520 raise ValueError('The reducer just failed')
3521
3522 return NotImplemented
3523
3524class AbstractHookTests(unittest.TestCase):
3525 def test_pickler_hook(self):
3526 # test the ability of a custom, user-defined CPickler subclass to
3527 # override the default reducing routines of any type using the method
3528 # reducer_override
3529
3530 def f():
3531 pass
3532
3533 def g():
3534 pass
3535
3536 def h():
3537 pass
3538
3539 class MyClass:
3540 pass
3541
3542 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
3543 with self.subTest(proto=proto):
3544 bio = io.BytesIO()
3545 p = self.pickler_class(bio, proto)
3546
3547 p.dump([f, MyClass, math.log])
3548 new_f, some_str, math_log = pickle.loads(bio.getvalue())
3549
3550 self.assertEqual(new_f, 5)
3551 self.assertEqual(some_str, 'some str')
3552 # math.log does not have its usual reducer overriden, so the
3553 # custom reduction callback should silently direct the pickler
3554 # to the default pickling by attribute, by returning
3555 # NotImplemented
3556 self.assertIs(math_log, math.log)
3557
3558 with self.assertRaises(pickle.PicklingError):
3559 p.dump(g)
3560
3561 with self.assertRaisesRegex(
3562 ValueError, 'The reducer just failed'):
3563 p.dump(h)
3564
Pierre Glaser0f2f35e2020-02-02 19:55:21 +01003565 @support.cpython_only
3566 def test_reducer_override_no_reference_cycle(self):
3567 # bpo-39492: reducer_override used to induce a spurious reference cycle
3568 # inside the Pickler object, that could prevent all serialized objects
3569 # from being garbage-collected without explicity invoking gc.collect.
3570
3571 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
3572 with self.subTest(proto=proto):
3573 def f():
3574 pass
3575
3576 wr = weakref.ref(f)
3577
3578 bio = io.BytesIO()
3579 p = self.pickler_class(bio, proto)
3580 p.dump(f)
3581 new_f = pickle.loads(bio.getvalue())
3582 assert new_f == 5
3583
3584 del p
3585 del f
3586
3587 self.assertIsNone(wr())
3588
Pierre Glaser289f1f82019-05-08 23:08:25 +02003589
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01003590class AbstractDispatchTableTests(unittest.TestCase):
3591
3592 def test_default_dispatch_table(self):
3593 # No dispatch_table attribute by default
3594 f = io.BytesIO()
3595 p = self.pickler_class(f, 0)
3596 with self.assertRaises(AttributeError):
3597 p.dispatch_table
3598 self.assertFalse(hasattr(p, 'dispatch_table'))
3599
3600 def test_class_dispatch_table(self):
3601 # A dispatch_table attribute can be specified class-wide
3602 dt = self.get_dispatch_table()
3603
3604 class MyPickler(self.pickler_class):
3605 dispatch_table = dt
3606
3607 def dumps(obj, protocol=None):
3608 f = io.BytesIO()
3609 p = MyPickler(f, protocol)
3610 self.assertEqual(p.dispatch_table, dt)
3611 p.dump(obj)
3612 return f.getvalue()
3613
3614 self._test_dispatch_table(dumps, dt)
3615
3616 def test_instance_dispatch_table(self):
3617 # A dispatch_table attribute can also be specified instance-wide
3618 dt = self.get_dispatch_table()
3619
3620 def dumps(obj, protocol=None):
3621 f = io.BytesIO()
3622 p = self.pickler_class(f, protocol)
3623 p.dispatch_table = dt
3624 self.assertEqual(p.dispatch_table, dt)
3625 p.dump(obj)
3626 return f.getvalue()
3627
3628 self._test_dispatch_table(dumps, dt)
3629
3630 def _test_dispatch_table(self, dumps, dispatch_table):
3631 def custom_load_dump(obj):
3632 return pickle.loads(dumps(obj, 0))
3633
3634 def default_load_dump(obj):
3635 return pickle.loads(pickle.dumps(obj, 0))
3636
3637 # pickling complex numbers using protocol 0 relies on copyreg
3638 # so check pickling a complex number still works
3639 z = 1 + 2j
3640 self.assertEqual(custom_load_dump(z), z)
3641 self.assertEqual(default_load_dump(z), z)
3642
3643 # modify pickling of complex
3644 REDUCE_1 = 'reduce_1'
3645 def reduce_1(obj):
3646 return str, (REDUCE_1,)
3647 dispatch_table[complex] = reduce_1
3648 self.assertEqual(custom_load_dump(z), REDUCE_1)
3649 self.assertEqual(default_load_dump(z), z)
3650
3651 # check picklability of AAA and BBB
3652 a = AAA()
3653 b = BBB()
3654 self.assertEqual(custom_load_dump(a), REDUCE_A)
3655 self.assertIsInstance(custom_load_dump(b), BBB)
3656 self.assertEqual(default_load_dump(a), REDUCE_A)
3657 self.assertIsInstance(default_load_dump(b), BBB)
3658
3659 # modify pickling of BBB
3660 dispatch_table[BBB] = reduce_1
3661 self.assertEqual(custom_load_dump(a), REDUCE_A)
3662 self.assertEqual(custom_load_dump(b), REDUCE_1)
3663 self.assertEqual(default_load_dump(a), REDUCE_A)
3664 self.assertIsInstance(default_load_dump(b), BBB)
3665
3666 # revert pickling of BBB and modify pickling of AAA
3667 REDUCE_2 = 'reduce_2'
3668 def reduce_2(obj):
3669 return str, (REDUCE_2,)
3670 dispatch_table[AAA] = reduce_2
3671 del dispatch_table[BBB]
3672 self.assertEqual(custom_load_dump(a), REDUCE_2)
3673 self.assertIsInstance(custom_load_dump(b), BBB)
3674 self.assertEqual(default_load_dump(a), REDUCE_A)
3675 self.assertIsInstance(default_load_dump(b), BBB)
3676
Pierre Glaser65d98d02019-05-08 21:40:25 +02003677 # End-to-end testing of save_reduce with the state_setter keyword
3678 # argument. This is a dispatch_table test as the primary goal of
3679 # state_setter is to tweak objects reduction behavior.
3680 # In particular, state_setter is useful when the default __setstate__
3681 # behavior is not flexible enough.
3682
3683 # No custom reducer for b has been registered for now, so
3684 # BBB.__setstate__ should be used at unpickling time
3685 self.assertEqual(default_load_dump(b).a, "BBB.__setstate__")
3686
3687 def reduce_bbb(obj):
3688 return BBB, (), obj.__dict__, None, None, setstate_bbb
3689
3690 dispatch_table[BBB] = reduce_bbb
3691
3692 # The custom reducer reduce_bbb includes a state setter, that should
3693 # have priority over BBB.__setstate__
3694 self.assertEqual(custom_load_dump(b).a, "custom state_setter")
3695
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01003696
Guido van Rossum98297ee2007-11-06 21:34:58 +00003697if __name__ == "__main__":
3698 # Print some stuff that can be used to rewrite DATA{0,1,2}
3699 from pickletools import dis
3700 x = create_data()
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03003701 for i in range(pickle.HIGHEST_PROTOCOL+1):
Guido van Rossum98297ee2007-11-06 21:34:58 +00003702 p = pickle.dumps(x, i)
3703 print("DATA{0} = (".format(i))
3704 for j in range(0, len(p), 20):
3705 b = bytes(p[j:j+20])
3706 print(" {0!r}".format(b))
3707 print(")")
3708 print()
3709 print("# Disassembly of DATA{0}".format(i))
3710 print("DATA{0}_DIS = \"\"\"\\".format(i))
3711 dis(p)
3712 print("\"\"\"")
3713 print()