blob: fd641e31617b62d063ff82e5d40ecf5c9d9e0765 [file] [log] [blame]
Serhiy Storchakabfe18242015-03-31 13:12:37 +03001import collections
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002import copyreg
Serhiy Storchakabfe18242015-03-31 13:12:37 +03003import dbm
Collin Winter771d8342009-04-16 03:18:06 +00004import io
Serhiy Storchakabfe18242015-03-31 13:12:37 +03005import functools
Tim Peters4190fb82003-02-02 16:09:05 +00006import pickle
Tim Peters31f119e2003-02-03 16:20:13 +00007import pickletools
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08008import struct
Antoine Pitrou82be19f2011-08-29 23:09:33 +02009import sys
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +010010import unittest
Antoine Pitrou16c4ce12011-03-11 21:30:43 +010011import weakref
Antoine Pitroud9dfaa92009-06-04 20:32:06 +000012from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +000013
Antoine Pitrou82be19f2011-08-29 23:09:33 +020014from test.support import (
Antoine Pitrouee763e22011-08-29 23:14:53 +020015 TestFailed, TESTFN, run_with_locale, no_tracing,
Antoine Pitrou94190bb2011-10-04 10:22:36 +020016 _2G, _4G, bigmemtest,
Antoine Pitrou82be19f2011-08-29 23:09:33 +020017 )
Tim Peterse089c682001-04-10 03:41:41 +000018
Guido van Rossum98297ee2007-11-06 21:34:58 +000019from pickle import bytes_types
20
Serhiy Storchakac6b54b42015-09-29 15:33:24 +030021requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
22 "test is only meaningful on 32-bit builds")
23
Tim Petersee1a53c2003-02-02 02:57:53 +000024# Tests that try a number of pickle protocols should have a
25# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000026# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000027protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000028
Tim Peters22e71712003-02-03 22:27:38 +000029
30# Return True if opcode code appears in the pickle, else False.
31def opcode_in_pickle(code, pickle):
32 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000033 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000034 return True
35 return False
36
Tim Peters8d2613a2003-02-11 16:40:16 +000037# Return the number of times opcode code appears in pickle.
38def count_opcode(code, pickle):
39 n = 0
40 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000041 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000042 n += 1
43 return n
44
Antoine Pitrou04248a82010-10-12 20:51:21 +000045
46class UnseekableIO(io.BytesIO):
47 def peek(self, *args):
48 raise NotImplementedError
49
50 def seekable(self):
51 return False
52
53 def seek(self, *args):
54 raise io.UnsupportedOperation
55
56 def tell(self):
57 raise io.UnsupportedOperation
58
59
Tim Peters3e667d52003-02-04 21:47:44 +000060# We can't very well test the extension registry without putting known stuff
61# in it, but we have to be careful to restore its original state. Code
62# should do this:
63#
64# e = ExtensionSaver(extension_code)
65# try:
66# fiddle w/ the extension registry's stuff for extension_code
67# finally:
68# e.restore()
69
70class ExtensionSaver:
71 # Remember current registration for code (if any), and remove it (if
72 # there is one).
73 def __init__(self, code):
74 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000075 if code in copyreg._inverted_registry:
76 self.pair = copyreg._inverted_registry[code]
77 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000078 else:
79 self.pair = None
80
81 # Restore previous registration for code.
82 def restore(self):
83 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000084 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000085 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000086 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000087 pair = self.pair
88 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000089 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000090
Jeremy Hylton66426532001-10-15 21:38:56 +000091class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000092 def __eq__(self, other):
93 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000094
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000095class D(C):
96 def __init__(self, arg):
97 pass
98
99class E(C):
100 def __getinitargs__(self):
101 return ()
102
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100103class H(object):
104 pass
105
Jeremy Hylton66426532001-10-15 21:38:56 +0000106import __main__
107__main__.C = C
108C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000109__main__.D = D
110D.__module__ = "__main__"
111__main__.E = E
112E.__module__ = "__main__"
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100113__main__.H = H
114H.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000115
116class myint(int):
117 def __init__(self, x):
118 self.str = str(x)
119
120class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000121
Jeremy Hylton66426532001-10-15 21:38:56 +0000122 def __init__(self, a, b):
123 self.a = a
124 self.b = b
125
126 def __getinitargs__(self):
127 return self.a, self.b
128
Guido van Rossum04a86612001-12-19 16:58:54 +0000129class metaclass(type):
130 pass
131
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000132class use_metaclass(object, metaclass=metaclass):
133 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000134
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200135class pickling_metaclass(type):
136 def __eq__(self, other):
137 return (type(self) == type(other) and
138 self.reduce_args == other.reduce_args)
139
140 def __reduce__(self):
141 return (create_dynamic_class, self.reduce_args)
142
143def create_dynamic_class(name, bases):
144 result = pickling_metaclass(name, bases, dict())
145 result.reduce_args = (name, bases)
146 return result
147
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300148# DATA0 .. DATA4 are the pickles we expect under the various protocols, for
Tim Peters70b02d72003-02-02 17:26:40 +0000149# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000150
Guido van Rossum98297ee2007-11-06 21:34:58 +0000151DATA0 = (
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200152 b'(lp0\nL0L\naL1L\naF2.0\n'
153 b'ac__builtin__\ncomple'
154 b'x\np1\n(F3.0\nF0.0\ntp2\n'
155 b'Rp3\naL1L\naL-1L\naL255'
156 b'L\naL-255L\naL-256L\naL'
157 b'65535L\naL-65535L\naL-'
158 b'65536L\naL2147483647L'
159 b'\naL-2147483647L\naL-2'
160 b'147483648L\na(Vabc\np4'
161 b'\ng4\nccopy_reg\n_recon'
162 b'structor\np5\n(c__main'
163 b'__\nC\np6\nc__builtin__'
164 b'\nobject\np7\nNtp8\nRp9\n'
165 b'(dp10\nVfoo\np11\nL1L\ns'
166 b'Vbar\np12\nL2L\nsbg9\ntp'
167 b'13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000168)
Tim Peterse9358162001-01-22 22:05:20 +0000169
Guido van Rossum98297ee2007-11-06 21:34:58 +0000170# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000171DATA0_DIS = """\
172 0: ( MARK
173 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000174 2: p PUT 0
175 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000176 9: a APPEND
177 10: L LONG 1
178 14: a APPEND
179 15: F FLOAT 2.0
180 20: a APPEND
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200181 21: c GLOBAL '__builtin__ complex'
182 42: p PUT 1
183 45: ( MARK
184 46: F FLOAT 3.0
185 51: F FLOAT 0.0
186 56: t TUPLE (MARK at 45)
187 57: p PUT 2
188 60: R REDUCE
189 61: p PUT 3
190 64: a APPEND
191 65: L LONG 1
192 69: a APPEND
193 70: L LONG -1
194 75: a APPEND
195 76: L LONG 255
196 82: a APPEND
197 83: L LONG -255
198 90: a APPEND
199 91: L LONG -256
200 98: a APPEND
201 99: L LONG 65535
202 107: a APPEND
203 108: L LONG -65535
204 117: a APPEND
205 118: L LONG -65536
206 127: a APPEND
207 128: L LONG 2147483647
208 141: a APPEND
209 142: L LONG -2147483647
210 156: a APPEND
211 157: L LONG -2147483648
212 171: a APPEND
213 172: ( MARK
214 173: V UNICODE 'abc'
215 178: p PUT 4
216 181: g GET 4
217 184: c GLOBAL 'copy_reg _reconstructor'
218 209: p PUT 5
219 212: ( MARK
220 213: c GLOBAL '__main__ C'
221 225: p PUT 6
222 228: c GLOBAL '__builtin__ object'
223 248: p PUT 7
224 251: N NONE
225 252: t TUPLE (MARK at 212)
226 253: p PUT 8
227 256: R REDUCE
228 257: p PUT 9
229 260: ( MARK
230 261: d DICT (MARK at 260)
231 262: p PUT 10
232 266: V UNICODE 'foo'
233 271: p PUT 11
234 275: L LONG 1
235 279: s SETITEM
236 280: V UNICODE 'bar'
237 285: p PUT 12
238 289: L LONG 2
239 293: s SETITEM
240 294: b BUILD
241 295: g GET 9
242 298: t TUPLE (MARK at 172)
243 299: p PUT 13
244 303: a APPEND
245 304: g GET 13
246 308: a APPEND
247 309: L LONG 5
248 313: a APPEND
249 314: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000250highest protocol among opcodes = 0
251"""
252
Guido van Rossum98297ee2007-11-06 21:34:58 +0000253DATA1 = (
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200254 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c__'
255 b'builtin__\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000256 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
257 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
258 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
259 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200260 b'cq\x04h\x04ccopy_reg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000261 b'nstructor\nq\x05(c__main'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200262 b'__\nC\nq\x06c__builtin__\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000263 b'object\nq\x07Ntq\x08Rq\t}q\n('
264 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
265 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
266)
Tim Peters70b02d72003-02-02 17:26:40 +0000267
Guido van Rossum98297ee2007-11-06 21:34:58 +0000268# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000269DATA1_DIS = """\
270 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000271 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000272 3: ( MARK
273 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000274 6: K BININT1 1
275 8: G BINFLOAT 2.0
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200276 17: c GLOBAL '__builtin__ complex'
277 38: q BINPUT 1
278 40: ( MARK
279 41: G BINFLOAT 3.0
280 50: G BINFLOAT 0.0
281 59: t TUPLE (MARK at 40)
282 60: q BINPUT 2
283 62: R REDUCE
284 63: q BINPUT 3
285 65: K BININT1 1
286 67: J BININT -1
287 72: K BININT1 255
288 74: J BININT -255
289 79: J BININT -256
290 84: M BININT2 65535
291 87: J BININT -65535
292 92: J BININT -65536
293 97: J BININT 2147483647
294 102: J BININT -2147483647
295 107: J BININT -2147483648
296 112: ( MARK
297 113: X BINUNICODE 'abc'
298 121: q BINPUT 4
299 123: h BINGET 4
300 125: c GLOBAL 'copy_reg _reconstructor'
301 150: q BINPUT 5
302 152: ( MARK
303 153: c GLOBAL '__main__ C'
304 165: q BINPUT 6
305 167: c GLOBAL '__builtin__ object'
306 187: q BINPUT 7
307 189: N NONE
308 190: t TUPLE (MARK at 152)
309 191: q BINPUT 8
310 193: R REDUCE
311 194: q BINPUT 9
312 196: } EMPTY_DICT
313 197: q BINPUT 10
314 199: ( MARK
315 200: X BINUNICODE 'foo'
316 208: q BINPUT 11
317 210: K BININT1 1
318 212: X BINUNICODE 'bar'
319 220: q BINPUT 12
320 222: K BININT1 2
321 224: u SETITEMS (MARK at 199)
322 225: b BUILD
323 226: h BINGET 9
324 228: t TUPLE (MARK at 112)
325 229: q BINPUT 13
326 231: h BINGET 13
327 233: K BININT1 5
328 235: e APPENDS (MARK at 3)
329 236: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000330highest protocol among opcodes = 1
331"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000332
Guido van Rossum98297ee2007-11-06 21:34:58 +0000333DATA2 = (
334 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200335 b'__builtin__\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000336 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
337 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
338 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
339 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
340 b'bcq\x04h\x04c__main__\nC\nq\x05'
341 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
342 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
343 b'\nK\x05e.'
344)
Tim Petersfc273752003-03-02 04:54:24 +0000345
Guido van Rossum98297ee2007-11-06 21:34:58 +0000346# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000347DATA2_DIS = """\
348 0: \x80 PROTO 2
349 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000350 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000351 5: ( MARK
352 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000353 8: K BININT1 1
354 10: G BINFLOAT 2.0
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200355 19: c GLOBAL '__builtin__ complex'
356 40: q BINPUT 1
357 42: G BINFLOAT 3.0
358 51: G BINFLOAT 0.0
359 60: \x86 TUPLE2
360 61: q BINPUT 2
361 63: R REDUCE
362 64: q BINPUT 3
363 66: K BININT1 1
364 68: J BININT -1
365 73: K BININT1 255
366 75: J BININT -255
367 80: J BININT -256
368 85: M BININT2 65535
369 88: J BININT -65535
370 93: J BININT -65536
371 98: J BININT 2147483647
372 103: J BININT -2147483647
373 108: J BININT -2147483648
374 113: ( MARK
375 114: X BINUNICODE 'abc'
376 122: q BINPUT 4
377 124: h BINGET 4
378 126: c GLOBAL '__main__ C'
379 138: q BINPUT 5
380 140: ) EMPTY_TUPLE
381 141: \x81 NEWOBJ
382 142: q BINPUT 6
383 144: } EMPTY_DICT
384 145: q BINPUT 7
385 147: ( MARK
386 148: X BINUNICODE 'foo'
387 156: q BINPUT 8
388 158: K BININT1 1
389 160: X BINUNICODE 'bar'
390 168: q BINPUT 9
391 170: K BININT1 2
392 172: u SETITEMS (MARK at 147)
393 173: b BUILD
394 174: h BINGET 6
395 176: t TUPLE (MARK at 113)
396 177: q BINPUT 10
397 179: h BINGET 10
398 181: K BININT1 5
399 183: e APPENDS (MARK at 5)
400 184: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000401highest protocol among opcodes = 2
402"""
403
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300404DATA3 = (
405 b'\x80\x03]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
406 b'builtins\ncomplex\nq\x01G'
407 b'@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00\x86q\x02'
408 b'Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff'
409 b'\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7f'
410 b'J\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00abcq'
411 b'\x04h\x04c__main__\nC\nq\x05)\x81q'
412 b'\x06}q\x07(X\x03\x00\x00\x00barq\x08K\x02X\x03\x00'
413 b'\x00\x00fooq\tK\x01ubh\x06tq\nh\nK\x05'
414 b'e.'
415)
416
417# Disassembly of DATA3
418DATA3_DIS = """\
419 0: \x80 PROTO 3
420 2: ] EMPTY_LIST
421 3: q BINPUT 0
422 5: ( MARK
423 6: K BININT1 0
424 8: K BININT1 1
425 10: G BINFLOAT 2.0
426 19: c GLOBAL 'builtins complex'
427 37: q BINPUT 1
428 39: G BINFLOAT 3.0
429 48: G BINFLOAT 0.0
430 57: \x86 TUPLE2
431 58: q BINPUT 2
432 60: R REDUCE
433 61: q BINPUT 3
434 63: K BININT1 1
435 65: J BININT -1
436 70: K BININT1 255
437 72: J BININT -255
438 77: J BININT -256
439 82: M BININT2 65535
440 85: J BININT -65535
441 90: J BININT -65536
442 95: J BININT 2147483647
443 100: J BININT -2147483647
444 105: J BININT -2147483648
445 110: ( MARK
446 111: X BINUNICODE 'abc'
447 119: q BINPUT 4
448 121: h BINGET 4
449 123: c GLOBAL '__main__ C'
450 135: q BINPUT 5
451 137: ) EMPTY_TUPLE
452 138: \x81 NEWOBJ
453 139: q BINPUT 6
454 141: } EMPTY_DICT
455 142: q BINPUT 7
456 144: ( MARK
457 145: X BINUNICODE 'bar'
458 153: q BINPUT 8
459 155: K BININT1 2
460 157: X BINUNICODE 'foo'
461 165: q BINPUT 9
462 167: K BININT1 1
463 169: u SETITEMS (MARK at 144)
464 170: b BUILD
465 171: h BINGET 6
466 173: t TUPLE (MARK at 110)
467 174: q BINPUT 10
468 176: h BINGET 10
469 178: K BININT1 5
470 180: e APPENDS (MARK at 5)
471 181: . STOP
472highest protocol among opcodes = 2
473"""
474
475DATA4 = (
476 b'\x80\x04\x95\xa8\x00\x00\x00\x00\x00\x00\x00]\x94(K\x00K\x01G@'
477 b'\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x07'
478 b'complex\x94\x93\x94G@\x08\x00\x00\x00\x00\x00\x00G'
479 b'\x00\x00\x00\x00\x00\x00\x00\x00\x86\x94R\x94K\x01J\xff\xff\xff\xffK'
480 b'\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ'
481 b'\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80('
482 b'\x8c\x03abc\x94h\x06\x8c\x08__main__\x94\x8c'
483 b'\x01C\x94\x93\x94)\x81\x94}\x94(\x8c\x03bar\x94K\x02\x8c'
484 b'\x03foo\x94K\x01ubh\nt\x94h\x0eK\x05e.'
485)
486
487# Disassembly of DATA4
488DATA4_DIS = """\
489 0: \x80 PROTO 4
490 2: \x95 FRAME 168
491 11: ] EMPTY_LIST
492 12: \x94 MEMOIZE
493 13: ( MARK
494 14: K BININT1 0
495 16: K BININT1 1
496 18: G BINFLOAT 2.0
497 27: \x8c SHORT_BINUNICODE 'builtins'
498 37: \x94 MEMOIZE
499 38: \x8c SHORT_BINUNICODE 'complex'
500 47: \x94 MEMOIZE
501 48: \x93 STACK_GLOBAL
502 49: \x94 MEMOIZE
503 50: G BINFLOAT 3.0
504 59: G BINFLOAT 0.0
505 68: \x86 TUPLE2
506 69: \x94 MEMOIZE
507 70: R REDUCE
508 71: \x94 MEMOIZE
509 72: K BININT1 1
510 74: J BININT -1
511 79: K BININT1 255
512 81: J BININT -255
513 86: J BININT -256
514 91: M BININT2 65535
515 94: J BININT -65535
516 99: J BININT -65536
517 104: J BININT 2147483647
518 109: J BININT -2147483647
519 114: J BININT -2147483648
520 119: ( MARK
521 120: \x8c SHORT_BINUNICODE 'abc'
522 125: \x94 MEMOIZE
523 126: h BINGET 6
524 128: \x8c SHORT_BINUNICODE '__main__'
525 138: \x94 MEMOIZE
526 139: \x8c SHORT_BINUNICODE 'C'
527 142: \x94 MEMOIZE
528 143: \x93 STACK_GLOBAL
529 144: \x94 MEMOIZE
530 145: ) EMPTY_TUPLE
531 146: \x81 NEWOBJ
532 147: \x94 MEMOIZE
533 148: } EMPTY_DICT
534 149: \x94 MEMOIZE
535 150: ( MARK
536 151: \x8c SHORT_BINUNICODE 'bar'
537 156: \x94 MEMOIZE
538 157: K BININT1 2
539 159: \x8c SHORT_BINUNICODE 'foo'
540 164: \x94 MEMOIZE
541 165: K BININT1 1
542 167: u SETITEMS (MARK at 150)
543 168: b BUILD
544 169: h BINGET 10
545 171: t TUPLE (MARK at 119)
546 172: \x94 MEMOIZE
547 173: h BINGET 14
548 175: K BININT1 5
549 177: e APPENDS (MARK at 13)
550 178: . STOP
551highest protocol among opcodes = 4
552"""
553
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000554# set([1,2]) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300555DATA_SET = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000556
557# xrange(5) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300558DATA_XRANGE = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000559
560# a SimpleCookie() object pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300561DATA_COOKIE = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
562 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
563 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
564 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
565 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
566 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000567
568# set([3]) pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300569DATA_SET2 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000570
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100571python2_exceptions_without_args = (
572 ArithmeticError,
573 AssertionError,
574 AttributeError,
575 BaseException,
576 BufferError,
577 BytesWarning,
578 DeprecationWarning,
579 EOFError,
580 EnvironmentError,
581 Exception,
582 FloatingPointError,
583 FutureWarning,
584 GeneratorExit,
585 IOError,
586 ImportError,
587 ImportWarning,
588 IndentationError,
589 IndexError,
590 KeyError,
591 KeyboardInterrupt,
592 LookupError,
593 MemoryError,
594 NameError,
595 NotImplementedError,
596 OSError,
597 OverflowError,
598 PendingDeprecationWarning,
599 ReferenceError,
600 RuntimeError,
601 RuntimeWarning,
602 # StandardError is gone in Python 3, we map it to Exception
603 StopIteration,
604 SyntaxError,
605 SyntaxWarning,
606 SystemError,
607 SystemExit,
608 TabError,
609 TypeError,
610 UnboundLocalError,
611 UnicodeError,
612 UnicodeWarning,
613 UserWarning,
614 ValueError,
615 Warning,
616 ZeroDivisionError,
617)
618
619exception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.'
620
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100621# UnicodeEncodeError object pickled from 2.x with protocol 2
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300622DATA_UEERR = (b'\x80\x02cexceptions\nUnicodeEncodeError\n'
623 b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01'
624 b'U\x03badq\x03tq\x04Rq\x05.')
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100625
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000626
Jeremy Hylton66426532001-10-15 21:38:56 +0000627def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000628 c = C()
629 c.foo = 1
630 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000631 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000632 # Append some integer test cases at cPickle.c's internal size
633 # cutoffs.
634 uint1max = 0xff
635 uint2max = 0xffff
636 int4max = 0x7fffffff
637 x.extend([1, -1,
638 uint1max, -uint1max, -uint1max-1,
639 uint2max, -uint2max, -uint2max-1,
640 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000641 y = ('abc', 'abc', c, c)
642 x.append(y)
643 x.append(y)
644 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000645 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000646
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100647
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300648class AbstractUnpickleTests(unittest.TestCase):
649 # Subclass must define self.loads.
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +0100650
Jeremy Hylton66426532001-10-15 21:38:56 +0000651 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000652
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100653 def assert_is_copy(self, obj, objcopy, msg=None):
654 """Utility method to verify if two objects are copies of each others.
655 """
656 if msg is None:
657 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
658 self.assertEqual(obj, objcopy, msg=msg)
659 self.assertIs(type(obj), type(objcopy), msg=msg)
660 if hasattr(obj, '__dict__'):
661 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
662 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
663 if hasattr(obj, '__slots__'):
664 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
665 for slot in obj.__slots__:
666 self.assertEqual(
667 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
668 self.assertEqual(getattr(obj, slot, None),
669 getattr(objcopy, slot, None), msg=msg)
670
Guido van Rossum98297ee2007-11-06 21:34:58 +0000671 def test_load_from_data0(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100672 self.assert_is_copy(self._testdata, self.loads(DATA0))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000673
674 def test_load_from_data1(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100675 self.assert_is_copy(self._testdata, self.loads(DATA1))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000676
677 def test_load_from_data2(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100678 self.assert_is_copy(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000679
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300680 def test_load_from_data3(self):
681 self.assert_is_copy(self._testdata, self.loads(DATA3))
682
683 def test_load_from_data4(self):
684 self.assert_is_copy(self._testdata, self.loads(DATA4))
685
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000686 def test_load_classic_instance(self):
687 # See issue5180. Test loading 2.x pickles that
688 # contain an instance of old style class.
689 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
690 xname = X.__name__.encode('ascii')
691 # Protocol 0 (text mode pickle):
692 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200693 0: ( MARK
694 1: i INST '__main__ X' (MARK at 0)
695 13: p PUT 0
696 16: ( MARK
697 17: d DICT (MARK at 16)
698 18: p PUT 1
699 21: b BUILD
700 22: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000701 """
702 pickle0 = (b"(i__main__\n"
703 b"X\n"
704 b"p0\n"
705 b"(dp1\nb.").replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100706 self.assert_is_copy(X(*args), self.loads(pickle0))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000707
708 # Protocol 1 (binary mode pickle)
709 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200710 0: ( MARK
711 1: c GLOBAL '__main__ X'
712 13: q BINPUT 0
713 15: o OBJ (MARK at 0)
714 16: q BINPUT 1
715 18: } EMPTY_DICT
716 19: q BINPUT 2
717 21: b BUILD
718 22: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000719 """
720 pickle1 = (b'(c__main__\n'
721 b'X\n'
722 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100723 self.assert_is_copy(X(*args), self.loads(pickle1))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000724
725 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
726 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200727 0: \x80 PROTO 2
728 2: ( MARK
729 3: c GLOBAL '__main__ X'
730 15: q BINPUT 0
731 17: o OBJ (MARK at 2)
732 18: q BINPUT 1
733 20: } EMPTY_DICT
734 21: q BINPUT 2
735 23: b BUILD
736 24: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000737 """
738 pickle2 = (b'\x80\x02(c__main__\n'
739 b'X\n'
740 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100741 self.assert_is_copy(X(*args), self.loads(pickle2))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000742
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300743 def test_maxint64(self):
744 maxint64 = (1 << 63) - 1
745 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
746 got = self.loads(data)
747 self.assert_is_copy(maxint64, got)
748
749 # Try too with a bogus literal.
750 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
751 self.assertRaises(ValueError, self.loads, data)
752
753 def test_pop_empty_stack(self):
754 # Test issue7455
755 s = b'0'
756 self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s)
757
758 def test_unpickle_from_2x(self):
759 # Unpickle non-trivial data from Python 2.x.
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300760 loaded = self.loads(DATA_SET)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300761 self.assertEqual(loaded, set([1, 2]))
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300762 loaded = self.loads(DATA_XRANGE)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300763 self.assertEqual(type(loaded), type(range(0)))
764 self.assertEqual(list(loaded), list(range(5)))
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300765 loaded = self.loads(DATA_COOKIE)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300766 self.assertEqual(type(loaded), SimpleCookie)
767 self.assertEqual(list(loaded.keys()), ["key"])
768 self.assertEqual(loaded["key"].value, "value")
769
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300770 # Exception objects without arguments pickled from 2.x with protocol 2
771 for exc in python2_exceptions_without_args:
772 data = exception_pickle.replace(b'?', exc.__name__.encode("ascii"))
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300773 loaded = self.loads(data)
774 self.assertIs(type(loaded), exc)
775
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300776 # StandardError is mapped to Exception, test that separately
777 loaded = self.loads(exception_pickle.replace(b'?', b'StandardError'))
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300778 self.assertIs(type(loaded), Exception)
779
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300780 loaded = self.loads(DATA_UEERR)
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300781 self.assertIs(type(loaded), UnicodeEncodeError)
782 self.assertEqual(loaded.object, "foo")
783 self.assertEqual(loaded.encoding, "ascii")
784 self.assertEqual(loaded.start, 0)
785 self.assertEqual(loaded.end, 1)
786 self.assertEqual(loaded.reason, "bad")
787
788 def test_load_python2_str_as_bytes(self):
789 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
790 self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
791 encoding="bytes"), b'a\x00\xa0')
792 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
793 self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
794 encoding="bytes"), b'a\x00\xa0')
795 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
796 self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
797 encoding="bytes"), b'a\x00\xa0')
798
799 def test_load_python2_unicode_as_str(self):
800 # From Python 2: pickle.dumps(u'π', protocol=0)
801 self.assertEqual(self.loads(b'V\\u03c0\n.',
802 encoding='bytes'), 'π')
803 # From Python 2: pickle.dumps(u'π', protocol=1)
804 self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
805 encoding="bytes"), 'π')
806 # From Python 2: pickle.dumps(u'π', protocol=2)
807 self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
808 encoding="bytes"), 'π')
809
810 def test_load_long_python2_str_as_bytes(self):
811 # From Python 2: pickle.dumps('x' * 300, protocol=1)
812 self.assertEqual(self.loads(pickle.BINSTRING +
813 struct.pack("<I", 300) +
814 b'x' * 300 + pickle.STOP,
815 encoding='bytes'), b'x' * 300)
816
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300817 def test_constants(self):
818 self.assertIsNone(self.loads(b'N.'))
819 self.assertIs(self.loads(b'\x88.'), True)
820 self.assertIs(self.loads(b'\x89.'), False)
821 self.assertIs(self.loads(b'I01\n.'), True)
822 self.assertIs(self.loads(b'I00\n.'), False)
823
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300824 def test_empty_bytestring(self):
825 # issue 11286
826 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
827 self.assertEqual(empty, '')
828
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300829 def test_short_binbytes(self):
830 dumped = b'\x80\x03C\x04\xe2\x82\xac\x00.'
831 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
832
833 def test_binbytes(self):
834 dumped = b'\x80\x03B\x04\x00\x00\x00\xe2\x82\xac\x00.'
835 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
836
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300837 @requires_32b
838 def test_negative_32b_binbytes(self):
839 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
840 dumped = b'\x80\x03B\xff\xff\xff\xffxyzq\x00.'
841 with self.assertRaises((pickle.UnpicklingError, OverflowError)):
842 self.loads(dumped)
843
844 @requires_32b
845 def test_negative_32b_binunicode(self):
846 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
847 dumped = b'\x80\x03X\xff\xff\xff\xffxyzq\x00.'
848 with self.assertRaises((pickle.UnpicklingError, OverflowError)):
849 self.loads(dumped)
850
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300851 def test_short_binunicode(self):
852 dumped = b'\x80\x04\x8c\x04\xe2\x82\xac\x00.'
853 self.assertEqual(self.loads(dumped), '\u20ac\x00')
854
855 def test_misc_get(self):
856 self.assertRaises(KeyError, self.loads, b'g0\np0')
857 self.assert_is_copy([(100,), (100,)],
858 self.loads(b'((Kdtp0\nh\x00l.))'))
859
Serhiy Storchakae0606192015-09-29 22:10:07 +0300860 def test_binbytes8(self):
861 dumped = b'\x80\x04\x8e\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
862 self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
863
864 def test_binunicode8(self):
865 dumped = b'\x80\x04\x8d\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
866 self.assertEqual(self.loads(dumped), '\u20ac\x00')
867
868 @requires_32b
869 def test_large_32b_binbytes8(self):
870 dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
871 with self.assertRaises((pickle.UnpicklingError, OverflowError)):
872 self.loads(dumped)
873
874 @requires_32b
875 def test_large_32b_binunicode8(self):
876 dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
877 with self.assertRaises((pickle.UnpicklingError, OverflowError)):
878 self.loads(dumped)
879
Serhiy Storchakab8b951f2015-09-29 15:49:58 +0300880 def test_get(self):
881 pickled = b'((lp100000\ng100000\nt.'
882 unpickled = self.loads(pickled)
883 self.assertEqual(unpickled, ([],)*2)
884 self.assertIs(unpickled[0], unpickled[1])
885
886 def test_binget(self):
887 pickled = b'(]q\xffh\xfft.'
888 unpickled = self.loads(pickled)
889 self.assertEqual(unpickled, ([],)*2)
890 self.assertIs(unpickled[0], unpickled[1])
891
892 def test_long_binget(self):
893 pickled = b'(]r\x00\x00\x01\x00j\x00\x00\x01\x00t.'
894 unpickled = self.loads(pickled)
895 self.assertEqual(unpickled, ([],)*2)
896 self.assertIs(unpickled[0], unpickled[1])
897
898 def test_dup(self):
899 pickled = b'((l2t.'
900 unpickled = self.loads(pickled)
901 self.assertEqual(unpickled, ([],)*2)
902 self.assertIs(unpickled[0], unpickled[1])
903
Serhiy Storchakac6b54b42015-09-29 15:33:24 +0300904 def test_negative_put(self):
905 # Issue #12847
906 dumped = b'Va\np-1\n.'
907 self.assertRaises(ValueError, self.loads, dumped)
908
909 @requires_32b
910 def test_negative_32b_binput(self):
911 # Issue #12847
912 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
913 self.assertRaises(ValueError, self.loads, dumped)
914
915 def test_badly_escaped_string(self):
916 self.assertRaises(ValueError, self.loads, b"S'\\'\n.")
917
918 def test_badly_quoted_string(self):
919 # Issue #17710
920 badpickles = [b"S'\n.",
921 b'S"\n.',
922 b'S\' \n.',
923 b'S" \n.',
924 b'S\'"\n.',
925 b'S"\'\n.',
926 b"S' ' \n.",
927 b'S" " \n.',
928 b"S ''\n.",
929 b'S ""\n.',
930 b'S \n.',
931 b'S\n.',
932 b'S.']
933 for p in badpickles:
934 self.assertRaises(pickle.UnpicklingError, self.loads, p)
935
936 def test_correctly_quoted_string(self):
937 goodpickles = [(b"S''\n.", ''),
938 (b'S""\n.', ''),
939 (b'S"\\n"\n.', '\n'),
940 (b"S'\\n'\n.", '\n')]
941 for p, expected in goodpickles:
942 self.assertEqual(self.loads(p), expected)
943
944 def test_frame_readline(self):
945 pickled = b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00I42\n.'
946 # 0: \x80 PROTO 4
947 # 2: \x95 FRAME 5
948 # 11: I INT 42
949 # 15: . STOP
950 self.assertEqual(self.loads(pickled), 42)
951
952 def test_compat_unpickle(self):
953 # xrange(1, 7)
954 pickled = b'\x80\x02c__builtin__\nxrange\nK\x01K\x07K\x01\x87R.'
955 unpickled = self.loads(pickled)
956 self.assertIs(type(unpickled), range)
957 self.assertEqual(unpickled, range(1, 7))
958 self.assertEqual(list(unpickled), [1, 2, 3, 4, 5, 6])
959 # reduce
960 pickled = b'\x80\x02c__builtin__\nreduce\n.'
961 self.assertIs(self.loads(pickled), functools.reduce)
962 # whichdb.whichdb
963 pickled = b'\x80\x02cwhichdb\nwhichdb\n.'
964 self.assertIs(self.loads(pickled), dbm.whichdb)
965 # Exception(), StandardError()
966 for name in (b'Exception', b'StandardError'):
967 pickled = (b'\x80\x02cexceptions\n' + name + b'\nU\x03ugh\x85R.')
968 unpickled = self.loads(pickled)
969 self.assertIs(type(unpickled), Exception)
970 self.assertEqual(str(unpickled), 'ugh')
971 # UserDict.UserDict({1: 2}), UserDict.IterableUserDict({1: 2})
972 for name in (b'UserDict', b'IterableUserDict'):
973 pickled = (b'\x80\x02(cUserDict\n' + name +
974 b'\no}U\x04data}K\x01K\x02ssb.')
975 unpickled = self.loads(pickled)
976 self.assertIs(type(unpickled), collections.UserDict)
977 self.assertEqual(unpickled, collections.UserDict({1: 2}))
978
979
980class AbstractPickleTests(unittest.TestCase):
981 # Subclass must define self.dumps, self.loads.
982
983 optimized = False
984
985 _testdata = AbstractUnpickleTests._testdata
986
987 def setUp(self):
988 pass
989
990 assert_is_copy = AbstractUnpickleTests.assert_is_copy
991
992 def test_misc(self):
993 # test various datatypes not tested by testdata
994 for proto in protocols:
995 x = myint(4)
996 s = self.dumps(x, proto)
997 y = self.loads(s)
998 self.assert_is_copy(x, y)
999
1000 x = (1, ())
1001 s = self.dumps(x, proto)
1002 y = self.loads(s)
1003 self.assert_is_copy(x, y)
1004
1005 x = initarg(1, x)
1006 s = self.dumps(x, proto)
1007 y = self.loads(s)
1008 self.assert_is_copy(x, y)
1009
1010 # XXX test __reduce__ protocol?
1011
1012 def test_roundtrip_equality(self):
1013 expected = self._testdata
1014 for proto in protocols:
1015 s = self.dumps(expected, proto)
1016 got = self.loads(s)
1017 self.assert_is_copy(expected, got)
1018
Tim Peters70b02d72003-02-02 17:26:40 +00001019 # There are gratuitous differences between pickles produced by
1020 # pickle and cPickle, largely because cPickle starts PUT indices at
1021 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
1022 # there's a comment with an exclamation point there whose meaning
1023 # is a mystery. cPickle also suppresses PUT for objects with a refcount
1024 # of 1.
1025 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +00001026 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +00001027 from pickletools import dis
1028
1029 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
1030 s = self.dumps(self._testdata, proto)
1031 filelike = StringIO()
1032 dis(s, out=filelike)
1033 got = filelike.getvalue()
1034 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +00001035
1036 def test_recursive_list(self):
1037 l = []
1038 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +00001039 for proto in protocols:
1040 s = self.dumps(l, proto)
1041 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001042 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001043 self.assertEqual(len(x), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001044 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +00001045
Collin Winter8ca69de2009-05-26 16:53:41 +00001046 def test_recursive_tuple(self):
1047 t = ([],)
1048 t[0].append(t)
1049 for proto in protocols:
1050 s = self.dumps(t, proto)
1051 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001052 self.assertIsInstance(x, tuple)
Collin Winter8ca69de2009-05-26 16:53:41 +00001053 self.assertEqual(len(x), 1)
1054 self.assertEqual(len(x[0]), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001055 self.assertTrue(x is x[0][0])
Collin Winter8ca69de2009-05-26 16:53:41 +00001056
Jeremy Hylton66426532001-10-15 21:38:56 +00001057 def test_recursive_dict(self):
1058 d = {}
1059 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +00001060 for proto in protocols:
1061 s = self.dumps(d, proto)
1062 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001063 self.assertIsInstance(x, dict)
Guido van Rossumcc2b0162007-02-11 06:12:03 +00001064 self.assertEqual(list(x.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001065 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001066
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001067 def test_recursive_set(self):
1068 h = H()
1069 y = set({h})
1070 h.attr = y
1071 for proto in protocols:
1072 s = self.dumps(y, proto)
1073 x = self.loads(s)
1074 self.assertIsInstance(x, set)
1075 self.assertIs(list(x)[0].attr, x)
1076 self.assertEqual(len(x), 1)
1077
1078 def test_recursive_frozenset(self):
1079 h = H()
1080 y = frozenset({h})
1081 h.attr = y
1082 for proto in protocols:
1083 s = self.dumps(y, proto)
1084 x = self.loads(s)
1085 self.assertIsInstance(x, frozenset)
1086 self.assertIs(list(x)[0].attr, x)
1087 self.assertEqual(len(x), 1)
1088
Jeremy Hylton66426532001-10-15 21:38:56 +00001089 def test_recursive_inst(self):
1090 i = C()
1091 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +00001092 for proto in protocols:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001093 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +00001094 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001095 self.assertIsInstance(x, C)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001096 self.assertEqual(dir(x), dir(i))
Ezio Melottiaaef3442013-03-04 15:17:56 +02001097 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001098
1099 def test_recursive_multi(self):
1100 l = []
1101 d = {1:l}
1102 i = C()
1103 i.attr = d
1104 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +00001105 for proto in protocols:
1106 s = self.dumps(l, proto)
1107 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001108 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +00001109 self.assertEqual(len(x), 1)
1110 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +00001111 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001112 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +00001113
Walter Dörwald9b775532007-06-08 14:30:53 +00001114 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +00001115 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +00001116 '<\\>', '<\\\U00012345>',
1117 # surrogates
1118 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +00001119 for proto in protocols:
1120 for u in endcases:
1121 p = self.dumps(u, proto)
1122 u2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001123 self.assert_is_copy(u, u2)
Tim Peterse089c682001-04-10 03:41:41 +00001124
Alexandre Vassalotti554d8782008-12-27 07:32:41 +00001125 def test_unicode_high_plane(self):
1126 t = '\U00012345'
1127 for proto in protocols:
1128 p = self.dumps(t, proto)
1129 t2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001130 self.assert_is_copy(t, t2)
Alexandre Vassalotti554d8782008-12-27 07:32:41 +00001131
Guido van Rossumf4169812008-03-17 22:56:06 +00001132 def test_bytes(self):
1133 for proto in protocols:
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001134 for s in b'', b'xyz', b'xyz'*100:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001135 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001136 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001137 for s in [bytes([i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001138 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001139 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -05001140 for s in [bytes([i, i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +02001141 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001142 self.assert_is_copy(s, self.loads(p))
Guido van Rossumf4169812008-03-17 22:56:06 +00001143
Jeremy Hylton66426532001-10-15 21:38:56 +00001144 def test_ints(self):
Tim Petersee1a53c2003-02-02 02:57:53 +00001145 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +00001146 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +00001147 while n:
1148 for expected in (-n, n):
1149 s = self.dumps(expected, proto)
1150 n2 = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001151 self.assert_is_copy(expected, n2)
Tim Petersee1a53c2003-02-02 02:57:53 +00001152 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +00001153
Tim Petersee1a53c2003-02-02 02:57:53 +00001154 def test_long(self):
1155 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +00001156 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +00001157 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +00001158 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +00001159 for npos in nbase-1, nbase, nbase+1:
1160 for n in npos, -npos:
1161 pickle = self.dumps(n, proto)
1162 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001163 self.assert_is_copy(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +00001164 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
1165 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +00001166 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +00001167 nbase += nbase << 1000000
1168 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +00001169 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +00001170 got = self.loads(p)
Antoine Pitroud5df1942013-11-23 21:20:49 +01001171 # assert_is_copy is very expensive here as it precomputes
1172 # a failure message by computing the repr() of n and got,
1173 # we just do the check ourselves.
1174 self.assertIs(type(got), int)
1175 self.assertEqual(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +00001176
Mark Dickinsoncddcf442009-01-24 21:46:33 +00001177 def test_float(self):
1178 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
1179 3.14, 263.44582062374053, 6.022e23, 1e30]
1180 test_values = test_values + [-x for x in test_values]
1181 for proto in protocols:
1182 for value in test_values:
1183 pickle = self.dumps(value, proto)
1184 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001185 self.assert_is_copy(value, got)
Mark Dickinsoncddcf442009-01-24 21:46:33 +00001186
Thomas Wouters477c8d52006-05-27 19:21:47 +00001187 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
1188 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +00001189 # make sure that floats are formatted locale independent with proto 0
1190 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001191
Jeremy Hylton66426532001-10-15 21:38:56 +00001192 def test_reduce(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +01001193 for proto in protocols:
1194 inst = AAA()
1195 dumped = self.dumps(inst, proto)
1196 loaded = self.loads(dumped)
1197 self.assertEqual(loaded, REDUCE_A)
Jeremy Hylton66426532001-10-15 21:38:56 +00001198
1199 def test_getinitargs(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +01001200 for proto in protocols:
1201 inst = initarg(1, 2)
1202 dumped = self.dumps(inst, proto)
1203 loaded = self.loads(dumped)
1204 self.assert_is_copy(inst, loaded)
Jeremy Hylton66426532001-10-15 21:38:56 +00001205
Guido van Rossum04a86612001-12-19 16:58:54 +00001206 def test_metaclass(self):
1207 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +00001208 for proto in protocols:
1209 s = self.dumps(a, proto)
1210 b = self.loads(s)
1211 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +00001212
Antoine Pitrouffd41d92011-10-04 09:23:04 +02001213 def test_dynamic_class(self):
1214 a = create_dynamic_class("my_dynamic_class", (object,))
1215 copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
1216 for proto in protocols:
1217 s = self.dumps(a, proto)
1218 b = self.loads(s)
1219 self.assertEqual(a, b)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001220 self.assertIs(type(a), type(b))
Antoine Pitrouffd41d92011-10-04 09:23:04 +02001221
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001222 def test_structseq(self):
1223 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +00001224 import os
Tim Peters70b02d72003-02-02 17:26:40 +00001225
1226 t = time.localtime()
1227 for proto in protocols:
1228 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +00001229 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001230 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +00001231 if hasattr(os, "stat"):
1232 t = os.stat(os.curdir)
1233 s = self.dumps(t, proto)
1234 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001235 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +00001236 if hasattr(os, "statvfs"):
1237 t = os.statvfs(os.curdir)
1238 s = self.dumps(t, proto)
1239 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001240 self.assert_is_copy(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +00001241
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001242 def test_ellipsis(self):
1243 for proto in protocols:
1244 s = self.dumps(..., proto)
1245 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001246 self.assertIs(..., u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001247
1248 def test_notimplemented(self):
1249 for proto in protocols:
1250 s = self.dumps(NotImplemented, proto)
1251 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001252 self.assertIs(NotImplemented, u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +01001253
Alexandre Vassalotti19b6fa62013-11-30 16:06:39 -08001254 def test_singleton_types(self):
1255 # Issue #6477: Test that types of built-in singletons can be pickled.
1256 singletons = [None, ..., NotImplemented]
1257 for singleton in singletons:
1258 for proto in protocols:
1259 s = self.dumps(type(singleton), proto)
1260 u = self.loads(s)
1261 self.assertIs(type(singleton), u)
1262
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001263 # Tests for protocol 2
1264
Tim Peters4190fb82003-02-02 16:09:05 +00001265 def test_proto(self):
Tim Peters4190fb82003-02-02 16:09:05 +00001266 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001267 pickled = self.dumps(None, proto)
Tim Peters4190fb82003-02-02 16:09:05 +00001268 if proto >= 2:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001269 proto_header = pickle.PROTO + bytes([proto])
1270 self.assertTrue(pickled.startswith(proto_header))
1271 else:
1272 self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)
Tim Peters4190fb82003-02-02 16:09:05 +00001273
1274 oob = protocols[-1] + 1 # a future protocol
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001275 build_none = pickle.NONE + pickle.STOP
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001276 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +00001277 try:
1278 self.loads(badpickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001279 except ValueError as err:
1280 self.assertIn("unsupported pickle protocol", str(err))
Tim Peters4190fb82003-02-02 16:09:05 +00001281 else:
1282 self.fail("expected bad protocol number to raise ValueError")
1283
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001284 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +00001285 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +00001286 for proto in protocols:
1287 s = self.dumps(x, proto)
1288 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001289 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001290 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001291
1292 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +00001293 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +00001294 for proto in protocols:
1295 s = self.dumps(x, proto)
1296 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001297 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +00001298 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +00001299
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001300 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +00001301 # Map (proto, len(tuple)) to expected opcode.
1302 expected_opcode = {(0, 0): pickle.TUPLE,
1303 (0, 1): pickle.TUPLE,
1304 (0, 2): pickle.TUPLE,
1305 (0, 3): pickle.TUPLE,
1306 (0, 4): pickle.TUPLE,
1307
1308 (1, 0): pickle.EMPTY_TUPLE,
1309 (1, 1): pickle.TUPLE,
1310 (1, 2): pickle.TUPLE,
1311 (1, 3): pickle.TUPLE,
1312 (1, 4): pickle.TUPLE,
1313
1314 (2, 0): pickle.EMPTY_TUPLE,
1315 (2, 1): pickle.TUPLE1,
1316 (2, 2): pickle.TUPLE2,
1317 (2, 3): pickle.TUPLE3,
1318 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001319
1320 (3, 0): pickle.EMPTY_TUPLE,
1321 (3, 1): pickle.TUPLE1,
1322 (3, 2): pickle.TUPLE2,
1323 (3, 3): pickle.TUPLE3,
1324 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +00001325 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001326 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +00001327 b = (1,)
1328 c = (1, 2)
1329 d = (1, 2, 3)
1330 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +00001331 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +00001332 for x in a, b, c, d, e:
1333 s = self.dumps(x, proto)
1334 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001335 self.assert_is_copy(x, y)
1336 expected = expected_opcode[min(proto, 3), len(x)]
1337 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters1d63c9f2003-02-02 20:29:39 +00001338
Guido van Rossum7d97d312003-01-28 04:25:27 +00001339 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +00001340 # Map (proto, singleton) to expected opcode.
1341 expected_opcode = {(0, None): pickle.NONE,
1342 (1, None): pickle.NONE,
1343 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001344 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +00001345
1346 (0, True): pickle.INT,
1347 (1, True): pickle.INT,
1348 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001349 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +00001350
1351 (0, False): pickle.INT,
1352 (1, False): pickle.INT,
1353 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +00001354 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +00001355 }
Tim Peters4190fb82003-02-02 16:09:05 +00001356 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +00001357 for x in None, False, True:
1358 s = self.dumps(x, proto)
1359 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001360 self.assertTrue(x is y, (proto, x, s, y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001361 expected = expected_opcode[min(proto, 3), x]
1362 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters3c67d792003-02-02 17:59:11 +00001363
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001364 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001365 x = MyTuple([1, 2, 3])
1366 x.foo = 42
1367 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001368 for proto in protocols:
1369 s = self.dumps(x, proto)
1370 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001371 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001372
1373 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001374 x = MyList([1, 2, 3])
1375 x.foo = 42
1376 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001377 for proto in protocols:
1378 s = self.dumps(x, proto)
1379 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001380 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001381
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001382 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001383 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001384 for C in myclasses:
1385 B = C.__base__
1386 x = C(C.sample)
1387 x.foo = 42
1388 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001389 y = self.loads(s)
1390 detail = (proto, C, B, x, y, type(y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001391 self.assert_is_copy(x, y) # XXX revisit
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001392 self.assertEqual(B(x), B(y), detail)
1393 self.assertEqual(x.__dict__, y.__dict__, detail)
1394
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01001395 def test_newobj_proxies(self):
1396 # NEWOBJ should use the __class__ rather than the raw type
1397 classes = myclasses[:]
1398 # Cannot create weakproxies to these classes
1399 for c in (MyInt, MyTuple):
1400 classes.remove(c)
1401 for proto in protocols:
1402 for C in classes:
1403 B = C.__base__
1404 x = C(C.sample)
1405 x.foo = 42
1406 p = weakref.proxy(x)
1407 s = self.dumps(p, proto)
1408 y = self.loads(s)
1409 self.assertEqual(type(y), type(x)) # rather than type(p)
1410 detail = (proto, C, B, x, y, type(y))
1411 self.assertEqual(B(x), B(y), detail)
1412 self.assertEqual(x.__dict__, y.__dict__, detail)
1413
Benjamin Peterson80f78a32015-07-02 16:18:38 -05001414 def test_newobj_not_class(self):
1415 # Issue 24552
1416 global SimpleNewObj
1417 save = SimpleNewObj
Benjamin Petersond3a2a952015-07-02 16:58:22 -05001418 o = SimpleNewObj.__new__(SimpleNewObj)
Benjamin Peterson80f78a32015-07-02 16:18:38 -05001419 b = self.dumps(o, 4)
1420 try:
1421 SimpleNewObj = 42
1422 self.assertRaises((TypeError, pickle.UnpicklingError), self.loads, b)
1423 finally:
1424 SimpleNewObj = save
1425
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001426 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001427 # an object of that type. Check that the resulting pickle uses opcode
1428 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001429
Tim Peters22e71712003-02-03 22:27:38 +00001430 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001431 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001432 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001433 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001434 x = MyList([1, 2, 3])
1435 x.foo = 42
1436 x.bar = "hello"
1437
Tim Peters22e71712003-02-03 22:27:38 +00001438 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001439 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001440 self.assertIn(__name__.encode("utf-8"), s1)
1441 self.assertIn(b"MyList", s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001442 self.assertFalse(opcode_in_pickle(opcode, s1))
Tim Peters3e667d52003-02-04 21:47:44 +00001443
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001444 y = self.loads(s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001445 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001446
Tim Peters22e71712003-02-03 22:27:38 +00001447 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001448 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001449 self.assertNotIn(__name__.encode("utf-8"), s2)
1450 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001451 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +00001452
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001453 y = self.loads(s2)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001454 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001455 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001456 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001457
1458 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001459 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1460 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001461
1462 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001463 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1464 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1465 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001466
1467 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001468 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1469 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1470 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1471
Tim Peters8d2613a2003-02-11 16:40:16 +00001472 def test_list_chunking(self):
1473 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +00001474 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001475 for proto in protocols:
1476 s = self.dumps(x, proto)
1477 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001478 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001479 num_appends = count_opcode(pickle.APPENDS, s)
1480 self.assertEqual(num_appends, proto > 0)
1481
1482 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001483 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001484 for proto in protocols:
1485 s = self.dumps(x, proto)
1486 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001487 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001488 num_appends = count_opcode(pickle.APPENDS, s)
1489 if proto == 0:
1490 self.assertEqual(num_appends, 0)
1491 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001492 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001493
1494 def test_dict_chunking(self):
1495 n = 10 # too small to chunk
1496 x = dict.fromkeys(range(n))
1497 for proto in protocols:
1498 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +00001499 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00001500 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001501 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001502 num_setitems = count_opcode(pickle.SETITEMS, s)
1503 self.assertEqual(num_setitems, proto > 0)
1504
1505 n = 2500 # expect at least two chunks when proto > 0
1506 x = dict.fromkeys(range(n))
1507 for proto in protocols:
1508 s = self.dumps(x, proto)
1509 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001510 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001511 num_setitems = count_opcode(pickle.SETITEMS, s)
1512 if proto == 0:
1513 self.assertEqual(num_setitems, 0)
1514 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001515 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001516
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001517 def test_set_chunking(self):
1518 n = 10 # too small to chunk
1519 x = set(range(n))
1520 for proto in protocols:
1521 s = self.dumps(x, proto)
1522 y = self.loads(s)
1523 self.assert_is_copy(x, y)
1524 num_additems = count_opcode(pickle.ADDITEMS, s)
1525 if proto < 4:
1526 self.assertEqual(num_additems, 0)
1527 else:
1528 self.assertEqual(num_additems, 1)
1529
1530 n = 2500 # expect at least two chunks when proto >= 4
1531 x = set(range(n))
1532 for proto in protocols:
1533 s = self.dumps(x, proto)
1534 y = self.loads(s)
1535 self.assert_is_copy(x, y)
1536 num_additems = count_opcode(pickle.ADDITEMS, s)
1537 if proto < 4:
1538 self.assertEqual(num_additems, 0)
1539 else:
1540 self.assertGreaterEqual(num_additems, 2)
1541
Tim Peterse9ef2032003-02-13 18:42:00 +00001542 def test_simple_newobj(self):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001543 x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__
Tim Peterse9ef2032003-02-13 18:42:00 +00001544 x.abc = 666
1545 for proto in protocols:
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001546 with self.subTest(proto=proto):
1547 s = self.dumps(x, proto)
1548 if proto < 1:
1549 self.assertIn(b'\nL64206', s) # LONG
1550 else:
1551 self.assertIn(b'M\xce\xfa', s) # BININT2
1552 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1553 2 <= proto)
1554 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1555 y = self.loads(s) # will raise TypeError if __init__ called
1556 self.assert_is_copy(x, y)
1557
1558 def test_complex_newobj(self):
1559 x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__
1560 x.abc = 666
1561 for proto in protocols:
1562 with self.subTest(proto=proto):
1563 s = self.dumps(x, proto)
1564 if proto < 1:
1565 self.assertIn(b'\nL64206', s) # LONG
1566 elif proto < 2:
1567 self.assertIn(b'M\xce\xfa', s) # BININT2
1568 elif proto < 4:
1569 self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
1570 else:
1571 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1572 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1573 2 <= proto)
1574 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1575 y = self.loads(s) # will raise TypeError if __init__ called
1576 self.assert_is_copy(x, y)
1577
1578 def test_complex_newobj_ex(self):
1579 x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__
1580 x.abc = 666
1581 for proto in protocols:
1582 with self.subTest(proto=proto):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001583 s = self.dumps(x, proto)
1584 if proto < 1:
1585 self.assertIn(b'\nL64206', s) # LONG
1586 elif proto < 2:
1587 self.assertIn(b'M\xce\xfa', s) # BININT2
Serhiy Storchaka0d554d72015-10-10 22:42:18 +03001588 elif proto < 4:
1589 self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001590 else:
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001591 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1592 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s))
1593 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1594 4 <= proto)
1595 y = self.loads(s) # will raise TypeError if __init__ called
1596 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001597
Tim Peters42f08ac2003-02-11 22:43:24 +00001598 def test_newobj_list_slots(self):
1599 x = SlotList([1, 2, 3])
1600 x.foo = 42
1601 x.bar = "hello"
1602 s = self.dumps(x, 2)
1603 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001604 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001605
Guido van Rossum2a30b212003-02-18 22:41:24 +00001606 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001607 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001608 x = REX_one()
1609 self.assertEqual(x._reduce_called, 0)
1610 s = self.dumps(x, proto)
1611 self.assertEqual(x._reduce_called, 1)
1612 y = self.loads(s)
1613 self.assertEqual(y._reduce_called, 0)
1614
1615 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001616 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001617 x = REX_two()
1618 self.assertEqual(x._proto, None)
1619 s = self.dumps(x, proto)
1620 self.assertEqual(x._proto, proto)
1621 y = self.loads(s)
1622 self.assertEqual(y._proto, None)
1623
1624 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001625 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001626 x = REX_three()
1627 self.assertEqual(x._proto, None)
1628 s = self.dumps(x, proto)
1629 self.assertEqual(x._proto, proto)
1630 y = self.loads(s)
1631 self.assertEqual(y._proto, None)
1632
Guido van Rossumd8faa362007-04-27 19:54:29 +00001633 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001634 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001635 x = REX_four()
1636 self.assertEqual(x._proto, None)
1637 s = self.dumps(x, proto)
1638 self.assertEqual(x._proto, proto)
1639 y = self.loads(s)
1640 self.assertEqual(y._proto, proto)
1641
1642 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001643 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001644 x = REX_five()
1645 self.assertEqual(x._reduce_called, 0)
1646 s = self.dumps(x, proto)
1647 self.assertEqual(x._reduce_called, 1)
1648 y = self.loads(s)
1649 self.assertEqual(y._reduce_called, 1)
1650
Brett Cannon31f59292011-02-21 19:29:56 +00001651 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001652 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001653 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001654 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001655 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001656 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001657
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001658 def test_reduce_bad_iterator(self):
1659 # Issue4176: crash when 4th and 5th items of __reduce__()
1660 # are not iterators
1661 class C(object):
1662 def __reduce__(self):
1663 # 4th item is not an iterator
1664 return list, (), None, [], None
1665 class D(object):
1666 def __reduce__(self):
1667 # 5th item is not an iterator
1668 return dict, (), None, None, []
1669
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001670 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001671 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001672 try:
1673 self.dumps(C(), proto)
1674 except (pickle.PickleError):
1675 pass
1676 try:
1677 self.dumps(D(), proto)
1678 except (pickle.PickleError):
1679 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001680
Collin Winter771d8342009-04-16 03:18:06 +00001681 def test_many_puts_and_gets(self):
1682 # Test that internal data structures correctly deal with lots of
1683 # puts/gets.
1684 keys = ("aaa" + str(i) for i in range(100))
1685 large_dict = dict((k, [4, 5, 6]) for k in keys)
1686 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1687
1688 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001689 with self.subTest(proto=proto):
1690 dumped = self.dumps(obj, proto)
1691 loaded = self.loads(dumped)
1692 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00001693
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001694 def test_attribute_name_interning(self):
1695 # Test that attribute names of pickled objects are interned when
1696 # unpickling.
1697 for proto in protocols:
1698 x = C()
1699 x.foo = 42
1700 x.bar = "hello"
1701 s = self.dumps(x, proto)
1702 y = self.loads(s)
1703 x_keys = sorted(x.__dict__)
1704 y_keys = sorted(y.__dict__)
1705 for x_key, y_key in zip(x_keys, y_keys):
1706 self.assertIs(x_key, y_key)
1707
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001708 def test_pickle_to_2x(self):
1709 # Pickle non-trivial data with protocol 2, expecting that it yields
1710 # the same result as Python 2.x did.
1711 # NOTE: this test is a bit too strong since we can produce different
1712 # bytecode that 2.x will still understand.
1713 dumped = self.dumps(range(5), 2)
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001714 self.assertEqual(dumped, DATA_XRANGE)
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001715 dumped = self.dumps(set([3]), 2)
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03001716 self.assertEqual(dumped, DATA_SET2)
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001717
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001718 def test_large_pickles(self):
1719 # Test the correctness of internal buffering routines when handling
1720 # large data.
1721 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001722 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001723 dumped = self.dumps(data, proto)
1724 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001725 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001726 self.assertEqual(loaded, data)
1727
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001728 def test_int_pickling_efficiency(self):
1729 # Test compacity of int representation (see issue #12744)
1730 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001731 with self.subTest(proto=proto):
1732 pickles = [self.dumps(2**n, proto) for n in range(70)]
1733 sizes = list(map(len, pickles))
1734 # the size function is monotonic
1735 self.assertEqual(sorted(sizes), sizes)
1736 if proto >= 2:
1737 for p in pickles:
1738 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001739
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001740 def _check_pickling_with_opcode(self, obj, opcode, proto):
1741 pickled = self.dumps(obj, proto)
1742 self.assertTrue(opcode_in_pickle(opcode, pickled))
1743 unpickled = self.loads(pickled)
1744 self.assertEqual(obj, unpickled)
1745
1746 def test_appends_on_non_lists(self):
1747 # Issue #17720
1748 obj = REX_six([1, 2, 3])
1749 for proto in protocols:
1750 if proto == 0:
1751 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1752 else:
1753 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1754
1755 def test_setitems_on_non_dicts(self):
1756 obj = REX_seven({1: -1, 2: -2, 3: -3})
1757 for proto in protocols:
1758 if proto == 0:
1759 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1760 else:
1761 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1762
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001763 # Exercise framing (proto >= 4) for significant workloads
1764
1765 FRAME_SIZE_TARGET = 64 * 1024
1766
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001767 def check_frame_opcodes(self, pickled):
1768 """
1769 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
1770 """
1771 frame_opcode_size = 9
1772 last_arg = last_pos = None
1773 for op, arg, pos in pickletools.genops(pickled):
1774 if op.name != 'FRAME':
1775 continue
1776 if last_pos is not None:
1777 # The previous frame's size should be equal to the number
1778 # of bytes up to the current frame.
1779 frame_size = pos - last_pos - frame_opcode_size
1780 self.assertEqual(frame_size, last_arg)
1781 last_arg, last_pos = arg, pos
1782 # The last frame's size should be equal to the number of bytes up
1783 # to the pickle's end.
1784 frame_size = len(pickled) - last_pos - frame_opcode_size
1785 self.assertEqual(frame_size, last_arg)
1786
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001787 def test_framing_many_objects(self):
1788 obj = list(range(10**5))
1789 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1790 with self.subTest(proto=proto):
1791 pickled = self.dumps(obj, proto)
1792 unpickled = self.loads(pickled)
1793 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001794 bytes_per_frame = (len(pickled) /
1795 count_opcode(pickle.FRAME, pickled))
1796 self.assertGreater(bytes_per_frame,
1797 self.FRAME_SIZE_TARGET / 2)
1798 self.assertLessEqual(bytes_per_frame,
1799 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001800 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001801
1802 def test_framing_large_objects(self):
1803 N = 1024 * 1024
1804 obj = [b'x' * N, b'y' * N, b'z' * N]
1805 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1806 with self.subTest(proto=proto):
1807 pickled = self.dumps(obj, proto)
1808 unpickled = self.loads(pickled)
1809 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001810 n_frames = count_opcode(pickle.FRAME, pickled)
Alexandre Vassalotti28d271e2013-12-01 16:27:46 -08001811 self.assertGreaterEqual(n_frames, len(obj))
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001812 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001813
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001814 def test_optional_frames(self):
1815 if pickle.HIGHEST_PROTOCOL < 4:
1816 return
1817
1818 def remove_frames(pickled, keep_frame=None):
1819 """Remove frame opcodes from the given pickle."""
1820 frame_starts = []
1821 # 1 byte for the opcode and 8 for the argument
1822 frame_opcode_size = 9
1823 for opcode, _, pos in pickletools.genops(pickled):
1824 if opcode.name == 'FRAME':
1825 frame_starts.append(pos)
1826
1827 newpickle = bytearray()
1828 last_frame_end = 0
1829 for i, pos in enumerate(frame_starts):
1830 if keep_frame and keep_frame(i):
1831 continue
1832 newpickle += pickled[last_frame_end:pos]
1833 last_frame_end = pos + frame_opcode_size
1834 newpickle += pickled[last_frame_end:]
1835 return newpickle
1836
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001837 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001838 num_frames = 20
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001839 obj = [bytes([i]) * frame_size for i in range(num_frames)]
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001840
1841 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1842 pickled = self.dumps(obj, proto)
1843
1844 frameless_pickle = remove_frames(pickled)
1845 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
1846 self.assertEqual(obj, self.loads(frameless_pickle))
1847
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001848 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001849 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
1850 count_opcode(pickle.FRAME, pickled))
1851 self.assertEqual(obj, self.loads(some_frames_pickle))
1852
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001853 def test_nested_names(self):
1854 global Nested
1855 class Nested:
1856 class A:
1857 class B:
1858 class C:
1859 pass
Serhiy Storchaka58e41342015-03-31 14:07:24 +03001860 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001861 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
1862 with self.subTest(proto=proto, obj=obj):
1863 unpickled = self.loads(self.dumps(obj, proto))
1864 self.assertIs(obj, unpickled)
1865
Serhiy Storchaka58e41342015-03-31 14:07:24 +03001866 def test_recursive_nested_names(self):
1867 global Recursive
1868 class Recursive:
1869 pass
1870 Recursive.mod = sys.modules[Recursive.__module__]
1871 Recursive.__qualname__ = 'Recursive.mod.Recursive'
1872 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1873 with self.subTest(proto=proto):
1874 unpickled = self.loads(self.dumps(Recursive, proto))
1875 self.assertIs(unpickled, Recursive)
1876 del Recursive.mod # break reference loop
1877
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001878 def test_py_methods(self):
1879 global PyMethodsTest
1880 class PyMethodsTest:
1881 @staticmethod
1882 def cheese():
1883 return "cheese"
1884 @classmethod
1885 def wine(cls):
1886 assert cls is PyMethodsTest
1887 return "wine"
1888 def biscuits(self):
1889 assert isinstance(self, PyMethodsTest)
1890 return "biscuits"
1891 class Nested:
1892 "Nested class"
1893 @staticmethod
1894 def ketchup():
1895 return "ketchup"
1896 @classmethod
1897 def maple(cls):
1898 assert cls is PyMethodsTest.Nested
1899 return "maple"
1900 def pie(self):
1901 assert isinstance(self, PyMethodsTest.Nested)
1902 return "pie"
1903
1904 py_methods = (
1905 PyMethodsTest.cheese,
1906 PyMethodsTest.wine,
1907 PyMethodsTest().biscuits,
1908 PyMethodsTest.Nested.ketchup,
1909 PyMethodsTest.Nested.maple,
1910 PyMethodsTest.Nested().pie
1911 )
1912 py_unbound_methods = (
1913 (PyMethodsTest.biscuits, PyMethodsTest),
1914 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
1915 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03001916 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001917 for method in py_methods:
1918 with self.subTest(proto=proto, method=method):
1919 unpickled = self.loads(self.dumps(method, proto))
1920 self.assertEqual(method(), unpickled())
1921 for method, cls in py_unbound_methods:
1922 obj = cls()
1923 with self.subTest(proto=proto, method=method):
1924 unpickled = self.loads(self.dumps(method, proto))
1925 self.assertEqual(method(obj), unpickled(obj))
1926
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001927 def test_c_methods(self):
1928 global Subclass
1929 class Subclass(tuple):
1930 class Nested(str):
1931 pass
1932
1933 c_methods = (
1934 # bound built-in method
1935 ("abcd".index, ("c",)),
1936 # unbound built-in method
1937 (str.index, ("abcd", "c")),
1938 # bound "slot" method
1939 ([1, 2, 3].__len__, ()),
1940 # unbound "slot" method
1941 (list.__len__, ([1, 2, 3],)),
1942 # bound "coexist" method
1943 ({1, 2}.__contains__, (2,)),
1944 # unbound "coexist" method
1945 (set.__contains__, ({1, 2}, 2)),
1946 # built-in class method
1947 (dict.fromkeys, (("a", 1), ("b", 2))),
1948 # built-in static method
1949 (bytearray.maketrans, (b"abc", b"xyz")),
1950 # subclass methods
1951 (Subclass([1,2,2]).count, (2,)),
1952 (Subclass.count, (Subclass([1,2,2]), 2)),
1953 (Subclass.Nested("sweet").count, ("e",)),
1954 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
1955 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03001956 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001957 for method, args in c_methods:
1958 with self.subTest(proto=proto, method=method):
1959 unpickled = self.loads(self.dumps(method, proto))
1960 self.assertEqual(method(*args), unpickled(*args))
1961
Serhiy Storchakabfe18242015-03-31 13:12:37 +03001962 def test_compat_pickle(self):
1963 tests = [
1964 (range(1, 7), '__builtin__', 'xrange'),
1965 (map(int, '123'), 'itertools', 'imap'),
1966 (functools.reduce, '__builtin__', 'reduce'),
1967 (dbm.whichdb, 'whichdb', 'whichdb'),
1968 (Exception(), 'exceptions', 'Exception'),
1969 (collections.UserDict(), 'UserDict', 'IterableUserDict'),
1970 (collections.UserList(), 'UserList', 'UserList'),
1971 (collections.defaultdict(), 'collections', 'defaultdict'),
1972 ]
1973 for val, mod, name in tests:
1974 for proto in range(3):
1975 with self.subTest(type=type(val), proto=proto):
1976 pickled = self.dumps(val, proto)
1977 self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled)
1978 self.assertIs(type(self.loads(pickled)), type(val))
1979
Antoine Pitrou6cd5eda2014-12-02 00:20:03 +01001980 def test_local_lookup_error(self):
1981 # Test that whichmodule() errors out cleanly when looking up
1982 # an assumed globally-reachable object fails.
1983 def f():
1984 pass
1985 # Since the function is local, lookup will fail
1986 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1987 with self.assertRaises((AttributeError, pickle.PicklingError)):
1988 pickletools.dis(self.dumps(f, proto))
1989 # Same without a __module__ attribute (exercises a different path
1990 # in _pickle.c).
1991 del f.__module__
1992 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1993 with self.assertRaises((AttributeError, pickle.PicklingError)):
1994 pickletools.dis(self.dumps(f, proto))
1995 # Yet a different path.
1996 f.__name__ = f.__qualname__
1997 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1998 with self.assertRaises((AttributeError, pickle.PicklingError)):
1999 pickletools.dis(self.dumps(f, proto))
2000
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002001
2002class BigmemPickleTests(unittest.TestCase):
2003
2004 # Binary protocols can serialize longs of up to 2GB-1
2005
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002006 @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002007 def test_huge_long_32b(self, size):
2008 data = 1 << (8 * size)
2009 try:
2010 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002011 if proto < 2:
2012 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002013 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002014 with self.assertRaises((ValueError, OverflowError)):
2015 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002016 finally:
2017 data = None
2018
2019 # Protocol 3 can serialize up to 4GB-1 as a bytes object
2020 # (older protocols don't have a dedicated opcode for bytes and are
2021 # too inefficient)
2022
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002023 @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002024 def test_huge_bytes_32b(self, size):
2025 data = b"abcd" * (size // 4)
2026 try:
2027 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002028 if proto < 3:
2029 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002030 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002031 try:
2032 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002033 header = (pickle.BINBYTES +
2034 struct.pack("<I", len(data)))
2035 data_start = pickled.index(data)
2036 self.assertEqual(
2037 header,
2038 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002039 finally:
2040 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002041 finally:
2042 data = None
2043
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002044 @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002045 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002046 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002047 try:
2048 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002049 if proto < 3:
2050 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002051 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002052 if proto == 3:
2053 # Protocol 3 does not support large bytes objects.
2054 # Verify that we do not crash when processing one.
2055 with self.assertRaises((ValueError, OverflowError)):
2056 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002057 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002058 try:
2059 pickled = self.dumps(data, protocol=proto)
2060 header = (pickle.BINBYTES8 +
2061 struct.pack("<Q", len(data)))
2062 data_start = pickled.index(data)
2063 self.assertEqual(
2064 header,
2065 pickled[data_start-len(header):data_start])
2066 finally:
2067 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002068 finally:
2069 data = None
2070
2071 # All protocols use 1-byte per printable ASCII character; we add another
2072 # byte because the encoded form has to be copied into the internal buffer.
2073
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002074 @bigmemtest(size=_2G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002075 def test_huge_str_32b(self, size):
2076 data = "abcd" * (size // 4)
2077 try:
2078 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002079 if proto == 0:
2080 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002081 with self.subTest(proto=proto):
2082 try:
2083 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002084 header = (pickle.BINUNICODE +
2085 struct.pack("<I", len(data)))
2086 data_start = pickled.index(b'abcd')
2087 self.assertEqual(
2088 header,
2089 pickled[data_start-len(header):data_start])
2090 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2091 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002092 finally:
2093 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002094 finally:
2095 data = None
2096
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002097 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
2098 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
2099 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02002100
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02002101 @bigmemtest(size=_4G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002102 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002103 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002104 try:
2105 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002106 if proto == 0:
2107 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002108 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002109 if proto < 4:
2110 with self.assertRaises((ValueError, OverflowError)):
2111 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08002112 continue
2113 try:
2114 pickled = self.dumps(data, protocol=proto)
2115 header = (pickle.BINUNICODE8 +
2116 struct.pack("<Q", len(data)))
2117 data_start = pickled.index(b'abcd')
2118 self.assertEqual(
2119 header,
2120 pickled[data_start-len(header):data_start])
2121 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
2122 pickled.index(b"abcd")), len(data))
2123 finally:
2124 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02002125 finally:
2126 data = None
2127
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02002128
Guido van Rossum2a30b212003-02-18 22:41:24 +00002129# Test classes for reduce_ex
2130
2131class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002132 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00002133 _reduce_called = 0
2134 def __reduce__(self):
2135 self._reduce_called = 1
2136 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00002137
2138class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002139 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00002140 _proto = None
2141 def __reduce_ex__(self, proto):
2142 self._proto = proto
2143 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00002144
2145class REX_three(object):
2146 _proto = None
2147 def __reduce_ex__(self, proto):
2148 self._proto = proto
2149 return REX_two, ()
2150 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00002151 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00002152
Guido van Rossumd8faa362007-04-27 19:54:29 +00002153class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002154 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00002155 _proto = None
2156 def __reduce_ex__(self, proto):
2157 self._proto = proto
2158 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002159
2160class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002161 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00002162 _reduce_called = 0
2163 def __reduce__(self):
2164 self._reduce_called = 1
2165 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002166
2167class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002168 """This class is used to check the 4th argument (list iterator) of
2169 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002170 """
2171 def __init__(self, items=None):
2172 self.items = items if items is not None else []
2173 def __eq__(self, other):
2174 return type(self) is type(other) and self.items == self.items
2175 def append(self, item):
2176 self.items.append(item)
2177 def __reduce__(self):
2178 return type(self), (), None, iter(self.items), None
2179
2180class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002181 """This class is used to check the 5th argument (dict iterator) of
2182 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07002183 """
2184 def __init__(self, table=None):
2185 self.table = table if table is not None else {}
2186 def __eq__(self, other):
2187 return type(self) is type(other) and self.table == self.table
2188 def __setitem__(self, key, value):
2189 self.table[key] = value
2190 def __reduce__(self):
2191 return type(self), (), None, None, iter(self.table.items())
2192
Guido van Rossumd8faa362007-04-27 19:54:29 +00002193
Guido van Rossum2a30b212003-02-18 22:41:24 +00002194# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00002195
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002196class MyInt(int):
2197 sample = 1
2198
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002199class MyFloat(float):
2200 sample = 1.0
2201
2202class MyComplex(complex):
2203 sample = 1.0 + 0.0j
2204
2205class MyStr(str):
2206 sample = "hello"
2207
Guido van Rossumef87d6e2007-05-02 19:09:54 +00002208class MyUnicode(str):
2209 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002210
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002211class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002212 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002213
2214class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002215 sample = [1, 2, 3]
2216
2217class MyDict(dict):
2218 sample = {"a": 1, "b": 2}
2219
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002220class MySet(set):
2221 sample = {"a", "b"}
2222
2223class MyFrozenSet(frozenset):
2224 sample = frozenset({"a", "b"})
2225
Mark Dickinson5c2db372009-12-05 20:28:34 +00002226myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00002227 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002228 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002229 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002230
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002231
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00002232class SlotList(MyList):
2233 __slots__ = ["foo"]
2234
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002235class SimpleNewObj(int):
2236 def __init__(self, *args, **kwargs):
Tim Peterse9ef2032003-02-13 18:42:00 +00002237 # raise an error, to make sure this isn't called
2238 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002239 def __eq__(self, other):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002240 return int(self) == int(other) and self.__dict__ == other.__dict__
2241
2242class ComplexNewObj(SimpleNewObj):
2243 def __getnewargs__(self):
2244 return ('%X' % self, 16)
2245
2246class ComplexNewObjEx(SimpleNewObj):
2247 def __getnewargs_ex__(self):
2248 return ('%X' % self,), {'base': 16}
Tim Peterse9ef2032003-02-13 18:42:00 +00002249
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002250class BadGetattr:
2251 def __getattr__(self, key):
2252 self.foo
2253
Collin Winter771d8342009-04-16 03:18:06 +00002254
Jeremy Hylton66426532001-10-15 21:38:56 +00002255class AbstractPickleModuleTests(unittest.TestCase):
2256
2257 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002258 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00002259 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002260 try:
2261 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002262 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002263 finally:
2264 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00002265
2266 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002267 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00002268 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002269 try:
2270 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002271 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002272 finally:
2273 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002274
Collin Winter771d8342009-04-16 03:18:06 +00002275 def test_load_from_and_dump_to_file(self):
2276 stream = io.BytesIO()
2277 data = [123, {}, 124]
2278 pickle.dump(data, stream)
2279 stream.seek(0)
2280 unpickled = pickle.load(stream)
2281 self.assertEqual(unpickled, data)
2282
Tim Petersc0c93702003-02-13 19:30:57 +00002283 def test_highest_protocol(self):
2284 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002285 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00002286
Martin v. Löwis544f1192004-07-27 05:22:33 +00002287 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00002288 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00002289 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002290 pickle.dump(123, f, -1)
2291 pickle.dump(123, file=f, protocol=-1)
2292 pickle.dumps(123, -1)
2293 pickle.dumps(123, protocol=-1)
2294 pickle.Pickler(f, -1)
2295 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00002296
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002297 def test_bad_init(self):
2298 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002299 # Override initialization without calling __init__() of the superclass.
2300 class BadPickler(pickle.Pickler):
2301 def __init__(self): pass
2302
2303 class BadUnpickler(pickle.Unpickler):
2304 def __init__(self): pass
2305
2306 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
2307 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
2308
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00002309 def test_bad_input(self):
2310 # Test issue4298
2311 s = bytes([0x58, 0, 0, 0, 0x54])
2312 self.assertRaises(EOFError, pickle.loads, s)
2313
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002314
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002315class AbstractPersistentPicklerTests(unittest.TestCase):
2316
2317 # This class defines persistent_id() and persistent_load()
2318 # functions that should be used by the pickler. All even integers
2319 # are pickled using persistent ids.
2320
2321 def persistent_id(self, object):
2322 if isinstance(object, int) and object % 2 == 0:
2323 self.id_count += 1
2324 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002325 elif object == "test_false_value":
2326 self.false_count += 1
2327 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002328 else:
2329 return None
2330
2331 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002332 if not oid:
2333 self.load_false_count += 1
2334 return "test_false_value"
2335 else:
2336 self.load_count += 1
2337 object = int(oid)
2338 assert object % 2 == 0
2339 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002340
2341 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002342 L = list(range(10)) + ["test_false_value"]
2343 for proto in protocols:
2344 self.id_count = 0
2345 self.false_count = 0
2346 self.load_false_count = 0
2347 self.load_count = 0
2348 self.assertEqual(self.loads(self.dumps(L, proto)), L)
2349 self.assertEqual(self.id_count, 5)
2350 self.assertEqual(self.false_count, 1)
2351 self.assertEqual(self.load_count, 5)
2352 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00002353
Collin Winter771d8342009-04-16 03:18:06 +00002354
2355class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
2356
2357 pickler_class = None
2358 unpickler_class = None
2359
2360 def setUp(self):
2361 assert self.pickler_class
2362 assert self.unpickler_class
2363
2364 def test_clear_pickler_memo(self):
2365 # To test whether clear_memo() has any effect, we pickle an object,
2366 # then pickle it again without clearing the memo; the two serialized
2367 # forms should be different. If we clear_memo() and then pickle the
2368 # object again, the third serialized form should be identical to the
2369 # first one we obtained.
2370 data = ["abcdefg", "abcdefg", 44]
2371 f = io.BytesIO()
2372 pickler = self.pickler_class(f)
2373
2374 pickler.dump(data)
2375 first_pickled = f.getvalue()
2376
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002377 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00002378 f.seek(0)
2379 f.truncate()
2380
2381 pickler.dump(data)
2382 second_pickled = f.getvalue()
2383
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002384 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00002385 pickler.clear_memo()
2386 f.seek(0)
2387 f.truncate()
2388
2389 pickler.dump(data)
2390 third_pickled = f.getvalue()
2391
2392 self.assertNotEqual(first_pickled, second_pickled)
2393 self.assertEqual(first_pickled, third_pickled)
2394
2395 def test_priming_pickler_memo(self):
2396 # Verify that we can set the Pickler's memo attribute.
2397 data = ["abcdefg", "abcdefg", 44]
2398 f = io.BytesIO()
2399 pickler = self.pickler_class(f)
2400
2401 pickler.dump(data)
2402 first_pickled = f.getvalue()
2403
2404 f = io.BytesIO()
2405 primed = self.pickler_class(f)
2406 primed.memo = pickler.memo
2407
2408 primed.dump(data)
2409 primed_pickled = f.getvalue()
2410
2411 self.assertNotEqual(first_pickled, primed_pickled)
2412
2413 def test_priming_unpickler_memo(self):
2414 # Verify that we can set the Unpickler's memo attribute.
2415 data = ["abcdefg", "abcdefg", 44]
2416 f = io.BytesIO()
2417 pickler = self.pickler_class(f)
2418
2419 pickler.dump(data)
2420 first_pickled = f.getvalue()
2421
2422 f = io.BytesIO()
2423 primed = self.pickler_class(f)
2424 primed.memo = pickler.memo
2425
2426 primed.dump(data)
2427 primed_pickled = f.getvalue()
2428
2429 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2430 unpickled_data1 = unpickler.load()
2431
2432 self.assertEqual(unpickled_data1, data)
2433
2434 primed = self.unpickler_class(io.BytesIO(primed_pickled))
2435 primed.memo = unpickler.memo
2436 unpickled_data2 = primed.load()
2437
2438 primed.memo.clear()
2439
2440 self.assertEqual(unpickled_data2, data)
2441 self.assertTrue(unpickled_data2 is unpickled_data1)
2442
2443 def test_reusing_unpickler_objects(self):
2444 data1 = ["abcdefg", "abcdefg", 44]
2445 f = io.BytesIO()
2446 pickler = self.pickler_class(f)
2447 pickler.dump(data1)
2448 pickled1 = f.getvalue()
2449
2450 data2 = ["abcdefg", 44, 44]
2451 f = io.BytesIO()
2452 pickler = self.pickler_class(f)
2453 pickler.dump(data2)
2454 pickled2 = f.getvalue()
2455
2456 f = io.BytesIO()
2457 f.write(pickled1)
2458 f.seek(0)
2459 unpickler = self.unpickler_class(f)
2460 self.assertEqual(unpickler.load(), data1)
2461
2462 f.seek(0)
2463 f.truncate()
2464 f.write(pickled2)
2465 f.seek(0)
2466 self.assertEqual(unpickler.load(), data2)
2467
Antoine Pitrou04248a82010-10-12 20:51:21 +00002468 def _check_multiple_unpicklings(self, ioclass):
2469 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002470 with self.subTest(proto=proto):
2471 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2472 f = ioclass()
2473 pickler = self.pickler_class(f, protocol=proto)
2474 pickler.dump(data1)
2475 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002476
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002477 N = 5
2478 f = ioclass(pickled * N)
2479 unpickler = self.unpickler_class(f)
2480 for i in range(N):
2481 if f.seekable():
2482 pos = f.tell()
2483 self.assertEqual(unpickler.load(), data1)
2484 if f.seekable():
2485 self.assertEqual(f.tell(), pos + len(pickled))
2486 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002487
2488 def test_multiple_unpicklings_seekable(self):
2489 self._check_multiple_unpicklings(io.BytesIO)
2490
2491 def test_multiple_unpicklings_unseekable(self):
2492 self._check_multiple_unpicklings(UnseekableIO)
2493
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002494 def test_unpickling_buffering_readline(self):
2495 # Issue #12687: the unpickler's buffering logic could fail with
2496 # text mode opcodes.
2497 data = list(range(10))
2498 for proto in protocols:
2499 for buf_size in range(1, 11):
2500 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2501 pickler = self.pickler_class(f, protocol=proto)
2502 pickler.dump(data)
2503 f.seek(0)
2504 unpickler = self.unpickler_class(f)
2505 self.assertEqual(unpickler.load(), data)
2506
Collin Winter771d8342009-04-16 03:18:06 +00002507
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002508# Tests for dispatch_table attribute
2509
2510REDUCE_A = 'reduce_A'
2511
2512class AAA(object):
2513 def __reduce__(self):
2514 return str, (REDUCE_A,)
2515
2516class BBB(object):
2517 pass
2518
2519class AbstractDispatchTableTests(unittest.TestCase):
2520
2521 def test_default_dispatch_table(self):
2522 # No dispatch_table attribute by default
2523 f = io.BytesIO()
2524 p = self.pickler_class(f, 0)
2525 with self.assertRaises(AttributeError):
2526 p.dispatch_table
2527 self.assertFalse(hasattr(p, 'dispatch_table'))
2528
2529 def test_class_dispatch_table(self):
2530 # A dispatch_table attribute can be specified class-wide
2531 dt = self.get_dispatch_table()
2532
2533 class MyPickler(self.pickler_class):
2534 dispatch_table = dt
2535
2536 def dumps(obj, protocol=None):
2537 f = io.BytesIO()
2538 p = MyPickler(f, protocol)
2539 self.assertEqual(p.dispatch_table, dt)
2540 p.dump(obj)
2541 return f.getvalue()
2542
2543 self._test_dispatch_table(dumps, dt)
2544
2545 def test_instance_dispatch_table(self):
2546 # A dispatch_table attribute can also be specified instance-wide
2547 dt = self.get_dispatch_table()
2548
2549 def dumps(obj, protocol=None):
2550 f = io.BytesIO()
2551 p = self.pickler_class(f, protocol)
2552 p.dispatch_table = dt
2553 self.assertEqual(p.dispatch_table, dt)
2554 p.dump(obj)
2555 return f.getvalue()
2556
2557 self._test_dispatch_table(dumps, dt)
2558
2559 def _test_dispatch_table(self, dumps, dispatch_table):
2560 def custom_load_dump(obj):
2561 return pickle.loads(dumps(obj, 0))
2562
2563 def default_load_dump(obj):
2564 return pickle.loads(pickle.dumps(obj, 0))
2565
2566 # pickling complex numbers using protocol 0 relies on copyreg
2567 # so check pickling a complex number still works
2568 z = 1 + 2j
2569 self.assertEqual(custom_load_dump(z), z)
2570 self.assertEqual(default_load_dump(z), z)
2571
2572 # modify pickling of complex
2573 REDUCE_1 = 'reduce_1'
2574 def reduce_1(obj):
2575 return str, (REDUCE_1,)
2576 dispatch_table[complex] = reduce_1
2577 self.assertEqual(custom_load_dump(z), REDUCE_1)
2578 self.assertEqual(default_load_dump(z), z)
2579
2580 # check picklability of AAA and BBB
2581 a = AAA()
2582 b = BBB()
2583 self.assertEqual(custom_load_dump(a), REDUCE_A)
2584 self.assertIsInstance(custom_load_dump(b), BBB)
2585 self.assertEqual(default_load_dump(a), REDUCE_A)
2586 self.assertIsInstance(default_load_dump(b), BBB)
2587
2588 # modify pickling of BBB
2589 dispatch_table[BBB] = reduce_1
2590 self.assertEqual(custom_load_dump(a), REDUCE_A)
2591 self.assertEqual(custom_load_dump(b), REDUCE_1)
2592 self.assertEqual(default_load_dump(a), REDUCE_A)
2593 self.assertIsInstance(default_load_dump(b), BBB)
2594
2595 # revert pickling of BBB and modify pickling of AAA
2596 REDUCE_2 = 'reduce_2'
2597 def reduce_2(obj):
2598 return str, (REDUCE_2,)
2599 dispatch_table[AAA] = reduce_2
2600 del dispatch_table[BBB]
2601 self.assertEqual(custom_load_dump(a), REDUCE_2)
2602 self.assertIsInstance(custom_load_dump(b), BBB)
2603 self.assertEqual(default_load_dump(a), REDUCE_A)
2604 self.assertIsInstance(default_load_dump(b), BBB)
2605
2606
Guido van Rossum98297ee2007-11-06 21:34:58 +00002607if __name__ == "__main__":
2608 # Print some stuff that can be used to rewrite DATA{0,1,2}
2609 from pickletools import dis
2610 x = create_data()
Serhiy Storchakab8b951f2015-09-29 15:49:58 +03002611 for i in range(pickle.HIGHEST_PROTOCOL+1):
Guido van Rossum98297ee2007-11-06 21:34:58 +00002612 p = pickle.dumps(x, i)
2613 print("DATA{0} = (".format(i))
2614 for j in range(0, len(p), 20):
2615 b = bytes(p[j:j+20])
2616 print(" {0!r}".format(b))
2617 print(")")
2618 print()
2619 print("# Disassembly of DATA{0}".format(i))
2620 print("DATA{0}_DIS = \"\"\"\\".format(i))
2621 dis(p)
2622 print("\"\"\"")
2623 print()