blob: 3d54617f68ba4a7d1e4f6cac597fe59b39ffcc5f [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
Antoine Pitrou82be19f2011-08-29 23:09:33 +020025from test.support import (
Serhiy Storchaka7279bef2015-11-29 13:12:10 +020026 TestFailed, TESTFN, run_with_locale, no_tracing,
tjb9004371c0a2019-02-18 23:30:51 +080027 _2G, _4G, bigmemtest, reap_threads, forget,
Victor Stinnerb39d41b2020-06-17 18:40:14 +020028 save_restore_warnings_filters
Antoine Pitrou82be19f2011-08-29 23:09:33 +020029 )
Tim Peterse089c682001-04-10 03:41:41 +000030
Guido van Rossum98297ee2007-11-06 21:34:58 +000031from pickle import bytes_types
32
Victor Stinnerb39d41b2020-06-17 18:40:14 +020033
34# bpo-41003: Save/restore warnings filters to leave them unchanged.
35# Ignore filters installed by numpy.
36try:
37 with save_restore_warnings_filters():
38 import numpy as np
39except ImportError:
40 np = None
41
42
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030043requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
44 "test is only meaningful on 32-bit builds")
45
Tim Petersee1a53c2003-02-02 02:57:53 +000046# Tests that try a number of pickle protocols should have a
47# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000048# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000049protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000050
Tim Peters22e71712003-02-03 22:27:38 +000051
52# Return True if opcode code appears in the pickle, else False.
53def opcode_in_pickle(code, pickle):
54 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000055 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000056 return True
57 return False
58
Tim Peters8d2613a2003-02-11 16:40:16 +000059# Return the number of times opcode code appears in pickle.
60def count_opcode(code, pickle):
61 n = 0
62 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000063 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000064 n += 1
65 return n
66
Antoine Pitrou04248a82010-10-12 20:51:21 +000067
68class UnseekableIO(io.BytesIO):
69 def peek(self, *args):
70 raise NotImplementedError
71
72 def seekable(self):
73 return False
74
75 def seek(self, *args):
76 raise io.UnsupportedOperation
77
78 def tell(self):
79 raise io.UnsupportedOperation
80
81
Antoine Pitrou9f378722020-02-23 23:33:53 +010082class MinimalIO(object):
83 """
84 A file-like object that doesn't support readinto().
85 """
86 def __init__(self, *args):
87 self._bio = io.BytesIO(*args)
88 self.getvalue = self._bio.getvalue
89 self.read = self._bio.read
90 self.readline = self._bio.readline
91 self.write = self._bio.write
92
93
Tim Peters3e667d52003-02-04 21:47:44 +000094# We can't very well test the extension registry without putting known stuff
95# in it, but we have to be careful to restore its original state. Code
96# should do this:
97#
98# e = ExtensionSaver(extension_code)
99# try:
100# fiddle w/ the extension registry's stuff for extension_code
101# finally:
102# e.restore()
103
104class ExtensionSaver:
105 # Remember current registration for code (if any), and remove it (if
106 # there is one).
107 def __init__(self, code):
108 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000109 if code in copyreg._inverted_registry:
110 self.pair = copyreg._inverted_registry[code]
111 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000112 else:
113 self.pair = None
114
115 # Restore previous registration for code.
116 def restore(self):
117 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000118 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +0000119 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000120 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000121 pair = self.pair
122 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000123 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +0000124
Jeremy Hylton66426532001-10-15 21:38:56 +0000125class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000126 def __eq__(self, other):
127 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +0000128
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000129class D(C):
130 def __init__(self, arg):
131 pass
132
133class E(C):
134 def __getinitargs__(self):
135 return ()
136
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100137class H(object):
138 pass
139
Serhiy Storchaka608c2132015-11-07 11:16:10 +0200140# Hashable mutable key
141class K(object):
142 def __init__(self, value):
143 self.value = value
144
145 def __reduce__(self):
146 # Shouldn't support the recursion itself
147 return K, (self.value,)
148
Jeremy Hylton66426532001-10-15 21:38:56 +0000149import __main__
150__main__.C = C
151C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000152__main__.D = D
153D.__module__ = "__main__"
154__main__.E = E
155E.__module__ = "__main__"
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100156__main__.H = H
157H.__module__ = "__main__"
Serhiy Storchaka608c2132015-11-07 11:16:10 +0200158__main__.K = K
159K.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000160
161class myint(int):
162 def __init__(self, x):
163 self.str = str(x)
164
165class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000166
Jeremy Hylton66426532001-10-15 21:38:56 +0000167 def __init__(self, a, b):
168 self.a = a
169 self.b = b
170
171 def __getinitargs__(self):
172 return self.a, self.b
173
Guido van Rossum04a86612001-12-19 16:58:54 +0000174class metaclass(type):
175 pass
176
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000177class use_metaclass(object, metaclass=metaclass):
178 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000179
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200180class pickling_metaclass(type):
181 def __eq__(self, other):
182 return (type(self) == type(other) and
183 self.reduce_args == other.reduce_args)
184
185 def __reduce__(self):
186 return (create_dynamic_class, self.reduce_args)
187
188def create_dynamic_class(name, bases):
189 result = pickling_metaclass(name, bases, dict())
190 result.reduce_args = (name, bases)
191 return result
192
Antoine Pitrou91f43802019-05-26 17:10:09 +0200193
194class ZeroCopyBytes(bytes):
195 readonly = True
196 c_contiguous = True
197 f_contiguous = True
198 zero_copy_reconstruct = True
199
200 def __reduce_ex__(self, protocol):
201 if protocol >= 5:
202 return type(self)._reconstruct, (pickle.PickleBuffer(self),), None
203 else:
204 return type(self)._reconstruct, (bytes(self),)
205
206 def __repr__(self):
207 return "{}({!r})".format(self.__class__.__name__, bytes(self))
208
209 __str__ = __repr__
210
211 @classmethod
212 def _reconstruct(cls, obj):
213 with memoryview(obj) as m:
214 obj = m.obj
215 if type(obj) is cls:
216 # Zero-copy
217 return obj
218 else:
219 return cls(obj)
220
221
222class ZeroCopyBytearray(bytearray):
223 readonly = False
224 c_contiguous = True
225 f_contiguous = True
226 zero_copy_reconstruct = True
227
228 def __reduce_ex__(self, protocol):
229 if protocol >= 5:
230 return type(self)._reconstruct, (pickle.PickleBuffer(self),), None
231 else:
232 return type(self)._reconstruct, (bytes(self),)
233
234 def __repr__(self):
235 return "{}({!r})".format(self.__class__.__name__, bytes(self))
236
237 __str__ = __repr__
238
239 @classmethod
240 def _reconstruct(cls, obj):
241 with memoryview(obj) as m:
242 obj = m.obj
243 if type(obj) is cls:
244 # Zero-copy
245 return obj
246 else:
247 return cls(obj)
248
249
250if _testbuffer is not None:
251
252 class PicklableNDArray:
253 # A not-really-zero-copy picklable ndarray, as the ndarray()
254 # constructor doesn't allow for it
255
256 zero_copy_reconstruct = False
257
258 def __init__(self, *args, **kwargs):
259 self.array = _testbuffer.ndarray(*args, **kwargs)
260
261 def __getitem__(self, idx):
262 cls = type(self)
263 new = cls.__new__(cls)
264 new.array = self.array[idx]
265 return new
266
267 @property
268 def readonly(self):
269 return self.array.readonly
270
271 @property
272 def c_contiguous(self):
273 return self.array.c_contiguous
274
275 @property
276 def f_contiguous(self):
277 return self.array.f_contiguous
278
279 def __eq__(self, other):
280 if not isinstance(other, PicklableNDArray):
281 return NotImplemented
282 return (other.array.format == self.array.format and
283 other.array.shape == self.array.shape and
284 other.array.strides == self.array.strides and
285 other.array.readonly == self.array.readonly and
286 other.array.tobytes() == self.array.tobytes())
287
288 def __ne__(self, other):
289 if not isinstance(other, PicklableNDArray):
290 return NotImplemented
291 return not (self == other)
292
293 def __repr__(self):
294 return (f"{type(self)}(shape={self.array.shape},"
295 f"strides={self.array.strides}, "
296 f"bytes={self.array.tobytes()})")
297
298 def __reduce_ex__(self, protocol):
299 if not self.array.contiguous:
300 raise NotImplementedError("Reconstructing a non-contiguous "
301 "ndarray does not seem possible")
302 ndarray_kwargs = {"shape": self.array.shape,
303 "strides": self.array.strides,
304 "format": self.array.format,
305 "flags": (0 if self.readonly
306 else _testbuffer.ND_WRITABLE)}
307 pb = pickle.PickleBuffer(self.array)
308 if protocol >= 5:
309 return (type(self)._reconstruct,
310 (pb, ndarray_kwargs))
311 else:
312 # Need to serialize the bytes in physical order
313 with pb.raw() as m:
314 return (type(self)._reconstruct,
315 (m.tobytes(), ndarray_kwargs))
316
317 @classmethod
318 def _reconstruct(cls, obj, kwargs):
319 with memoryview(obj) as m:
320 # For some reason, ndarray() wants a list of integers...
321 # XXX This only works if format == 'B'
322 items = list(m.tobytes())
323 return cls(items, **kwargs)
324
325
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300326# DATA0 .. DATA4 are the pickles we expect under the various protocols, for
Tim Peters70b02d72003-02-02 17:26:40 +0000327# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000328
Guido van Rossum98297ee2007-11-06 21:34:58 +0000329DATA0 = (
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200330 b'(lp0\nL0L\naL1L\naF2.0\n'
331 b'ac__builtin__\ncomple'
332 b'x\np1\n(F3.0\nF0.0\ntp2\n'
333 b'Rp3\naL1L\naL-1L\naL255'
334 b'L\naL-255L\naL-256L\naL'
335 b'65535L\naL-65535L\naL-'
336 b'65536L\naL2147483647L'
337 b'\naL-2147483647L\naL-2'
338 b'147483648L\na(Vabc\np4'
339 b'\ng4\nccopy_reg\n_recon'
340 b'structor\np5\n(c__main'
341 b'__\nC\np6\nc__builtin__'
342 b'\nobject\np7\nNtp8\nRp9\n'
343 b'(dp10\nVfoo\np11\nL1L\ns'
344 b'Vbar\np12\nL2L\nsbg9\ntp'
345 b'13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000346)
Tim Peterse9358162001-01-22 22:05:20 +0000347
Guido van Rossum98297ee2007-11-06 21:34:58 +0000348# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000349DATA0_DIS = """\
350 0: ( MARK
351 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000352 2: p PUT 0
353 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000354 9: a APPEND
355 10: L LONG 1
356 14: a APPEND
357 15: F FLOAT 2.0
358 20: a APPEND
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200359 21: c GLOBAL '__builtin__ complex'
360 42: p PUT 1
361 45: ( MARK
362 46: F FLOAT 3.0
363 51: F FLOAT 0.0
364 56: t TUPLE (MARK at 45)
365 57: p PUT 2
366 60: R REDUCE
367 61: p PUT 3
368 64: a APPEND
369 65: L LONG 1
370 69: a APPEND
371 70: L LONG -1
372 75: a APPEND
373 76: L LONG 255
374 82: a APPEND
375 83: L LONG -255
376 90: a APPEND
377 91: L LONG -256
378 98: a APPEND
379 99: L LONG 65535
380 107: a APPEND
381 108: L LONG -65535
382 117: a APPEND
383 118: L LONG -65536
384 127: a APPEND
385 128: L LONG 2147483647
386 141: a APPEND
387 142: L LONG -2147483647
388 156: a APPEND
389 157: L LONG -2147483648
390 171: a APPEND
391 172: ( MARK
392 173: V UNICODE 'abc'
393 178: p PUT 4
394 181: g GET 4
395 184: c GLOBAL 'copy_reg _reconstructor'
396 209: p PUT 5
397 212: ( MARK
398 213: c GLOBAL '__main__ C'
399 225: p PUT 6
400 228: c GLOBAL '__builtin__ object'
401 248: p PUT 7
402 251: N NONE
403 252: t TUPLE (MARK at 212)
404 253: p PUT 8
405 256: R REDUCE
406 257: p PUT 9
407 260: ( MARK
408 261: d DICT (MARK at 260)
409 262: p PUT 10
410 266: V UNICODE 'foo'
411 271: p PUT 11
412 275: L LONG 1
413 279: s SETITEM
414 280: V UNICODE 'bar'
415 285: p PUT 12
416 289: L LONG 2
417 293: s SETITEM
418 294: b BUILD
419 295: g GET 9
420 298: t TUPLE (MARK at 172)
421 299: p PUT 13
422 303: a APPEND
423 304: g GET 13
424 308: a APPEND
425 309: L LONG 5
426 313: a APPEND
427 314: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000428highest protocol among opcodes = 0
429"""
430
Guido van Rossum98297ee2007-11-06 21:34:58 +0000431DATA1 = (
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200432 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c__'
433 b'builtin__\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000434 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
435 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
436 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
437 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200438 b'cq\x04h\x04ccopy_reg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000439 b'nstructor\nq\x05(c__main'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200440 b'__\nC\nq\x06c__builtin__\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000441 b'object\nq\x07Ntq\x08Rq\t}q\n('
442 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
443 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
444)
Tim Peters70b02d72003-02-02 17:26:40 +0000445
Guido van Rossum98297ee2007-11-06 21:34:58 +0000446# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000447DATA1_DIS = """\
448 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000449 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000450 3: ( MARK
451 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000452 6: K BININT1 1
453 8: G BINFLOAT 2.0
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200454 17: c GLOBAL '__builtin__ complex'
455 38: q BINPUT 1
456 40: ( MARK
457 41: G BINFLOAT 3.0
458 50: G BINFLOAT 0.0
459 59: t TUPLE (MARK at 40)
460 60: q BINPUT 2
461 62: R REDUCE
462 63: q BINPUT 3
463 65: K BININT1 1
464 67: J BININT -1
465 72: K BININT1 255
466 74: J BININT -255
467 79: J BININT -256
468 84: M BININT2 65535
469 87: J BININT -65535
470 92: J BININT -65536
471 97: J BININT 2147483647
472 102: J BININT -2147483647
473 107: J BININT -2147483648
474 112: ( MARK
475 113: X BINUNICODE 'abc'
476 121: q BINPUT 4
477 123: h BINGET 4
478 125: c GLOBAL 'copy_reg _reconstructor'
479 150: q BINPUT 5
480 152: ( MARK
481 153: c GLOBAL '__main__ C'
482 165: q BINPUT 6
483 167: c GLOBAL '__builtin__ object'
484 187: q BINPUT 7
485 189: N NONE
486 190: t TUPLE (MARK at 152)
487 191: q BINPUT 8
488 193: R REDUCE
489 194: q BINPUT 9
490 196: } EMPTY_DICT
491 197: q BINPUT 10
492 199: ( MARK
493 200: X BINUNICODE 'foo'
494 208: q BINPUT 11
495 210: K BININT1 1
496 212: X BINUNICODE 'bar'
497 220: q BINPUT 12
498 222: K BININT1 2
499 224: u SETITEMS (MARK at 199)
500 225: b BUILD
501 226: h BINGET 9
502 228: t TUPLE (MARK at 112)
503 229: q BINPUT 13
504 231: h BINGET 13
505 233: K BININT1 5
506 235: e APPENDS (MARK at 3)
507 236: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000508highest protocol among opcodes = 1
509"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000510
Guido van Rossum98297ee2007-11-06 21:34:58 +0000511DATA2 = (
512 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200513 b'__builtin__\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000514 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
515 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
516 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
517 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
518 b'bcq\x04h\x04c__main__\nC\nq\x05'
519 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
520 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
521 b'\nK\x05e.'
522)
Tim Petersfc273752003-03-02 04:54:24 +0000523
Guido van Rossum98297ee2007-11-06 21:34:58 +0000524# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000525DATA2_DIS = """\
526 0: \x80 PROTO 2
527 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000528 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000529 5: ( MARK
530 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000531 8: K BININT1 1
532 10: G BINFLOAT 2.0
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200533 19: c GLOBAL '__builtin__ complex'
534 40: q BINPUT 1
535 42: G BINFLOAT 3.0
536 51: G BINFLOAT 0.0
537 60: \x86 TUPLE2
538 61: q BINPUT 2
539 63: R REDUCE
540 64: q BINPUT 3
541 66: K BININT1 1
542 68: J BININT -1
543 73: K BININT1 255
544 75: J BININT -255
545 80: J BININT -256
546 85: M BININT2 65535
547 88: J BININT -65535
548 93: J BININT -65536
549 98: J BININT 2147483647
550 103: J BININT -2147483647
551 108: J BININT -2147483648
552 113: ( MARK
553 114: X BINUNICODE 'abc'
554 122: q BINPUT 4
555 124: h BINGET 4
556 126: c GLOBAL '__main__ C'
557 138: q BINPUT 5
558 140: ) EMPTY_TUPLE
559 141: \x81 NEWOBJ
560 142: q BINPUT 6
561 144: } EMPTY_DICT
562 145: q BINPUT 7
563 147: ( MARK
564 148: X BINUNICODE 'foo'
565 156: q BINPUT 8
566 158: K BININT1 1
567 160: X BINUNICODE 'bar'
568 168: q BINPUT 9
569 170: K BININT1 2
570 172: u SETITEMS (MARK at 147)
571 173: b BUILD
572 174: h BINGET 6
573 176: t TUPLE (MARK at 113)
574 177: q BINPUT 10
575 179: h BINGET 10
576 181: K BININT1 5
577 183: e APPENDS (MARK at 5)
578 184: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000579highest protocol among opcodes = 2
580"""
581
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300582DATA3 = (
583 b'\x80\x03]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
584 b'builtins\ncomplex\nq\x01G'
585 b'@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00\x86q\x02'
586 b'Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff'
587 b'\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7f'
588 b'J\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00abcq'
589 b'\x04h\x04c__main__\nC\nq\x05)\x81q'
590 b'\x06}q\x07(X\x03\x00\x00\x00barq\x08K\x02X\x03\x00'
591 b'\x00\x00fooq\tK\x01ubh\x06tq\nh\nK\x05'
592 b'e.'
593)
594
595# Disassembly of DATA3
596DATA3_DIS = """\
597 0: \x80 PROTO 3
598 2: ] EMPTY_LIST
599 3: q BINPUT 0
600 5: ( MARK
601 6: K BININT1 0
602 8: K BININT1 1
603 10: G BINFLOAT 2.0
604 19: c GLOBAL 'builtins complex'
605 37: q BINPUT 1
606 39: G BINFLOAT 3.0
607 48: G BINFLOAT 0.0
608 57: \x86 TUPLE2
609 58: q BINPUT 2
610 60: R REDUCE
611 61: q BINPUT 3
612 63: K BININT1 1
613 65: J BININT -1
614 70: K BININT1 255
615 72: J BININT -255
616 77: J BININT -256
617 82: M BININT2 65535
618 85: J BININT -65535
619 90: J BININT -65536
620 95: J BININT 2147483647
621 100: J BININT -2147483647
622 105: J BININT -2147483648
623 110: ( MARK
624 111: X BINUNICODE 'abc'
625 119: q BINPUT 4
626 121: h BINGET 4
627 123: c GLOBAL '__main__ C'
628 135: q BINPUT 5
629 137: ) EMPTY_TUPLE
630 138: \x81 NEWOBJ
631 139: q BINPUT 6
632 141: } EMPTY_DICT
633 142: q BINPUT 7
634 144: ( MARK
635 145: X BINUNICODE 'bar'
636 153: q BINPUT 8
637 155: K BININT1 2
638 157: X BINUNICODE 'foo'
639 165: q BINPUT 9
640 167: K BININT1 1
641 169: u SETITEMS (MARK at 144)
642 170: b BUILD
643 171: h BINGET 6
644 173: t TUPLE (MARK at 110)
645 174: q BINPUT 10
646 176: h BINGET 10
647 178: K BININT1 5
648 180: e APPENDS (MARK at 5)
649 181: . STOP
650highest protocol among opcodes = 2
651"""
652
653DATA4 = (
654 b'\x80\x04\x95\xa8\x00\x00\x00\x00\x00\x00\x00]\x94(K\x00K\x01G@'
655 b'\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x07'
656 b'complex\x94\x93\x94G@\x08\x00\x00\x00\x00\x00\x00G'
657 b'\x00\x00\x00\x00\x00\x00\x00\x00\x86\x94R\x94K\x01J\xff\xff\xff\xffK'
658 b'\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ'
659 b'\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80('
660 b'\x8c\x03abc\x94h\x06\x8c\x08__main__\x94\x8c'
661 b'\x01C\x94\x93\x94)\x81\x94}\x94(\x8c\x03bar\x94K\x02\x8c'
662 b'\x03foo\x94K\x01ubh\nt\x94h\x0eK\x05e.'
663)
664
665# Disassembly of DATA4
666DATA4_DIS = """\
667 0: \x80 PROTO 4
668 2: \x95 FRAME 168
669 11: ] EMPTY_LIST
670 12: \x94 MEMOIZE
671 13: ( MARK
672 14: K BININT1 0
673 16: K BININT1 1
674 18: G BINFLOAT 2.0
675 27: \x8c SHORT_BINUNICODE 'builtins'
676 37: \x94 MEMOIZE
677 38: \x8c SHORT_BINUNICODE 'complex'
678 47: \x94 MEMOIZE
679 48: \x93 STACK_GLOBAL
680 49: \x94 MEMOIZE
681 50: G BINFLOAT 3.0
682 59: G BINFLOAT 0.0
683 68: \x86 TUPLE2
684 69: \x94 MEMOIZE
685 70: R REDUCE
686 71: \x94 MEMOIZE
687 72: K BININT1 1
688 74: J BININT -1
689 79: K BININT1 255
690 81: J BININT -255
691 86: J BININT -256
692 91: M BININT2 65535
693 94: J BININT -65535
694 99: J BININT -65536
695 104: J BININT 2147483647
696 109: J BININT -2147483647
697 114: J BININT -2147483648
698 119: ( MARK
699 120: \x8c SHORT_BINUNICODE 'abc'
700 125: \x94 MEMOIZE
701 126: h BINGET 6
702 128: \x8c SHORT_BINUNICODE '__main__'
703 138: \x94 MEMOIZE
704 139: \x8c SHORT_BINUNICODE 'C'
705 142: \x94 MEMOIZE
706 143: \x93 STACK_GLOBAL
707 144: \x94 MEMOIZE
708 145: ) EMPTY_TUPLE
709 146: \x81 NEWOBJ
710 147: \x94 MEMOIZE
711 148: } EMPTY_DICT
712 149: \x94 MEMOIZE
713 150: ( MARK
714 151: \x8c SHORT_BINUNICODE 'bar'
715 156: \x94 MEMOIZE
716 157: K BININT1 2
717 159: \x8c SHORT_BINUNICODE 'foo'
718 164: \x94 MEMOIZE
719 165: K BININT1 1
720 167: u SETITEMS (MARK at 150)
721 168: b BUILD
722 169: h BINGET 10
723 171: t TUPLE (MARK at 119)
724 172: \x94 MEMOIZE
725 173: h BINGET 14
726 175: K BININT1 5
727 177: e APPENDS (MARK at 13)
728 178: . STOP
729highest protocol among opcodes = 4
730"""
731
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000732# set([1,2]) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300733DATA_SET = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000734
735# xrange(5) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300736DATA_XRANGE = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000737
738# a SimpleCookie() object pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300739DATA_COOKIE = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
740 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
741 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
742 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
743 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
744 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000745
746# set([3]) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300747DATA_SET2 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000748
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100749python2_exceptions_without_args = (
750 ArithmeticError,
751 AssertionError,
752 AttributeError,
753 BaseException,
754 BufferError,
755 BytesWarning,
756 DeprecationWarning,
757 EOFError,
758 EnvironmentError,
759 Exception,
760 FloatingPointError,
761 FutureWarning,
762 GeneratorExit,
763 IOError,
764 ImportError,
765 ImportWarning,
766 IndentationError,
767 IndexError,
768 KeyError,
769 KeyboardInterrupt,
770 LookupError,
771 MemoryError,
772 NameError,
773 NotImplementedError,
774 OSError,
775 OverflowError,
776 PendingDeprecationWarning,
777 ReferenceError,
778 RuntimeError,
779 RuntimeWarning,
780 # StandardError is gone in Python 3, we map it to Exception
781 StopIteration,
782 SyntaxError,
783 SyntaxWarning,
784 SystemError,
785 SystemExit,
786 TabError,
787 TypeError,
788 UnboundLocalError,
789 UnicodeError,
790 UnicodeWarning,
791 UserWarning,
792 ValueError,
793 Warning,
794 ZeroDivisionError,
795)
796
797exception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.'
798
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100799# UnicodeEncodeError object pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300800DATA_UEERR = (b'\x80\x02cexceptions\nUnicodeEncodeError\n'
801 b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01'
802 b'U\x03badq\x03tq\x04Rq\x05.')
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100803
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000804
Jeremy Hylton66426532001-10-15 21:38:56 +0000805def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000806 c = C()
807 c.foo = 1
808 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000809 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000810 # Append some integer test cases at cPickle.c's internal size
811 # cutoffs.
812 uint1max = 0xff
813 uint2max = 0xffff
814 int4max = 0x7fffffff
815 x.extend([1, -1,
816 uint1max, -uint1max, -uint1max-1,
817 uint2max, -uint2max, -uint2max-1,
818 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000819 y = ('abc', 'abc', c, c)
820 x.append(y)
821 x.append(y)
822 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000823 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000824
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100825
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300826class AbstractUnpickleTests(unittest.TestCase):
827 # Subclass must define self.loads.
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +0100828
Jeremy Hylton66426532001-10-15 21:38:56 +0000829 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000830
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100831 def assert_is_copy(self, obj, objcopy, msg=None):
832 """Utility method to verify if two objects are copies of each others.
833 """
834 if msg is None:
835 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
836 self.assertEqual(obj, objcopy, msg=msg)
837 self.assertIs(type(obj), type(objcopy), msg=msg)
838 if hasattr(obj, '__dict__'):
839 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
840 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
841 if hasattr(obj, '__slots__'):
842 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
843 for slot in obj.__slots__:
844 self.assertEqual(
845 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
846 self.assertEqual(getattr(obj, slot, None),
847 getattr(objcopy, slot, None), msg=msg)
848
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200849 def check_unpickling_error(self, errors, data):
850 with self.subTest(data=data), \
851 self.assertRaises(errors):
852 try:
853 self.loads(data)
854 except BaseException as exc:
855 if support.verbose > 1:
856 print('%-32r - %s: %s' %
857 (data, exc.__class__.__name__, exc))
858 raise
859
Guido van Rossum98297ee2007-11-06 21:34:58 +0000860 def test_load_from_data0(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100861 self.assert_is_copy(self._testdata, self.loads(DATA0))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000862
863 def test_load_from_data1(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100864 self.assert_is_copy(self._testdata, self.loads(DATA1))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000865
866 def test_load_from_data2(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100867 self.assert_is_copy(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000868
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300869 def test_load_from_data3(self):
870 self.assert_is_copy(self._testdata, self.loads(DATA3))
871
872 def test_load_from_data4(self):
873 self.assert_is_copy(self._testdata, self.loads(DATA4))
874
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000875 def test_load_classic_instance(self):
876 # See issue5180. Test loading 2.x pickles that
877 # contain an instance of old style class.
878 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
879 xname = X.__name__.encode('ascii')
880 # Protocol 0 (text mode pickle):
881 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200882 0: ( MARK
883 1: i INST '__main__ X' (MARK at 0)
884 13: p PUT 0
885 16: ( MARK
886 17: d DICT (MARK at 16)
887 18: p PUT 1
888 21: b BUILD
889 22: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000890 """
891 pickle0 = (b"(i__main__\n"
892 b"X\n"
893 b"p0\n"
894 b"(dp1\nb.").replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100895 self.assert_is_copy(X(*args), self.loads(pickle0))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000896
897 # Protocol 1 (binary mode pickle)
898 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200899 0: ( MARK
900 1: c GLOBAL '__main__ X'
901 13: q BINPUT 0
902 15: o OBJ (MARK at 0)
903 16: q BINPUT 1
904 18: } EMPTY_DICT
905 19: q BINPUT 2
906 21: b BUILD
907 22: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000908 """
909 pickle1 = (b'(c__main__\n'
910 b'X\n'
911 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100912 self.assert_is_copy(X(*args), self.loads(pickle1))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000913
914 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
915 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200916 0: \x80 PROTO 2
917 2: ( MARK
918 3: c GLOBAL '__main__ X'
919 15: q BINPUT 0
920 17: o OBJ (MARK at 2)
921 18: q BINPUT 1
922 20: } EMPTY_DICT
923 21: q BINPUT 2
924 23: b BUILD
925 24: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000926 """
927 pickle2 = (b'\x80\x02(c__main__\n'
928 b'X\n'
929 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100930 self.assert_is_copy(X(*args), self.loads(pickle2))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000931
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300932 def test_maxint64(self):
933 maxint64 = (1 << 63) - 1
934 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
935 got = self.loads(data)
936 self.assert_is_copy(maxint64, got)
937
938 # Try too with a bogus literal.
939 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200940 self.check_unpickling_error(ValueError, data)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300941
942 def test_unpickle_from_2x(self):
943 # Unpickle non-trivial data from Python 2.x.
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300944 loaded = self.loads(DATA_SET)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300945 self.assertEqual(loaded, set([1, 2]))
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300946 loaded = self.loads(DATA_XRANGE)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300947 self.assertEqual(type(loaded), type(range(0)))
948 self.assertEqual(list(loaded), list(range(5)))
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300949 loaded = self.loads(DATA_COOKIE)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300950 self.assertEqual(type(loaded), SimpleCookie)
951 self.assertEqual(list(loaded.keys()), ["key"])
952 self.assertEqual(loaded["key"].value, "value")
953
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300954 # Exception objects without arguments pickled from 2.x with protocol 2
955 for exc in python2_exceptions_without_args:
956 data = exception_pickle.replace(b'?', exc.__name__.encode("ascii"))
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300957 loaded = self.loads(data)
958 self.assertIs(type(loaded), exc)
959
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300960 # StandardError is mapped to Exception, test that separately
961 loaded = self.loads(exception_pickle.replace(b'?', b'StandardError'))
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300962 self.assertIs(type(loaded), Exception)
963
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300964 loaded = self.loads(DATA_UEERR)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300965 self.assertIs(type(loaded), UnicodeEncodeError)
966 self.assertEqual(loaded.object, "foo")
967 self.assertEqual(loaded.encoding, "ascii")
968 self.assertEqual(loaded.start, 0)
969 self.assertEqual(loaded.end, 1)
970 self.assertEqual(loaded.reason, "bad")
971
972 def test_load_python2_str_as_bytes(self):
973 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
974 self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
975 encoding="bytes"), b'a\x00\xa0')
976 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
977 self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
978 encoding="bytes"), b'a\x00\xa0')
979 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
980 self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
981 encoding="bytes"), b'a\x00\xa0')
982
983 def test_load_python2_unicode_as_str(self):
984 # From Python 2: pickle.dumps(u'π', protocol=0)
985 self.assertEqual(self.loads(b'V\\u03c0\n.',
986 encoding='bytes'), 'π')
987 # From Python 2: pickle.dumps(u'π', protocol=1)
988 self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
989 encoding="bytes"), 'π')
990 # From Python 2: pickle.dumps(u'π', protocol=2)
991 self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
992 encoding="bytes"), 'π')
993
994 def test_load_long_python2_str_as_bytes(self):
995 # From Python 2: pickle.dumps('x' * 300, protocol=1)
996 self.assertEqual(self.loads(pickle.BINSTRING +
997 struct.pack("<I", 300) +
998 b'x' * 300 + pickle.STOP,
999 encoding='bytes'), b'x' * 300)
1000
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001001 def test_constants(self):
1002 self.assertIsNone(self.loads(b'N.'))
1003 self.assertIs(self.loads(b'\x88.'), True)
1004 self.assertIs(self.loads(b'\x89.'), False)
1005 self.assertIs(self.loads(b'I01\n.'), True)
1006 self.assertIs(self.loads(b'I00\n.'), False)
1007
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001008 def test_empty_bytestring(self):
1009 # issue 11286
1010 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1011 self.assertEqual(empty, '')
1012
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001013 def test_short_binbytes(self):
1014 dumped = b'\x80\x03C\x04\xe2\x82\xac\x00.'
1015 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
1016
1017 def test_binbytes(self):
1018 dumped = b'\x80\x03B\x04\x00\x00\x00\xe2\x82\xac\x00.'
1019 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
1020
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001021 @requires_32b
1022 def test_negative_32b_binbytes(self):
1023 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1024 dumped = b'\x80\x03B\xff\xff\xff\xffxyzq\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001025 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
1026 dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001027
1028 @requires_32b
1029 def test_negative_32b_binunicode(self):
1030 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1031 dumped = b'\x80\x03X\xff\xff\xff\xffxyzq\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001032 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
1033 dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001034
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001035 def test_short_binunicode(self):
1036 dumped = b'\x80\x04\x8c\x04\xe2\x82\xac\x00.'
1037 self.assertEqual(self.loads(dumped), '\u20ac\x00')
1038
1039 def test_misc_get(self):
Claudiu Popa6f03b232019-11-24 20:15:08 +01001040 self.check_unpickling_error(pickle.UnpicklingError, b'g0\np0')
1041 self.check_unpickling_error(pickle.UnpicklingError, b'jens:')
1042 self.check_unpickling_error(pickle.UnpicklingError, b'hens:')
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001043 self.assert_is_copy([(100,), (100,)],
1044 self.loads(b'((Kdtp0\nh\x00l.))'))
1045
Serhiy Storchakae0606192015-09-29 22:10:07 +03001046 def test_binbytes8(self):
1047 dumped = b'\x80\x04\x8e\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
1048 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
1049
1050 def test_binunicode8(self):
1051 dumped = b'\x80\x04\x8d\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
1052 self.assertEqual(self.loads(dumped), '\u20ac\x00')
1053
Antoine Pitrou91f43802019-05-26 17:10:09 +02001054 def test_bytearray8(self):
1055 dumped = b'\x80\x05\x96\x03\x00\x00\x00\x00\x00\x00\x00xxx.'
1056 self.assertEqual(self.loads(dumped), bytearray(b'xxx'))
1057
Serhiy Storchakae0606192015-09-29 22:10:07 +03001058 @requires_32b
1059 def test_large_32b_binbytes8(self):
1060 dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001061 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
1062 dumped)
Serhiy Storchakae0606192015-09-29 22:10:07 +03001063
1064 @requires_32b
Antoine Pitrou91f43802019-05-26 17:10:09 +02001065 def test_large_32b_bytearray8(self):
1066 dumped = b'\x80\x05\x96\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
1067 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
1068 dumped)
1069
1070 @requires_32b
Serhiy Storchakae0606192015-09-29 22:10:07 +03001071 def test_large_32b_binunicode8(self):
1072 dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001073 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
1074 dumped)
Serhiy Storchakae0606192015-09-29 22:10:07 +03001075
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001076 def test_get(self):
1077 pickled = b'((lp100000\ng100000\nt.'
1078 unpickled = self.loads(pickled)
1079 self.assertEqual(unpickled, ([],)*2)
1080 self.assertIs(unpickled[0], unpickled[1])
1081
1082 def test_binget(self):
1083 pickled = b'(]q\xffh\xfft.'
1084 unpickled = self.loads(pickled)
1085 self.assertEqual(unpickled, ([],)*2)
1086 self.assertIs(unpickled[0], unpickled[1])
1087
1088 def test_long_binget(self):
1089 pickled = b'(]r\x00\x00\x01\x00j\x00\x00\x01\x00t.'
1090 unpickled = self.loads(pickled)
1091 self.assertEqual(unpickled, ([],)*2)
1092 self.assertIs(unpickled[0], unpickled[1])
1093
1094 def test_dup(self):
1095 pickled = b'((l2t.'
1096 unpickled = self.loads(pickled)
1097 self.assertEqual(unpickled, ([],)*2)
1098 self.assertIs(unpickled[0], unpickled[1])
1099
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001100 def test_negative_put(self):
1101 # Issue #12847
1102 dumped = b'Va\np-1\n.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001103 self.check_unpickling_error(ValueError, dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001104
1105 @requires_32b
1106 def test_negative_32b_binput(self):
1107 # Issue #12847
1108 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001109 self.check_unpickling_error(ValueError, dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001110
1111 def test_badly_escaped_string(self):
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001112 self.check_unpickling_error(ValueError, b"S'\\'\n.")
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001113
1114 def test_badly_quoted_string(self):
1115 # Issue #17710
1116 badpickles = [b"S'\n.",
1117 b'S"\n.',
1118 b'S\' \n.',
1119 b'S" \n.',
1120 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.']
1129 for p in badpickles:
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001130 self.check_unpickling_error(pickle.UnpicklingError, p)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001131
1132 def test_correctly_quoted_string(self):
1133 goodpickles = [(b"S''\n.", ''),
1134 (b'S""\n.', ''),
1135 (b'S"\\n"\n.', '\n'),
1136 (b"S'\\n'\n.", '\n')]
1137 for p, expected in goodpickles:
1138 self.assertEqual(self.loads(p), expected)
1139
1140 def test_frame_readline(self):
1141 pickled = b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00I42\n.'
1142 # 0: \x80 PROTO 4
1143 # 2: \x95 FRAME 5
1144 # 11: I INT 42
1145 # 15: . STOP
1146 self.assertEqual(self.loads(pickled), 42)
1147
1148 def test_compat_unpickle(self):
1149 # xrange(1, 7)
1150 pickled = b'\x80\x02c__builtin__\nxrange\nK\x01K\x07K\x01\x87R.'
1151 unpickled = self.loads(pickled)
1152 self.assertIs(type(unpickled), range)
1153 self.assertEqual(unpickled, range(1, 7))
1154 self.assertEqual(list(unpickled), [1, 2, 3, 4, 5, 6])
1155 # reduce
1156 pickled = b'\x80\x02c__builtin__\nreduce\n.'
1157 self.assertIs(self.loads(pickled), functools.reduce)
1158 # whichdb.whichdb
1159 pickled = b'\x80\x02cwhichdb\nwhichdb\n.'
1160 self.assertIs(self.loads(pickled), dbm.whichdb)
1161 # Exception(), StandardError()
1162 for name in (b'Exception', b'StandardError'):
1163 pickled = (b'\x80\x02cexceptions\n' + name + b'\nU\x03ugh\x85R.')
1164 unpickled = self.loads(pickled)
1165 self.assertIs(type(unpickled), Exception)
1166 self.assertEqual(str(unpickled), 'ugh')
1167 # UserDict.UserDict({1: 2}), UserDict.IterableUserDict({1: 2})
1168 for name in (b'UserDict', b'IterableUserDict'):
1169 pickled = (b'\x80\x02(cUserDict\n' + name +
1170 b'\no}U\x04data}K\x01K\x02ssb.')
1171 unpickled = self.loads(pickled)
1172 self.assertIs(type(unpickled), collections.UserDict)
1173 self.assertEqual(unpickled, collections.UserDict({1: 2}))
1174
Miss Islington (bot)57c984f2020-07-13 06:09:27 -07001175 def test_bad_reduce(self):
1176 self.assertEqual(self.loads(b'cbuiltins\nint\n)R.'), 0)
1177 self.check_unpickling_error(TypeError, b'N)R.')
1178 self.check_unpickling_error(TypeError, b'cbuiltins\nint\nNR.')
1179
1180 def test_bad_newobj(self):
1181 error = (pickle.UnpicklingError, TypeError)
1182 self.assertEqual(self.loads(b'cbuiltins\nint\n)\x81.'), 0)
1183 self.check_unpickling_error(error, b'cbuiltins\nlen\n)\x81.')
1184 self.check_unpickling_error(error, b'cbuiltins\nint\nN\x81.')
1185
1186 def test_bad_newobj_ex(self):
1187 error = (pickle.UnpicklingError, TypeError)
1188 self.assertEqual(self.loads(b'cbuiltins\nint\n)}\x92.'), 0)
1189 self.check_unpickling_error(error, b'cbuiltins\nlen\n)}\x92.')
1190 self.check_unpickling_error(error, b'cbuiltins\nint\nN}\x92.')
1191 self.check_unpickling_error(error, b'cbuiltins\nint\n)N\x92.')
1192
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001193 def test_bad_stack(self):
1194 badpickles = [
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001195 b'.', # STOP
1196 b'0', # POP
1197 b'1', # POP_MARK
1198 b'2', # DUP
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001199 b'(2',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001200 b'R', # REDUCE
1201 b')R',
1202 b'a', # APPEND
1203 b'Na',
1204 b'b', # BUILD
1205 b'Nb',
1206 b'd', # DICT
1207 b'e', # APPENDS
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001208 b'(e',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001209 b'ibuiltins\nlist\n', # INST
1210 b'l', # LIST
1211 b'o', # OBJ
1212 b'(o',
1213 b'p1\n', # PUT
1214 b'q\x00', # BINPUT
1215 b'r\x00\x00\x00\x00', # LONG_BINPUT
1216 b's', # SETITEM
1217 b'Ns',
1218 b'NNs',
1219 b't', # TUPLE
1220 b'u', # SETITEMS
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001221 b'(u',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001222 b'}(Nu',
1223 b'\x81', # NEWOBJ
1224 b')\x81',
1225 b'\x85', # TUPLE1
1226 b'\x86', # TUPLE2
1227 b'N\x86',
1228 b'\x87', # TUPLE3
1229 b'N\x87',
1230 b'NN\x87',
1231 b'\x90', # ADDITEMS
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001232 b'(\x90',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001233 b'\x91', # FROZENSET
1234 b'\x92', # NEWOBJ_EX
1235 b')}\x92',
1236 b'\x93', # STACK_GLOBAL
1237 b'Vlist\n\x93',
1238 b'\x94', # MEMOIZE
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001239 ]
1240 for p in badpickles:
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001241 self.check_unpickling_error(self.bad_stack_errors, p)
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001242
1243 def test_bad_mark(self):
1244 badpickles = [
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001245 b'N(.', # STOP
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001246 b'N(2', # DUP
1247 b'cbuiltins\nlist\n)(R', # REDUCE
1248 b'cbuiltins\nlist\n()R',
1249 b']N(a', # APPEND
1250 # BUILD
1251 b'cbuiltins\nValueError\n)R}(b',
1252 b'cbuiltins\nValueError\n)R(}b',
1253 b'(Nd', # DICT
1254 b'N(p1\n', # PUT
1255 b'N(q\x00', # BINPUT
1256 b'N(r\x00\x00\x00\x00', # LONG_BINPUT
1257 b'}NN(s', # SETITEM
1258 b'}N(Ns',
1259 b'}(NNs',
1260 b'}((u', # SETITEMS
1261 b'cbuiltins\nlist\n)(\x81', # NEWOBJ
1262 b'cbuiltins\nlist\n()\x81',
1263 b'N(\x85', # TUPLE1
1264 b'NN(\x86', # TUPLE2
1265 b'N(N\x86',
1266 b'NNN(\x87', # TUPLE3
1267 b'NN(N\x87',
1268 b'N(NN\x87',
1269 b']((\x90', # ADDITEMS
1270 # NEWOBJ_EX
1271 b'cbuiltins\nlist\n)}(\x92',
1272 b'cbuiltins\nlist\n)(}\x92',
1273 b'cbuiltins\nlist\n()}\x92',
1274 # STACK_GLOBAL
1275 b'Vbuiltins\n(Vlist\n\x93',
1276 b'Vbuiltins\nVlist\n(\x93',
1277 b'N(\x94', # MEMOIZE
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001278 ]
1279 for p in badpickles:
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001280 self.check_unpickling_error(self.bad_stack_errors, p)
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001281
1282 def test_truncated_data(self):
1283 self.check_unpickling_error(EOFError, b'')
1284 self.check_unpickling_error(EOFError, b'N')
1285 badpickles = [
1286 b'B', # BINBYTES
1287 b'B\x03\x00\x00',
1288 b'B\x03\x00\x00\x00',
1289 b'B\x03\x00\x00\x00ab',
1290 b'C', # SHORT_BINBYTES
1291 b'C\x03',
1292 b'C\x03ab',
1293 b'F', # FLOAT
1294 b'F0.0',
1295 b'F0.00',
1296 b'G', # BINFLOAT
1297 b'G\x00\x00\x00\x00\x00\x00\x00',
1298 b'I', # INT
1299 b'I0',
1300 b'J', # BININT
1301 b'J\x00\x00\x00',
1302 b'K', # BININT1
1303 b'L', # LONG
1304 b'L0',
1305 b'L10',
1306 b'L0L',
1307 b'L10L',
1308 b'M', # BININT2
1309 b'M\x00',
1310 # b'P', # PERSID
1311 # b'Pabc',
1312 b'S', # STRING
1313 b"S'abc'",
1314 b'T', # BINSTRING
1315 b'T\x03\x00\x00',
1316 b'T\x03\x00\x00\x00',
1317 b'T\x03\x00\x00\x00ab',
1318 b'U', # SHORT_BINSTRING
1319 b'U\x03',
1320 b'U\x03ab',
1321 b'V', # UNICODE
1322 b'Vabc',
1323 b'X', # BINUNICODE
1324 b'X\x03\x00\x00',
1325 b'X\x03\x00\x00\x00',
1326 b'X\x03\x00\x00\x00ab',
1327 b'(c', # GLOBAL
1328 b'(cbuiltins',
1329 b'(cbuiltins\n',
1330 b'(cbuiltins\nlist',
1331 b'Ng', # GET
1332 b'Ng0',
1333 b'(i', # INST
1334 b'(ibuiltins',
1335 b'(ibuiltins\n',
1336 b'(ibuiltins\nlist',
1337 b'Nh', # BINGET
1338 b'Nj', # LONG_BINGET
1339 b'Nj\x00\x00\x00',
1340 b'Np', # PUT
1341 b'Np0',
1342 b'Nq', # BINPUT
1343 b'Nr', # LONG_BINPUT
1344 b'Nr\x00\x00\x00',
1345 b'\x80', # PROTO
1346 b'\x82', # EXT1
1347 b'\x83', # EXT2
1348 b'\x84\x01',
1349 b'\x84', # EXT4
1350 b'\x84\x01\x00\x00',
1351 b'\x8a', # LONG1
1352 b'\x8b', # LONG4
1353 b'\x8b\x00\x00\x00',
1354 b'\x8c', # SHORT_BINUNICODE
1355 b'\x8c\x03',
1356 b'\x8c\x03ab',
1357 b'\x8d', # BINUNICODE8
1358 b'\x8d\x03\x00\x00\x00\x00\x00\x00',
1359 b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00',
1360 b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00ab',
1361 b'\x8e', # BINBYTES8
1362 b'\x8e\x03\x00\x00\x00\x00\x00\x00',
1363 b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00',
1364 b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00ab',
Antoine Pitrou91f43802019-05-26 17:10:09 +02001365 b'\x96', # BYTEARRAY8
1366 b'\x96\x03\x00\x00\x00\x00\x00\x00',
1367 b'\x96\x03\x00\x00\x00\x00\x00\x00\x00',
1368 b'\x96\x03\x00\x00\x00\x00\x00\x00\x00ab',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001369 b'\x95', # FRAME
1370 b'\x95\x02\x00\x00\x00\x00\x00\x00',
1371 b'\x95\x02\x00\x00\x00\x00\x00\x00\x00',
1372 b'\x95\x02\x00\x00\x00\x00\x00\x00\x00N',
1373 ]
1374 for p in badpickles:
1375 self.check_unpickling_error(self.truncated_errors, p)
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001376
tjb9004371c0a2019-02-18 23:30:51 +08001377 @reap_threads
1378 def test_unpickle_module_race(self):
1379 # https://bugs.python.org/issue34572
1380 locker_module = dedent("""
1381 import threading
1382 barrier = threading.Barrier(2)
1383 """)
1384 locking_import_module = dedent("""
1385 import locker
1386 locker.barrier.wait()
1387 class ToBeUnpickled(object):
1388 pass
1389 """)
1390
1391 os.mkdir(TESTFN)
1392 self.addCleanup(shutil.rmtree, TESTFN)
1393 sys.path.insert(0, TESTFN)
1394 self.addCleanup(sys.path.remove, TESTFN)
1395 with open(os.path.join(TESTFN, "locker.py"), "wb") as f:
1396 f.write(locker_module.encode('utf-8'))
1397 with open(os.path.join(TESTFN, "locking_import.py"), "wb") as f:
1398 f.write(locking_import_module.encode('utf-8'))
1399 self.addCleanup(forget, "locker")
1400 self.addCleanup(forget, "locking_import")
1401
1402 import locker
1403
1404 pickle_bytes = (
1405 b'\x80\x03clocking_import\nToBeUnpickled\nq\x00)\x81q\x01.')
1406
1407 # Then try to unpickle two of these simultaneously
1408 # One of them will cause the module import, and we want it to block
1409 # until the other one either:
1410 # - fails (before the patch for this issue)
1411 # - blocks on the import lock for the module, as it should
1412 results = []
1413 barrier = threading.Barrier(3)
1414 def t():
1415 # This ensures the threads have all started
1416 # presumably barrier release is faster than thread startup
1417 barrier.wait()
1418 results.append(pickle.loads(pickle_bytes))
1419
1420 t1 = threading.Thread(target=t)
1421 t2 = threading.Thread(target=t)
1422 t1.start()
1423 t2.start()
1424
1425 barrier.wait()
1426 # could have delay here
1427 locker.barrier.wait()
1428
1429 t1.join()
1430 t2.join()
1431
1432 from locking_import import ToBeUnpickled
1433 self.assertEqual(
1434 [type(x) for x in results],
1435 [ToBeUnpickled] * 2)
1436
1437
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001438
1439class AbstractPickleTests(unittest.TestCase):
1440 # Subclass must define self.dumps, self.loads.
1441
1442 optimized = False
1443
1444 _testdata = AbstractUnpickleTests._testdata
1445
1446 def setUp(self):
1447 pass
1448
1449 assert_is_copy = AbstractUnpickleTests.assert_is_copy
1450
1451 def test_misc(self):
1452 # test various datatypes not tested by testdata
1453 for proto in protocols:
1454 x = myint(4)
1455 s = self.dumps(x, proto)
1456 y = self.loads(s)
1457 self.assert_is_copy(x, y)
1458
1459 x = (1, ())
1460 s = self.dumps(x, proto)
1461 y = self.loads(s)
1462 self.assert_is_copy(x, y)
1463
1464 x = initarg(1, x)
1465 s = self.dumps(x, proto)
1466 y = self.loads(s)
1467 self.assert_is_copy(x, y)
1468
1469 # XXX test __reduce__ protocol?
1470
1471 def test_roundtrip_equality(self):
1472 expected = self._testdata
1473 for proto in protocols:
1474 s = self.dumps(expected, proto)
1475 got = self.loads(s)
1476 self.assert_is_copy(expected, got)
1477
Tim Peters70b02d72003-02-02 17:26:40 +00001478 # There are gratuitous differences between pickles produced by
1479 # pickle and cPickle, largely because cPickle starts PUT indices at
1480 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
1481 # there's a comment with an exclamation point there whose meaning
1482 # is a mystery. cPickle also suppresses PUT for objects with a refcount
1483 # of 1.
1484 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +00001485 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +00001486 from pickletools import dis
1487
1488 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
1489 s = self.dumps(self._testdata, proto)
1490 filelike = StringIO()
1491 dis(s, out=filelike)
1492 got = filelike.getvalue()
1493 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +00001494
1495 def test_recursive_list(self):
1496 l = []
1497 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +00001498 for proto in protocols:
1499 s = self.dumps(l, proto)
1500 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001501 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001502 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001503 self.assertIs(x[0], x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001504
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001505 def test_recursive_tuple_and_list(self):
Collin Winter8ca69de2009-05-26 16:53:41 +00001506 t = ([],)
1507 t[0].append(t)
1508 for proto in protocols:
1509 s = self.dumps(t, proto)
1510 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001511 self.assertIsInstance(x, tuple)
Collin Winter8ca69de2009-05-26 16:53:41 +00001512 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001513 self.assertIsInstance(x[0], list)
Collin Winter8ca69de2009-05-26 16:53:41 +00001514 self.assertEqual(len(x[0]), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001515 self.assertIs(x[0][0], x)
Collin Winter8ca69de2009-05-26 16:53:41 +00001516
Jeremy Hylton66426532001-10-15 21:38:56 +00001517 def test_recursive_dict(self):
1518 d = {}
1519 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +00001520 for proto in protocols:
1521 s = self.dumps(d, proto)
1522 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001523 self.assertIsInstance(x, dict)
Guido van Rossumcc2b0162007-02-11 06:12:03 +00001524 self.assertEqual(list(x.keys()), [1])
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001525 self.assertIs(x[1], x)
1526
1527 def test_recursive_dict_key(self):
1528 d = {}
1529 k = K(d)
1530 d[k] = 1
1531 for proto in protocols:
1532 s = self.dumps(d, proto)
1533 x = self.loads(s)
1534 self.assertIsInstance(x, dict)
1535 self.assertEqual(len(x.keys()), 1)
1536 self.assertIsInstance(list(x.keys())[0], K)
1537 self.assertIs(list(x.keys())[0].value, x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001538
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001539 def test_recursive_set(self):
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001540 y = set()
1541 k = K(y)
1542 y.add(k)
1543 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001544 s = self.dumps(y, proto)
1545 x = self.loads(s)
1546 self.assertIsInstance(x, set)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001547 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001548 self.assertIsInstance(list(x)[0], K)
1549 self.assertIs(list(x)[0].value, x)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001550
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001551 def test_recursive_list_subclass(self):
1552 y = MyList()
1553 y.append(y)
1554 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001555 s = self.dumps(y, proto)
1556 x = self.loads(s)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001557 self.assertIsInstance(x, MyList)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001558 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001559 self.assertIs(x[0], x)
1560
1561 def test_recursive_dict_subclass(self):
1562 d = MyDict()
1563 d[1] = d
1564 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1565 s = self.dumps(d, proto)
1566 x = self.loads(s)
1567 self.assertIsInstance(x, MyDict)
1568 self.assertEqual(list(x.keys()), [1])
1569 self.assertIs(x[1], x)
1570
1571 def test_recursive_dict_subclass_key(self):
1572 d = MyDict()
1573 k = K(d)
1574 d[k] = 1
1575 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1576 s = self.dumps(d, proto)
1577 x = self.loads(s)
1578 self.assertIsInstance(x, MyDict)
1579 self.assertEqual(len(list(x.keys())), 1)
1580 self.assertIsInstance(list(x.keys())[0], K)
1581 self.assertIs(list(x.keys())[0].value, x)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001582
Jeremy Hylton66426532001-10-15 21:38:56 +00001583 def test_recursive_inst(self):
1584 i = C()
1585 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +00001586 for proto in protocols:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001587 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +00001588 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001589 self.assertIsInstance(x, C)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001590 self.assertEqual(dir(x), dir(i))
Ezio Melottiaaef3442013-03-04 15:17:56 +02001591 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001592
1593 def test_recursive_multi(self):
1594 l = []
1595 d = {1:l}
1596 i = C()
1597 i.attr = d
1598 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +00001599 for proto in protocols:
1600 s = self.dumps(l, proto)
1601 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001602 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001603 self.assertEqual(len(x), 1)
1604 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +00001605 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001606 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001607
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001608 def check_recursive_collection_and_inst(self, factory):
1609 h = H()
1610 y = factory([h])
1611 h.attr = y
1612 for proto in protocols:
1613 s = self.dumps(y, proto)
1614 x = self.loads(s)
1615 self.assertIsInstance(x, type(y))
1616 self.assertEqual(len(x), 1)
1617 self.assertIsInstance(list(x)[0], H)
1618 self.assertIs(list(x)[0].attr, x)
1619
1620 def test_recursive_list_and_inst(self):
1621 self.check_recursive_collection_and_inst(list)
1622
1623 def test_recursive_tuple_and_inst(self):
1624 self.check_recursive_collection_and_inst(tuple)
1625
1626 def test_recursive_dict_and_inst(self):
1627 self.check_recursive_collection_and_inst(dict.fromkeys)
1628
1629 def test_recursive_set_and_inst(self):
1630 self.check_recursive_collection_and_inst(set)
1631
1632 def test_recursive_frozenset_and_inst(self):
1633 self.check_recursive_collection_and_inst(frozenset)
1634
1635 def test_recursive_list_subclass_and_inst(self):
1636 self.check_recursive_collection_and_inst(MyList)
1637
1638 def test_recursive_tuple_subclass_and_inst(self):
1639 self.check_recursive_collection_and_inst(MyTuple)
1640
1641 def test_recursive_dict_subclass_and_inst(self):
1642 self.check_recursive_collection_and_inst(MyDict.fromkeys)
1643
1644 def test_recursive_set_subclass_and_inst(self):
1645 self.check_recursive_collection_and_inst(MySet)
1646
1647 def test_recursive_frozenset_subclass_and_inst(self):
1648 self.check_recursive_collection_and_inst(MyFrozenSet)
1649
Walter Dörwald9b775532007-06-08 14:30:53 +00001650 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +00001651 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +00001652 '<\\>', '<\\\U00012345>',
1653 # surrogates
1654 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +00001655 for proto in protocols:
1656 for u in endcases:
1657 p = self.dumps(u, proto)
1658 u2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001659 self.assert_is_copy(u, u2)
Tim Peterse089c682001-04-10 03:41:41 +00001660
Alexandre Vassalotti554d8782008-12-27 07:32:41 +00001661 def test_unicode_high_plane(self):
1662 t = '\U00012345'
1663 for proto in protocols:
1664 p = self.dumps(t, proto)
1665 t2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001666 self.assert_is_copy(t, t2)
Alexandre Vassalotti554d8782008-12-27 07:32:41 +00001667
Guido van Rossumf4169812008-03-17 22:56:06 +00001668 def test_bytes(self):
1669 for proto in protocols:
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001670 for s in b'', b'xyz', b'xyz'*100:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001671 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001672 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001673 for s in [bytes([i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001674 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001675 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001676 for s in [bytes([i, i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001677 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001678 self.assert_is_copy(s, self.loads(p))
Guido van Rossumf4169812008-03-17 22:56:06 +00001679
Antoine Pitrou91f43802019-05-26 17:10:09 +02001680 def test_bytearray(self):
1681 for proto in protocols:
1682 for s in b'', b'xyz', b'xyz'*100:
1683 b = bytearray(s)
1684 p = self.dumps(b, proto)
1685 bb = self.loads(p)
1686 self.assertIsNot(bb, b)
1687 self.assert_is_copy(b, bb)
1688 if proto <= 3:
1689 # bytearray is serialized using a global reference
1690 self.assertIn(b'bytearray', p)
1691 self.assertTrue(opcode_in_pickle(pickle.GLOBAL, p))
1692 elif proto == 4:
1693 self.assertIn(b'bytearray', p)
1694 self.assertTrue(opcode_in_pickle(pickle.STACK_GLOBAL, p))
1695 elif proto == 5:
1696 self.assertNotIn(b'bytearray', p)
1697 self.assertTrue(opcode_in_pickle(pickle.BYTEARRAY8, p))
1698
Jeremy Hylton66426532001-10-15 21:38:56 +00001699 def test_ints(self):
Tim Petersee1a53c2003-02-02 02:57:53 +00001700 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +00001701 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +00001702 while n:
1703 for expected in (-n, n):
1704 s = self.dumps(expected, proto)
1705 n2 = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001706 self.assert_is_copy(expected, n2)
Tim Petersee1a53c2003-02-02 02:57:53 +00001707 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +00001708
Tim Petersee1a53c2003-02-02 02:57:53 +00001709 def test_long(self):
1710 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +00001711 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +00001712 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +00001713 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +00001714 for npos in nbase-1, nbase, nbase+1:
1715 for n in npos, -npos:
1716 pickle = self.dumps(n, proto)
1717 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001718 self.assert_is_copy(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +00001719 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
1720 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +00001721 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +00001722 nbase += nbase << 1000000
1723 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +00001724 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +00001725 got = self.loads(p)
Antoine Pitroud5df1942013-11-23 21:20:49 +01001726 # assert_is_copy is very expensive here as it precomputes
1727 # a failure message by computing the repr() of n and got,
1728 # we just do the check ourselves.
1729 self.assertIs(type(got), int)
1730 self.assertEqual(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +00001731
Mark Dickinsoncddcf442009-01-24 21:46:33 +00001732 def test_float(self):
1733 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
1734 3.14, 263.44582062374053, 6.022e23, 1e30]
1735 test_values = test_values + [-x for x in test_values]
1736 for proto in protocols:
1737 for value in test_values:
1738 pickle = self.dumps(value, proto)
1739 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001740 self.assert_is_copy(value, got)
Mark Dickinsoncddcf442009-01-24 21:46:33 +00001741
Thomas Wouters477c8d52006-05-27 19:21:47 +00001742 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
1743 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +00001744 # make sure that floats are formatted locale independent with proto 0
1745 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001746
Jeremy Hylton66426532001-10-15 21:38:56 +00001747 def test_reduce(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +01001748 for proto in protocols:
1749 inst = AAA()
1750 dumped = self.dumps(inst, proto)
1751 loaded = self.loads(dumped)
1752 self.assertEqual(loaded, REDUCE_A)
Jeremy Hylton66426532001-10-15 21:38:56 +00001753
1754 def test_getinitargs(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +01001755 for proto in protocols:
1756 inst = initarg(1, 2)
1757 dumped = self.dumps(inst, proto)
1758 loaded = self.loads(dumped)
1759 self.assert_is_copy(inst, loaded)
Jeremy Hylton66426532001-10-15 21:38:56 +00001760
Guido van Rossum04a86612001-12-19 16:58:54 +00001761 def test_metaclass(self):
1762 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +00001763 for proto in protocols:
1764 s = self.dumps(a, proto)
1765 b = self.loads(s)
1766 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +00001767
Antoine Pitrouffd41d92011-10-04 09:23:04 +02001768 def test_dynamic_class(self):
1769 a = create_dynamic_class("my_dynamic_class", (object,))
1770 copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
1771 for proto in protocols:
1772 s = self.dumps(a, proto)
1773 b = self.loads(s)
1774 self.assertEqual(a, b)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001775 self.assertIs(type(a), type(b))
Antoine Pitrouffd41d92011-10-04 09:23:04 +02001776
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001777 def test_structseq(self):
1778 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +00001779 import os
Tim Peters70b02d72003-02-02 17:26:40 +00001780
1781 t = time.localtime()
1782 for proto in protocols:
1783 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +00001784 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001785 self.assert_is_copy(t, u)
Anthony Sottile8377cd42019-02-25 14:32:27 -08001786 t = os.stat(os.curdir)
1787 s = self.dumps(t, proto)
1788 u = self.loads(s)
1789 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +00001790 if hasattr(os, "statvfs"):
1791 t = os.statvfs(os.curdir)
1792 s = self.dumps(t, proto)
1793 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001794 self.assert_is_copy(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001795
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001796 def test_ellipsis(self):
1797 for proto in protocols:
1798 s = self.dumps(..., proto)
1799 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001800 self.assertIs(..., u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001801
1802 def test_notimplemented(self):
1803 for proto in protocols:
1804 s = self.dumps(NotImplemented, proto)
1805 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001806 self.assertIs(NotImplemented, u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001807
Alexandre Vassalotti19b6fa62013-11-30 16:06:39 -08001808 def test_singleton_types(self):
1809 # Issue #6477: Test that types of built-in singletons can be pickled.
1810 singletons = [None, ..., NotImplemented]
1811 for singleton in singletons:
1812 for proto in protocols:
1813 s = self.dumps(type(singleton), proto)
1814 u = self.loads(s)
1815 self.assertIs(type(singleton), u)
1816
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001817 # Tests for protocol 2
1818
Tim Peters4190fb82003-02-02 16:09:05 +00001819 def test_proto(self):
Tim Peters4190fb82003-02-02 16:09:05 +00001820 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001821 pickled = self.dumps(None, proto)
Tim Peters4190fb82003-02-02 16:09:05 +00001822 if proto >= 2:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001823 proto_header = pickle.PROTO + bytes([proto])
1824 self.assertTrue(pickled.startswith(proto_header))
1825 else:
1826 self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)
Tim Peters4190fb82003-02-02 16:09:05 +00001827
1828 oob = protocols[-1] + 1 # a future protocol
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001829 build_none = pickle.NONE + pickle.STOP
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001830 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +00001831 try:
1832 self.loads(badpickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001833 except ValueError as err:
1834 self.assertIn("unsupported pickle protocol", str(err))
Tim Peters4190fb82003-02-02 16:09:05 +00001835 else:
1836 self.fail("expected bad protocol number to raise ValueError")
1837
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001838 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +00001839 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +00001840 for proto in protocols:
1841 s = self.dumps(x, proto)
1842 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001843 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001844 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001845
1846 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +00001847 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +00001848 for proto in protocols:
1849 s = self.dumps(x, proto)
1850 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001851 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001852 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001853
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001854 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +00001855 # Map (proto, len(tuple)) to expected opcode.
1856 expected_opcode = {(0, 0): pickle.TUPLE,
1857 (0, 1): pickle.TUPLE,
1858 (0, 2): pickle.TUPLE,
1859 (0, 3): pickle.TUPLE,
1860 (0, 4): pickle.TUPLE,
1861
1862 (1, 0): pickle.EMPTY_TUPLE,
1863 (1, 1): pickle.TUPLE,
1864 (1, 2): pickle.TUPLE,
1865 (1, 3): pickle.TUPLE,
1866 (1, 4): pickle.TUPLE,
1867
1868 (2, 0): pickle.EMPTY_TUPLE,
1869 (2, 1): pickle.TUPLE1,
1870 (2, 2): pickle.TUPLE2,
1871 (2, 3): pickle.TUPLE3,
1872 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001873
1874 (3, 0): pickle.EMPTY_TUPLE,
1875 (3, 1): pickle.TUPLE1,
1876 (3, 2): pickle.TUPLE2,
1877 (3, 3): pickle.TUPLE3,
1878 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +00001879 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001880 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +00001881 b = (1,)
1882 c = (1, 2)
1883 d = (1, 2, 3)
1884 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +00001885 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001886 for x in a, b, c, d, e:
1887 s = self.dumps(x, proto)
1888 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001889 self.assert_is_copy(x, y)
1890 expected = expected_opcode[min(proto, 3), len(x)]
1891 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters1d63c9f2003-02-02 20:29:39 +00001892
Guido van Rossum7d97d312003-01-28 04:25:27 +00001893 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +00001894 # Map (proto, singleton) to expected opcode.
1895 expected_opcode = {(0, None): pickle.NONE,
1896 (1, None): pickle.NONE,
1897 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001898 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +00001899
1900 (0, True): pickle.INT,
1901 (1, True): pickle.INT,
1902 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001903 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +00001904
1905 (0, False): pickle.INT,
1906 (1, False): pickle.INT,
1907 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001908 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +00001909 }
Tim Peters4190fb82003-02-02 16:09:05 +00001910 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +00001911 for x in None, False, True:
1912 s = self.dumps(x, proto)
1913 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001914 self.assertTrue(x is y, (proto, x, s, y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001915 expected = expected_opcode[min(proto, 3), x]
1916 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters3c67d792003-02-02 17:59:11 +00001917
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001918 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001919 x = MyTuple([1, 2, 3])
1920 x.foo = 42
1921 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001922 for proto in protocols:
1923 s = self.dumps(x, proto)
1924 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001925 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001926
1927 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001928 x = MyList([1, 2, 3])
1929 x.foo = 42
1930 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001931 for proto in protocols:
1932 s = self.dumps(x, proto)
1933 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001934 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001935
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001936 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001937 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001938 for C in myclasses:
1939 B = C.__base__
1940 x = C(C.sample)
1941 x.foo = 42
1942 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001943 y = self.loads(s)
1944 detail = (proto, C, B, x, y, type(y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001945 self.assert_is_copy(x, y) # XXX revisit
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001946 self.assertEqual(B(x), B(y), detail)
1947 self.assertEqual(x.__dict__, y.__dict__, detail)
1948
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01001949 def test_newobj_proxies(self):
1950 # NEWOBJ should use the __class__ rather than the raw type
1951 classes = myclasses[:]
1952 # Cannot create weakproxies to these classes
1953 for c in (MyInt, MyTuple):
1954 classes.remove(c)
1955 for proto in protocols:
1956 for C in classes:
1957 B = C.__base__
1958 x = C(C.sample)
1959 x.foo = 42
1960 p = weakref.proxy(x)
1961 s = self.dumps(p, proto)
1962 y = self.loads(s)
1963 self.assertEqual(type(y), type(x)) # rather than type(p)
1964 detail = (proto, C, B, x, y, type(y))
1965 self.assertEqual(B(x), B(y), detail)
1966 self.assertEqual(x.__dict__, y.__dict__, detail)
1967
Serhiy Storchaka0aaecb32020-10-25 17:56:17 +02001968 def test_newobj_overridden_new(self):
1969 # Test that Python class with C implemented __new__ is pickleable
1970 for proto in protocols:
1971 x = MyIntWithNew2(1)
1972 x.foo = 42
1973 s = self.dumps(x, proto)
1974 y = self.loads(s)
1975 self.assertIs(type(y), MyIntWithNew2)
1976 self.assertEqual(int(y), 1)
1977 self.assertEqual(y.foo, 42)
1978
Benjamin Peterson80f78a32015-07-02 16:18:38 -05001979 def test_newobj_not_class(self):
1980 # Issue 24552
1981 global SimpleNewObj
1982 save = SimpleNewObj
Benjamin Petersond3a2a952015-07-02 16:58:22 -05001983 o = SimpleNewObj.__new__(SimpleNewObj)
Benjamin Peterson80f78a32015-07-02 16:18:38 -05001984 b = self.dumps(o, 4)
1985 try:
1986 SimpleNewObj = 42
1987 self.assertRaises((TypeError, pickle.UnpicklingError), self.loads, b)
1988 finally:
1989 SimpleNewObj = save
1990
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001991 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001992 # an object of that type. Check that the resulting pickle uses opcode
1993 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001994
Tim Peters22e71712003-02-03 22:27:38 +00001995 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001996 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001997 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001998 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001999 x = MyList([1, 2, 3])
2000 x.foo = 42
2001 x.bar = "hello"
2002
Tim Peters22e71712003-02-03 22:27:38 +00002003 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002004 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00002005 self.assertIn(__name__.encode("utf-8"), s1)
2006 self.assertIn(b"MyList", s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002007 self.assertFalse(opcode_in_pickle(opcode, s1))
Tim Peters3e667d52003-02-04 21:47:44 +00002008
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002009 y = self.loads(s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002010 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002011
Tim Peters22e71712003-02-03 22:27:38 +00002012 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002013 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00002014 self.assertNotIn(__name__.encode("utf-8"), s2)
2015 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +00002016 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +00002017
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002018 y = self.loads(s2)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002019 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002020 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00002021 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00002022
2023 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00002024 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
2025 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002026
2027 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00002028 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
2029 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
2030 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002031
2032 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00002033 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
2034 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
2035 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
2036
Tim Peters8d2613a2003-02-11 16:40:16 +00002037 def test_list_chunking(self):
2038 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +00002039 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00002040 for proto in protocols:
2041 s = self.dumps(x, proto)
2042 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002043 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00002044 num_appends = count_opcode(pickle.APPENDS, s)
2045 self.assertEqual(num_appends, proto > 0)
2046
2047 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +00002048 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00002049 for proto in protocols:
2050 s = self.dumps(x, proto)
2051 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002052 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00002053 num_appends = count_opcode(pickle.APPENDS, s)
2054 if proto == 0:
2055 self.assertEqual(num_appends, 0)
2056 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00002057 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00002058
2059 def test_dict_chunking(self):
2060 n = 10 # too small to chunk
2061 x = dict.fromkeys(range(n))
2062 for proto in protocols:
2063 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +00002064 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00002065 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002066 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00002067 num_setitems = count_opcode(pickle.SETITEMS, s)
2068 self.assertEqual(num_setitems, proto > 0)
2069
2070 n = 2500 # expect at least two chunks when proto > 0
2071 x = dict.fromkeys(range(n))
2072 for proto in protocols:
2073 s = self.dumps(x, proto)
2074 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002075 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00002076 num_setitems = count_opcode(pickle.SETITEMS, s)
2077 if proto == 0:
2078 self.assertEqual(num_setitems, 0)
2079 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00002080 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00002081
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002082 def test_set_chunking(self):
2083 n = 10 # too small to chunk
2084 x = set(range(n))
2085 for proto in protocols:
2086 s = self.dumps(x, proto)
2087 y = self.loads(s)
2088 self.assert_is_copy(x, y)
2089 num_additems = count_opcode(pickle.ADDITEMS, s)
2090 if proto < 4:
2091 self.assertEqual(num_additems, 0)
2092 else:
2093 self.assertEqual(num_additems, 1)
2094
2095 n = 2500 # expect at least two chunks when proto >= 4
2096 x = set(range(n))
2097 for proto in protocols:
2098 s = self.dumps(x, proto)
2099 y = self.loads(s)
2100 self.assert_is_copy(x, y)
2101 num_additems = count_opcode(pickle.ADDITEMS, s)
2102 if proto < 4:
2103 self.assertEqual(num_additems, 0)
2104 else:
2105 self.assertGreaterEqual(num_additems, 2)
2106
Tim Peterse9ef2032003-02-13 18:42:00 +00002107 def test_simple_newobj(self):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002108 x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__
Tim Peterse9ef2032003-02-13 18:42:00 +00002109 x.abc = 666
2110 for proto in protocols:
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002111 with self.subTest(proto=proto):
2112 s = self.dumps(x, proto)
2113 if proto < 1:
Serhiy Storchaka3daaafb2017-11-16 09:44:43 +02002114 self.assertIn(b'\nI64206', s) # INT
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002115 else:
2116 self.assertIn(b'M\xce\xfa', s) # BININT2
2117 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
2118 2 <= proto)
2119 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
2120 y = self.loads(s) # will raise TypeError if __init__ called
2121 self.assert_is_copy(x, y)
2122
2123 def test_complex_newobj(self):
2124 x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__
2125 x.abc = 666
2126 for proto in protocols:
2127 with self.subTest(proto=proto):
2128 s = self.dumps(x, proto)
2129 if proto < 1:
Serhiy Storchaka3daaafb2017-11-16 09:44:43 +02002130 self.assertIn(b'\nI64206', s) # INT
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002131 elif proto < 2:
2132 self.assertIn(b'M\xce\xfa', s) # BININT2
2133 elif proto < 4:
2134 self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
2135 else:
2136 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
2137 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
2138 2 <= proto)
2139 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
2140 y = self.loads(s) # will raise TypeError if __init__ called
2141 self.assert_is_copy(x, y)
2142
2143 def test_complex_newobj_ex(self):
2144 x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__
2145 x.abc = 666
2146 for proto in protocols:
2147 with self.subTest(proto=proto):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002148 s = self.dumps(x, proto)
2149 if proto < 1:
Serhiy Storchaka3daaafb2017-11-16 09:44:43 +02002150 self.assertIn(b'\nI64206', s) # INT
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002151 elif proto < 2:
2152 self.assertIn(b'M\xce\xfa', s) # BININT2
Serhiy Storchaka0d554d72015-10-10 22:42:18 +03002153 elif proto < 4:
2154 self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002155 else:
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002156 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
2157 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s))
2158 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
2159 4 <= proto)
2160 y = self.loads(s) # will raise TypeError if __init__ called
2161 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00002162
Tim Peters42f08ac2003-02-11 22:43:24 +00002163 def test_newobj_list_slots(self):
2164 x = SlotList([1, 2, 3])
2165 x.foo = 42
2166 x.bar = "hello"
2167 s = self.dumps(x, 2)
2168 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002169 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00002170
Guido van Rossum2a30b212003-02-18 22:41:24 +00002171 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00002172 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00002173 x = REX_one()
2174 self.assertEqual(x._reduce_called, 0)
2175 s = self.dumps(x, proto)
2176 self.assertEqual(x._reduce_called, 1)
2177 y = self.loads(s)
2178 self.assertEqual(y._reduce_called, 0)
2179
2180 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00002181 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00002182 x = REX_two()
2183 self.assertEqual(x._proto, None)
2184 s = self.dumps(x, proto)
2185 self.assertEqual(x._proto, proto)
2186 y = self.loads(s)
2187 self.assertEqual(y._proto, None)
2188
2189 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00002190 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00002191 x = REX_three()
2192 self.assertEqual(x._proto, None)
2193 s = self.dumps(x, proto)
2194 self.assertEqual(x._proto, proto)
2195 y = self.loads(s)
2196 self.assertEqual(y._proto, None)
2197
Guido van Rossumd8faa362007-04-27 19:54:29 +00002198 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00002199 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002200 x = REX_four()
2201 self.assertEqual(x._proto, None)
2202 s = self.dumps(x, proto)
2203 self.assertEqual(x._proto, proto)
2204 y = self.loads(s)
2205 self.assertEqual(y._proto, proto)
2206
2207 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00002208 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002209 x = REX_five()
2210 self.assertEqual(x._reduce_called, 0)
2211 s = self.dumps(x, proto)
2212 self.assertEqual(x._reduce_called, 1)
2213 y = self.loads(s)
2214 self.assertEqual(y._reduce_called, 1)
2215
Brett Cannon31f59292011-02-21 19:29:56 +00002216 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002217 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002218 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002219 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002220 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002221 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002222
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00002223 def test_reduce_bad_iterator(self):
2224 # Issue4176: crash when 4th and 5th items of __reduce__()
2225 # are not iterators
2226 class C(object):
2227 def __reduce__(self):
2228 # 4th item is not an iterator
2229 return list, (), None, [], None
2230 class D(object):
2231 def __reduce__(self):
2232 # 5th item is not an iterator
2233 return dict, (), None, None, []
2234
Serhiy Storchakabeb652c2015-12-30 21:00:08 +02002235 # Python implementation is less strict and also accepts iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00002236 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00002237 try:
2238 self.dumps(C(), proto)
Serhiy Storchakabeb652c2015-12-30 21:00:08 +02002239 except pickle.PicklingError:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00002240 pass
2241 try:
2242 self.dumps(D(), proto)
Serhiy Storchakabeb652c2015-12-30 21:00:08 +02002243 except pickle.PicklingError:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00002244 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00002245
Collin Winter771d8342009-04-16 03:18:06 +00002246 def test_many_puts_and_gets(self):
2247 # Test that internal data structures correctly deal with lots of
2248 # puts/gets.
2249 keys = ("aaa" + str(i) for i in range(100))
2250 large_dict = dict((k, [4, 5, 6]) for k in keys)
2251 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
2252
2253 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002254 with self.subTest(proto=proto):
2255 dumped = self.dumps(obj, proto)
2256 loaded = self.loads(dumped)
2257 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00002258
Antoine Pitroua9f48a02009-05-02 21:41:14 +00002259 def test_attribute_name_interning(self):
2260 # Test that attribute names of pickled objects are interned when
2261 # unpickling.
2262 for proto in protocols:
2263 x = C()
2264 x.foo = 42
2265 x.bar = "hello"
2266 s = self.dumps(x, proto)
2267 y = self.loads(s)
2268 x_keys = sorted(x.__dict__)
2269 y_keys = sorted(y.__dict__)
2270 for x_key, y_key in zip(x_keys, y_keys):
2271 self.assertIs(x_key, y_key)
2272
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00002273 def test_pickle_to_2x(self):
2274 # Pickle non-trivial data with protocol 2, expecting that it yields
2275 # the same result as Python 2.x did.
2276 # NOTE: this test is a bit too strong since we can produce different
2277 # bytecode that 2.x will still understand.
2278 dumped = self.dumps(range(5), 2)
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03002279 self.assertEqual(dumped, DATA_XRANGE)
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00002280 dumped = self.dumps(set([3]), 2)
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03002281 self.assertEqual(dumped, DATA_SET2)
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00002282
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00002283 def test_large_pickles(self):
2284 # Test the correctness of internal buffering routines when handling
2285 # large data.
2286 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00002287 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00002288 dumped = self.dumps(data, proto)
2289 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002290 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00002291 self.assertEqual(loaded, data)
2292
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002293 def test_int_pickling_efficiency(self):
2294 # Test compacity of int representation (see issue #12744)
2295 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002296 with self.subTest(proto=proto):
2297 pickles = [self.dumps(2**n, proto) for n in range(70)]
2298 sizes = list(map(len, pickles))
2299 # the size function is monotonic
2300 self.assertEqual(sorted(sizes), sizes)
2301 if proto >= 2:
2302 for p in pickles:
2303 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002304
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002305 def _check_pickling_with_opcode(self, obj, opcode, proto):
2306 pickled = self.dumps(obj, proto)
2307 self.assertTrue(opcode_in_pickle(opcode, pickled))
2308 unpickled = self.loads(pickled)
2309 self.assertEqual(obj, unpickled)
2310
2311 def test_appends_on_non_lists(self):
2312 # Issue #17720
2313 obj = REX_six([1, 2, 3])
2314 for proto in protocols:
2315 if proto == 0:
2316 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
2317 else:
2318 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
2319
2320 def test_setitems_on_non_dicts(self):
2321 obj = REX_seven({1: -1, 2: -2, 3: -3})
2322 for proto in protocols:
2323 if proto == 0:
2324 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
2325 else:
2326 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
2327
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002328 # Exercise framing (proto >= 4) for significant workloads
2329
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002330 FRAME_SIZE_MIN = 4
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002331 FRAME_SIZE_TARGET = 64 * 1024
2332
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002333 def check_frame_opcodes(self, pickled):
2334 """
2335 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002336
2337 Note that binary objects that are larger than FRAME_SIZE_TARGET are not
2338 framed by default and are therefore considered a frame by themselves in
2339 the following consistency check.
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002340 """
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002341 frame_end = frameless_start = None
Antoine Pitrou91f43802019-05-26 17:10:09 +02002342 frameless_opcodes = {'BINBYTES', 'BINUNICODE', 'BINBYTES8',
2343 'BINUNICODE8', 'BYTEARRAY8'}
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002344 for op, arg, pos in pickletools.genops(pickled):
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002345 if frame_end is not None:
2346 self.assertLessEqual(pos, frame_end)
2347 if pos == frame_end:
2348 frame_end = None
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002349
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002350 if frame_end is not None: # framed
2351 self.assertNotEqual(op.name, 'FRAME')
2352 if op.name in frameless_opcodes:
2353 # Only short bytes and str objects should be written
2354 # in a frame
2355 self.assertLessEqual(len(arg), self.FRAME_SIZE_TARGET)
2356
2357 else: # not framed
2358 if (op.name == 'FRAME' or
2359 (op.name in frameless_opcodes and
2360 len(arg) > self.FRAME_SIZE_TARGET)):
2361 # Frame or large bytes or str object
2362 if frameless_start is not None:
2363 # Only short data should be written outside of a frame
2364 self.assertLess(pos - frameless_start,
2365 self.FRAME_SIZE_MIN)
2366 frameless_start = None
2367 elif frameless_start is None and op.name != 'PROTO':
2368 frameless_start = pos
2369
2370 if op.name == 'FRAME':
2371 self.assertGreaterEqual(arg, self.FRAME_SIZE_MIN)
2372 frame_end = pos + 9 + arg
2373
2374 pos = len(pickled)
2375 if frame_end is not None:
2376 self.assertEqual(frame_end, pos)
2377 elif frameless_start is not None:
2378 self.assertLess(pos - frameless_start, self.FRAME_SIZE_MIN)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002379
Neil Schemenauer52a48e62019-07-30 11:08:18 -07002380 @support.skip_if_pgo_task
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002381 def test_framing_many_objects(self):
2382 obj = list(range(10**5))
2383 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2384 with self.subTest(proto=proto):
2385 pickled = self.dumps(obj, proto)
2386 unpickled = self.loads(pickled)
2387 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01002388 bytes_per_frame = (len(pickled) /
2389 count_opcode(pickle.FRAME, pickled))
2390 self.assertGreater(bytes_per_frame,
2391 self.FRAME_SIZE_TARGET / 2)
2392 self.assertLessEqual(bytes_per_frame,
2393 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002394 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002395
2396 def test_framing_large_objects(self):
2397 N = 1024 * 1024
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002398 small_items = [[i] for i in range(10)]
2399 obj = [b'x' * N, *small_items, b'y' * N, 'z' * N]
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002400 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
Serhiy Storchaka0a2da502018-01-11 13:03:20 +02002401 for fast in [False, True]:
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002402 with self.subTest(proto=proto, fast=fast):
Serhiy Storchaka0a2da502018-01-11 13:03:20 +02002403 if not fast:
2404 # fast=False by default.
2405 # This covers in-memory pickling with pickle.dumps().
2406 pickled = self.dumps(obj, proto)
2407 else:
2408 # Pickler is required when fast=True.
2409 if not hasattr(self, 'pickler'):
2410 continue
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002411 buf = io.BytesIO()
2412 pickler = self.pickler(buf, protocol=proto)
2413 pickler.fast = fast
2414 pickler.dump(obj)
2415 pickled = buf.getvalue()
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002416 unpickled = self.loads(pickled)
2417 # More informative error message in case of failure.
2418 self.assertEqual([len(x) for x in obj],
2419 [len(x) for x in unpickled])
2420 # Perform full equality check if the lengths match.
2421 self.assertEqual(obj, unpickled)
2422 n_frames = count_opcode(pickle.FRAME, pickled)
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002423 # A single frame for small objects between
2424 # first two large objects.
2425 self.assertEqual(n_frames, 1)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002426 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002427
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002428 def test_optional_frames(self):
2429 if pickle.HIGHEST_PROTOCOL < 4:
2430 return
2431
2432 def remove_frames(pickled, keep_frame=None):
2433 """Remove frame opcodes from the given pickle."""
2434 frame_starts = []
2435 # 1 byte for the opcode and 8 for the argument
2436 frame_opcode_size = 9
2437 for opcode, _, pos in pickletools.genops(pickled):
2438 if opcode.name == 'FRAME':
2439 frame_starts.append(pos)
2440
2441 newpickle = bytearray()
2442 last_frame_end = 0
2443 for i, pos in enumerate(frame_starts):
2444 if keep_frame and keep_frame(i):
2445 continue
2446 newpickle += pickled[last_frame_end:pos]
2447 last_frame_end = pos + frame_opcode_size
2448 newpickle += pickled[last_frame_end:]
2449 return newpickle
2450
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08002451 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002452 num_frames = 20
penguindustin96466302019-05-06 14:57:17 -04002453 # Large byte objects (dict values) intermittent with small objects
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002454 # (dict keys)
Antoine Pitrou91f43802019-05-26 17:10:09 +02002455 for bytes_type in (bytes, bytearray):
2456 obj = {i: bytes_type([i]) * frame_size for i in range(num_frames)}
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002457
Antoine Pitrou91f43802019-05-26 17:10:09 +02002458 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2459 pickled = self.dumps(obj, proto)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002460
Antoine Pitrou91f43802019-05-26 17:10:09 +02002461 frameless_pickle = remove_frames(pickled)
2462 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
2463 self.assertEqual(obj, self.loads(frameless_pickle))
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002464
Antoine Pitrou91f43802019-05-26 17:10:09 +02002465 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
2466 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
2467 count_opcode(pickle.FRAME, pickled))
2468 self.assertEqual(obj, self.loads(some_frames_pickle))
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002469
Neil Schemenauer52a48e62019-07-30 11:08:18 -07002470 @support.skip_if_pgo_task
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002471 def test_framed_write_sizes_with_delayed_writer(self):
2472 class ChunkAccumulator:
2473 """Accumulate pickler output in a list of raw chunks."""
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002474 def __init__(self):
2475 self.chunks = []
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002476 def write(self, chunk):
2477 self.chunks.append(chunk)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002478 def concatenate_chunks(self):
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002479 return b"".join(self.chunks)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002480
2481 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002482 objects = [(str(i).encode('ascii'), i % 42, {'i': str(i)})
2483 for i in range(int(1e4))]
2484 # Add a large unique ASCII string
2485 objects.append('0123456789abcdef' *
2486 (self.FRAME_SIZE_TARGET // 16 + 1))
2487
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002488 # Protocol 4 packs groups of small objects into frames and issues
2489 # calls to write only once or twice per frame:
2490 # The C pickler issues one call to write per-frame (header and
2491 # contents) while Python pickler issues two calls to write: one for
2492 # the frame header and one for the frame binary contents.
2493 writer = ChunkAccumulator()
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002494 self.pickler(writer, proto).dump(objects)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002495
2496 # Actually read the binary content of the chunks after the end
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002497 # of the call to dump: any memoryview passed to write should not
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002498 # be released otherwise this delayed access would not be possible.
2499 pickled = writer.concatenate_chunks()
2500 reconstructed = self.loads(pickled)
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002501 self.assertEqual(reconstructed, objects)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002502 self.assertGreater(len(writer.chunks), 1)
2503
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002504 # memoryviews should own the memory.
2505 del objects
2506 support.gc_collect()
2507 self.assertEqual(writer.concatenate_chunks(), pickled)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002508
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002509 n_frames = (len(pickled) - 1) // self.FRAME_SIZE_TARGET + 1
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002510 # There should be at least one call to write per frame
2511 self.assertGreaterEqual(len(writer.chunks), n_frames)
2512
2513 # but not too many either: there can be one for the proto,
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002514 # one per-frame header, one per frame for the actual contents,
2515 # and two for the header.
2516 self.assertLessEqual(len(writer.chunks), 2 * n_frames + 3)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002517
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002518 chunk_sizes = [len(c) for c in writer.chunks]
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002519 large_sizes = [s for s in chunk_sizes
2520 if s >= self.FRAME_SIZE_TARGET]
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002521 medium_sizes = [s for s in chunk_sizes
2522 if 9 < s < self.FRAME_SIZE_TARGET]
2523 small_sizes = [s for s in chunk_sizes if s <= 9]
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002524
2525 # Large chunks should not be too large:
2526 for chunk_size in large_sizes:
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002527 self.assertLess(chunk_size, 2 * self.FRAME_SIZE_TARGET,
2528 chunk_sizes)
2529 # There shouldn't bee too many small chunks: the protocol header,
2530 # the frame headers and the large string headers are written
2531 # in small chunks.
2532 self.assertLessEqual(len(small_sizes),
2533 len(large_sizes) + len(medium_sizes) + 3,
2534 chunk_sizes)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002535
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002536 def test_nested_names(self):
2537 global Nested
2538 class Nested:
2539 class A:
2540 class B:
2541 class C:
2542 pass
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002543 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002544 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
2545 with self.subTest(proto=proto, obj=obj):
2546 unpickled = self.loads(self.dumps(obj, proto))
2547 self.assertIs(obj, unpickled)
2548
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002549 def test_recursive_nested_names(self):
2550 global Recursive
2551 class Recursive:
2552 pass
2553 Recursive.mod = sys.modules[Recursive.__module__]
2554 Recursive.__qualname__ = 'Recursive.mod.Recursive'
2555 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2556 with self.subTest(proto=proto):
2557 unpickled = self.loads(self.dumps(Recursive, proto))
2558 self.assertIs(unpickled, Recursive)
2559 del Recursive.mod # break reference loop
2560
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002561 def test_py_methods(self):
2562 global PyMethodsTest
2563 class PyMethodsTest:
2564 @staticmethod
2565 def cheese():
2566 return "cheese"
2567 @classmethod
2568 def wine(cls):
2569 assert cls is PyMethodsTest
2570 return "wine"
2571 def biscuits(self):
2572 assert isinstance(self, PyMethodsTest)
2573 return "biscuits"
2574 class Nested:
2575 "Nested class"
2576 @staticmethod
2577 def ketchup():
2578 return "ketchup"
2579 @classmethod
2580 def maple(cls):
2581 assert cls is PyMethodsTest.Nested
2582 return "maple"
2583 def pie(self):
2584 assert isinstance(self, PyMethodsTest.Nested)
2585 return "pie"
2586
2587 py_methods = (
2588 PyMethodsTest.cheese,
2589 PyMethodsTest.wine,
2590 PyMethodsTest().biscuits,
2591 PyMethodsTest.Nested.ketchup,
2592 PyMethodsTest.Nested.maple,
2593 PyMethodsTest.Nested().pie
2594 )
2595 py_unbound_methods = (
2596 (PyMethodsTest.biscuits, PyMethodsTest),
2597 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
2598 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002599 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002600 for method in py_methods:
2601 with self.subTest(proto=proto, method=method):
2602 unpickled = self.loads(self.dumps(method, proto))
2603 self.assertEqual(method(), unpickled())
2604 for method, cls in py_unbound_methods:
2605 obj = cls()
2606 with self.subTest(proto=proto, method=method):
2607 unpickled = self.loads(self.dumps(method, proto))
2608 self.assertEqual(method(obj), unpickled(obj))
2609
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002610 def test_c_methods(self):
2611 global Subclass
2612 class Subclass(tuple):
2613 class Nested(str):
2614 pass
2615
2616 c_methods = (
2617 # bound built-in method
2618 ("abcd".index, ("c",)),
2619 # unbound built-in method
2620 (str.index, ("abcd", "c")),
2621 # bound "slot" method
2622 ([1, 2, 3].__len__, ()),
2623 # unbound "slot" method
2624 (list.__len__, ([1, 2, 3],)),
2625 # bound "coexist" method
2626 ({1, 2}.__contains__, (2,)),
2627 # unbound "coexist" method
2628 (set.__contains__, ({1, 2}, 2)),
2629 # built-in class method
2630 (dict.fromkeys, (("a", 1), ("b", 2))),
2631 # built-in static method
2632 (bytearray.maketrans, (b"abc", b"xyz")),
2633 # subclass methods
2634 (Subclass([1,2,2]).count, (2,)),
2635 (Subclass.count, (Subclass([1,2,2]), 2)),
2636 (Subclass.Nested("sweet").count, ("e",)),
2637 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
2638 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002639 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002640 for method, args in c_methods:
2641 with self.subTest(proto=proto, method=method):
2642 unpickled = self.loads(self.dumps(method, proto))
2643 self.assertEqual(method(*args), unpickled(*args))
2644
Serhiy Storchakabfe18242015-03-31 13:12:37 +03002645 def test_compat_pickle(self):
2646 tests = [
2647 (range(1, 7), '__builtin__', 'xrange'),
2648 (map(int, '123'), 'itertools', 'imap'),
2649 (functools.reduce, '__builtin__', 'reduce'),
2650 (dbm.whichdb, 'whichdb', 'whichdb'),
2651 (Exception(), 'exceptions', 'Exception'),
2652 (collections.UserDict(), 'UserDict', 'IterableUserDict'),
2653 (collections.UserList(), 'UserList', 'UserList'),
2654 (collections.defaultdict(), 'collections', 'defaultdict'),
2655 ]
2656 for val, mod, name in tests:
2657 for proto in range(3):
2658 with self.subTest(type=type(val), proto=proto):
2659 pickled = self.dumps(val, proto)
2660 self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled)
2661 self.assertIs(type(self.loads(pickled)), type(val))
2662
Antoine Pitrou6cd5eda2014-12-02 00:20:03 +01002663 def test_local_lookup_error(self):
2664 # Test that whichmodule() errors out cleanly when looking up
2665 # an assumed globally-reachable object fails.
2666 def f():
2667 pass
2668 # Since the function is local, lookup will fail
2669 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2670 with self.assertRaises((AttributeError, pickle.PicklingError)):
2671 pickletools.dis(self.dumps(f, proto))
2672 # Same without a __module__ attribute (exercises a different path
2673 # in _pickle.c).
2674 del f.__module__
2675 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2676 with self.assertRaises((AttributeError, pickle.PicklingError)):
2677 pickletools.dis(self.dumps(f, proto))
2678 # Yet a different path.
2679 f.__name__ = f.__qualname__
2680 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2681 with self.assertRaises((AttributeError, pickle.PicklingError)):
2682 pickletools.dis(self.dumps(f, proto))
2683
Antoine Pitrou91f43802019-05-26 17:10:09 +02002684 #
2685 # PEP 574 tests below
2686 #
2687
2688 def buffer_like_objects(self):
2689 # Yield buffer-like objects with the bytestring "abcdef" in them
2690 bytestring = b"abcdefgh"
2691 yield ZeroCopyBytes(bytestring)
2692 yield ZeroCopyBytearray(bytestring)
2693 if _testbuffer is not None:
2694 items = list(bytestring)
2695 value = int.from_bytes(bytestring, byteorder='little')
2696 for flags in (0, _testbuffer.ND_WRITABLE):
2697 # 1-D, contiguous
2698 yield PicklableNDArray(items, format='B', shape=(8,),
2699 flags=flags)
2700 # 2-D, C-contiguous
2701 yield PicklableNDArray(items, format='B', shape=(4, 2),
2702 strides=(2, 1), flags=flags)
2703 # 2-D, Fortran-contiguous
2704 yield PicklableNDArray(items, format='B',
2705 shape=(4, 2), strides=(1, 4),
2706 flags=flags)
2707
2708 def test_in_band_buffers(self):
2709 # Test in-band buffers (PEP 574)
2710 for obj in self.buffer_like_objects():
2711 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2712 data = self.dumps(obj, proto)
2713 if obj.c_contiguous and proto >= 5:
2714 # The raw memory bytes are serialized in physical order
2715 self.assertIn(b"abcdefgh", data)
2716 self.assertEqual(count_opcode(pickle.NEXT_BUFFER, data), 0)
2717 if proto >= 5:
2718 self.assertEqual(count_opcode(pickle.SHORT_BINBYTES, data),
2719 1 if obj.readonly else 0)
2720 self.assertEqual(count_opcode(pickle.BYTEARRAY8, data),
2721 0 if obj.readonly else 1)
2722 # Return a true value from buffer_callback should have
2723 # the same effect
2724 def buffer_callback(obj):
2725 return True
2726 data2 = self.dumps(obj, proto,
2727 buffer_callback=buffer_callback)
2728 self.assertEqual(data2, data)
2729
2730 new = self.loads(data)
2731 # It's a copy
2732 self.assertIsNot(new, obj)
2733 self.assertIs(type(new), type(obj))
2734 self.assertEqual(new, obj)
2735
2736 # XXX Unfortunately cannot test non-contiguous array
2737 # (see comment in PicklableNDArray.__reduce_ex__)
2738
2739 def test_oob_buffers(self):
2740 # Test out-of-band buffers (PEP 574)
2741 for obj in self.buffer_like_objects():
2742 for proto in range(0, 5):
2743 # Need protocol >= 5 for buffer_callback
2744 with self.assertRaises(ValueError):
2745 self.dumps(obj, proto,
2746 buffer_callback=[].append)
2747 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
2748 buffers = []
2749 buffer_callback = lambda pb: buffers.append(pb.raw())
2750 data = self.dumps(obj, proto,
2751 buffer_callback=buffer_callback)
2752 self.assertNotIn(b"abcdefgh", data)
2753 self.assertEqual(count_opcode(pickle.SHORT_BINBYTES, data), 0)
2754 self.assertEqual(count_opcode(pickle.BYTEARRAY8, data), 0)
2755 self.assertEqual(count_opcode(pickle.NEXT_BUFFER, data), 1)
2756 self.assertEqual(count_opcode(pickle.READONLY_BUFFER, data),
2757 1 if obj.readonly else 0)
2758
2759 if obj.c_contiguous:
2760 self.assertEqual(bytes(buffers[0]), b"abcdefgh")
2761 # Need buffers argument to unpickle properly
2762 with self.assertRaises(pickle.UnpicklingError):
2763 self.loads(data)
2764
2765 new = self.loads(data, buffers=buffers)
2766 if obj.zero_copy_reconstruct:
2767 # Zero-copy achieved
2768 self.assertIs(new, obj)
2769 else:
2770 self.assertIs(type(new), type(obj))
2771 self.assertEqual(new, obj)
2772 # Non-sequence buffers accepted too
2773 new = self.loads(data, buffers=iter(buffers))
2774 if obj.zero_copy_reconstruct:
2775 # Zero-copy achieved
2776 self.assertIs(new, obj)
2777 else:
2778 self.assertIs(type(new), type(obj))
2779 self.assertEqual(new, obj)
2780
2781 def test_oob_buffers_writable_to_readonly(self):
2782 # Test reconstructing readonly object from writable buffer
2783 obj = ZeroCopyBytes(b"foobar")
2784 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
2785 buffers = []
2786 buffer_callback = buffers.append
2787 data = self.dumps(obj, proto, buffer_callback=buffer_callback)
2788
2789 buffers = map(bytearray, buffers)
2790 new = self.loads(data, buffers=buffers)
2791 self.assertIs(type(new), type(obj))
2792 self.assertEqual(new, obj)
2793
2794 def test_picklebuffer_error(self):
2795 # PickleBuffer forbidden with protocol < 5
2796 pb = pickle.PickleBuffer(b"foobar")
2797 for proto in range(0, 5):
2798 with self.assertRaises(pickle.PickleError):
2799 self.dumps(pb, proto)
2800
2801 def test_buffer_callback_error(self):
2802 def buffer_callback(buffers):
2803 1/0
2804 pb = pickle.PickleBuffer(b"foobar")
2805 with self.assertRaises(ZeroDivisionError):
2806 self.dumps(pb, 5, buffer_callback=buffer_callback)
2807
2808 def test_buffers_error(self):
2809 pb = pickle.PickleBuffer(b"foobar")
2810 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
2811 data = self.dumps(pb, proto, buffer_callback=[].append)
2812 # Non iterable buffers
2813 with self.assertRaises(TypeError):
2814 self.loads(data, buffers=object())
2815 # Buffer iterable exhausts too early
2816 with self.assertRaises(pickle.UnpicklingError):
2817 self.loads(data, buffers=[])
2818
Markus Mohrhard898318b2019-07-26 00:00:34 +08002819 def test_inband_accept_default_buffers_argument(self):
2820 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
2821 data_pickled = self.dumps(1, proto, buffer_callback=None)
2822 data = self.loads(data_pickled, buffers=None)
2823
Antoine Pitrou91f43802019-05-26 17:10:09 +02002824 @unittest.skipIf(np is None, "Test needs Numpy")
2825 def test_buffers_numpy(self):
2826 def check_no_copy(x, y):
2827 np.testing.assert_equal(x, y)
2828 self.assertEqual(x.ctypes.data, y.ctypes.data)
2829
2830 def check_copy(x, y):
2831 np.testing.assert_equal(x, y)
2832 self.assertNotEqual(x.ctypes.data, y.ctypes.data)
2833
2834 def check_array(arr):
2835 # In-band
2836 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2837 data = self.dumps(arr, proto)
2838 new = self.loads(data)
2839 check_copy(arr, new)
2840 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
2841 buffer_callback = lambda _: True
2842 data = self.dumps(arr, proto, buffer_callback=buffer_callback)
2843 new = self.loads(data)
2844 check_copy(arr, new)
2845 # Out-of-band
2846 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
2847 buffers = []
2848 buffer_callback = buffers.append
2849 data = self.dumps(arr, proto, buffer_callback=buffer_callback)
2850 new = self.loads(data, buffers=buffers)
2851 if arr.flags.c_contiguous or arr.flags.f_contiguous:
2852 check_no_copy(arr, new)
2853 else:
2854 check_copy(arr, new)
2855
2856 # 1-D
2857 arr = np.arange(6)
2858 check_array(arr)
2859 # 1-D, non-contiguous
2860 check_array(arr[::2])
2861 # 2-D, C-contiguous
2862 arr = np.arange(12).reshape((3, 4))
2863 check_array(arr)
2864 # 2-D, F-contiguous
2865 check_array(arr.T)
2866 # 2-D, non-contiguous
2867 check_array(arr[::2])
2868
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002869
2870class BigmemPickleTests(unittest.TestCase):
2871
Victor Stinner8c663fd2017-11-08 14:44:44 -08002872 # Binary protocols can serialize longs of up to 2 GiB-1
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002873
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002874 @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002875 def test_huge_long_32b(self, size):
2876 data = 1 << (8 * size)
2877 try:
2878 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002879 if proto < 2:
2880 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002881 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002882 with self.assertRaises((ValueError, OverflowError)):
2883 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002884 finally:
2885 data = None
2886
Victor Stinner8c663fd2017-11-08 14:44:44 -08002887 # Protocol 3 can serialize up to 4 GiB-1 as a bytes object
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002888 # (older protocols don't have a dedicated opcode for bytes and are
2889 # too inefficient)
2890
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002891 @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002892 def test_huge_bytes_32b(self, size):
2893 data = b"abcd" * (size // 4)
2894 try:
2895 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002896 if proto < 3:
2897 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002898 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002899 try:
2900 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002901 header = (pickle.BINBYTES +
2902 struct.pack("<I", len(data)))
2903 data_start = pickled.index(data)
2904 self.assertEqual(
2905 header,
2906 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002907 finally:
2908 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002909 finally:
2910 data = None
2911
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002912 @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002913 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002914 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002915 try:
2916 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002917 if proto < 3:
2918 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002919 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002920 if proto == 3:
2921 # Protocol 3 does not support large bytes objects.
2922 # Verify that we do not crash when processing one.
2923 with self.assertRaises((ValueError, OverflowError)):
2924 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002925 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002926 try:
2927 pickled = self.dumps(data, protocol=proto)
2928 header = (pickle.BINBYTES8 +
2929 struct.pack("<Q", len(data)))
2930 data_start = pickled.index(data)
2931 self.assertEqual(
2932 header,
2933 pickled[data_start-len(header):data_start])
2934 finally:
2935 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002936 finally:
2937 data = None
2938
2939 # All protocols use 1-byte per printable ASCII character; we add another
2940 # byte because the encoded form has to be copied into the internal buffer.
2941
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002942 @bigmemtest(size=_2G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002943 def test_huge_str_32b(self, size):
2944 data = "abcd" * (size // 4)
2945 try:
2946 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002947 if proto == 0:
2948 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002949 with self.subTest(proto=proto):
2950 try:
2951 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002952 header = (pickle.BINUNICODE +
2953 struct.pack("<I", len(data)))
2954 data_start = pickled.index(b'abcd')
2955 self.assertEqual(
2956 header,
2957 pickled[data_start-len(header):data_start])
2958 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2959 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002960 finally:
2961 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002962 finally:
2963 data = None
2964
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002965 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
2966 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
2967 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02002968
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002969 @bigmemtest(size=_4G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002970 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002971 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002972 try:
2973 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002974 if proto == 0:
2975 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002976 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002977 if proto < 4:
2978 with self.assertRaises((ValueError, OverflowError)):
2979 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002980 continue
2981 try:
2982 pickled = self.dumps(data, protocol=proto)
2983 header = (pickle.BINUNICODE8 +
2984 struct.pack("<Q", len(data)))
2985 data_start = pickled.index(b'abcd')
2986 self.assertEqual(
2987 header,
2988 pickled[data_start-len(header):data_start])
2989 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2990 pickled.index(b"abcd")), len(data))
2991 finally:
2992 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002993 finally:
2994 data = None
2995
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002996
Guido van Rossum2a30b212003-02-18 22:41:24 +00002997# Test classes for reduce_ex
2998
2999class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003000 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00003001 _reduce_called = 0
3002 def __reduce__(self):
3003 self._reduce_called = 1
3004 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00003005
3006class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003007 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00003008 _proto = None
3009 def __reduce_ex__(self, proto):
3010 self._proto = proto
3011 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00003012
3013class REX_three(object):
3014 _proto = None
3015 def __reduce_ex__(self, proto):
3016 self._proto = proto
3017 return REX_two, ()
3018 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00003019 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00003020
Guido van Rossumd8faa362007-04-27 19:54:29 +00003021class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003022 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00003023 _proto = None
3024 def __reduce_ex__(self, proto):
3025 self._proto = proto
3026 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00003027
3028class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003029 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00003030 _reduce_called = 0
3031 def __reduce__(self):
3032 self._reduce_called = 1
3033 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003034
3035class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003036 """This class is used to check the 4th argument (list iterator) of
3037 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003038 """
3039 def __init__(self, items=None):
3040 self.items = items if items is not None else []
3041 def __eq__(self, other):
Serhiy Storchakabe700022016-03-04 09:39:47 +02003042 return type(self) is type(other) and self.items == other.items
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003043 def append(self, item):
3044 self.items.append(item)
3045 def __reduce__(self):
3046 return type(self), (), None, iter(self.items), None
3047
3048class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003049 """This class is used to check the 5th argument (dict iterator) of
3050 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003051 """
3052 def __init__(self, table=None):
3053 self.table = table if table is not None else {}
3054 def __eq__(self, other):
Serhiy Storchakabe700022016-03-04 09:39:47 +02003055 return type(self) is type(other) and self.table == other.table
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07003056 def __setitem__(self, key, value):
3057 self.table[key] = value
3058 def __reduce__(self):
3059 return type(self), (), None, None, iter(self.table.items())
3060
Guido van Rossumd8faa362007-04-27 19:54:29 +00003061
Guido van Rossum2a30b212003-02-18 22:41:24 +00003062# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00003063
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003064class MyInt(int):
3065 sample = 1
3066
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003067class MyFloat(float):
3068 sample = 1.0
3069
3070class MyComplex(complex):
3071 sample = 1.0 + 0.0j
3072
3073class MyStr(str):
3074 sample = "hello"
3075
Guido van Rossumef87d6e2007-05-02 19:09:54 +00003076class MyUnicode(str):
3077 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003078
Guido van Rossum533dbcf2003-01-28 17:55:05 +00003079class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003080 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00003081
3082class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003083 sample = [1, 2, 3]
3084
3085class MyDict(dict):
3086 sample = {"a": 1, "b": 2}
3087
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003088class MySet(set):
3089 sample = {"a", "b"}
3090
3091class MyFrozenSet(frozenset):
3092 sample = frozenset({"a", "b"})
3093
Mark Dickinson5c2db372009-12-05 20:28:34 +00003094myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00003095 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003096 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003097 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00003098
Serhiy Storchaka0aaecb32020-10-25 17:56:17 +02003099class MyIntWithNew(int):
3100 def __new__(cls, value):
3101 raise AssertionError
3102
3103class MyIntWithNew2(MyIntWithNew):
3104 __new__ = int.__new__
3105
Guido van Rossum533dbcf2003-01-28 17:55:05 +00003106
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00003107class SlotList(MyList):
3108 __slots__ = ["foo"]
3109
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02003110class SimpleNewObj(int):
3111 def __init__(self, *args, **kwargs):
Tim Peterse9ef2032003-02-13 18:42:00 +00003112 # raise an error, to make sure this isn't called
3113 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003114 def __eq__(self, other):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02003115 return int(self) == int(other) and self.__dict__ == other.__dict__
3116
3117class ComplexNewObj(SimpleNewObj):
3118 def __getnewargs__(self):
3119 return ('%X' % self, 16)
3120
3121class ComplexNewObjEx(SimpleNewObj):
3122 def __getnewargs_ex__(self):
3123 return ('%X' % self,), {'base': 16}
Tim Peterse9ef2032003-02-13 18:42:00 +00003124
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00003125class BadGetattr:
3126 def __getattr__(self, key):
3127 self.foo
3128
Collin Winter771d8342009-04-16 03:18:06 +00003129
Jeremy Hylton66426532001-10-15 21:38:56 +00003130class AbstractPickleModuleTests(unittest.TestCase):
3131
3132 def test_dump_closed_file(self):
Walter Dörwald11b41f62007-06-20 12:46:31 +00003133 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00003134 try:
3135 f.close()
Serhiy Storchaka65452562017-11-15 14:01:08 +02003136 self.assertRaises(ValueError, self.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00003137 finally:
Serhiy Storchaka38ab7d42019-05-31 11:29:39 +03003138 support.unlink(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00003139
3140 def test_load_closed_file(self):
Walter Dörwald11b41f62007-06-20 12:46:31 +00003141 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00003142 try:
3143 f.close()
Serhiy Storchaka65452562017-11-15 14:01:08 +02003144 self.assertRaises(ValueError, self.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00003145 finally:
Serhiy Storchaka38ab7d42019-05-31 11:29:39 +03003146 support.unlink(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00003147
Collin Winter771d8342009-04-16 03:18:06 +00003148 def test_load_from_and_dump_to_file(self):
3149 stream = io.BytesIO()
3150 data = [123, {}, 124]
Serhiy Storchaka65452562017-11-15 14:01:08 +02003151 self.dump(data, stream)
Collin Winter771d8342009-04-16 03:18:06 +00003152 stream.seek(0)
Serhiy Storchaka65452562017-11-15 14:01:08 +02003153 unpickled = self.load(stream)
Collin Winter771d8342009-04-16 03:18:06 +00003154 self.assertEqual(unpickled, data)
3155
Tim Petersc0c93702003-02-13 19:30:57 +00003156 def test_highest_protocol(self):
3157 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrou91f43802019-05-26 17:10:09 +02003158 self.assertEqual(pickle.HIGHEST_PROTOCOL, 5)
Tim Petersc0c93702003-02-13 19:30:57 +00003159
Martin v. Löwis544f1192004-07-27 05:22:33 +00003160 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00003161 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00003162 # With and without keyword arguments
Serhiy Storchaka65452562017-11-15 14:01:08 +02003163 self.dump(123, f, -1)
3164 self.dump(123, file=f, protocol=-1)
3165 self.dumps(123, -1)
3166 self.dumps(123, protocol=-1)
3167 self.Pickler(f, -1)
3168 self.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00003169
Serhiy Storchaka38ab7d42019-05-31 11:29:39 +03003170 def test_dump_text_file(self):
3171 f = open(TESTFN, "w")
3172 try:
3173 for proto in protocols:
3174 self.assertRaises(TypeError, self.dump, 123, f, proto)
3175 finally:
3176 f.close()
3177 support.unlink(TESTFN)
3178
3179 def test_incomplete_input(self):
3180 s = io.BytesIO(b"X''.")
3181 self.assertRaises((EOFError, struct.error, pickle.UnpicklingError), self.load, s)
3182
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00003183 def test_bad_init(self):
3184 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00003185 # Override initialization without calling __init__() of the superclass.
Serhiy Storchaka65452562017-11-15 14:01:08 +02003186 class BadPickler(self.Pickler):
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00003187 def __init__(self): pass
3188
Serhiy Storchaka65452562017-11-15 14:01:08 +02003189 class BadUnpickler(self.Unpickler):
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00003190 def __init__(self): pass
3191
3192 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
3193 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
3194
Antoine Pitrou91f43802019-05-26 17:10:09 +02003195 def check_dumps_loads_oob_buffers(self, dumps, loads):
3196 # No need to do the full gamut of tests here, just enough to
3197 # check that dumps() and loads() redirect their arguments
3198 # to the underlying Pickler and Unpickler, respectively.
3199 obj = ZeroCopyBytes(b"foo")
3200
3201 for proto in range(0, 5):
3202 # Need protocol >= 5 for buffer_callback
3203 with self.assertRaises(ValueError):
3204 dumps(obj, protocol=proto,
3205 buffer_callback=[].append)
3206 for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
3207 buffers = []
3208 buffer_callback = buffers.append
3209 data = dumps(obj, protocol=proto,
3210 buffer_callback=buffer_callback)
3211 self.assertNotIn(b"foo", data)
3212 self.assertEqual(bytes(buffers[0]), b"foo")
3213 # Need buffers argument to unpickle properly
3214 with self.assertRaises(pickle.UnpicklingError):
3215 loads(data)
3216 new = loads(data, buffers=buffers)
3217 self.assertIs(new, obj)
3218
3219 def test_dumps_loads_oob_buffers(self):
3220 # Test out-of-band buffers (PEP 574) with top-level dumps() and loads()
3221 self.check_dumps_loads_oob_buffers(self.dumps, self.loads)
3222
3223 def test_dump_load_oob_buffers(self):
3224 # Test out-of-band buffers (PEP 574) with top-level dump() and load()
3225 def dumps(obj, **kwargs):
3226 f = io.BytesIO()
3227 self.dump(obj, f, **kwargs)
3228 return f.getvalue()
3229
3230 def loads(data, **kwargs):
3231 f = io.BytesIO(data)
3232 return self.load(f, **kwargs)
3233
3234 self.check_dumps_loads_oob_buffers(dumps, loads)
3235
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00003236
Jeremy Hylton4c8be852002-11-13 22:10:47 +00003237class AbstractPersistentPicklerTests(unittest.TestCase):
3238
3239 # This class defines persistent_id() and persistent_load()
3240 # functions that should be used by the pickler. All even integers
3241 # are pickled using persistent ids.
3242
3243 def persistent_id(self, object):
3244 if isinstance(object, int) and object % 2 == 0:
3245 self.id_count += 1
3246 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08003247 elif object == "test_false_value":
3248 self.false_count += 1
3249 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00003250 else:
3251 return None
3252
3253 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08003254 if not oid:
3255 self.load_false_count += 1
3256 return "test_false_value"
3257 else:
3258 self.load_count += 1
3259 object = int(oid)
3260 assert object % 2 == 0
3261 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00003262
3263 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08003264 L = list(range(10)) + ["test_false_value"]
3265 for proto in protocols:
3266 self.id_count = 0
3267 self.false_count = 0
3268 self.load_false_count = 0
3269 self.load_count = 0
3270 self.assertEqual(self.loads(self.dumps(L, proto)), L)
3271 self.assertEqual(self.id_count, 5)
3272 self.assertEqual(self.false_count, 1)
3273 self.assertEqual(self.load_count, 5)
3274 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00003275
Collin Winter771d8342009-04-16 03:18:06 +00003276
Serhiy Storchakadec25af2016-07-17 11:24:17 +03003277class AbstractIdentityPersistentPicklerTests(unittest.TestCase):
3278
3279 def persistent_id(self, obj):
3280 return obj
3281
3282 def persistent_load(self, pid):
3283 return pid
3284
3285 def _check_return_correct_type(self, obj, proto):
3286 unpickled = self.loads(self.dumps(obj, proto))
3287 self.assertIsInstance(unpickled, type(obj))
3288 self.assertEqual(unpickled, obj)
3289
3290 def test_return_correct_type(self):
3291 for proto in protocols:
3292 # Protocol 0 supports only ASCII strings.
3293 if proto == 0:
3294 self._check_return_correct_type("abc", 0)
3295 else:
3296 for obj in [b"abc\n", "abc\n", -1, -1.1 * 0.1, str]:
3297 self._check_return_correct_type(obj, proto)
3298
3299 def test_protocol0_is_ascii_only(self):
3300 non_ascii_str = "\N{EMPTY SET}"
3301 self.assertRaises(pickle.PicklingError, self.dumps, non_ascii_str, 0)
3302 pickled = pickle.PERSID + non_ascii_str.encode('utf-8') + b'\n.'
3303 self.assertRaises(pickle.UnpicklingError, self.loads, pickled)
3304
3305
Collin Winter771d8342009-04-16 03:18:06 +00003306class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
3307
3308 pickler_class = None
3309 unpickler_class = None
3310
3311 def setUp(self):
3312 assert self.pickler_class
3313 assert self.unpickler_class
3314
3315 def test_clear_pickler_memo(self):
3316 # To test whether clear_memo() has any effect, we pickle an object,
3317 # then pickle it again without clearing the memo; the two serialized
3318 # forms should be different. If we clear_memo() and then pickle the
3319 # object again, the third serialized form should be identical to the
3320 # first one we obtained.
3321 data = ["abcdefg", "abcdefg", 44]
Serhiy Storchakac8695292018-04-04 00:11:27 +03003322 for proto in protocols:
3323 f = io.BytesIO()
3324 pickler = self.pickler_class(f, proto)
Collin Winter771d8342009-04-16 03:18:06 +00003325
Serhiy Storchakac8695292018-04-04 00:11:27 +03003326 pickler.dump(data)
3327 first_pickled = f.getvalue()
Collin Winter771d8342009-04-16 03:18:06 +00003328
Serhiy Storchakac8695292018-04-04 00:11:27 +03003329 # Reset BytesIO object.
3330 f.seek(0)
3331 f.truncate()
Collin Winter771d8342009-04-16 03:18:06 +00003332
Serhiy Storchakac8695292018-04-04 00:11:27 +03003333 pickler.dump(data)
3334 second_pickled = f.getvalue()
Collin Winter771d8342009-04-16 03:18:06 +00003335
Serhiy Storchakac8695292018-04-04 00:11:27 +03003336 # Reset the Pickler and BytesIO objects.
3337 pickler.clear_memo()
3338 f.seek(0)
3339 f.truncate()
Collin Winter771d8342009-04-16 03:18:06 +00003340
Serhiy Storchakac8695292018-04-04 00:11:27 +03003341 pickler.dump(data)
3342 third_pickled = f.getvalue()
Collin Winter771d8342009-04-16 03:18:06 +00003343
Serhiy Storchakac8695292018-04-04 00:11:27 +03003344 self.assertNotEqual(first_pickled, second_pickled)
3345 self.assertEqual(first_pickled, third_pickled)
Collin Winter771d8342009-04-16 03:18:06 +00003346
3347 def test_priming_pickler_memo(self):
3348 # Verify that we can set the Pickler's memo attribute.
3349 data = ["abcdefg", "abcdefg", 44]
3350 f = io.BytesIO()
3351 pickler = self.pickler_class(f)
3352
3353 pickler.dump(data)
3354 first_pickled = f.getvalue()
3355
3356 f = io.BytesIO()
3357 primed = self.pickler_class(f)
3358 primed.memo = pickler.memo
3359
3360 primed.dump(data)
3361 primed_pickled = f.getvalue()
3362
3363 self.assertNotEqual(first_pickled, primed_pickled)
3364
3365 def test_priming_unpickler_memo(self):
3366 # Verify that we can set the Unpickler's memo attribute.
3367 data = ["abcdefg", "abcdefg", 44]
3368 f = io.BytesIO()
3369 pickler = self.pickler_class(f)
3370
3371 pickler.dump(data)
3372 first_pickled = f.getvalue()
3373
3374 f = io.BytesIO()
3375 primed = self.pickler_class(f)
3376 primed.memo = pickler.memo
3377
3378 primed.dump(data)
3379 primed_pickled = f.getvalue()
3380
3381 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
3382 unpickled_data1 = unpickler.load()
3383
3384 self.assertEqual(unpickled_data1, data)
3385
3386 primed = self.unpickler_class(io.BytesIO(primed_pickled))
3387 primed.memo = unpickler.memo
3388 unpickled_data2 = primed.load()
3389
3390 primed.memo.clear()
3391
3392 self.assertEqual(unpickled_data2, data)
3393 self.assertTrue(unpickled_data2 is unpickled_data1)
3394
3395 def test_reusing_unpickler_objects(self):
3396 data1 = ["abcdefg", "abcdefg", 44]
3397 f = io.BytesIO()
3398 pickler = self.pickler_class(f)
3399 pickler.dump(data1)
3400 pickled1 = f.getvalue()
3401
3402 data2 = ["abcdefg", 44, 44]
3403 f = io.BytesIO()
3404 pickler = self.pickler_class(f)
3405 pickler.dump(data2)
3406 pickled2 = f.getvalue()
3407
3408 f = io.BytesIO()
3409 f.write(pickled1)
3410 f.seek(0)
3411 unpickler = self.unpickler_class(f)
3412 self.assertEqual(unpickler.load(), data1)
3413
3414 f.seek(0)
3415 f.truncate()
3416 f.write(pickled2)
3417 f.seek(0)
3418 self.assertEqual(unpickler.load(), data2)
3419
Antoine Pitrou9f378722020-02-23 23:33:53 +01003420 def _check_multiple_unpicklings(self, ioclass, *, seekable=True):
Antoine Pitrou04248a82010-10-12 20:51:21 +00003421 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003422 with self.subTest(proto=proto):
3423 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
3424 f = ioclass()
3425 pickler = self.pickler_class(f, protocol=proto)
3426 pickler.dump(data1)
3427 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00003428
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003429 N = 5
3430 f = ioclass(pickled * N)
3431 unpickler = self.unpickler_class(f)
3432 for i in range(N):
Antoine Pitrou9f378722020-02-23 23:33:53 +01003433 if seekable:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003434 pos = f.tell()
3435 self.assertEqual(unpickler.load(), data1)
Antoine Pitrou9f378722020-02-23 23:33:53 +01003436 if seekable:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01003437 self.assertEqual(f.tell(), pos + len(pickled))
3438 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00003439
3440 def test_multiple_unpicklings_seekable(self):
3441 self._check_multiple_unpicklings(io.BytesIO)
3442
3443 def test_multiple_unpicklings_unseekable(self):
Antoine Pitrou9f378722020-02-23 23:33:53 +01003444 self._check_multiple_unpicklings(UnseekableIO, seekable=False)
3445
3446 def test_multiple_unpicklings_minimal(self):
3447 # File-like object that doesn't support peek() and readinto()
3448 # (bpo-39681)
3449 self._check_multiple_unpicklings(MinimalIO, seekable=False)
Antoine Pitrou04248a82010-10-12 20:51:21 +00003450
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02003451 def test_unpickling_buffering_readline(self):
3452 # Issue #12687: the unpickler's buffering logic could fail with
3453 # text mode opcodes.
3454 data = list(range(10))
3455 for proto in protocols:
3456 for buf_size in range(1, 11):
3457 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
3458 pickler = self.pickler_class(f, protocol=proto)
3459 pickler.dump(data)
3460 f.seek(0)
3461 unpickler = self.unpickler_class(f)
3462 self.assertEqual(unpickler.load(), data)
3463
Collin Winter771d8342009-04-16 03:18:06 +00003464
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01003465# Tests for dispatch_table attribute
3466
3467REDUCE_A = 'reduce_A'
3468
3469class AAA(object):
3470 def __reduce__(self):
3471 return str, (REDUCE_A,)
3472
3473class BBB(object):
Pierre Glaser65d98d02019-05-08 21:40:25 +02003474 def __init__(self):
3475 # Add an instance attribute to enable state-saving routines at pickling
3476 # time.
3477 self.a = "some attribute"
3478
3479 def __setstate__(self, state):
3480 self.a = "BBB.__setstate__"
3481
3482
3483def setstate_bbb(obj, state):
3484 """Custom state setter for BBB objects
3485
3486 Such callable may be created by other persons than the ones who created the
3487 BBB class. If passed as the state_setter item of a custom reducer, this
3488 allows for custom state setting behavior of BBB objects. One can think of
3489 it as the analogous of list_setitems or dict_setitems but for foreign
3490 classes/functions.
3491 """
3492 obj.a = "custom state_setter"
3493
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01003494
Pierre Glaser289f1f82019-05-08 23:08:25 +02003495
3496class AbstractCustomPicklerClass:
3497 """Pickler implementing a reducing hook using reducer_override."""
3498 def reducer_override(self, obj):
3499 obj_name = getattr(obj, "__name__", None)
3500
3501 if obj_name == 'f':
3502 # asking the pickler to save f as 5
3503 return int, (5, )
3504
3505 if obj_name == 'MyClass':
3506 return str, ('some str',)
3507
3508 elif obj_name == 'g':
3509 # in this case, the callback returns an invalid result (not a 2-5
3510 # tuple or a string), the pickler should raise a proper error.
3511 return False
3512
3513 elif obj_name == 'h':
3514 # Simulate a case when the reducer fails. The error should
3515 # be propagated to the original ``dump`` call.
3516 raise ValueError('The reducer just failed')
3517
3518 return NotImplemented
3519
3520class AbstractHookTests(unittest.TestCase):
3521 def test_pickler_hook(self):
3522 # test the ability of a custom, user-defined CPickler subclass to
3523 # override the default reducing routines of any type using the method
3524 # reducer_override
3525
3526 def f():
3527 pass
3528
3529 def g():
3530 pass
3531
3532 def h():
3533 pass
3534
3535 class MyClass:
3536 pass
3537
3538 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
3539 with self.subTest(proto=proto):
3540 bio = io.BytesIO()
3541 p = self.pickler_class(bio, proto)
3542
3543 p.dump([f, MyClass, math.log])
3544 new_f, some_str, math_log = pickle.loads(bio.getvalue())
3545
3546 self.assertEqual(new_f, 5)
3547 self.assertEqual(some_str, 'some str')
3548 # math.log does not have its usual reducer overriden, so the
3549 # custom reduction callback should silently direct the pickler
3550 # to the default pickling by attribute, by returning
3551 # NotImplemented
3552 self.assertIs(math_log, math.log)
3553
3554 with self.assertRaises(pickle.PicklingError):
3555 p.dump(g)
3556
3557 with self.assertRaisesRegex(
3558 ValueError, 'The reducer just failed'):
3559 p.dump(h)
3560
Pierre Glaser0f2f35e2020-02-02 19:55:21 +01003561 @support.cpython_only
3562 def test_reducer_override_no_reference_cycle(self):
3563 # bpo-39492: reducer_override used to induce a spurious reference cycle
3564 # inside the Pickler object, that could prevent all serialized objects
3565 # from being garbage-collected without explicity invoking gc.collect.
3566
3567 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
3568 with self.subTest(proto=proto):
3569 def f():
3570 pass
3571
3572 wr = weakref.ref(f)
3573
3574 bio = io.BytesIO()
3575 p = self.pickler_class(bio, proto)
3576 p.dump(f)
3577 new_f = pickle.loads(bio.getvalue())
3578 assert new_f == 5
3579
3580 del p
3581 del f
3582
3583 self.assertIsNone(wr())
3584
Pierre Glaser289f1f82019-05-08 23:08:25 +02003585
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01003586class AbstractDispatchTableTests(unittest.TestCase):
3587
3588 def test_default_dispatch_table(self):
3589 # No dispatch_table attribute by default
3590 f = io.BytesIO()
3591 p = self.pickler_class(f, 0)
3592 with self.assertRaises(AttributeError):
3593 p.dispatch_table
3594 self.assertFalse(hasattr(p, 'dispatch_table'))
3595
3596 def test_class_dispatch_table(self):
3597 # A dispatch_table attribute can be specified class-wide
3598 dt = self.get_dispatch_table()
3599
3600 class MyPickler(self.pickler_class):
3601 dispatch_table = dt
3602
3603 def dumps(obj, protocol=None):
3604 f = io.BytesIO()
3605 p = MyPickler(f, protocol)
3606 self.assertEqual(p.dispatch_table, dt)
3607 p.dump(obj)
3608 return f.getvalue()
3609
3610 self._test_dispatch_table(dumps, dt)
3611
3612 def test_instance_dispatch_table(self):
3613 # A dispatch_table attribute can also be specified instance-wide
3614 dt = self.get_dispatch_table()
3615
3616 def dumps(obj, protocol=None):
3617 f = io.BytesIO()
3618 p = self.pickler_class(f, protocol)
3619 p.dispatch_table = dt
3620 self.assertEqual(p.dispatch_table, dt)
3621 p.dump(obj)
3622 return f.getvalue()
3623
3624 self._test_dispatch_table(dumps, dt)
3625
3626 def _test_dispatch_table(self, dumps, dispatch_table):
3627 def custom_load_dump(obj):
3628 return pickle.loads(dumps(obj, 0))
3629
3630 def default_load_dump(obj):
3631 return pickle.loads(pickle.dumps(obj, 0))
3632
3633 # pickling complex numbers using protocol 0 relies on copyreg
3634 # so check pickling a complex number still works
3635 z = 1 + 2j
3636 self.assertEqual(custom_load_dump(z), z)
3637 self.assertEqual(default_load_dump(z), z)
3638
3639 # modify pickling of complex
3640 REDUCE_1 = 'reduce_1'
3641 def reduce_1(obj):
3642 return str, (REDUCE_1,)
3643 dispatch_table[complex] = reduce_1
3644 self.assertEqual(custom_load_dump(z), REDUCE_1)
3645 self.assertEqual(default_load_dump(z), z)
3646
3647 # check picklability of AAA and BBB
3648 a = AAA()
3649 b = BBB()
3650 self.assertEqual(custom_load_dump(a), REDUCE_A)
3651 self.assertIsInstance(custom_load_dump(b), BBB)
3652 self.assertEqual(default_load_dump(a), REDUCE_A)
3653 self.assertIsInstance(default_load_dump(b), BBB)
3654
3655 # modify pickling of BBB
3656 dispatch_table[BBB] = reduce_1
3657 self.assertEqual(custom_load_dump(a), REDUCE_A)
3658 self.assertEqual(custom_load_dump(b), REDUCE_1)
3659 self.assertEqual(default_load_dump(a), REDUCE_A)
3660 self.assertIsInstance(default_load_dump(b), BBB)
3661
3662 # revert pickling of BBB and modify pickling of AAA
3663 REDUCE_2 = 'reduce_2'
3664 def reduce_2(obj):
3665 return str, (REDUCE_2,)
3666 dispatch_table[AAA] = reduce_2
3667 del dispatch_table[BBB]
3668 self.assertEqual(custom_load_dump(a), REDUCE_2)
3669 self.assertIsInstance(custom_load_dump(b), BBB)
3670 self.assertEqual(default_load_dump(a), REDUCE_A)
3671 self.assertIsInstance(default_load_dump(b), BBB)
3672
Pierre Glaser65d98d02019-05-08 21:40:25 +02003673 # End-to-end testing of save_reduce with the state_setter keyword
3674 # argument. This is a dispatch_table test as the primary goal of
3675 # state_setter is to tweak objects reduction behavior.
3676 # In particular, state_setter is useful when the default __setstate__
3677 # behavior is not flexible enough.
3678
3679 # No custom reducer for b has been registered for now, so
3680 # BBB.__setstate__ should be used at unpickling time
3681 self.assertEqual(default_load_dump(b).a, "BBB.__setstate__")
3682
3683 def reduce_bbb(obj):
3684 return BBB, (), obj.__dict__, None, None, setstate_bbb
3685
3686 dispatch_table[BBB] = reduce_bbb
3687
3688 # The custom reducer reduce_bbb includes a state setter, that should
3689 # have priority over BBB.__setstate__
3690 self.assertEqual(custom_load_dump(b).a, "custom state_setter")
3691
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01003692
Guido van Rossum98297ee2007-11-06 21:34:58 +00003693if __name__ == "__main__":
3694 # Print some stuff that can be used to rewrite DATA{0,1,2}
3695 from pickletools import dis
3696 x = create_data()
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03003697 for i in range(pickle.HIGHEST_PROTOCOL+1):
Guido van Rossum98297ee2007-11-06 21:34:58 +00003698 p = pickle.dumps(x, i)
3699 print("DATA{0} = (".format(i))
3700 for j in range(0, len(p), 20):
3701 b = bytes(p[j:j+20])
3702 print(" {0!r}".format(b))
3703 print(")")
3704 print()
3705 print("# Disassembly of DATA{0}".format(i))
3706 print("DATA{0}_DIS = \"\"\"\\".format(i))
3707 dis(p)
3708 print("\"\"\"")
3709 print()