blob: 8f687c49e69049e4e786d15466270bb8093549a1 [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
Tim Peters4190fb82003-02-02 16:09:05 +00007import pickle
Tim Peters31f119e2003-02-03 16:20:13 +00008import pickletools
tjb9004371c0a2019-02-18 23:30:51 +08009import shutil
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -080010import struct
Antoine Pitrou82be19f2011-08-29 23:09:33 +020011import sys
tjb9004371c0a2019-02-18 23:30:51 +080012import threading
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +010013import unittest
Antoine Pitrou16c4ce12011-03-11 21:30:43 +010014import weakref
tjb9004371c0a2019-02-18 23:30:51 +080015from textwrap import dedent
Antoine Pitroud9dfaa92009-06-04 20:32:06 +000016from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +000017
Serhiy Storchaka7279bef2015-11-29 13:12:10 +020018from test import support
Antoine Pitrou82be19f2011-08-29 23:09:33 +020019from test.support import (
Serhiy Storchaka7279bef2015-11-29 13:12:10 +020020 TestFailed, TESTFN, run_with_locale, no_tracing,
tjb9004371c0a2019-02-18 23:30:51 +080021 _2G, _4G, bigmemtest, reap_threads, forget,
Antoine Pitrou82be19f2011-08-29 23:09:33 +020022 )
Tim Peterse089c682001-04-10 03:41:41 +000023
Guido van Rossum98297ee2007-11-06 21:34:58 +000024from pickle import bytes_types
25
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030026requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
27 "test is only meaningful on 32-bit builds")
28
Tim Petersee1a53c2003-02-02 02:57:53 +000029# Tests that try a number of pickle protocols should have a
30# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000031# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000032protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000033
Tim Peters22e71712003-02-03 22:27:38 +000034
35# Return True if opcode code appears in the pickle, else False.
36def opcode_in_pickle(code, pickle):
37 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000038 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000039 return True
40 return False
41
Tim Peters8d2613a2003-02-11 16:40:16 +000042# Return the number of times opcode code appears in pickle.
43def count_opcode(code, pickle):
44 n = 0
45 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000046 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000047 n += 1
48 return n
49
Antoine Pitrou04248a82010-10-12 20:51:21 +000050
51class UnseekableIO(io.BytesIO):
52 def peek(self, *args):
53 raise NotImplementedError
54
55 def seekable(self):
56 return False
57
58 def seek(self, *args):
59 raise io.UnsupportedOperation
60
61 def tell(self):
62 raise io.UnsupportedOperation
63
64
Tim Peters3e667d52003-02-04 21:47:44 +000065# We can't very well test the extension registry without putting known stuff
66# in it, but we have to be careful to restore its original state. Code
67# should do this:
68#
69# e = ExtensionSaver(extension_code)
70# try:
71# fiddle w/ the extension registry's stuff for extension_code
72# finally:
73# e.restore()
74
75class ExtensionSaver:
76 # Remember current registration for code (if any), and remove it (if
77 # there is one).
78 def __init__(self, code):
79 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000080 if code in copyreg._inverted_registry:
81 self.pair = copyreg._inverted_registry[code]
82 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000083 else:
84 self.pair = None
85
86 # Restore previous registration for code.
87 def restore(self):
88 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000089 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000090 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000091 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000092 pair = self.pair
93 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000094 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000095
Jeremy Hylton66426532001-10-15 21:38:56 +000096class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000097 def __eq__(self, other):
98 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000099
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000100class D(C):
101 def __init__(self, arg):
102 pass
103
104class E(C):
105 def __getinitargs__(self):
106 return ()
107
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100108class H(object):
109 pass
110
Serhiy Storchaka608c2132015-11-07 11:16:10 +0200111# Hashable mutable key
112class K(object):
113 def __init__(self, value):
114 self.value = value
115
116 def __reduce__(self):
117 # Shouldn't support the recursion itself
118 return K, (self.value,)
119
Jeremy Hylton66426532001-10-15 21:38:56 +0000120import __main__
121__main__.C = C
122C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000123__main__.D = D
124D.__module__ = "__main__"
125__main__.E = E
126E.__module__ = "__main__"
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100127__main__.H = H
128H.__module__ = "__main__"
Serhiy Storchaka608c2132015-11-07 11:16:10 +0200129__main__.K = K
130K.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000131
132class myint(int):
133 def __init__(self, x):
134 self.str = str(x)
135
136class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000137
Jeremy Hylton66426532001-10-15 21:38:56 +0000138 def __init__(self, a, b):
139 self.a = a
140 self.b = b
141
142 def __getinitargs__(self):
143 return self.a, self.b
144
Guido van Rossum04a86612001-12-19 16:58:54 +0000145class metaclass(type):
146 pass
147
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000148class use_metaclass(object, metaclass=metaclass):
149 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000150
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200151class pickling_metaclass(type):
152 def __eq__(self, other):
153 return (type(self) == type(other) and
154 self.reduce_args == other.reduce_args)
155
156 def __reduce__(self):
157 return (create_dynamic_class, self.reduce_args)
158
159def create_dynamic_class(name, bases):
160 result = pickling_metaclass(name, bases, dict())
161 result.reduce_args = (name, bases)
162 return result
163
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300164# DATA0 .. DATA4 are the pickles we expect under the various protocols, for
Tim Peters70b02d72003-02-02 17:26:40 +0000165# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000166
Guido van Rossum98297ee2007-11-06 21:34:58 +0000167DATA0 = (
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200168 b'(lp0\nL0L\naL1L\naF2.0\n'
169 b'ac__builtin__\ncomple'
170 b'x\np1\n(F3.0\nF0.0\ntp2\n'
171 b'Rp3\naL1L\naL-1L\naL255'
172 b'L\naL-255L\naL-256L\naL'
173 b'65535L\naL-65535L\naL-'
174 b'65536L\naL2147483647L'
175 b'\naL-2147483647L\naL-2'
176 b'147483648L\na(Vabc\np4'
177 b'\ng4\nccopy_reg\n_recon'
178 b'structor\np5\n(c__main'
179 b'__\nC\np6\nc__builtin__'
180 b'\nobject\np7\nNtp8\nRp9\n'
181 b'(dp10\nVfoo\np11\nL1L\ns'
182 b'Vbar\np12\nL2L\nsbg9\ntp'
183 b'13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000184)
Tim Peterse9358162001-01-22 22:05:20 +0000185
Guido van Rossum98297ee2007-11-06 21:34:58 +0000186# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000187DATA0_DIS = """\
188 0: ( MARK
189 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000190 2: p PUT 0
191 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000192 9: a APPEND
193 10: L LONG 1
194 14: a APPEND
195 15: F FLOAT 2.0
196 20: a APPEND
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200197 21: c GLOBAL '__builtin__ complex'
198 42: p PUT 1
199 45: ( MARK
200 46: F FLOAT 3.0
201 51: F FLOAT 0.0
202 56: t TUPLE (MARK at 45)
203 57: p PUT 2
204 60: R REDUCE
205 61: p PUT 3
206 64: a APPEND
207 65: L LONG 1
208 69: a APPEND
209 70: L LONG -1
210 75: a APPEND
211 76: L LONG 255
212 82: a APPEND
213 83: L LONG -255
214 90: a APPEND
215 91: L LONG -256
216 98: a APPEND
217 99: L LONG 65535
218 107: a APPEND
219 108: L LONG -65535
220 117: a APPEND
221 118: L LONG -65536
222 127: a APPEND
223 128: L LONG 2147483647
224 141: a APPEND
225 142: L LONG -2147483647
226 156: a APPEND
227 157: L LONG -2147483648
228 171: a APPEND
229 172: ( MARK
230 173: V UNICODE 'abc'
231 178: p PUT 4
232 181: g GET 4
233 184: c GLOBAL 'copy_reg _reconstructor'
234 209: p PUT 5
235 212: ( MARK
236 213: c GLOBAL '__main__ C'
237 225: p PUT 6
238 228: c GLOBAL '__builtin__ object'
239 248: p PUT 7
240 251: N NONE
241 252: t TUPLE (MARK at 212)
242 253: p PUT 8
243 256: R REDUCE
244 257: p PUT 9
245 260: ( MARK
246 261: d DICT (MARK at 260)
247 262: p PUT 10
248 266: V UNICODE 'foo'
249 271: p PUT 11
250 275: L LONG 1
251 279: s SETITEM
252 280: V UNICODE 'bar'
253 285: p PUT 12
254 289: L LONG 2
255 293: s SETITEM
256 294: b BUILD
257 295: g GET 9
258 298: t TUPLE (MARK at 172)
259 299: p PUT 13
260 303: a APPEND
261 304: g GET 13
262 308: a APPEND
263 309: L LONG 5
264 313: a APPEND
265 314: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000266highest protocol among opcodes = 0
267"""
268
Guido van Rossum98297ee2007-11-06 21:34:58 +0000269DATA1 = (
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200270 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c__'
271 b'builtin__\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000272 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
273 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
274 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
275 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200276 b'cq\x04h\x04ccopy_reg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000277 b'nstructor\nq\x05(c__main'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200278 b'__\nC\nq\x06c__builtin__\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000279 b'object\nq\x07Ntq\x08Rq\t}q\n('
280 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
281 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
282)
Tim Peters70b02d72003-02-02 17:26:40 +0000283
Guido van Rossum98297ee2007-11-06 21:34:58 +0000284# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000285DATA1_DIS = """\
286 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000287 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000288 3: ( MARK
289 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000290 6: K BININT1 1
291 8: G BINFLOAT 2.0
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200292 17: c GLOBAL '__builtin__ complex'
293 38: q BINPUT 1
294 40: ( MARK
295 41: G BINFLOAT 3.0
296 50: G BINFLOAT 0.0
297 59: t TUPLE (MARK at 40)
298 60: q BINPUT 2
299 62: R REDUCE
300 63: q BINPUT 3
301 65: K BININT1 1
302 67: J BININT -1
303 72: K BININT1 255
304 74: J BININT -255
305 79: J BININT -256
306 84: M BININT2 65535
307 87: J BININT -65535
308 92: J BININT -65536
309 97: J BININT 2147483647
310 102: J BININT -2147483647
311 107: J BININT -2147483648
312 112: ( MARK
313 113: X BINUNICODE 'abc'
314 121: q BINPUT 4
315 123: h BINGET 4
316 125: c GLOBAL 'copy_reg _reconstructor'
317 150: q BINPUT 5
318 152: ( MARK
319 153: c GLOBAL '__main__ C'
320 165: q BINPUT 6
321 167: c GLOBAL '__builtin__ object'
322 187: q BINPUT 7
323 189: N NONE
324 190: t TUPLE (MARK at 152)
325 191: q BINPUT 8
326 193: R REDUCE
327 194: q BINPUT 9
328 196: } EMPTY_DICT
329 197: q BINPUT 10
330 199: ( MARK
331 200: X BINUNICODE 'foo'
332 208: q BINPUT 11
333 210: K BININT1 1
334 212: X BINUNICODE 'bar'
335 220: q BINPUT 12
336 222: K BININT1 2
337 224: u SETITEMS (MARK at 199)
338 225: b BUILD
339 226: h BINGET 9
340 228: t TUPLE (MARK at 112)
341 229: q BINPUT 13
342 231: h BINGET 13
343 233: K BININT1 5
344 235: e APPENDS (MARK at 3)
345 236: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000346highest protocol among opcodes = 1
347"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000348
Guido van Rossum98297ee2007-11-06 21:34:58 +0000349DATA2 = (
350 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200351 b'__builtin__\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000352 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
353 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
354 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
355 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
356 b'bcq\x04h\x04c__main__\nC\nq\x05'
357 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
358 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
359 b'\nK\x05e.'
360)
Tim Petersfc273752003-03-02 04:54:24 +0000361
Guido van Rossum98297ee2007-11-06 21:34:58 +0000362# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000363DATA2_DIS = """\
364 0: \x80 PROTO 2
365 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000366 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000367 5: ( MARK
368 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000369 8: K BININT1 1
370 10: G BINFLOAT 2.0
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200371 19: c GLOBAL '__builtin__ complex'
372 40: q BINPUT 1
373 42: G BINFLOAT 3.0
374 51: G BINFLOAT 0.0
375 60: \x86 TUPLE2
376 61: q BINPUT 2
377 63: R REDUCE
378 64: q BINPUT 3
379 66: K BININT1 1
380 68: J BININT -1
381 73: K BININT1 255
382 75: J BININT -255
383 80: J BININT -256
384 85: M BININT2 65535
385 88: J BININT -65535
386 93: J BININT -65536
387 98: J BININT 2147483647
388 103: J BININT -2147483647
389 108: J BININT -2147483648
390 113: ( MARK
391 114: X BINUNICODE 'abc'
392 122: q BINPUT 4
393 124: h BINGET 4
394 126: c GLOBAL '__main__ C'
395 138: q BINPUT 5
396 140: ) EMPTY_TUPLE
397 141: \x81 NEWOBJ
398 142: q BINPUT 6
399 144: } EMPTY_DICT
400 145: q BINPUT 7
401 147: ( MARK
402 148: X BINUNICODE 'foo'
403 156: q BINPUT 8
404 158: K BININT1 1
405 160: X BINUNICODE 'bar'
406 168: q BINPUT 9
407 170: K BININT1 2
408 172: u SETITEMS (MARK at 147)
409 173: b BUILD
410 174: h BINGET 6
411 176: t TUPLE (MARK at 113)
412 177: q BINPUT 10
413 179: h BINGET 10
414 181: K BININT1 5
415 183: e APPENDS (MARK at 5)
416 184: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000417highest protocol among opcodes = 2
418"""
419
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300420DATA3 = (
421 b'\x80\x03]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
422 b'builtins\ncomplex\nq\x01G'
423 b'@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00\x86q\x02'
424 b'Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff'
425 b'\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7f'
426 b'J\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00abcq'
427 b'\x04h\x04c__main__\nC\nq\x05)\x81q'
428 b'\x06}q\x07(X\x03\x00\x00\x00barq\x08K\x02X\x03\x00'
429 b'\x00\x00fooq\tK\x01ubh\x06tq\nh\nK\x05'
430 b'e.'
431)
432
433# Disassembly of DATA3
434DATA3_DIS = """\
435 0: \x80 PROTO 3
436 2: ] EMPTY_LIST
437 3: q BINPUT 0
438 5: ( MARK
439 6: K BININT1 0
440 8: K BININT1 1
441 10: G BINFLOAT 2.0
442 19: c GLOBAL 'builtins complex'
443 37: q BINPUT 1
444 39: G BINFLOAT 3.0
445 48: G BINFLOAT 0.0
446 57: \x86 TUPLE2
447 58: q BINPUT 2
448 60: R REDUCE
449 61: q BINPUT 3
450 63: K BININT1 1
451 65: J BININT -1
452 70: K BININT1 255
453 72: J BININT -255
454 77: J BININT -256
455 82: M BININT2 65535
456 85: J BININT -65535
457 90: J BININT -65536
458 95: J BININT 2147483647
459 100: J BININT -2147483647
460 105: J BININT -2147483648
461 110: ( MARK
462 111: X BINUNICODE 'abc'
463 119: q BINPUT 4
464 121: h BINGET 4
465 123: c GLOBAL '__main__ C'
466 135: q BINPUT 5
467 137: ) EMPTY_TUPLE
468 138: \x81 NEWOBJ
469 139: q BINPUT 6
470 141: } EMPTY_DICT
471 142: q BINPUT 7
472 144: ( MARK
473 145: X BINUNICODE 'bar'
474 153: q BINPUT 8
475 155: K BININT1 2
476 157: X BINUNICODE 'foo'
477 165: q BINPUT 9
478 167: K BININT1 1
479 169: u SETITEMS (MARK at 144)
480 170: b BUILD
481 171: h BINGET 6
482 173: t TUPLE (MARK at 110)
483 174: q BINPUT 10
484 176: h BINGET 10
485 178: K BININT1 5
486 180: e APPENDS (MARK at 5)
487 181: . STOP
488highest protocol among opcodes = 2
489"""
490
491DATA4 = (
492 b'\x80\x04\x95\xa8\x00\x00\x00\x00\x00\x00\x00]\x94(K\x00K\x01G@'
493 b'\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x07'
494 b'complex\x94\x93\x94G@\x08\x00\x00\x00\x00\x00\x00G'
495 b'\x00\x00\x00\x00\x00\x00\x00\x00\x86\x94R\x94K\x01J\xff\xff\xff\xffK'
496 b'\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ'
497 b'\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80('
498 b'\x8c\x03abc\x94h\x06\x8c\x08__main__\x94\x8c'
499 b'\x01C\x94\x93\x94)\x81\x94}\x94(\x8c\x03bar\x94K\x02\x8c'
500 b'\x03foo\x94K\x01ubh\nt\x94h\x0eK\x05e.'
501)
502
503# Disassembly of DATA4
504DATA4_DIS = """\
505 0: \x80 PROTO 4
506 2: \x95 FRAME 168
507 11: ] EMPTY_LIST
508 12: \x94 MEMOIZE
509 13: ( MARK
510 14: K BININT1 0
511 16: K BININT1 1
512 18: G BINFLOAT 2.0
513 27: \x8c SHORT_BINUNICODE 'builtins'
514 37: \x94 MEMOIZE
515 38: \x8c SHORT_BINUNICODE 'complex'
516 47: \x94 MEMOIZE
517 48: \x93 STACK_GLOBAL
518 49: \x94 MEMOIZE
519 50: G BINFLOAT 3.0
520 59: G BINFLOAT 0.0
521 68: \x86 TUPLE2
522 69: \x94 MEMOIZE
523 70: R REDUCE
524 71: \x94 MEMOIZE
525 72: K BININT1 1
526 74: J BININT -1
527 79: K BININT1 255
528 81: J BININT -255
529 86: J BININT -256
530 91: M BININT2 65535
531 94: J BININT -65535
532 99: J BININT -65536
533 104: J BININT 2147483647
534 109: J BININT -2147483647
535 114: J BININT -2147483648
536 119: ( MARK
537 120: \x8c SHORT_BINUNICODE 'abc'
538 125: \x94 MEMOIZE
539 126: h BINGET 6
540 128: \x8c SHORT_BINUNICODE '__main__'
541 138: \x94 MEMOIZE
542 139: \x8c SHORT_BINUNICODE 'C'
543 142: \x94 MEMOIZE
544 143: \x93 STACK_GLOBAL
545 144: \x94 MEMOIZE
546 145: ) EMPTY_TUPLE
547 146: \x81 NEWOBJ
548 147: \x94 MEMOIZE
549 148: } EMPTY_DICT
550 149: \x94 MEMOIZE
551 150: ( MARK
552 151: \x8c SHORT_BINUNICODE 'bar'
553 156: \x94 MEMOIZE
554 157: K BININT1 2
555 159: \x8c SHORT_BINUNICODE 'foo'
556 164: \x94 MEMOIZE
557 165: K BININT1 1
558 167: u SETITEMS (MARK at 150)
559 168: b BUILD
560 169: h BINGET 10
561 171: t TUPLE (MARK at 119)
562 172: \x94 MEMOIZE
563 173: h BINGET 14
564 175: K BININT1 5
565 177: e APPENDS (MARK at 13)
566 178: . STOP
567highest protocol among opcodes = 4
568"""
569
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000570# set([1,2]) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300571DATA_SET = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000572
573# xrange(5) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300574DATA_XRANGE = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000575
576# a SimpleCookie() object pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300577DATA_COOKIE = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
578 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
579 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
580 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
581 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
582 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000583
584# set([3]) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300585DATA_SET2 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000586
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100587python2_exceptions_without_args = (
588 ArithmeticError,
589 AssertionError,
590 AttributeError,
591 BaseException,
592 BufferError,
593 BytesWarning,
594 DeprecationWarning,
595 EOFError,
596 EnvironmentError,
597 Exception,
598 FloatingPointError,
599 FutureWarning,
600 GeneratorExit,
601 IOError,
602 ImportError,
603 ImportWarning,
604 IndentationError,
605 IndexError,
606 KeyError,
607 KeyboardInterrupt,
608 LookupError,
609 MemoryError,
610 NameError,
611 NotImplementedError,
612 OSError,
613 OverflowError,
614 PendingDeprecationWarning,
615 ReferenceError,
616 RuntimeError,
617 RuntimeWarning,
618 # StandardError is gone in Python 3, we map it to Exception
619 StopIteration,
620 SyntaxError,
621 SyntaxWarning,
622 SystemError,
623 SystemExit,
624 TabError,
625 TypeError,
626 UnboundLocalError,
627 UnicodeError,
628 UnicodeWarning,
629 UserWarning,
630 ValueError,
631 Warning,
632 ZeroDivisionError,
633)
634
635exception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.'
636
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100637# UnicodeEncodeError object pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300638DATA_UEERR = (b'\x80\x02cexceptions\nUnicodeEncodeError\n'
639 b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01'
640 b'U\x03badq\x03tq\x04Rq\x05.')
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100641
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000642
Jeremy Hylton66426532001-10-15 21:38:56 +0000643def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000644 c = C()
645 c.foo = 1
646 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000647 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000648 # Append some integer test cases at cPickle.c's internal size
649 # cutoffs.
650 uint1max = 0xff
651 uint2max = 0xffff
652 int4max = 0x7fffffff
653 x.extend([1, -1,
654 uint1max, -uint1max, -uint1max-1,
655 uint2max, -uint2max, -uint2max-1,
656 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000657 y = ('abc', 'abc', c, c)
658 x.append(y)
659 x.append(y)
660 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000661 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000662
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100663
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300664class AbstractUnpickleTests(unittest.TestCase):
665 # Subclass must define self.loads.
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +0100666
Jeremy Hylton66426532001-10-15 21:38:56 +0000667 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000668
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100669 def assert_is_copy(self, obj, objcopy, msg=None):
670 """Utility method to verify if two objects are copies of each others.
671 """
672 if msg is None:
673 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
674 self.assertEqual(obj, objcopy, msg=msg)
675 self.assertIs(type(obj), type(objcopy), msg=msg)
676 if hasattr(obj, '__dict__'):
677 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
678 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
679 if hasattr(obj, '__slots__'):
680 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
681 for slot in obj.__slots__:
682 self.assertEqual(
683 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
684 self.assertEqual(getattr(obj, slot, None),
685 getattr(objcopy, slot, None), msg=msg)
686
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200687 def check_unpickling_error(self, errors, data):
688 with self.subTest(data=data), \
689 self.assertRaises(errors):
690 try:
691 self.loads(data)
692 except BaseException as exc:
693 if support.verbose > 1:
694 print('%-32r - %s: %s' %
695 (data, exc.__class__.__name__, exc))
696 raise
697
Guido van Rossum98297ee2007-11-06 21:34:58 +0000698 def test_load_from_data0(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100699 self.assert_is_copy(self._testdata, self.loads(DATA0))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000700
701 def test_load_from_data1(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100702 self.assert_is_copy(self._testdata, self.loads(DATA1))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000703
704 def test_load_from_data2(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100705 self.assert_is_copy(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000706
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300707 def test_load_from_data3(self):
708 self.assert_is_copy(self._testdata, self.loads(DATA3))
709
710 def test_load_from_data4(self):
711 self.assert_is_copy(self._testdata, self.loads(DATA4))
712
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000713 def test_load_classic_instance(self):
714 # See issue5180. Test loading 2.x pickles that
715 # contain an instance of old style class.
716 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
717 xname = X.__name__.encode('ascii')
718 # Protocol 0 (text mode pickle):
719 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200720 0: ( MARK
721 1: i INST '__main__ X' (MARK at 0)
722 13: p PUT 0
723 16: ( MARK
724 17: d DICT (MARK at 16)
725 18: p PUT 1
726 21: b BUILD
727 22: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000728 """
729 pickle0 = (b"(i__main__\n"
730 b"X\n"
731 b"p0\n"
732 b"(dp1\nb.").replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100733 self.assert_is_copy(X(*args), self.loads(pickle0))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000734
735 # Protocol 1 (binary mode pickle)
736 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200737 0: ( MARK
738 1: c GLOBAL '__main__ X'
739 13: q BINPUT 0
740 15: o OBJ (MARK at 0)
741 16: q BINPUT 1
742 18: } EMPTY_DICT
743 19: q BINPUT 2
744 21: b BUILD
745 22: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000746 """
747 pickle1 = (b'(c__main__\n'
748 b'X\n'
749 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100750 self.assert_is_copy(X(*args), self.loads(pickle1))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000751
752 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
753 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200754 0: \x80 PROTO 2
755 2: ( MARK
756 3: c GLOBAL '__main__ X'
757 15: q BINPUT 0
758 17: o OBJ (MARK at 2)
759 18: q BINPUT 1
760 20: } EMPTY_DICT
761 21: q BINPUT 2
762 23: b BUILD
763 24: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000764 """
765 pickle2 = (b'\x80\x02(c__main__\n'
766 b'X\n'
767 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100768 self.assert_is_copy(X(*args), self.loads(pickle2))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000769
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300770 def test_maxint64(self):
771 maxint64 = (1 << 63) - 1
772 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
773 got = self.loads(data)
774 self.assert_is_copy(maxint64, got)
775
776 # Try too with a bogus literal.
777 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200778 self.check_unpickling_error(ValueError, data)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300779
780 def test_unpickle_from_2x(self):
781 # Unpickle non-trivial data from Python 2.x.
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300782 loaded = self.loads(DATA_SET)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300783 self.assertEqual(loaded, set([1, 2]))
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300784 loaded = self.loads(DATA_XRANGE)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300785 self.assertEqual(type(loaded), type(range(0)))
786 self.assertEqual(list(loaded), list(range(5)))
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300787 loaded = self.loads(DATA_COOKIE)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300788 self.assertEqual(type(loaded), SimpleCookie)
789 self.assertEqual(list(loaded.keys()), ["key"])
790 self.assertEqual(loaded["key"].value, "value")
791
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300792 # Exception objects without arguments pickled from 2.x with protocol 2
793 for exc in python2_exceptions_without_args:
794 data = exception_pickle.replace(b'?', exc.__name__.encode("ascii"))
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300795 loaded = self.loads(data)
796 self.assertIs(type(loaded), exc)
797
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300798 # StandardError is mapped to Exception, test that separately
799 loaded = self.loads(exception_pickle.replace(b'?', b'StandardError'))
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300800 self.assertIs(type(loaded), Exception)
801
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300802 loaded = self.loads(DATA_UEERR)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300803 self.assertIs(type(loaded), UnicodeEncodeError)
804 self.assertEqual(loaded.object, "foo")
805 self.assertEqual(loaded.encoding, "ascii")
806 self.assertEqual(loaded.start, 0)
807 self.assertEqual(loaded.end, 1)
808 self.assertEqual(loaded.reason, "bad")
809
810 def test_load_python2_str_as_bytes(self):
811 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
812 self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
813 encoding="bytes"), b'a\x00\xa0')
814 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
815 self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
816 encoding="bytes"), b'a\x00\xa0')
817 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
818 self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
819 encoding="bytes"), b'a\x00\xa0')
820
821 def test_load_python2_unicode_as_str(self):
822 # From Python 2: pickle.dumps(u'π', protocol=0)
823 self.assertEqual(self.loads(b'V\\u03c0\n.',
824 encoding='bytes'), 'π')
825 # From Python 2: pickle.dumps(u'π', protocol=1)
826 self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
827 encoding="bytes"), 'π')
828 # From Python 2: pickle.dumps(u'π', protocol=2)
829 self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
830 encoding="bytes"), 'π')
831
832 def test_load_long_python2_str_as_bytes(self):
833 # From Python 2: pickle.dumps('x' * 300, protocol=1)
834 self.assertEqual(self.loads(pickle.BINSTRING +
835 struct.pack("<I", 300) +
836 b'x' * 300 + pickle.STOP,
837 encoding='bytes'), b'x' * 300)
838
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300839 def test_constants(self):
840 self.assertIsNone(self.loads(b'N.'))
841 self.assertIs(self.loads(b'\x88.'), True)
842 self.assertIs(self.loads(b'\x89.'), False)
843 self.assertIs(self.loads(b'I01\n.'), True)
844 self.assertIs(self.loads(b'I00\n.'), False)
845
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300846 def test_empty_bytestring(self):
847 # issue 11286
848 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
849 self.assertEqual(empty, '')
850
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300851 def test_short_binbytes(self):
852 dumped = b'\x80\x03C\x04\xe2\x82\xac\x00.'
853 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
854
855 def test_binbytes(self):
856 dumped = b'\x80\x03B\x04\x00\x00\x00\xe2\x82\xac\x00.'
857 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
858
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300859 @requires_32b
860 def test_negative_32b_binbytes(self):
861 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
862 dumped = b'\x80\x03B\xff\xff\xff\xffxyzq\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200863 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
864 dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300865
866 @requires_32b
867 def test_negative_32b_binunicode(self):
868 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
869 dumped = b'\x80\x03X\xff\xff\xff\xffxyzq\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200870 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
871 dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300872
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300873 def test_short_binunicode(self):
874 dumped = b'\x80\x04\x8c\x04\xe2\x82\xac\x00.'
875 self.assertEqual(self.loads(dumped), '\u20ac\x00')
876
877 def test_misc_get(self):
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200878 self.check_unpickling_error(KeyError, b'g0\np0')
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300879 self.assert_is_copy([(100,), (100,)],
880 self.loads(b'((Kdtp0\nh\x00l.))'))
881
Serhiy Storchakae0606192015-09-29 22:10:07 +0300882 def test_binbytes8(self):
883 dumped = b'\x80\x04\x8e\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
884 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
885
886 def test_binunicode8(self):
887 dumped = b'\x80\x04\x8d\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
888 self.assertEqual(self.loads(dumped), '\u20ac\x00')
889
890 @requires_32b
891 def test_large_32b_binbytes8(self):
892 dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200893 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
894 dumped)
Serhiy Storchakae0606192015-09-29 22:10:07 +0300895
896 @requires_32b
897 def test_large_32b_binunicode8(self):
898 dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200899 self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
900 dumped)
Serhiy Storchakae0606192015-09-29 22:10:07 +0300901
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300902 def test_get(self):
903 pickled = b'((lp100000\ng100000\nt.'
904 unpickled = self.loads(pickled)
905 self.assertEqual(unpickled, ([],)*2)
906 self.assertIs(unpickled[0], unpickled[1])
907
908 def test_binget(self):
909 pickled = b'(]q\xffh\xfft.'
910 unpickled = self.loads(pickled)
911 self.assertEqual(unpickled, ([],)*2)
912 self.assertIs(unpickled[0], unpickled[1])
913
914 def test_long_binget(self):
915 pickled = b'(]r\x00\x00\x01\x00j\x00\x00\x01\x00t.'
916 unpickled = self.loads(pickled)
917 self.assertEqual(unpickled, ([],)*2)
918 self.assertIs(unpickled[0], unpickled[1])
919
920 def test_dup(self):
921 pickled = b'((l2t.'
922 unpickled = self.loads(pickled)
923 self.assertEqual(unpickled, ([],)*2)
924 self.assertIs(unpickled[0], unpickled[1])
925
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300926 def test_negative_put(self):
927 # Issue #12847
928 dumped = b'Va\np-1\n.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200929 self.check_unpickling_error(ValueError, dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300930
931 @requires_32b
932 def test_negative_32b_binput(self):
933 # Issue #12847
934 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200935 self.check_unpickling_error(ValueError, dumped)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300936
937 def test_badly_escaped_string(self):
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200938 self.check_unpickling_error(ValueError, b"S'\\'\n.")
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300939
940 def test_badly_quoted_string(self):
941 # Issue #17710
942 badpickles = [b"S'\n.",
943 b'S"\n.',
944 b'S\' \n.',
945 b'S" \n.',
946 b'S\'"\n.',
947 b'S"\'\n.',
948 b"S' ' \n.",
949 b'S" " \n.',
950 b"S ''\n.",
951 b'S ""\n.',
952 b'S \n.',
953 b'S\n.',
954 b'S.']
955 for p in badpickles:
Serhiy Storchaka7279bef2015-11-29 13:12:10 +0200956 self.check_unpickling_error(pickle.UnpicklingError, p)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300957
958 def test_correctly_quoted_string(self):
959 goodpickles = [(b"S''\n.", ''),
960 (b'S""\n.', ''),
961 (b'S"\\n"\n.', '\n'),
962 (b"S'\\n'\n.", '\n')]
963 for p, expected in goodpickles:
964 self.assertEqual(self.loads(p), expected)
965
966 def test_frame_readline(self):
967 pickled = b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00I42\n.'
968 # 0: \x80 PROTO 4
969 # 2: \x95 FRAME 5
970 # 11: I INT 42
971 # 15: . STOP
972 self.assertEqual(self.loads(pickled), 42)
973
974 def test_compat_unpickle(self):
975 # xrange(1, 7)
976 pickled = b'\x80\x02c__builtin__\nxrange\nK\x01K\x07K\x01\x87R.'
977 unpickled = self.loads(pickled)
978 self.assertIs(type(unpickled), range)
979 self.assertEqual(unpickled, range(1, 7))
980 self.assertEqual(list(unpickled), [1, 2, 3, 4, 5, 6])
981 # reduce
982 pickled = b'\x80\x02c__builtin__\nreduce\n.'
983 self.assertIs(self.loads(pickled), functools.reduce)
984 # whichdb.whichdb
985 pickled = b'\x80\x02cwhichdb\nwhichdb\n.'
986 self.assertIs(self.loads(pickled), dbm.whichdb)
987 # Exception(), StandardError()
988 for name in (b'Exception', b'StandardError'):
989 pickled = (b'\x80\x02cexceptions\n' + name + b'\nU\x03ugh\x85R.')
990 unpickled = self.loads(pickled)
991 self.assertIs(type(unpickled), Exception)
992 self.assertEqual(str(unpickled), 'ugh')
993 # UserDict.UserDict({1: 2}), UserDict.IterableUserDict({1: 2})
994 for name in (b'UserDict', b'IterableUserDict'):
995 pickled = (b'\x80\x02(cUserDict\n' + name +
996 b'\no}U\x04data}K\x01K\x02ssb.')
997 unpickled = self.loads(pickled)
998 self.assertIs(type(unpickled), collections.UserDict)
999 self.assertEqual(unpickled, collections.UserDict({1: 2}))
1000
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001001 def test_bad_stack(self):
1002 badpickles = [
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001003 b'.', # STOP
1004 b'0', # POP
1005 b'1', # POP_MARK
1006 b'2', # DUP
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001007 b'(2',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001008 b'R', # REDUCE
1009 b')R',
1010 b'a', # APPEND
1011 b'Na',
1012 b'b', # BUILD
1013 b'Nb',
1014 b'd', # DICT
1015 b'e', # APPENDS
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001016 b'(e',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001017 b'ibuiltins\nlist\n', # INST
1018 b'l', # LIST
1019 b'o', # OBJ
1020 b'(o',
1021 b'p1\n', # PUT
1022 b'q\x00', # BINPUT
1023 b'r\x00\x00\x00\x00', # LONG_BINPUT
1024 b's', # SETITEM
1025 b'Ns',
1026 b'NNs',
1027 b't', # TUPLE
1028 b'u', # SETITEMS
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001029 b'(u',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001030 b'}(Nu',
1031 b'\x81', # NEWOBJ
1032 b')\x81',
1033 b'\x85', # TUPLE1
1034 b'\x86', # TUPLE2
1035 b'N\x86',
1036 b'\x87', # TUPLE3
1037 b'N\x87',
1038 b'NN\x87',
1039 b'\x90', # ADDITEMS
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001040 b'(\x90',
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001041 b'\x91', # FROZENSET
1042 b'\x92', # NEWOBJ_EX
1043 b')}\x92',
1044 b'\x93', # STACK_GLOBAL
1045 b'Vlist\n\x93',
1046 b'\x94', # MEMOIZE
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001047 ]
1048 for p in badpickles:
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001049 self.check_unpickling_error(self.bad_stack_errors, p)
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001050
1051 def test_bad_mark(self):
1052 badpickles = [
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001053 b'N(.', # STOP
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001054 b'N(2', # DUP
1055 b'cbuiltins\nlist\n)(R', # REDUCE
1056 b'cbuiltins\nlist\n()R',
1057 b']N(a', # APPEND
1058 # BUILD
1059 b'cbuiltins\nValueError\n)R}(b',
1060 b'cbuiltins\nValueError\n)R(}b',
1061 b'(Nd', # DICT
1062 b'N(p1\n', # PUT
1063 b'N(q\x00', # BINPUT
1064 b'N(r\x00\x00\x00\x00', # LONG_BINPUT
1065 b'}NN(s', # SETITEM
1066 b'}N(Ns',
1067 b'}(NNs',
1068 b'}((u', # SETITEMS
1069 b'cbuiltins\nlist\n)(\x81', # NEWOBJ
1070 b'cbuiltins\nlist\n()\x81',
1071 b'N(\x85', # TUPLE1
1072 b'NN(\x86', # TUPLE2
1073 b'N(N\x86',
1074 b'NNN(\x87', # TUPLE3
1075 b'NN(N\x87',
1076 b'N(NN\x87',
1077 b']((\x90', # ADDITEMS
1078 # NEWOBJ_EX
1079 b'cbuiltins\nlist\n)}(\x92',
1080 b'cbuiltins\nlist\n)(}\x92',
1081 b'cbuiltins\nlist\n()}\x92',
1082 # STACK_GLOBAL
1083 b'Vbuiltins\n(Vlist\n\x93',
1084 b'Vbuiltins\nVlist\n(\x93',
1085 b'N(\x94', # MEMOIZE
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001086 ]
1087 for p in badpickles:
Serhiy Storchaka59fb6342015-12-06 22:01:35 +02001088 self.check_unpickling_error(self.bad_stack_errors, p)
Serhiy Storchaka7279bef2015-11-29 13:12:10 +02001089
1090 def test_truncated_data(self):
1091 self.check_unpickling_error(EOFError, b'')
1092 self.check_unpickling_error(EOFError, b'N')
1093 badpickles = [
1094 b'B', # BINBYTES
1095 b'B\x03\x00\x00',
1096 b'B\x03\x00\x00\x00',
1097 b'B\x03\x00\x00\x00ab',
1098 b'C', # SHORT_BINBYTES
1099 b'C\x03',
1100 b'C\x03ab',
1101 b'F', # FLOAT
1102 b'F0.0',
1103 b'F0.00',
1104 b'G', # BINFLOAT
1105 b'G\x00\x00\x00\x00\x00\x00\x00',
1106 b'I', # INT
1107 b'I0',
1108 b'J', # BININT
1109 b'J\x00\x00\x00',
1110 b'K', # BININT1
1111 b'L', # LONG
1112 b'L0',
1113 b'L10',
1114 b'L0L',
1115 b'L10L',
1116 b'M', # BININT2
1117 b'M\x00',
1118 # b'P', # PERSID
1119 # b'Pabc',
1120 b'S', # STRING
1121 b"S'abc'",
1122 b'T', # BINSTRING
1123 b'T\x03\x00\x00',
1124 b'T\x03\x00\x00\x00',
1125 b'T\x03\x00\x00\x00ab',
1126 b'U', # SHORT_BINSTRING
1127 b'U\x03',
1128 b'U\x03ab',
1129 b'V', # UNICODE
1130 b'Vabc',
1131 b'X', # BINUNICODE
1132 b'X\x03\x00\x00',
1133 b'X\x03\x00\x00\x00',
1134 b'X\x03\x00\x00\x00ab',
1135 b'(c', # GLOBAL
1136 b'(cbuiltins',
1137 b'(cbuiltins\n',
1138 b'(cbuiltins\nlist',
1139 b'Ng', # GET
1140 b'Ng0',
1141 b'(i', # INST
1142 b'(ibuiltins',
1143 b'(ibuiltins\n',
1144 b'(ibuiltins\nlist',
1145 b'Nh', # BINGET
1146 b'Nj', # LONG_BINGET
1147 b'Nj\x00\x00\x00',
1148 b'Np', # PUT
1149 b'Np0',
1150 b'Nq', # BINPUT
1151 b'Nr', # LONG_BINPUT
1152 b'Nr\x00\x00\x00',
1153 b'\x80', # PROTO
1154 b'\x82', # EXT1
1155 b'\x83', # EXT2
1156 b'\x84\x01',
1157 b'\x84', # EXT4
1158 b'\x84\x01\x00\x00',
1159 b'\x8a', # LONG1
1160 b'\x8b', # LONG4
1161 b'\x8b\x00\x00\x00',
1162 b'\x8c', # SHORT_BINUNICODE
1163 b'\x8c\x03',
1164 b'\x8c\x03ab',
1165 b'\x8d', # BINUNICODE8
1166 b'\x8d\x03\x00\x00\x00\x00\x00\x00',
1167 b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00',
1168 b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00ab',
1169 b'\x8e', # BINBYTES8
1170 b'\x8e\x03\x00\x00\x00\x00\x00\x00',
1171 b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00',
1172 b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00ab',
1173 b'\x95', # FRAME
1174 b'\x95\x02\x00\x00\x00\x00\x00\x00',
1175 b'\x95\x02\x00\x00\x00\x00\x00\x00\x00',
1176 b'\x95\x02\x00\x00\x00\x00\x00\x00\x00N',
1177 ]
1178 for p in badpickles:
1179 self.check_unpickling_error(self.truncated_errors, p)
Serhiy Storchakae9b30742015-11-23 15:17:43 +02001180
tjb9004371c0a2019-02-18 23:30:51 +08001181 @reap_threads
1182 def test_unpickle_module_race(self):
1183 # https://bugs.python.org/issue34572
1184 locker_module = dedent("""
1185 import threading
1186 barrier = threading.Barrier(2)
1187 """)
1188 locking_import_module = dedent("""
1189 import locker
1190 locker.barrier.wait()
1191 class ToBeUnpickled(object):
1192 pass
1193 """)
1194
1195 os.mkdir(TESTFN)
1196 self.addCleanup(shutil.rmtree, TESTFN)
1197 sys.path.insert(0, TESTFN)
1198 self.addCleanup(sys.path.remove, TESTFN)
1199 with open(os.path.join(TESTFN, "locker.py"), "wb") as f:
1200 f.write(locker_module.encode('utf-8'))
1201 with open(os.path.join(TESTFN, "locking_import.py"), "wb") as f:
1202 f.write(locking_import_module.encode('utf-8'))
1203 self.addCleanup(forget, "locker")
1204 self.addCleanup(forget, "locking_import")
1205
1206 import locker
1207
1208 pickle_bytes = (
1209 b'\x80\x03clocking_import\nToBeUnpickled\nq\x00)\x81q\x01.')
1210
1211 # Then try to unpickle two of these simultaneously
1212 # One of them will cause the module import, and we want it to block
1213 # until the other one either:
1214 # - fails (before the patch for this issue)
1215 # - blocks on the import lock for the module, as it should
1216 results = []
1217 barrier = threading.Barrier(3)
1218 def t():
1219 # This ensures the threads have all started
1220 # presumably barrier release is faster than thread startup
1221 barrier.wait()
1222 results.append(pickle.loads(pickle_bytes))
1223
1224 t1 = threading.Thread(target=t)
1225 t2 = threading.Thread(target=t)
1226 t1.start()
1227 t2.start()
1228
1229 barrier.wait()
1230 # could have delay here
1231 locker.barrier.wait()
1232
1233 t1.join()
1234 t2.join()
1235
1236 from locking_import import ToBeUnpickled
1237 self.assertEqual(
1238 [type(x) for x in results],
1239 [ToBeUnpickled] * 2)
1240
1241
Serhiy Storchakac6b54b42015-09-29 15:33:24 +03001242
1243class AbstractPickleTests(unittest.TestCase):
1244 # Subclass must define self.dumps, self.loads.
1245
1246 optimized = False
1247
1248 _testdata = AbstractUnpickleTests._testdata
1249
1250 def setUp(self):
1251 pass
1252
1253 assert_is_copy = AbstractUnpickleTests.assert_is_copy
1254
1255 def test_misc(self):
1256 # test various datatypes not tested by testdata
1257 for proto in protocols:
1258 x = myint(4)
1259 s = self.dumps(x, proto)
1260 y = self.loads(s)
1261 self.assert_is_copy(x, y)
1262
1263 x = (1, ())
1264 s = self.dumps(x, proto)
1265 y = self.loads(s)
1266 self.assert_is_copy(x, y)
1267
1268 x = initarg(1, x)
1269 s = self.dumps(x, proto)
1270 y = self.loads(s)
1271 self.assert_is_copy(x, y)
1272
1273 # XXX test __reduce__ protocol?
1274
1275 def test_roundtrip_equality(self):
1276 expected = self._testdata
1277 for proto in protocols:
1278 s = self.dumps(expected, proto)
1279 got = self.loads(s)
1280 self.assert_is_copy(expected, got)
1281
Tim Peters70b02d72003-02-02 17:26:40 +00001282 # There are gratuitous differences between pickles produced by
1283 # pickle and cPickle, largely because cPickle starts PUT indices at
1284 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
1285 # there's a comment with an exclamation point there whose meaning
1286 # is a mystery. cPickle also suppresses PUT for objects with a refcount
1287 # of 1.
1288 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +00001289 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +00001290 from pickletools import dis
1291
1292 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
1293 s = self.dumps(self._testdata, proto)
1294 filelike = StringIO()
1295 dis(s, out=filelike)
1296 got = filelike.getvalue()
1297 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +00001298
1299 def test_recursive_list(self):
1300 l = []
1301 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +00001302 for proto in protocols:
1303 s = self.dumps(l, proto)
1304 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001305 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001306 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001307 self.assertIs(x[0], x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001308
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001309 def test_recursive_tuple_and_list(self):
Collin Winter8ca69de2009-05-26 16:53:41 +00001310 t = ([],)
1311 t[0].append(t)
1312 for proto in protocols:
1313 s = self.dumps(t, proto)
1314 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001315 self.assertIsInstance(x, tuple)
Collin Winter8ca69de2009-05-26 16:53:41 +00001316 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001317 self.assertIsInstance(x[0], list)
Collin Winter8ca69de2009-05-26 16:53:41 +00001318 self.assertEqual(len(x[0]), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001319 self.assertIs(x[0][0], x)
Collin Winter8ca69de2009-05-26 16:53:41 +00001320
Jeremy Hylton66426532001-10-15 21:38:56 +00001321 def test_recursive_dict(self):
1322 d = {}
1323 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +00001324 for proto in protocols:
1325 s = self.dumps(d, proto)
1326 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001327 self.assertIsInstance(x, dict)
Guido van Rossumcc2b0162007-02-11 06:12:03 +00001328 self.assertEqual(list(x.keys()), [1])
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001329 self.assertIs(x[1], x)
1330
1331 def test_recursive_dict_key(self):
1332 d = {}
1333 k = K(d)
1334 d[k] = 1
1335 for proto in protocols:
1336 s = self.dumps(d, proto)
1337 x = self.loads(s)
1338 self.assertIsInstance(x, dict)
1339 self.assertEqual(len(x.keys()), 1)
1340 self.assertIsInstance(list(x.keys())[0], K)
1341 self.assertIs(list(x.keys())[0].value, x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001342
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001343 def test_recursive_set(self):
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001344 y = set()
1345 k = K(y)
1346 y.add(k)
1347 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001348 s = self.dumps(y, proto)
1349 x = self.loads(s)
1350 self.assertIsInstance(x, set)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001351 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001352 self.assertIsInstance(list(x)[0], K)
1353 self.assertIs(list(x)[0].value, x)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001354
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001355 def test_recursive_list_subclass(self):
1356 y = MyList()
1357 y.append(y)
1358 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001359 s = self.dumps(y, proto)
1360 x = self.loads(s)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001361 self.assertIsInstance(x, MyList)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001362 self.assertEqual(len(x), 1)
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001363 self.assertIs(x[0], x)
1364
1365 def test_recursive_dict_subclass(self):
1366 d = MyDict()
1367 d[1] = d
1368 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1369 s = self.dumps(d, proto)
1370 x = self.loads(s)
1371 self.assertIsInstance(x, MyDict)
1372 self.assertEqual(list(x.keys()), [1])
1373 self.assertIs(x[1], x)
1374
1375 def test_recursive_dict_subclass_key(self):
1376 d = MyDict()
1377 k = K(d)
1378 d[k] = 1
1379 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1380 s = self.dumps(d, proto)
1381 x = self.loads(s)
1382 self.assertIsInstance(x, MyDict)
1383 self.assertEqual(len(list(x.keys())), 1)
1384 self.assertIsInstance(list(x.keys())[0], K)
1385 self.assertIs(list(x.keys())[0].value, x)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001386
Jeremy Hylton66426532001-10-15 21:38:56 +00001387 def test_recursive_inst(self):
1388 i = C()
1389 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +00001390 for proto in protocols:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001391 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +00001392 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001393 self.assertIsInstance(x, C)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001394 self.assertEqual(dir(x), dir(i))
Ezio Melottiaaef3442013-03-04 15:17:56 +02001395 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001396
1397 def test_recursive_multi(self):
1398 l = []
1399 d = {1:l}
1400 i = C()
1401 i.attr = d
1402 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +00001403 for proto in protocols:
1404 s = self.dumps(l, proto)
1405 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001406 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001407 self.assertEqual(len(x), 1)
1408 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +00001409 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001410 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001411
Serhiy Storchaka608c2132015-11-07 11:16:10 +02001412 def check_recursive_collection_and_inst(self, factory):
1413 h = H()
1414 y = factory([h])
1415 h.attr = y
1416 for proto in protocols:
1417 s = self.dumps(y, proto)
1418 x = self.loads(s)
1419 self.assertIsInstance(x, type(y))
1420 self.assertEqual(len(x), 1)
1421 self.assertIsInstance(list(x)[0], H)
1422 self.assertIs(list(x)[0].attr, x)
1423
1424 def test_recursive_list_and_inst(self):
1425 self.check_recursive_collection_and_inst(list)
1426
1427 def test_recursive_tuple_and_inst(self):
1428 self.check_recursive_collection_and_inst(tuple)
1429
1430 def test_recursive_dict_and_inst(self):
1431 self.check_recursive_collection_and_inst(dict.fromkeys)
1432
1433 def test_recursive_set_and_inst(self):
1434 self.check_recursive_collection_and_inst(set)
1435
1436 def test_recursive_frozenset_and_inst(self):
1437 self.check_recursive_collection_and_inst(frozenset)
1438
1439 def test_recursive_list_subclass_and_inst(self):
1440 self.check_recursive_collection_and_inst(MyList)
1441
1442 def test_recursive_tuple_subclass_and_inst(self):
1443 self.check_recursive_collection_and_inst(MyTuple)
1444
1445 def test_recursive_dict_subclass_and_inst(self):
1446 self.check_recursive_collection_and_inst(MyDict.fromkeys)
1447
1448 def test_recursive_set_subclass_and_inst(self):
1449 self.check_recursive_collection_and_inst(MySet)
1450
1451 def test_recursive_frozenset_subclass_and_inst(self):
1452 self.check_recursive_collection_and_inst(MyFrozenSet)
1453
Walter Dörwald9b775532007-06-08 14:30:53 +00001454 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +00001455 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +00001456 '<\\>', '<\\\U00012345>',
1457 # surrogates
1458 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +00001459 for proto in protocols:
1460 for u in endcases:
1461 p = self.dumps(u, proto)
1462 u2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001463 self.assert_is_copy(u, u2)
Tim Peterse089c682001-04-10 03:41:41 +00001464
Alexandre Vassalotti554d8782008-12-27 07:32:41 +00001465 def test_unicode_high_plane(self):
1466 t = '\U00012345'
1467 for proto in protocols:
1468 p = self.dumps(t, proto)
1469 t2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001470 self.assert_is_copy(t, t2)
Alexandre Vassalotti554d8782008-12-27 07:32:41 +00001471
Guido van Rossumf4169812008-03-17 22:56:06 +00001472 def test_bytes(self):
1473 for proto in protocols:
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001474 for s in b'', b'xyz', b'xyz'*100:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001475 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001476 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001477 for s in [bytes([i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001478 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001479 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001480 for s in [bytes([i, i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001481 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001482 self.assert_is_copy(s, self.loads(p))
Guido van Rossumf4169812008-03-17 22:56:06 +00001483
Jeremy Hylton66426532001-10-15 21:38:56 +00001484 def test_ints(self):
Tim Petersee1a53c2003-02-02 02:57:53 +00001485 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +00001486 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +00001487 while n:
1488 for expected in (-n, n):
1489 s = self.dumps(expected, proto)
1490 n2 = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001491 self.assert_is_copy(expected, n2)
Tim Petersee1a53c2003-02-02 02:57:53 +00001492 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +00001493
Tim Petersee1a53c2003-02-02 02:57:53 +00001494 def test_long(self):
1495 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +00001496 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +00001497 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +00001498 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +00001499 for npos in nbase-1, nbase, nbase+1:
1500 for n in npos, -npos:
1501 pickle = self.dumps(n, proto)
1502 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001503 self.assert_is_copy(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +00001504 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
1505 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +00001506 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +00001507 nbase += nbase << 1000000
1508 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +00001509 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +00001510 got = self.loads(p)
Antoine Pitroud5df1942013-11-23 21:20:49 +01001511 # assert_is_copy is very expensive here as it precomputes
1512 # a failure message by computing the repr() of n and got,
1513 # we just do the check ourselves.
1514 self.assertIs(type(got), int)
1515 self.assertEqual(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +00001516
Mark Dickinsoncddcf442009-01-24 21:46:33 +00001517 def test_float(self):
1518 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
1519 3.14, 263.44582062374053, 6.022e23, 1e30]
1520 test_values = test_values + [-x for x in test_values]
1521 for proto in protocols:
1522 for value in test_values:
1523 pickle = self.dumps(value, proto)
1524 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001525 self.assert_is_copy(value, got)
Mark Dickinsoncddcf442009-01-24 21:46:33 +00001526
Thomas Wouters477c8d52006-05-27 19:21:47 +00001527 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
1528 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +00001529 # make sure that floats are formatted locale independent with proto 0
1530 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001531
Jeremy Hylton66426532001-10-15 21:38:56 +00001532 def test_reduce(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +01001533 for proto in protocols:
1534 inst = AAA()
1535 dumped = self.dumps(inst, proto)
1536 loaded = self.loads(dumped)
1537 self.assertEqual(loaded, REDUCE_A)
Jeremy Hylton66426532001-10-15 21:38:56 +00001538
1539 def test_getinitargs(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +01001540 for proto in protocols:
1541 inst = initarg(1, 2)
1542 dumped = self.dumps(inst, proto)
1543 loaded = self.loads(dumped)
1544 self.assert_is_copy(inst, loaded)
Jeremy Hylton66426532001-10-15 21:38:56 +00001545
Guido van Rossum04a86612001-12-19 16:58:54 +00001546 def test_metaclass(self):
1547 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +00001548 for proto in protocols:
1549 s = self.dumps(a, proto)
1550 b = self.loads(s)
1551 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +00001552
Antoine Pitrouffd41d92011-10-04 09:23:04 +02001553 def test_dynamic_class(self):
1554 a = create_dynamic_class("my_dynamic_class", (object,))
1555 copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
1556 for proto in protocols:
1557 s = self.dumps(a, proto)
1558 b = self.loads(s)
1559 self.assertEqual(a, b)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001560 self.assertIs(type(a), type(b))
Antoine Pitrouffd41d92011-10-04 09:23:04 +02001561
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001562 def test_structseq(self):
1563 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +00001564 import os
Tim Peters70b02d72003-02-02 17:26:40 +00001565
1566 t = time.localtime()
1567 for proto in protocols:
1568 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +00001569 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001570 self.assert_is_copy(t, u)
Anthony Sottile8377cd42019-02-25 14:32:27 -08001571 t = os.stat(os.curdir)
1572 s = self.dumps(t, proto)
1573 u = self.loads(s)
1574 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +00001575 if hasattr(os, "statvfs"):
1576 t = os.statvfs(os.curdir)
1577 s = self.dumps(t, proto)
1578 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001579 self.assert_is_copy(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001580
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001581 def test_ellipsis(self):
1582 for proto in protocols:
1583 s = self.dumps(..., proto)
1584 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001585 self.assertIs(..., u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001586
1587 def test_notimplemented(self):
1588 for proto in protocols:
1589 s = self.dumps(NotImplemented, proto)
1590 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001591 self.assertIs(NotImplemented, u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001592
Alexandre Vassalotti19b6fa62013-11-30 16:06:39 -08001593 def test_singleton_types(self):
1594 # Issue #6477: Test that types of built-in singletons can be pickled.
1595 singletons = [None, ..., NotImplemented]
1596 for singleton in singletons:
1597 for proto in protocols:
1598 s = self.dumps(type(singleton), proto)
1599 u = self.loads(s)
1600 self.assertIs(type(singleton), u)
1601
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001602 # Tests for protocol 2
1603
Tim Peters4190fb82003-02-02 16:09:05 +00001604 def test_proto(self):
Tim Peters4190fb82003-02-02 16:09:05 +00001605 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001606 pickled = self.dumps(None, proto)
Tim Peters4190fb82003-02-02 16:09:05 +00001607 if proto >= 2:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001608 proto_header = pickle.PROTO + bytes([proto])
1609 self.assertTrue(pickled.startswith(proto_header))
1610 else:
1611 self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)
Tim Peters4190fb82003-02-02 16:09:05 +00001612
1613 oob = protocols[-1] + 1 # a future protocol
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001614 build_none = pickle.NONE + pickle.STOP
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001615 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +00001616 try:
1617 self.loads(badpickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001618 except ValueError as err:
1619 self.assertIn("unsupported pickle protocol", str(err))
Tim Peters4190fb82003-02-02 16:09:05 +00001620 else:
1621 self.fail("expected bad protocol number to raise ValueError")
1622
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001623 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +00001624 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +00001625 for proto in protocols:
1626 s = self.dumps(x, proto)
1627 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001628 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001629 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001630
1631 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +00001632 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +00001633 for proto in protocols:
1634 s = self.dumps(x, proto)
1635 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001636 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001637 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001638
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001639 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +00001640 # Map (proto, len(tuple)) to expected opcode.
1641 expected_opcode = {(0, 0): pickle.TUPLE,
1642 (0, 1): pickle.TUPLE,
1643 (0, 2): pickle.TUPLE,
1644 (0, 3): pickle.TUPLE,
1645 (0, 4): pickle.TUPLE,
1646
1647 (1, 0): pickle.EMPTY_TUPLE,
1648 (1, 1): pickle.TUPLE,
1649 (1, 2): pickle.TUPLE,
1650 (1, 3): pickle.TUPLE,
1651 (1, 4): pickle.TUPLE,
1652
1653 (2, 0): pickle.EMPTY_TUPLE,
1654 (2, 1): pickle.TUPLE1,
1655 (2, 2): pickle.TUPLE2,
1656 (2, 3): pickle.TUPLE3,
1657 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001658
1659 (3, 0): pickle.EMPTY_TUPLE,
1660 (3, 1): pickle.TUPLE1,
1661 (3, 2): pickle.TUPLE2,
1662 (3, 3): pickle.TUPLE3,
1663 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +00001664 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001665 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +00001666 b = (1,)
1667 c = (1, 2)
1668 d = (1, 2, 3)
1669 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +00001670 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001671 for x in a, b, c, d, e:
1672 s = self.dumps(x, proto)
1673 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001674 self.assert_is_copy(x, y)
1675 expected = expected_opcode[min(proto, 3), len(x)]
1676 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters1d63c9f2003-02-02 20:29:39 +00001677
Guido van Rossum7d97d312003-01-28 04:25:27 +00001678 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +00001679 # Map (proto, singleton) to expected opcode.
1680 expected_opcode = {(0, None): pickle.NONE,
1681 (1, None): pickle.NONE,
1682 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001683 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +00001684
1685 (0, True): pickle.INT,
1686 (1, True): pickle.INT,
1687 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001688 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +00001689
1690 (0, False): pickle.INT,
1691 (1, False): pickle.INT,
1692 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001693 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +00001694 }
Tim Peters4190fb82003-02-02 16:09:05 +00001695 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +00001696 for x in None, False, True:
1697 s = self.dumps(x, proto)
1698 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001699 self.assertTrue(x is y, (proto, x, s, y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001700 expected = expected_opcode[min(proto, 3), x]
1701 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters3c67d792003-02-02 17:59:11 +00001702
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001703 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001704 x = MyTuple([1, 2, 3])
1705 x.foo = 42
1706 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001707 for proto in protocols:
1708 s = self.dumps(x, proto)
1709 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001710 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001711
1712 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001713 x = MyList([1, 2, 3])
1714 x.foo = 42
1715 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001716 for proto in protocols:
1717 s = self.dumps(x, proto)
1718 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001719 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001720
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001721 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001722 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001723 for C in myclasses:
1724 B = C.__base__
1725 x = C(C.sample)
1726 x.foo = 42
1727 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001728 y = self.loads(s)
1729 detail = (proto, C, B, x, y, type(y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001730 self.assert_is_copy(x, y) # XXX revisit
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001731 self.assertEqual(B(x), B(y), detail)
1732 self.assertEqual(x.__dict__, y.__dict__, detail)
1733
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01001734 def test_newobj_proxies(self):
1735 # NEWOBJ should use the __class__ rather than the raw type
1736 classes = myclasses[:]
1737 # Cannot create weakproxies to these classes
1738 for c in (MyInt, MyTuple):
1739 classes.remove(c)
1740 for proto in protocols:
1741 for C in classes:
1742 B = C.__base__
1743 x = C(C.sample)
1744 x.foo = 42
1745 p = weakref.proxy(x)
1746 s = self.dumps(p, proto)
1747 y = self.loads(s)
1748 self.assertEqual(type(y), type(x)) # rather than type(p)
1749 detail = (proto, C, B, x, y, type(y))
1750 self.assertEqual(B(x), B(y), detail)
1751 self.assertEqual(x.__dict__, y.__dict__, detail)
1752
Benjamin Peterson80f78a32015-07-02 16:18:38 -05001753 def test_newobj_not_class(self):
1754 # Issue 24552
1755 global SimpleNewObj
1756 save = SimpleNewObj
Benjamin Petersond3a2a952015-07-02 16:58:22 -05001757 o = SimpleNewObj.__new__(SimpleNewObj)
Benjamin Peterson80f78a32015-07-02 16:18:38 -05001758 b = self.dumps(o, 4)
1759 try:
1760 SimpleNewObj = 42
1761 self.assertRaises((TypeError, pickle.UnpicklingError), self.loads, b)
1762 finally:
1763 SimpleNewObj = save
1764
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001765 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001766 # an object of that type. Check that the resulting pickle uses opcode
1767 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001768
Tim Peters22e71712003-02-03 22:27:38 +00001769 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001770 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001771 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001772 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001773 x = MyList([1, 2, 3])
1774 x.foo = 42
1775 x.bar = "hello"
1776
Tim Peters22e71712003-02-03 22:27:38 +00001777 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001778 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001779 self.assertIn(__name__.encode("utf-8"), s1)
1780 self.assertIn(b"MyList", s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001781 self.assertFalse(opcode_in_pickle(opcode, s1))
Tim Peters3e667d52003-02-04 21:47:44 +00001782
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001783 y = self.loads(s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001784 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001785
Tim Peters22e71712003-02-03 22:27:38 +00001786 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001787 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001788 self.assertNotIn(__name__.encode("utf-8"), s2)
1789 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001790 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +00001791
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001792 y = self.loads(s2)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001793 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001794 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001795 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001796
1797 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001798 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1799 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001800
1801 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001802 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1803 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1804 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001805
1806 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001807 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1808 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1809 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1810
Tim Peters8d2613a2003-02-11 16:40:16 +00001811 def test_list_chunking(self):
1812 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +00001813 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001814 for proto in protocols:
1815 s = self.dumps(x, proto)
1816 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001817 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001818 num_appends = count_opcode(pickle.APPENDS, s)
1819 self.assertEqual(num_appends, proto > 0)
1820
1821 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001822 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001823 for proto in protocols:
1824 s = self.dumps(x, proto)
1825 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001826 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001827 num_appends = count_opcode(pickle.APPENDS, s)
1828 if proto == 0:
1829 self.assertEqual(num_appends, 0)
1830 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001831 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001832
1833 def test_dict_chunking(self):
1834 n = 10 # too small to chunk
1835 x = dict.fromkeys(range(n))
1836 for proto in protocols:
1837 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +00001838 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00001839 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001840 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001841 num_setitems = count_opcode(pickle.SETITEMS, s)
1842 self.assertEqual(num_setitems, proto > 0)
1843
1844 n = 2500 # expect at least two chunks when proto > 0
1845 x = dict.fromkeys(range(n))
1846 for proto in protocols:
1847 s = self.dumps(x, proto)
1848 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001849 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001850 num_setitems = count_opcode(pickle.SETITEMS, s)
1851 if proto == 0:
1852 self.assertEqual(num_setitems, 0)
1853 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001854 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001855
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001856 def test_set_chunking(self):
1857 n = 10 # too small to chunk
1858 x = set(range(n))
1859 for proto in protocols:
1860 s = self.dumps(x, proto)
1861 y = self.loads(s)
1862 self.assert_is_copy(x, y)
1863 num_additems = count_opcode(pickle.ADDITEMS, s)
1864 if proto < 4:
1865 self.assertEqual(num_additems, 0)
1866 else:
1867 self.assertEqual(num_additems, 1)
1868
1869 n = 2500 # expect at least two chunks when proto >= 4
1870 x = set(range(n))
1871 for proto in protocols:
1872 s = self.dumps(x, proto)
1873 y = self.loads(s)
1874 self.assert_is_copy(x, y)
1875 num_additems = count_opcode(pickle.ADDITEMS, s)
1876 if proto < 4:
1877 self.assertEqual(num_additems, 0)
1878 else:
1879 self.assertGreaterEqual(num_additems, 2)
1880
Tim Peterse9ef2032003-02-13 18:42:00 +00001881 def test_simple_newobj(self):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001882 x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__
Tim Peterse9ef2032003-02-13 18:42:00 +00001883 x.abc = 666
1884 for proto in protocols:
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001885 with self.subTest(proto=proto):
1886 s = self.dumps(x, proto)
1887 if proto < 1:
Serhiy Storchaka3daaafb2017-11-16 09:44:43 +02001888 self.assertIn(b'\nI64206', s) # INT
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001889 else:
1890 self.assertIn(b'M\xce\xfa', s) # BININT2
1891 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1892 2 <= proto)
1893 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1894 y = self.loads(s) # will raise TypeError if __init__ called
1895 self.assert_is_copy(x, y)
1896
1897 def test_complex_newobj(self):
1898 x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__
1899 x.abc = 666
1900 for proto in protocols:
1901 with self.subTest(proto=proto):
1902 s = self.dumps(x, proto)
1903 if proto < 1:
Serhiy Storchaka3daaafb2017-11-16 09:44:43 +02001904 self.assertIn(b'\nI64206', s) # INT
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001905 elif proto < 2:
1906 self.assertIn(b'M\xce\xfa', s) # BININT2
1907 elif proto < 4:
1908 self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
1909 else:
1910 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1911 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1912 2 <= proto)
1913 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1914 y = self.loads(s) # will raise TypeError if __init__ called
1915 self.assert_is_copy(x, y)
1916
1917 def test_complex_newobj_ex(self):
1918 x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__
1919 x.abc = 666
1920 for proto in protocols:
1921 with self.subTest(proto=proto):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001922 s = self.dumps(x, proto)
1923 if proto < 1:
Serhiy Storchaka3daaafb2017-11-16 09:44:43 +02001924 self.assertIn(b'\nI64206', s) # INT
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001925 elif proto < 2:
1926 self.assertIn(b'M\xce\xfa', s) # BININT2
Serhiy Storchaka0d554d72015-10-10 22:42:18 +03001927 elif proto < 4:
1928 self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001929 else:
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001930 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1931 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s))
1932 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1933 4 <= proto)
1934 y = self.loads(s) # will raise TypeError if __init__ called
1935 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001936
Tim Peters42f08ac2003-02-11 22:43:24 +00001937 def test_newobj_list_slots(self):
1938 x = SlotList([1, 2, 3])
1939 x.foo = 42
1940 x.bar = "hello"
1941 s = self.dumps(x, 2)
1942 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001943 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001944
Guido van Rossum2a30b212003-02-18 22:41:24 +00001945 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001946 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001947 x = REX_one()
1948 self.assertEqual(x._reduce_called, 0)
1949 s = self.dumps(x, proto)
1950 self.assertEqual(x._reduce_called, 1)
1951 y = self.loads(s)
1952 self.assertEqual(y._reduce_called, 0)
1953
1954 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001955 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001956 x = REX_two()
1957 self.assertEqual(x._proto, None)
1958 s = self.dumps(x, proto)
1959 self.assertEqual(x._proto, proto)
1960 y = self.loads(s)
1961 self.assertEqual(y._proto, None)
1962
1963 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001964 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001965 x = REX_three()
1966 self.assertEqual(x._proto, None)
1967 s = self.dumps(x, proto)
1968 self.assertEqual(x._proto, proto)
1969 y = self.loads(s)
1970 self.assertEqual(y._proto, None)
1971
Guido van Rossumd8faa362007-04-27 19:54:29 +00001972 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001973 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001974 x = REX_four()
1975 self.assertEqual(x._proto, None)
1976 s = self.dumps(x, proto)
1977 self.assertEqual(x._proto, proto)
1978 y = self.loads(s)
1979 self.assertEqual(y._proto, proto)
1980
1981 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001982 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001983 x = REX_five()
1984 self.assertEqual(x._reduce_called, 0)
1985 s = self.dumps(x, proto)
1986 self.assertEqual(x._reduce_called, 1)
1987 y = self.loads(s)
1988 self.assertEqual(y._reduce_called, 1)
1989
Brett Cannon31f59292011-02-21 19:29:56 +00001990 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001991 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001992 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001993 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001994 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001995 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001996
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001997 def test_reduce_bad_iterator(self):
1998 # Issue4176: crash when 4th and 5th items of __reduce__()
1999 # are not iterators
2000 class C(object):
2001 def __reduce__(self):
2002 # 4th item is not an iterator
2003 return list, (), None, [], None
2004 class D(object):
2005 def __reduce__(self):
2006 # 5th item is not an iterator
2007 return dict, (), None, None, []
2008
Serhiy Storchakabeb652c2015-12-30 21:00:08 +02002009 # Python implementation is less strict and also accepts iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00002010 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00002011 try:
2012 self.dumps(C(), proto)
Serhiy Storchakabeb652c2015-12-30 21:00:08 +02002013 except pickle.PicklingError:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00002014 pass
2015 try:
2016 self.dumps(D(), proto)
Serhiy Storchakabeb652c2015-12-30 21:00:08 +02002017 except pickle.PicklingError:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00002018 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00002019
Collin Winter771d8342009-04-16 03:18:06 +00002020 def test_many_puts_and_gets(self):
2021 # Test that internal data structures correctly deal with lots of
2022 # puts/gets.
2023 keys = ("aaa" + str(i) for i in range(100))
2024 large_dict = dict((k, [4, 5, 6]) for k in keys)
2025 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
2026
2027 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002028 with self.subTest(proto=proto):
2029 dumped = self.dumps(obj, proto)
2030 loaded = self.loads(dumped)
2031 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00002032
Antoine Pitroua9f48a02009-05-02 21:41:14 +00002033 def test_attribute_name_interning(self):
2034 # Test that attribute names of pickled objects are interned when
2035 # unpickling.
2036 for proto in protocols:
2037 x = C()
2038 x.foo = 42
2039 x.bar = "hello"
2040 s = self.dumps(x, proto)
2041 y = self.loads(s)
2042 x_keys = sorted(x.__dict__)
2043 y_keys = sorted(y.__dict__)
2044 for x_key, y_key in zip(x_keys, y_keys):
2045 self.assertIs(x_key, y_key)
2046
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00002047 def test_pickle_to_2x(self):
2048 # Pickle non-trivial data with protocol 2, expecting that it yields
2049 # the same result as Python 2.x did.
2050 # NOTE: this test is a bit too strong since we can produce different
2051 # bytecode that 2.x will still understand.
2052 dumped = self.dumps(range(5), 2)
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03002053 self.assertEqual(dumped, DATA_XRANGE)
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00002054 dumped = self.dumps(set([3]), 2)
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03002055 self.assertEqual(dumped, DATA_SET2)
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00002056
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00002057 def test_large_pickles(self):
2058 # Test the correctness of internal buffering routines when handling
2059 # large data.
2060 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00002061 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00002062 dumped = self.dumps(data, proto)
2063 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002064 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00002065 self.assertEqual(loaded, data)
2066
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002067 def test_int_pickling_efficiency(self):
2068 # Test compacity of int representation (see issue #12744)
2069 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002070 with self.subTest(proto=proto):
2071 pickles = [self.dumps(2**n, proto) for n in range(70)]
2072 sizes = list(map(len, pickles))
2073 # the size function is monotonic
2074 self.assertEqual(sorted(sizes), sizes)
2075 if proto >= 2:
2076 for p in pickles:
2077 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002078
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002079 def _check_pickling_with_opcode(self, obj, opcode, proto):
2080 pickled = self.dumps(obj, proto)
2081 self.assertTrue(opcode_in_pickle(opcode, pickled))
2082 unpickled = self.loads(pickled)
2083 self.assertEqual(obj, unpickled)
2084
2085 def test_appends_on_non_lists(self):
2086 # Issue #17720
2087 obj = REX_six([1, 2, 3])
2088 for proto in protocols:
2089 if proto == 0:
2090 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
2091 else:
2092 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
2093
2094 def test_setitems_on_non_dicts(self):
2095 obj = REX_seven({1: -1, 2: -2, 3: -3})
2096 for proto in protocols:
2097 if proto == 0:
2098 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
2099 else:
2100 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
2101
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002102 # Exercise framing (proto >= 4) for significant workloads
2103
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002104 FRAME_SIZE_MIN = 4
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002105 FRAME_SIZE_TARGET = 64 * 1024
2106
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002107 def check_frame_opcodes(self, pickled):
2108 """
2109 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002110
2111 Note that binary objects that are larger than FRAME_SIZE_TARGET are not
2112 framed by default and are therefore considered a frame by themselves in
2113 the following consistency check.
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002114 """
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002115 frame_end = frameless_start = None
2116 frameless_opcodes = {'BINBYTES', 'BINUNICODE', 'BINBYTES8', 'BINUNICODE8'}
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002117 for op, arg, pos in pickletools.genops(pickled):
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002118 if frame_end is not None:
2119 self.assertLessEqual(pos, frame_end)
2120 if pos == frame_end:
2121 frame_end = None
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002122
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002123 if frame_end is not None: # framed
2124 self.assertNotEqual(op.name, 'FRAME')
2125 if op.name in frameless_opcodes:
2126 # Only short bytes and str objects should be written
2127 # in a frame
2128 self.assertLessEqual(len(arg), self.FRAME_SIZE_TARGET)
2129
2130 else: # not framed
2131 if (op.name == 'FRAME' or
2132 (op.name in frameless_opcodes and
2133 len(arg) > self.FRAME_SIZE_TARGET)):
2134 # Frame or large bytes or str object
2135 if frameless_start is not None:
2136 # Only short data should be written outside of a frame
2137 self.assertLess(pos - frameless_start,
2138 self.FRAME_SIZE_MIN)
2139 frameless_start = None
2140 elif frameless_start is None and op.name != 'PROTO':
2141 frameless_start = pos
2142
2143 if op.name == 'FRAME':
2144 self.assertGreaterEqual(arg, self.FRAME_SIZE_MIN)
2145 frame_end = pos + 9 + arg
2146
2147 pos = len(pickled)
2148 if frame_end is not None:
2149 self.assertEqual(frame_end, pos)
2150 elif frameless_start is not None:
2151 self.assertLess(pos - frameless_start, self.FRAME_SIZE_MIN)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002152
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002153 def test_framing_many_objects(self):
2154 obj = list(range(10**5))
2155 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2156 with self.subTest(proto=proto):
2157 pickled = self.dumps(obj, proto)
2158 unpickled = self.loads(pickled)
2159 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01002160 bytes_per_frame = (len(pickled) /
2161 count_opcode(pickle.FRAME, pickled))
2162 self.assertGreater(bytes_per_frame,
2163 self.FRAME_SIZE_TARGET / 2)
2164 self.assertLessEqual(bytes_per_frame,
2165 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01002166 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002167
2168 def test_framing_large_objects(self):
2169 N = 1024 * 1024
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002170 small_items = [[i] for i in range(10)]
2171 obj = [b'x' * N, *small_items, b'y' * N, 'z' * N]
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002172 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
Serhiy Storchaka0a2da502018-01-11 13:03:20 +02002173 for fast in [False, True]:
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002174 with self.subTest(proto=proto, fast=fast):
Serhiy Storchaka0a2da502018-01-11 13:03:20 +02002175 if not fast:
2176 # fast=False by default.
2177 # This covers in-memory pickling with pickle.dumps().
2178 pickled = self.dumps(obj, proto)
2179 else:
2180 # Pickler is required when fast=True.
2181 if not hasattr(self, 'pickler'):
2182 continue
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002183 buf = io.BytesIO()
2184 pickler = self.pickler(buf, protocol=proto)
2185 pickler.fast = fast
2186 pickler.dump(obj)
2187 pickled = buf.getvalue()
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002188 unpickled = self.loads(pickled)
2189 # More informative error message in case of failure.
2190 self.assertEqual([len(x) for x in obj],
2191 [len(x) for x in unpickled])
2192 # Perform full equality check if the lengths match.
2193 self.assertEqual(obj, unpickled)
2194 n_frames = count_opcode(pickle.FRAME, pickled)
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002195 # A single frame for small objects between
2196 # first two large objects.
2197 self.assertEqual(n_frames, 1)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002198 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002199
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002200 def test_optional_frames(self):
2201 if pickle.HIGHEST_PROTOCOL < 4:
2202 return
2203
2204 def remove_frames(pickled, keep_frame=None):
2205 """Remove frame opcodes from the given pickle."""
2206 frame_starts = []
2207 # 1 byte for the opcode and 8 for the argument
2208 frame_opcode_size = 9
2209 for opcode, _, pos in pickletools.genops(pickled):
2210 if opcode.name == 'FRAME':
2211 frame_starts.append(pos)
2212
2213 newpickle = bytearray()
2214 last_frame_end = 0
2215 for i, pos in enumerate(frame_starts):
2216 if keep_frame and keep_frame(i):
2217 continue
2218 newpickle += pickled[last_frame_end:pos]
2219 last_frame_end = pos + frame_opcode_size
2220 newpickle += pickled[last_frame_end:]
2221 return newpickle
2222
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08002223 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002224 num_frames = 20
Serhiy Storchaka1211c9a2018-01-20 16:42:44 +02002225 # Large byte objects (dict values) intermitted with small objects
2226 # (dict keys)
2227 obj = {i: bytes([i]) * frame_size for i in range(num_frames)}
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002228
2229 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
2230 pickled = self.dumps(obj, proto)
2231
2232 frameless_pickle = remove_frames(pickled)
2233 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
2234 self.assertEqual(obj, self.loads(frameless_pickle))
2235
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08002236 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08002237 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
2238 count_opcode(pickle.FRAME, pickled))
2239 self.assertEqual(obj, self.loads(some_frames_pickle))
2240
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002241 def test_framed_write_sizes_with_delayed_writer(self):
2242 class ChunkAccumulator:
2243 """Accumulate pickler output in a list of raw chunks."""
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002244 def __init__(self):
2245 self.chunks = []
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002246 def write(self, chunk):
2247 self.chunks.append(chunk)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002248 def concatenate_chunks(self):
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002249 return b"".join(self.chunks)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002250
2251 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002252 objects = [(str(i).encode('ascii'), i % 42, {'i': str(i)})
2253 for i in range(int(1e4))]
2254 # Add a large unique ASCII string
2255 objects.append('0123456789abcdef' *
2256 (self.FRAME_SIZE_TARGET // 16 + 1))
2257
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002258 # Protocol 4 packs groups of small objects into frames and issues
2259 # calls to write only once or twice per frame:
2260 # The C pickler issues one call to write per-frame (header and
2261 # contents) while Python pickler issues two calls to write: one for
2262 # the frame header and one for the frame binary contents.
2263 writer = ChunkAccumulator()
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002264 self.pickler(writer, proto).dump(objects)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002265
2266 # Actually read the binary content of the chunks after the end
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002267 # of the call to dump: any memoryview passed to write should not
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002268 # be released otherwise this delayed access would not be possible.
2269 pickled = writer.concatenate_chunks()
2270 reconstructed = self.loads(pickled)
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002271 self.assertEqual(reconstructed, objects)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002272 self.assertGreater(len(writer.chunks), 1)
2273
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002274 # memoryviews should own the memory.
2275 del objects
2276 support.gc_collect()
2277 self.assertEqual(writer.concatenate_chunks(), pickled)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002278
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002279 n_frames = (len(pickled) - 1) // self.FRAME_SIZE_TARGET + 1
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002280 # There should be at least one call to write per frame
2281 self.assertGreaterEqual(len(writer.chunks), n_frames)
2282
2283 # but not too many either: there can be one for the proto,
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002284 # one per-frame header, one per frame for the actual contents,
2285 # and two for the header.
2286 self.assertLessEqual(len(writer.chunks), 2 * n_frames + 3)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002287
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002288 chunk_sizes = [len(c) for c in writer.chunks]
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002289 large_sizes = [s for s in chunk_sizes
2290 if s >= self.FRAME_SIZE_TARGET]
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002291 medium_sizes = [s for s in chunk_sizes
2292 if 9 < s < self.FRAME_SIZE_TARGET]
2293 small_sizes = [s for s in chunk_sizes if s <= 9]
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002294
2295 # Large chunks should not be too large:
2296 for chunk_size in large_sizes:
Serhiy Storchaka5b76bdb2018-01-13 00:28:31 +02002297 self.assertLess(chunk_size, 2 * self.FRAME_SIZE_TARGET,
2298 chunk_sizes)
2299 # There shouldn't bee too many small chunks: the protocol header,
2300 # the frame headers and the large string headers are written
2301 # in small chunks.
2302 self.assertLessEqual(len(small_sizes),
2303 len(large_sizes) + len(medium_sizes) + 3,
2304 chunk_sizes)
Olivier Grisel3cd7c6e2018-01-06 16:18:54 +01002305
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002306 def test_nested_names(self):
2307 global Nested
2308 class Nested:
2309 class A:
2310 class B:
2311 class C:
2312 pass
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002313 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002314 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
2315 with self.subTest(proto=proto, obj=obj):
2316 unpickled = self.loads(self.dumps(obj, proto))
2317 self.assertIs(obj, unpickled)
2318
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002319 def test_recursive_nested_names(self):
2320 global Recursive
2321 class Recursive:
2322 pass
2323 Recursive.mod = sys.modules[Recursive.__module__]
2324 Recursive.__qualname__ = 'Recursive.mod.Recursive'
2325 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2326 with self.subTest(proto=proto):
2327 unpickled = self.loads(self.dumps(Recursive, proto))
2328 self.assertIs(unpickled, Recursive)
2329 del Recursive.mod # break reference loop
2330
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002331 def test_py_methods(self):
2332 global PyMethodsTest
2333 class PyMethodsTest:
2334 @staticmethod
2335 def cheese():
2336 return "cheese"
2337 @classmethod
2338 def wine(cls):
2339 assert cls is PyMethodsTest
2340 return "wine"
2341 def biscuits(self):
2342 assert isinstance(self, PyMethodsTest)
2343 return "biscuits"
2344 class Nested:
2345 "Nested class"
2346 @staticmethod
2347 def ketchup():
2348 return "ketchup"
2349 @classmethod
2350 def maple(cls):
2351 assert cls is PyMethodsTest.Nested
2352 return "maple"
2353 def pie(self):
2354 assert isinstance(self, PyMethodsTest.Nested)
2355 return "pie"
2356
2357 py_methods = (
2358 PyMethodsTest.cheese,
2359 PyMethodsTest.wine,
2360 PyMethodsTest().biscuits,
2361 PyMethodsTest.Nested.ketchup,
2362 PyMethodsTest.Nested.maple,
2363 PyMethodsTest.Nested().pie
2364 )
2365 py_unbound_methods = (
2366 (PyMethodsTest.biscuits, PyMethodsTest),
2367 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
2368 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002369 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002370 for method in py_methods:
2371 with self.subTest(proto=proto, method=method):
2372 unpickled = self.loads(self.dumps(method, proto))
2373 self.assertEqual(method(), unpickled())
2374 for method, cls in py_unbound_methods:
2375 obj = cls()
2376 with self.subTest(proto=proto, method=method):
2377 unpickled = self.loads(self.dumps(method, proto))
2378 self.assertEqual(method(obj), unpickled(obj))
2379
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002380 def test_c_methods(self):
2381 global Subclass
2382 class Subclass(tuple):
2383 class Nested(str):
2384 pass
2385
2386 c_methods = (
2387 # bound built-in method
2388 ("abcd".index, ("c",)),
2389 # unbound built-in method
2390 (str.index, ("abcd", "c")),
2391 # bound "slot" method
2392 ([1, 2, 3].__len__, ()),
2393 # unbound "slot" method
2394 (list.__len__, ([1, 2, 3],)),
2395 # bound "coexist" method
2396 ({1, 2}.__contains__, (2,)),
2397 # unbound "coexist" method
2398 (set.__contains__, ({1, 2}, 2)),
2399 # built-in class method
2400 (dict.fromkeys, (("a", 1), ("b", 2))),
2401 # built-in static method
2402 (bytearray.maketrans, (b"abc", b"xyz")),
2403 # subclass methods
2404 (Subclass([1,2,2]).count, (2,)),
2405 (Subclass.count, (Subclass([1,2,2]), 2)),
2406 (Subclass.Nested("sweet").count, ("e",)),
2407 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
2408 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03002409 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002410 for method, args in c_methods:
2411 with self.subTest(proto=proto, method=method):
2412 unpickled = self.loads(self.dumps(method, proto))
2413 self.assertEqual(method(*args), unpickled(*args))
2414
Serhiy Storchakabfe18242015-03-31 13:12:37 +03002415 def test_compat_pickle(self):
2416 tests = [
2417 (range(1, 7), '__builtin__', 'xrange'),
2418 (map(int, '123'), 'itertools', 'imap'),
2419 (functools.reduce, '__builtin__', 'reduce'),
2420 (dbm.whichdb, 'whichdb', 'whichdb'),
2421 (Exception(), 'exceptions', 'Exception'),
2422 (collections.UserDict(), 'UserDict', 'IterableUserDict'),
2423 (collections.UserList(), 'UserList', 'UserList'),
2424 (collections.defaultdict(), 'collections', 'defaultdict'),
2425 ]
2426 for val, mod, name in tests:
2427 for proto in range(3):
2428 with self.subTest(type=type(val), proto=proto):
2429 pickled = self.dumps(val, proto)
2430 self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled)
2431 self.assertIs(type(self.loads(pickled)), type(val))
2432
Antoine Pitrou6cd5eda2014-12-02 00:20:03 +01002433 def test_local_lookup_error(self):
2434 # Test that whichmodule() errors out cleanly when looking up
2435 # an assumed globally-reachable object fails.
2436 def f():
2437 pass
2438 # Since the function is local, lookup will fail
2439 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2440 with self.assertRaises((AttributeError, pickle.PicklingError)):
2441 pickletools.dis(self.dumps(f, proto))
2442 # Same without a __module__ attribute (exercises a different path
2443 # in _pickle.c).
2444 del f.__module__
2445 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2446 with self.assertRaises((AttributeError, pickle.PicklingError)):
2447 pickletools.dis(self.dumps(f, proto))
2448 # Yet a different path.
2449 f.__name__ = f.__qualname__
2450 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
2451 with self.assertRaises((AttributeError, pickle.PicklingError)):
2452 pickletools.dis(self.dumps(f, proto))
2453
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002454
2455class BigmemPickleTests(unittest.TestCase):
2456
Victor Stinner8c663fd2017-11-08 14:44:44 -08002457 # Binary protocols can serialize longs of up to 2 GiB-1
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002458
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002459 @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002460 def test_huge_long_32b(self, size):
2461 data = 1 << (8 * size)
2462 try:
2463 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002464 if proto < 2:
2465 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002466 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002467 with self.assertRaises((ValueError, OverflowError)):
2468 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002469 finally:
2470 data = None
2471
Victor Stinner8c663fd2017-11-08 14:44:44 -08002472 # Protocol 3 can serialize up to 4 GiB-1 as a bytes object
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002473 # (older protocols don't have a dedicated opcode for bytes and are
2474 # too inefficient)
2475
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002476 @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002477 def test_huge_bytes_32b(self, size):
2478 data = b"abcd" * (size // 4)
2479 try:
2480 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002481 if proto < 3:
2482 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002483 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002484 try:
2485 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002486 header = (pickle.BINBYTES +
2487 struct.pack("<I", len(data)))
2488 data_start = pickled.index(data)
2489 self.assertEqual(
2490 header,
2491 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002492 finally:
2493 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002494 finally:
2495 data = None
2496
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002497 @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002498 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002499 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002500 try:
2501 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002502 if proto < 3:
2503 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002504 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002505 if proto == 3:
2506 # Protocol 3 does not support large bytes objects.
2507 # Verify that we do not crash when processing one.
2508 with self.assertRaises((ValueError, OverflowError)):
2509 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002510 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002511 try:
2512 pickled = self.dumps(data, protocol=proto)
2513 header = (pickle.BINBYTES8 +
2514 struct.pack("<Q", len(data)))
2515 data_start = pickled.index(data)
2516 self.assertEqual(
2517 header,
2518 pickled[data_start-len(header):data_start])
2519 finally:
2520 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002521 finally:
2522 data = None
2523
2524 # All protocols use 1-byte per printable ASCII character; we add another
2525 # byte because the encoded form has to be copied into the internal buffer.
2526
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002527 @bigmemtest(size=_2G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002528 def test_huge_str_32b(self, size):
2529 data = "abcd" * (size // 4)
2530 try:
2531 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002532 if proto == 0:
2533 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002534 with self.subTest(proto=proto):
2535 try:
2536 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002537 header = (pickle.BINUNICODE +
2538 struct.pack("<I", len(data)))
2539 data_start = pickled.index(b'abcd')
2540 self.assertEqual(
2541 header,
2542 pickled[data_start-len(header):data_start])
2543 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2544 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002545 finally:
2546 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002547 finally:
2548 data = None
2549
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002550 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
2551 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
2552 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02002553
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002554 @bigmemtest(size=_4G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002555 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002556 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002557 try:
2558 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002559 if proto == 0:
2560 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002561 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002562 if proto < 4:
2563 with self.assertRaises((ValueError, OverflowError)):
2564 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002565 continue
2566 try:
2567 pickled = self.dumps(data, protocol=proto)
2568 header = (pickle.BINUNICODE8 +
2569 struct.pack("<Q", len(data)))
2570 data_start = pickled.index(b'abcd')
2571 self.assertEqual(
2572 header,
2573 pickled[data_start-len(header):data_start])
2574 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2575 pickled.index(b"abcd")), len(data))
2576 finally:
2577 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002578 finally:
2579 data = None
2580
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002581
Guido van Rossum2a30b212003-02-18 22:41:24 +00002582# Test classes for reduce_ex
2583
2584class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002585 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00002586 _reduce_called = 0
2587 def __reduce__(self):
2588 self._reduce_called = 1
2589 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00002590
2591class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002592 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00002593 _proto = None
2594 def __reduce_ex__(self, proto):
2595 self._proto = proto
2596 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00002597
2598class REX_three(object):
2599 _proto = None
2600 def __reduce_ex__(self, proto):
2601 self._proto = proto
2602 return REX_two, ()
2603 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00002604 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00002605
Guido van Rossumd8faa362007-04-27 19:54:29 +00002606class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002607 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00002608 _proto = None
2609 def __reduce_ex__(self, proto):
2610 self._proto = proto
2611 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002612
2613class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002614 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00002615 _reduce_called = 0
2616 def __reduce__(self):
2617 self._reduce_called = 1
2618 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002619
2620class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002621 """This class is used to check the 4th argument (list iterator) of
2622 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002623 """
2624 def __init__(self, items=None):
2625 self.items = items if items is not None else []
2626 def __eq__(self, other):
Serhiy Storchakabe700022016-03-04 09:39:47 +02002627 return type(self) is type(other) and self.items == other.items
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002628 def append(self, item):
2629 self.items.append(item)
2630 def __reduce__(self):
2631 return type(self), (), None, iter(self.items), None
2632
2633class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002634 """This class is used to check the 5th argument (dict iterator) of
2635 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002636 """
2637 def __init__(self, table=None):
2638 self.table = table if table is not None else {}
2639 def __eq__(self, other):
Serhiy Storchakabe700022016-03-04 09:39:47 +02002640 return type(self) is type(other) and self.table == other.table
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002641 def __setitem__(self, key, value):
2642 self.table[key] = value
2643 def __reduce__(self):
2644 return type(self), (), None, None, iter(self.table.items())
2645
Guido van Rossumd8faa362007-04-27 19:54:29 +00002646
Guido van Rossum2a30b212003-02-18 22:41:24 +00002647# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00002648
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002649class MyInt(int):
2650 sample = 1
2651
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002652class MyFloat(float):
2653 sample = 1.0
2654
2655class MyComplex(complex):
2656 sample = 1.0 + 0.0j
2657
2658class MyStr(str):
2659 sample = "hello"
2660
Guido van Rossumef87d6e2007-05-02 19:09:54 +00002661class MyUnicode(str):
2662 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002663
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002664class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002665 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002666
2667class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002668 sample = [1, 2, 3]
2669
2670class MyDict(dict):
2671 sample = {"a": 1, "b": 2}
2672
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002673class MySet(set):
2674 sample = {"a", "b"}
2675
2676class MyFrozenSet(frozenset):
2677 sample = frozenset({"a", "b"})
2678
Mark Dickinson5c2db372009-12-05 20:28:34 +00002679myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00002680 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002681 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002682 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002683
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002684
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00002685class SlotList(MyList):
2686 __slots__ = ["foo"]
2687
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002688class SimpleNewObj(int):
2689 def __init__(self, *args, **kwargs):
Tim Peterse9ef2032003-02-13 18:42:00 +00002690 # raise an error, to make sure this isn't called
2691 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002692 def __eq__(self, other):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002693 return int(self) == int(other) and self.__dict__ == other.__dict__
2694
2695class ComplexNewObj(SimpleNewObj):
2696 def __getnewargs__(self):
2697 return ('%X' % self, 16)
2698
2699class ComplexNewObjEx(SimpleNewObj):
2700 def __getnewargs_ex__(self):
2701 return ('%X' % self,), {'base': 16}
Tim Peterse9ef2032003-02-13 18:42:00 +00002702
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002703class BadGetattr:
2704 def __getattr__(self, key):
2705 self.foo
2706
Collin Winter771d8342009-04-16 03:18:06 +00002707
Jeremy Hylton66426532001-10-15 21:38:56 +00002708class AbstractPickleModuleTests(unittest.TestCase):
2709
2710 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002711 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00002712 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002713 try:
2714 f.close()
Serhiy Storchaka65452562017-11-15 14:01:08 +02002715 self.assertRaises(ValueError, self.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002716 finally:
2717 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00002718
2719 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002720 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00002721 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002722 try:
2723 f.close()
Serhiy Storchaka65452562017-11-15 14:01:08 +02002724 self.assertRaises(ValueError, self.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002725 finally:
2726 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002727
Collin Winter771d8342009-04-16 03:18:06 +00002728 def test_load_from_and_dump_to_file(self):
2729 stream = io.BytesIO()
2730 data = [123, {}, 124]
Serhiy Storchaka65452562017-11-15 14:01:08 +02002731 self.dump(data, stream)
Collin Winter771d8342009-04-16 03:18:06 +00002732 stream.seek(0)
Serhiy Storchaka65452562017-11-15 14:01:08 +02002733 unpickled = self.load(stream)
Collin Winter771d8342009-04-16 03:18:06 +00002734 self.assertEqual(unpickled, data)
2735
Tim Petersc0c93702003-02-13 19:30:57 +00002736 def test_highest_protocol(self):
2737 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002738 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00002739
Martin v. Löwis544f1192004-07-27 05:22:33 +00002740 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00002741 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00002742 # With and without keyword arguments
Serhiy Storchaka65452562017-11-15 14:01:08 +02002743 self.dump(123, f, -1)
2744 self.dump(123, file=f, protocol=-1)
2745 self.dumps(123, -1)
2746 self.dumps(123, protocol=-1)
2747 self.Pickler(f, -1)
2748 self.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00002749
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002750 def test_bad_init(self):
2751 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002752 # Override initialization without calling __init__() of the superclass.
Serhiy Storchaka65452562017-11-15 14:01:08 +02002753 class BadPickler(self.Pickler):
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002754 def __init__(self): pass
2755
Serhiy Storchaka65452562017-11-15 14:01:08 +02002756 class BadUnpickler(self.Unpickler):
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002757 def __init__(self): pass
2758
2759 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
2760 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
2761
2762
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002763class AbstractPersistentPicklerTests(unittest.TestCase):
2764
2765 # This class defines persistent_id() and persistent_load()
2766 # functions that should be used by the pickler. All even integers
2767 # are pickled using persistent ids.
2768
2769 def persistent_id(self, object):
2770 if isinstance(object, int) and object % 2 == 0:
2771 self.id_count += 1
2772 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002773 elif object == "test_false_value":
2774 self.false_count += 1
2775 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002776 else:
2777 return None
2778
2779 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002780 if not oid:
2781 self.load_false_count += 1
2782 return "test_false_value"
2783 else:
2784 self.load_count += 1
2785 object = int(oid)
2786 assert object % 2 == 0
2787 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002788
2789 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002790 L = list(range(10)) + ["test_false_value"]
2791 for proto in protocols:
2792 self.id_count = 0
2793 self.false_count = 0
2794 self.load_false_count = 0
2795 self.load_count = 0
2796 self.assertEqual(self.loads(self.dumps(L, proto)), L)
2797 self.assertEqual(self.id_count, 5)
2798 self.assertEqual(self.false_count, 1)
2799 self.assertEqual(self.load_count, 5)
2800 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00002801
Collin Winter771d8342009-04-16 03:18:06 +00002802
Serhiy Storchakadec25af2016-07-17 11:24:17 +03002803class AbstractIdentityPersistentPicklerTests(unittest.TestCase):
2804
2805 def persistent_id(self, obj):
2806 return obj
2807
2808 def persistent_load(self, pid):
2809 return pid
2810
2811 def _check_return_correct_type(self, obj, proto):
2812 unpickled = self.loads(self.dumps(obj, proto))
2813 self.assertIsInstance(unpickled, type(obj))
2814 self.assertEqual(unpickled, obj)
2815
2816 def test_return_correct_type(self):
2817 for proto in protocols:
2818 # Protocol 0 supports only ASCII strings.
2819 if proto == 0:
2820 self._check_return_correct_type("abc", 0)
2821 else:
2822 for obj in [b"abc\n", "abc\n", -1, -1.1 * 0.1, str]:
2823 self._check_return_correct_type(obj, proto)
2824
2825 def test_protocol0_is_ascii_only(self):
2826 non_ascii_str = "\N{EMPTY SET}"
2827 self.assertRaises(pickle.PicklingError, self.dumps, non_ascii_str, 0)
2828 pickled = pickle.PERSID + non_ascii_str.encode('utf-8') + b'\n.'
2829 self.assertRaises(pickle.UnpicklingError, self.loads, pickled)
2830
2831
Collin Winter771d8342009-04-16 03:18:06 +00002832class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
2833
2834 pickler_class = None
2835 unpickler_class = None
2836
2837 def setUp(self):
2838 assert self.pickler_class
2839 assert self.unpickler_class
2840
2841 def test_clear_pickler_memo(self):
2842 # To test whether clear_memo() has any effect, we pickle an object,
2843 # then pickle it again without clearing the memo; the two serialized
2844 # forms should be different. If we clear_memo() and then pickle the
2845 # object again, the third serialized form should be identical to the
2846 # first one we obtained.
2847 data = ["abcdefg", "abcdefg", 44]
Serhiy Storchakac8695292018-04-04 00:11:27 +03002848 for proto in protocols:
2849 f = io.BytesIO()
2850 pickler = self.pickler_class(f, proto)
Collin Winter771d8342009-04-16 03:18:06 +00002851
Serhiy Storchakac8695292018-04-04 00:11:27 +03002852 pickler.dump(data)
2853 first_pickled = f.getvalue()
Collin Winter771d8342009-04-16 03:18:06 +00002854
Serhiy Storchakac8695292018-04-04 00:11:27 +03002855 # Reset BytesIO object.
2856 f.seek(0)
2857 f.truncate()
Collin Winter771d8342009-04-16 03:18:06 +00002858
Serhiy Storchakac8695292018-04-04 00:11:27 +03002859 pickler.dump(data)
2860 second_pickled = f.getvalue()
Collin Winter771d8342009-04-16 03:18:06 +00002861
Serhiy Storchakac8695292018-04-04 00:11:27 +03002862 # Reset the Pickler and BytesIO objects.
2863 pickler.clear_memo()
2864 f.seek(0)
2865 f.truncate()
Collin Winter771d8342009-04-16 03:18:06 +00002866
Serhiy Storchakac8695292018-04-04 00:11:27 +03002867 pickler.dump(data)
2868 third_pickled = f.getvalue()
Collin Winter771d8342009-04-16 03:18:06 +00002869
Serhiy Storchakac8695292018-04-04 00:11:27 +03002870 self.assertNotEqual(first_pickled, second_pickled)
2871 self.assertEqual(first_pickled, third_pickled)
Collin Winter771d8342009-04-16 03:18:06 +00002872
2873 def test_priming_pickler_memo(self):
2874 # Verify that we can set the Pickler's memo attribute.
2875 data = ["abcdefg", "abcdefg", 44]
2876 f = io.BytesIO()
2877 pickler = self.pickler_class(f)
2878
2879 pickler.dump(data)
2880 first_pickled = f.getvalue()
2881
2882 f = io.BytesIO()
2883 primed = self.pickler_class(f)
2884 primed.memo = pickler.memo
2885
2886 primed.dump(data)
2887 primed_pickled = f.getvalue()
2888
2889 self.assertNotEqual(first_pickled, primed_pickled)
2890
2891 def test_priming_unpickler_memo(self):
2892 # Verify that we can set the Unpickler's memo attribute.
2893 data = ["abcdefg", "abcdefg", 44]
2894 f = io.BytesIO()
2895 pickler = self.pickler_class(f)
2896
2897 pickler.dump(data)
2898 first_pickled = f.getvalue()
2899
2900 f = io.BytesIO()
2901 primed = self.pickler_class(f)
2902 primed.memo = pickler.memo
2903
2904 primed.dump(data)
2905 primed_pickled = f.getvalue()
2906
2907 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2908 unpickled_data1 = unpickler.load()
2909
2910 self.assertEqual(unpickled_data1, data)
2911
2912 primed = self.unpickler_class(io.BytesIO(primed_pickled))
2913 primed.memo = unpickler.memo
2914 unpickled_data2 = primed.load()
2915
2916 primed.memo.clear()
2917
2918 self.assertEqual(unpickled_data2, data)
2919 self.assertTrue(unpickled_data2 is unpickled_data1)
2920
2921 def test_reusing_unpickler_objects(self):
2922 data1 = ["abcdefg", "abcdefg", 44]
2923 f = io.BytesIO()
2924 pickler = self.pickler_class(f)
2925 pickler.dump(data1)
2926 pickled1 = f.getvalue()
2927
2928 data2 = ["abcdefg", 44, 44]
2929 f = io.BytesIO()
2930 pickler = self.pickler_class(f)
2931 pickler.dump(data2)
2932 pickled2 = f.getvalue()
2933
2934 f = io.BytesIO()
2935 f.write(pickled1)
2936 f.seek(0)
2937 unpickler = self.unpickler_class(f)
2938 self.assertEqual(unpickler.load(), data1)
2939
2940 f.seek(0)
2941 f.truncate()
2942 f.write(pickled2)
2943 f.seek(0)
2944 self.assertEqual(unpickler.load(), data2)
2945
Antoine Pitrou04248a82010-10-12 20:51:21 +00002946 def _check_multiple_unpicklings(self, ioclass):
2947 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002948 with self.subTest(proto=proto):
2949 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2950 f = ioclass()
2951 pickler = self.pickler_class(f, protocol=proto)
2952 pickler.dump(data1)
2953 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002954
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002955 N = 5
2956 f = ioclass(pickled * N)
2957 unpickler = self.unpickler_class(f)
2958 for i in range(N):
2959 if f.seekable():
2960 pos = f.tell()
2961 self.assertEqual(unpickler.load(), data1)
2962 if f.seekable():
2963 self.assertEqual(f.tell(), pos + len(pickled))
2964 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002965
2966 def test_multiple_unpicklings_seekable(self):
2967 self._check_multiple_unpicklings(io.BytesIO)
2968
2969 def test_multiple_unpicklings_unseekable(self):
2970 self._check_multiple_unpicklings(UnseekableIO)
2971
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002972 def test_unpickling_buffering_readline(self):
2973 # Issue #12687: the unpickler's buffering logic could fail with
2974 # text mode opcodes.
2975 data = list(range(10))
2976 for proto in protocols:
2977 for buf_size in range(1, 11):
2978 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2979 pickler = self.pickler_class(f, protocol=proto)
2980 pickler.dump(data)
2981 f.seek(0)
2982 unpickler = self.unpickler_class(f)
2983 self.assertEqual(unpickler.load(), data)
2984
Collin Winter771d8342009-04-16 03:18:06 +00002985
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002986# Tests for dispatch_table attribute
2987
2988REDUCE_A = 'reduce_A'
2989
2990class AAA(object):
2991 def __reduce__(self):
2992 return str, (REDUCE_A,)
2993
2994class BBB(object):
2995 pass
2996
2997class AbstractDispatchTableTests(unittest.TestCase):
2998
2999 def test_default_dispatch_table(self):
3000 # No dispatch_table attribute by default
3001 f = io.BytesIO()
3002 p = self.pickler_class(f, 0)
3003 with self.assertRaises(AttributeError):
3004 p.dispatch_table
3005 self.assertFalse(hasattr(p, 'dispatch_table'))
3006
3007 def test_class_dispatch_table(self):
3008 # A dispatch_table attribute can be specified class-wide
3009 dt = self.get_dispatch_table()
3010
3011 class MyPickler(self.pickler_class):
3012 dispatch_table = dt
3013
3014 def dumps(obj, protocol=None):
3015 f = io.BytesIO()
3016 p = MyPickler(f, protocol)
3017 self.assertEqual(p.dispatch_table, dt)
3018 p.dump(obj)
3019 return f.getvalue()
3020
3021 self._test_dispatch_table(dumps, dt)
3022
3023 def test_instance_dispatch_table(self):
3024 # A dispatch_table attribute can also be specified instance-wide
3025 dt = self.get_dispatch_table()
3026
3027 def dumps(obj, protocol=None):
3028 f = io.BytesIO()
3029 p = self.pickler_class(f, protocol)
3030 p.dispatch_table = dt
3031 self.assertEqual(p.dispatch_table, dt)
3032 p.dump(obj)
3033 return f.getvalue()
3034
3035 self._test_dispatch_table(dumps, dt)
3036
3037 def _test_dispatch_table(self, dumps, dispatch_table):
3038 def custom_load_dump(obj):
3039 return pickle.loads(dumps(obj, 0))
3040
3041 def default_load_dump(obj):
3042 return pickle.loads(pickle.dumps(obj, 0))
3043
3044 # pickling complex numbers using protocol 0 relies on copyreg
3045 # so check pickling a complex number still works
3046 z = 1 + 2j
3047 self.assertEqual(custom_load_dump(z), z)
3048 self.assertEqual(default_load_dump(z), z)
3049
3050 # modify pickling of complex
3051 REDUCE_1 = 'reduce_1'
3052 def reduce_1(obj):
3053 return str, (REDUCE_1,)
3054 dispatch_table[complex] = reduce_1
3055 self.assertEqual(custom_load_dump(z), REDUCE_1)
3056 self.assertEqual(default_load_dump(z), z)
3057
3058 # check picklability of AAA and BBB
3059 a = AAA()
3060 b = BBB()
3061 self.assertEqual(custom_load_dump(a), REDUCE_A)
3062 self.assertIsInstance(custom_load_dump(b), BBB)
3063 self.assertEqual(default_load_dump(a), REDUCE_A)
3064 self.assertIsInstance(default_load_dump(b), BBB)
3065
3066 # modify pickling of BBB
3067 dispatch_table[BBB] = reduce_1
3068 self.assertEqual(custom_load_dump(a), REDUCE_A)
3069 self.assertEqual(custom_load_dump(b), REDUCE_1)
3070 self.assertEqual(default_load_dump(a), REDUCE_A)
3071 self.assertIsInstance(default_load_dump(b), BBB)
3072
3073 # revert pickling of BBB and modify pickling of AAA
3074 REDUCE_2 = 'reduce_2'
3075 def reduce_2(obj):
3076 return str, (REDUCE_2,)
3077 dispatch_table[AAA] = reduce_2
3078 del dispatch_table[BBB]
3079 self.assertEqual(custom_load_dump(a), REDUCE_2)
3080 self.assertIsInstance(custom_load_dump(b), BBB)
3081 self.assertEqual(default_load_dump(a), REDUCE_A)
3082 self.assertIsInstance(default_load_dump(b), BBB)
3083
3084
Guido van Rossum98297ee2007-11-06 21:34:58 +00003085if __name__ == "__main__":
3086 # Print some stuff that can be used to rewrite DATA{0,1,2}
3087 from pickletools import dis
3088 x = create_data()
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03003089 for i in range(pickle.HIGHEST_PROTOCOL+1):
Guido van Rossum98297ee2007-11-06 21:34:58 +00003090 p = pickle.dumps(x, i)
3091 print("DATA{0} = (".format(i))
3092 for j in range(0, len(p), 20):
3093 b = bytes(p[j:j+20])
3094 print(" {0!r}".format(b))
3095 print(")")
3096 print()
3097 print("# Disassembly of DATA{0}".format(i))
3098 print("DATA{0}_DIS = \"\"\"\\".format(i))
3099 dis(p)
3100 print("\"\"\"")
3101 print()