blob: 78b548392812d5d871fa1aec539213bed14b130e [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
Tim Petersee1a53c2003-02-02 02:57:53 +000021# Tests that try a number of pickle protocols should have a
22# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000023# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000024protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000025
Tim Peters22e71712003-02-03 22:27:38 +000026
27# Return True if opcode code appears in the pickle, else False.
28def opcode_in_pickle(code, pickle):
29 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000030 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000031 return True
32 return False
33
Tim Peters8d2613a2003-02-11 16:40:16 +000034# Return the number of times opcode code appears in pickle.
35def count_opcode(code, pickle):
36 n = 0
37 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000038 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000039 n += 1
40 return n
41
Antoine Pitrou04248a82010-10-12 20:51:21 +000042
43class UnseekableIO(io.BytesIO):
44 def peek(self, *args):
45 raise NotImplementedError
46
47 def seekable(self):
48 return False
49
50 def seek(self, *args):
51 raise io.UnsupportedOperation
52
53 def tell(self):
54 raise io.UnsupportedOperation
55
56
Tim Peters3e667d52003-02-04 21:47:44 +000057# We can't very well test the extension registry without putting known stuff
58# in it, but we have to be careful to restore its original state. Code
59# should do this:
60#
61# e = ExtensionSaver(extension_code)
62# try:
63# fiddle w/ the extension registry's stuff for extension_code
64# finally:
65# e.restore()
66
67class ExtensionSaver:
68 # Remember current registration for code (if any), and remove it (if
69 # there is one).
70 def __init__(self, code):
71 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000072 if code in copyreg._inverted_registry:
73 self.pair = copyreg._inverted_registry[code]
74 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000075 else:
76 self.pair = None
77
78 # Restore previous registration for code.
79 def restore(self):
80 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000081 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000082 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000083 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000084 pair = self.pair
85 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000086 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000087
Jeremy Hylton66426532001-10-15 21:38:56 +000088class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000089 def __eq__(self, other):
90 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000091
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000092class D(C):
93 def __init__(self, arg):
94 pass
95
96class E(C):
97 def __getinitargs__(self):
98 return ()
99
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100100class H(object):
101 pass
102
Jeremy Hylton66426532001-10-15 21:38:56 +0000103import __main__
104__main__.C = C
105C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000106__main__.D = D
107D.__module__ = "__main__"
108__main__.E = E
109E.__module__ = "__main__"
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100110__main__.H = H
111H.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000112
113class myint(int):
114 def __init__(self, x):
115 self.str = str(x)
116
117class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000118
Jeremy Hylton66426532001-10-15 21:38:56 +0000119 def __init__(self, a, b):
120 self.a = a
121 self.b = b
122
123 def __getinitargs__(self):
124 return self.a, self.b
125
Guido van Rossum04a86612001-12-19 16:58:54 +0000126class metaclass(type):
127 pass
128
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000129class use_metaclass(object, metaclass=metaclass):
130 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000131
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200132class pickling_metaclass(type):
133 def __eq__(self, other):
134 return (type(self) == type(other) and
135 self.reduce_args == other.reduce_args)
136
137 def __reduce__(self):
138 return (create_dynamic_class, self.reduce_args)
139
140def create_dynamic_class(name, bases):
141 result = pickling_metaclass(name, bases, dict())
142 result.reduce_args = (name, bases)
143 return result
144
Tim Peters70b02d72003-02-02 17:26:40 +0000145# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
146# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000147
Guido van Rossum98297ee2007-11-06 21:34:58 +0000148DATA0 = (
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200149 b'(lp0\nL0L\naL1L\naF2.0\n'
150 b'ac__builtin__\ncomple'
151 b'x\np1\n(F3.0\nF0.0\ntp2\n'
152 b'Rp3\naL1L\naL-1L\naL255'
153 b'L\naL-255L\naL-256L\naL'
154 b'65535L\naL-65535L\naL-'
155 b'65536L\naL2147483647L'
156 b'\naL-2147483647L\naL-2'
157 b'147483648L\na(Vabc\np4'
158 b'\ng4\nccopy_reg\n_recon'
159 b'structor\np5\n(c__main'
160 b'__\nC\np6\nc__builtin__'
161 b'\nobject\np7\nNtp8\nRp9\n'
162 b'(dp10\nVfoo\np11\nL1L\ns'
163 b'Vbar\np12\nL2L\nsbg9\ntp'
164 b'13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000165)
Tim Peterse9358162001-01-22 22:05:20 +0000166
Guido van Rossum98297ee2007-11-06 21:34:58 +0000167# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000168DATA0_DIS = """\
169 0: ( MARK
170 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000171 2: p PUT 0
172 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000173 9: a APPEND
174 10: L LONG 1
175 14: a APPEND
176 15: F FLOAT 2.0
177 20: a APPEND
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200178 21: c GLOBAL '__builtin__ complex'
179 42: p PUT 1
180 45: ( MARK
181 46: F FLOAT 3.0
182 51: F FLOAT 0.0
183 56: t TUPLE (MARK at 45)
184 57: p PUT 2
185 60: R REDUCE
186 61: p PUT 3
187 64: a APPEND
188 65: L LONG 1
189 69: a APPEND
190 70: L LONG -1
191 75: a APPEND
192 76: L LONG 255
193 82: a APPEND
194 83: L LONG -255
195 90: a APPEND
196 91: L LONG -256
197 98: a APPEND
198 99: L LONG 65535
199 107: a APPEND
200 108: L LONG -65535
201 117: a APPEND
202 118: L LONG -65536
203 127: a APPEND
204 128: L LONG 2147483647
205 141: a APPEND
206 142: L LONG -2147483647
207 156: a APPEND
208 157: L LONG -2147483648
209 171: a APPEND
210 172: ( MARK
211 173: V UNICODE 'abc'
212 178: p PUT 4
213 181: g GET 4
214 184: c GLOBAL 'copy_reg _reconstructor'
215 209: p PUT 5
216 212: ( MARK
217 213: c GLOBAL '__main__ C'
218 225: p PUT 6
219 228: c GLOBAL '__builtin__ object'
220 248: p PUT 7
221 251: N NONE
222 252: t TUPLE (MARK at 212)
223 253: p PUT 8
224 256: R REDUCE
225 257: p PUT 9
226 260: ( MARK
227 261: d DICT (MARK at 260)
228 262: p PUT 10
229 266: V UNICODE 'foo'
230 271: p PUT 11
231 275: L LONG 1
232 279: s SETITEM
233 280: V UNICODE 'bar'
234 285: p PUT 12
235 289: L LONG 2
236 293: s SETITEM
237 294: b BUILD
238 295: g GET 9
239 298: t TUPLE (MARK at 172)
240 299: p PUT 13
241 303: a APPEND
242 304: g GET 13
243 308: a APPEND
244 309: L LONG 5
245 313: a APPEND
246 314: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000247highest protocol among opcodes = 0
248"""
249
Guido van Rossum98297ee2007-11-06 21:34:58 +0000250DATA1 = (
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200251 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c__'
252 b'builtin__\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000253 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
254 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
255 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
256 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200257 b'cq\x04h\x04ccopy_reg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000258 b'nstructor\nq\x05(c__main'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200259 b'__\nC\nq\x06c__builtin__\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000260 b'object\nq\x07Ntq\x08Rq\t}q\n('
261 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
262 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
263)
Tim Peters70b02d72003-02-02 17:26:40 +0000264
Guido van Rossum98297ee2007-11-06 21:34:58 +0000265# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000266DATA1_DIS = """\
267 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000268 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000269 3: ( MARK
270 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000271 6: K BININT1 1
272 8: G BINFLOAT 2.0
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200273 17: c GLOBAL '__builtin__ complex'
274 38: q BINPUT 1
275 40: ( MARK
276 41: G BINFLOAT 3.0
277 50: G BINFLOAT 0.0
278 59: t TUPLE (MARK at 40)
279 60: q BINPUT 2
280 62: R REDUCE
281 63: q BINPUT 3
282 65: K BININT1 1
283 67: J BININT -1
284 72: K BININT1 255
285 74: J BININT -255
286 79: J BININT -256
287 84: M BININT2 65535
288 87: J BININT -65535
289 92: J BININT -65536
290 97: J BININT 2147483647
291 102: J BININT -2147483647
292 107: J BININT -2147483648
293 112: ( MARK
294 113: X BINUNICODE 'abc'
295 121: q BINPUT 4
296 123: h BINGET 4
297 125: c GLOBAL 'copy_reg _reconstructor'
298 150: q BINPUT 5
299 152: ( MARK
300 153: c GLOBAL '__main__ C'
301 165: q BINPUT 6
302 167: c GLOBAL '__builtin__ object'
303 187: q BINPUT 7
304 189: N NONE
305 190: t TUPLE (MARK at 152)
306 191: q BINPUT 8
307 193: R REDUCE
308 194: q BINPUT 9
309 196: } EMPTY_DICT
310 197: q BINPUT 10
311 199: ( MARK
312 200: X BINUNICODE 'foo'
313 208: q BINPUT 11
314 210: K BININT1 1
315 212: X BINUNICODE 'bar'
316 220: q BINPUT 12
317 222: K BININT1 2
318 224: u SETITEMS (MARK at 199)
319 225: b BUILD
320 226: h BINGET 9
321 228: t TUPLE (MARK at 112)
322 229: q BINPUT 13
323 231: h BINGET 13
324 233: K BININT1 5
325 235: e APPENDS (MARK at 3)
326 236: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000327highest protocol among opcodes = 1
328"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000329
Guido van Rossum98297ee2007-11-06 21:34:58 +0000330DATA2 = (
331 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200332 b'__builtin__\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000333 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
334 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
335 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
336 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
337 b'bcq\x04h\x04c__main__\nC\nq\x05'
338 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
339 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
340 b'\nK\x05e.'
341)
Tim Petersfc273752003-03-02 04:54:24 +0000342
Guido van Rossum98297ee2007-11-06 21:34:58 +0000343# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000344DATA2_DIS = """\
345 0: \x80 PROTO 2
346 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000347 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000348 5: ( MARK
349 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000350 8: K BININT1 1
351 10: G BINFLOAT 2.0
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200352 19: c GLOBAL '__builtin__ complex'
353 40: q BINPUT 1
354 42: G BINFLOAT 3.0
355 51: G BINFLOAT 0.0
356 60: \x86 TUPLE2
357 61: q BINPUT 2
358 63: R REDUCE
359 64: q BINPUT 3
360 66: K BININT1 1
361 68: J BININT -1
362 73: K BININT1 255
363 75: J BININT -255
364 80: J BININT -256
365 85: M BININT2 65535
366 88: J BININT -65535
367 93: J BININT -65536
368 98: J BININT 2147483647
369 103: J BININT -2147483647
370 108: J BININT -2147483648
371 113: ( MARK
372 114: X BINUNICODE 'abc'
373 122: q BINPUT 4
374 124: h BINGET 4
375 126: c GLOBAL '__main__ C'
376 138: q BINPUT 5
377 140: ) EMPTY_TUPLE
378 141: \x81 NEWOBJ
379 142: q BINPUT 6
380 144: } EMPTY_DICT
381 145: q BINPUT 7
382 147: ( MARK
383 148: X BINUNICODE 'foo'
384 156: q BINPUT 8
385 158: K BININT1 1
386 160: X BINUNICODE 'bar'
387 168: q BINPUT 9
388 170: K BININT1 2
389 172: u SETITEMS (MARK at 147)
390 173: b BUILD
391 174: h BINGET 6
392 176: t TUPLE (MARK at 113)
393 177: q BINPUT 10
394 179: h BINGET 10
395 181: K BININT1 5
396 183: e APPENDS (MARK at 5)
397 184: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000398highest protocol among opcodes = 2
399"""
400
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000401# set([1,2]) pickled from 2.x with protocol 2
402DATA3 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
403
404# xrange(5) pickled from 2.x with protocol 2
405DATA4 = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
406
407# a SimpleCookie() object pickled from 2.x with protocol 2
408DATA5 = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
409 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
410 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
411 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
412 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
413 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
414
415# set([3]) pickled from 2.x with protocol 2
416DATA6 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
417
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100418python2_exceptions_without_args = (
419 ArithmeticError,
420 AssertionError,
421 AttributeError,
422 BaseException,
423 BufferError,
424 BytesWarning,
425 DeprecationWarning,
426 EOFError,
427 EnvironmentError,
428 Exception,
429 FloatingPointError,
430 FutureWarning,
431 GeneratorExit,
432 IOError,
433 ImportError,
434 ImportWarning,
435 IndentationError,
436 IndexError,
437 KeyError,
438 KeyboardInterrupt,
439 LookupError,
440 MemoryError,
441 NameError,
442 NotImplementedError,
443 OSError,
444 OverflowError,
445 PendingDeprecationWarning,
446 ReferenceError,
447 RuntimeError,
448 RuntimeWarning,
449 # StandardError is gone in Python 3, we map it to Exception
450 StopIteration,
451 SyntaxError,
452 SyntaxWarning,
453 SystemError,
454 SystemExit,
455 TabError,
456 TypeError,
457 UnboundLocalError,
458 UnicodeError,
459 UnicodeWarning,
460 UserWarning,
461 ValueError,
462 Warning,
463 ZeroDivisionError,
464)
465
466exception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.'
467
468# Exception objects without arguments pickled from 2.x with protocol 2
469DATA7 = {
470 exception :
471 exception_pickle.replace(b'?', exception.__name__.encode("ascii"))
472 for exception in python2_exceptions_without_args
473}
474
475# StandardError is mapped to Exception, test that separately
476DATA8 = exception_pickle.replace(b'?', b'StandardError')
477
478# UnicodeEncodeError object pickled from 2.x with protocol 2
479DATA9 = (b'\x80\x02cexceptions\nUnicodeEncodeError\n'
480 b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01'
481 b'U\x03badq\x03tq\x04Rq\x05.')
482
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000483
Jeremy Hylton66426532001-10-15 21:38:56 +0000484def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000485 c = C()
486 c.foo = 1
487 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000488 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000489 # Append some integer test cases at cPickle.c's internal size
490 # cutoffs.
491 uint1max = 0xff
492 uint2max = 0xffff
493 int4max = 0x7fffffff
494 x.extend([1, -1,
495 uint1max, -uint1max, -uint1max-1,
496 uint2max, -uint2max, -uint2max-1,
497 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000498 y = ('abc', 'abc', c, c)
499 x.append(y)
500 x.append(y)
501 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000502 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000503
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100504
Jeremy Hylton66426532001-10-15 21:38:56 +0000505class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000506 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000507
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +0100508 optimized = False
509
Jeremy Hylton66426532001-10-15 21:38:56 +0000510 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000511
Jeremy Hylton66426532001-10-15 21:38:56 +0000512 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000513 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000514
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100515 def assert_is_copy(self, obj, objcopy, msg=None):
516 """Utility method to verify if two objects are copies of each others.
517 """
518 if msg is None:
519 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
520 self.assertEqual(obj, objcopy, msg=msg)
521 self.assertIs(type(obj), type(objcopy), msg=msg)
522 if hasattr(obj, '__dict__'):
523 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
524 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
525 if hasattr(obj, '__slots__'):
526 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
527 for slot in obj.__slots__:
528 self.assertEqual(
529 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
530 self.assertEqual(getattr(obj, slot, None),
531 getattr(objcopy, slot, None), msg=msg)
532
Jeremy Hylton66426532001-10-15 21:38:56 +0000533 def test_misc(self):
534 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000535 for proto in protocols:
536 x = myint(4)
537 s = self.dumps(x, proto)
538 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100539 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000540
Tim Peters70b02d72003-02-02 17:26:40 +0000541 x = (1, ())
542 s = self.dumps(x, proto)
543 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100544 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000545
Tim Peters70b02d72003-02-02 17:26:40 +0000546 x = initarg(1, x)
547 s = self.dumps(x, proto)
548 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100549 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000550
Jeremy Hylton66426532001-10-15 21:38:56 +0000551 # XXX test __reduce__ protocol?
552
Tim Peters70b02d72003-02-02 17:26:40 +0000553 def test_roundtrip_equality(self):
554 expected = self._testdata
555 for proto in protocols:
556 s = self.dumps(expected, proto)
557 got = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100558 self.assert_is_copy(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000559
Guido van Rossum98297ee2007-11-06 21:34:58 +0000560 def test_load_from_data0(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100561 self.assert_is_copy(self._testdata, self.loads(DATA0))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000562
563 def test_load_from_data1(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100564 self.assert_is_copy(self._testdata, self.loads(DATA1))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000565
566 def test_load_from_data2(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100567 self.assert_is_copy(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000568
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000569 def test_load_classic_instance(self):
570 # See issue5180. Test loading 2.x pickles that
571 # contain an instance of old style class.
572 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
573 xname = X.__name__.encode('ascii')
574 # Protocol 0 (text mode pickle):
575 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200576 0: ( MARK
577 1: i INST '__main__ X' (MARK at 0)
578 13: p PUT 0
579 16: ( MARK
580 17: d DICT (MARK at 16)
581 18: p PUT 1
582 21: b BUILD
583 22: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000584 """
585 pickle0 = (b"(i__main__\n"
586 b"X\n"
587 b"p0\n"
588 b"(dp1\nb.").replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100589 self.assert_is_copy(X(*args), self.loads(pickle0))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000590
591 # Protocol 1 (binary mode pickle)
592 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200593 0: ( MARK
594 1: c GLOBAL '__main__ X'
595 13: q BINPUT 0
596 15: o OBJ (MARK at 0)
597 16: q BINPUT 1
598 18: } EMPTY_DICT
599 19: q BINPUT 2
600 21: b BUILD
601 22: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000602 """
603 pickle1 = (b'(c__main__\n'
604 b'X\n'
605 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100606 self.assert_is_copy(X(*args), self.loads(pickle1))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000607
608 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
609 """
Serhiy Storchakafa310ee2015-02-15 14:10:03 +0200610 0: \x80 PROTO 2
611 2: ( MARK
612 3: c GLOBAL '__main__ X'
613 15: q BINPUT 0
614 17: o OBJ (MARK at 2)
615 18: q BINPUT 1
616 20: } EMPTY_DICT
617 21: q BINPUT 2
618 23: b BUILD
619 24: . STOP
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000620 """
621 pickle2 = (b'\x80\x02(c__main__\n'
622 b'X\n'
623 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100624 self.assert_is_copy(X(*args), self.loads(pickle2))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000625
Tim Peters70b02d72003-02-02 17:26:40 +0000626 # There are gratuitous differences between pickles produced by
627 # pickle and cPickle, largely because cPickle starts PUT indices at
628 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
629 # there's a comment with an exclamation point there whose meaning
630 # is a mystery. cPickle also suppresses PUT for objects with a refcount
631 # of 1.
632 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000633 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000634 from pickletools import dis
635
636 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
637 s = self.dumps(self._testdata, proto)
638 filelike = StringIO()
639 dis(s, out=filelike)
640 got = filelike.getvalue()
641 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000642
643 def test_recursive_list(self):
644 l = []
645 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000646 for proto in protocols:
647 s = self.dumps(l, proto)
648 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100649 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000650 self.assertEqual(len(x), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000651 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000652
Collin Winter8ca69de2009-05-26 16:53:41 +0000653 def test_recursive_tuple(self):
654 t = ([],)
655 t[0].append(t)
656 for proto in protocols:
657 s = self.dumps(t, proto)
658 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100659 self.assertIsInstance(x, tuple)
Collin Winter8ca69de2009-05-26 16:53:41 +0000660 self.assertEqual(len(x), 1)
661 self.assertEqual(len(x[0]), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000662 self.assertTrue(x is x[0][0])
Collin Winter8ca69de2009-05-26 16:53:41 +0000663
Jeremy Hylton66426532001-10-15 21:38:56 +0000664 def test_recursive_dict(self):
665 d = {}
666 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000667 for proto in protocols:
668 s = self.dumps(d, proto)
669 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100670 self.assertIsInstance(x, dict)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000671 self.assertEqual(list(x.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000672 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000673
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100674 def test_recursive_set(self):
675 h = H()
676 y = set({h})
677 h.attr = y
678 for proto in protocols:
679 s = self.dumps(y, proto)
680 x = self.loads(s)
681 self.assertIsInstance(x, set)
682 self.assertIs(list(x)[0].attr, x)
683 self.assertEqual(len(x), 1)
684
685 def test_recursive_frozenset(self):
686 h = H()
687 y = frozenset({h})
688 h.attr = y
689 for proto in protocols:
690 s = self.dumps(y, proto)
691 x = self.loads(s)
692 self.assertIsInstance(x, frozenset)
693 self.assertIs(list(x)[0].attr, x)
694 self.assertEqual(len(x), 1)
695
Jeremy Hylton66426532001-10-15 21:38:56 +0000696 def test_recursive_inst(self):
697 i = C()
698 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000699 for proto in protocols:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200700 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +0000701 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100702 self.assertIsInstance(x, C)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000703 self.assertEqual(dir(x), dir(i))
Ezio Melottiaaef3442013-03-04 15:17:56 +0200704 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000705
706 def test_recursive_multi(self):
707 l = []
708 d = {1:l}
709 i = C()
710 i.attr = d
711 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000712 for proto in protocols:
713 s = self.dumps(l, proto)
714 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100715 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000716 self.assertEqual(len(x), 1)
717 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000718 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000719 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000720
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000721 def test_get(self):
722 self.assertRaises(KeyError, self.loads, b'g0\np0')
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100723 self.assert_is_copy([(100,), (100,)],
724 self.loads(b'((Kdtp0\nh\x00l.))'))
Jeremy Hylton66426532001-10-15 21:38:56 +0000725
Walter Dörwald9b775532007-06-08 14:30:53 +0000726 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000727 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +0000728 '<\\>', '<\\\U00012345>',
729 # surrogates
730 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000731 for proto in protocols:
732 for u in endcases:
733 p = self.dumps(u, proto)
734 u2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100735 self.assert_is_copy(u, u2)
Tim Peterse089c682001-04-10 03:41:41 +0000736
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000737 def test_unicode_high_plane(self):
738 t = '\U00012345'
739 for proto in protocols:
740 p = self.dumps(t, proto)
741 t2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100742 self.assert_is_copy(t, t2)
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000743
Guido van Rossumf4169812008-03-17 22:56:06 +0000744 def test_bytes(self):
745 for proto in protocols:
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500746 for s in b'', b'xyz', b'xyz'*100:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200747 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100748 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500749 for s in [bytes([i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200750 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100751 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500752 for s in [bytes([i, i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200753 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100754 self.assert_is_copy(s, self.loads(p))
Guido van Rossumf4169812008-03-17 22:56:06 +0000755
Jeremy Hylton66426532001-10-15 21:38:56 +0000756 def test_ints(self):
757 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000758 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000759 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000760 while n:
761 for expected in (-n, n):
762 s = self.dumps(expected, proto)
763 n2 = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100764 self.assert_is_copy(expected, n2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000765 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000766
Jeremy Hylton66426532001-10-15 21:38:56 +0000767 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000768 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000769 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000770 got = self.loads(data)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100771 self.assert_is_copy(maxint64, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000772
773 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000774 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000775 self.assertRaises(ValueError, self.loads, data)
776
Tim Petersee1a53c2003-02-02 02:57:53 +0000777 def test_long(self):
778 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000779 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000780 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000781 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000782 for npos in nbase-1, nbase, nbase+1:
783 for n in npos, -npos:
784 pickle = self.dumps(n, proto)
785 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100786 self.assert_is_copy(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +0000787 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
788 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000789 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000790 nbase += nbase << 1000000
791 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000792 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000793 got = self.loads(p)
Antoine Pitroud5df1942013-11-23 21:20:49 +0100794 # assert_is_copy is very expensive here as it precomputes
795 # a failure message by computing the repr() of n and got,
796 # we just do the check ourselves.
797 self.assertIs(type(got), int)
798 self.assertEqual(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +0000799
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000800 def test_float(self):
801 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
802 3.14, 263.44582062374053, 6.022e23, 1e30]
803 test_values = test_values + [-x for x in test_values]
804 for proto in protocols:
805 for value in test_values:
806 pickle = self.dumps(value, proto)
807 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100808 self.assert_is_copy(value, got)
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000809
Thomas Wouters477c8d52006-05-27 19:21:47 +0000810 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
811 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000812 # make sure that floats are formatted locale independent with proto 0
813 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000814
Jeremy Hylton66426532001-10-15 21:38:56 +0000815 def test_reduce(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +0100816 for proto in protocols:
817 inst = AAA()
818 dumped = self.dumps(inst, proto)
819 loaded = self.loads(dumped)
820 self.assertEqual(loaded, REDUCE_A)
Jeremy Hylton66426532001-10-15 21:38:56 +0000821
822 def test_getinitargs(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +0100823 for proto in protocols:
824 inst = initarg(1, 2)
825 dumped = self.dumps(inst, proto)
826 loaded = self.loads(dumped)
827 self.assert_is_copy(inst, loaded)
Jeremy Hylton66426532001-10-15 21:38:56 +0000828
Antoine Pitrou79035bd2012-06-26 23:04:48 +0200829 def test_pop_empty_stack(self):
830 # Test issue7455
831 s = b'0'
832 self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s)
833
Guido van Rossum04a86612001-12-19 16:58:54 +0000834 def test_metaclass(self):
835 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000836 for proto in protocols:
837 s = self.dumps(a, proto)
838 b = self.loads(s)
839 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000840
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200841 def test_dynamic_class(self):
842 a = create_dynamic_class("my_dynamic_class", (object,))
843 copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
844 for proto in protocols:
845 s = self.dumps(a, proto)
846 b = self.loads(s)
847 self.assertEqual(a, b)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100848 self.assertIs(type(a), type(b))
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200849
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000850 def test_structseq(self):
851 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000852 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000853
854 t = time.localtime()
855 for proto in protocols:
856 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000857 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100858 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000859 if hasattr(os, "stat"):
860 t = os.stat(os.curdir)
861 s = self.dumps(t, proto)
862 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100863 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000864 if hasattr(os, "statvfs"):
865 t = os.statvfs(os.curdir)
866 s = self.dumps(t, proto)
867 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100868 self.assert_is_copy(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000869
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100870 def test_ellipsis(self):
871 for proto in protocols:
872 s = self.dumps(..., proto)
873 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100874 self.assertIs(..., u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100875
876 def test_notimplemented(self):
877 for proto in protocols:
878 s = self.dumps(NotImplemented, proto)
879 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100880 self.assertIs(NotImplemented, u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100881
Alexandre Vassalotti19b6fa62013-11-30 16:06:39 -0800882 def test_singleton_types(self):
883 # Issue #6477: Test that types of built-in singletons can be pickled.
884 singletons = [None, ..., NotImplemented]
885 for singleton in singletons:
886 for proto in protocols:
887 s = self.dumps(type(singleton), proto)
888 u = self.loads(s)
889 self.assertIs(type(singleton), u)
890
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000891 # Tests for protocol 2
892
Tim Peters4190fb82003-02-02 16:09:05 +0000893 def test_proto(self):
Tim Peters4190fb82003-02-02 16:09:05 +0000894 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100895 pickled = self.dumps(None, proto)
Tim Peters4190fb82003-02-02 16:09:05 +0000896 if proto >= 2:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100897 proto_header = pickle.PROTO + bytes([proto])
898 self.assertTrue(pickled.startswith(proto_header))
899 else:
900 self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)
Tim Peters4190fb82003-02-02 16:09:05 +0000901
902 oob = protocols[-1] + 1 # a future protocol
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100903 build_none = pickle.NONE + pickle.STOP
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000904 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000905 try:
906 self.loads(badpickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100907 except ValueError as err:
908 self.assertIn("unsupported pickle protocol", str(err))
Tim Peters4190fb82003-02-02 16:09:05 +0000909 else:
910 self.fail("expected bad protocol number to raise ValueError")
911
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000912 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000913 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000914 for proto in protocols:
915 s = self.dumps(x, proto)
916 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100917 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000918 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000919
920 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000921 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000922 for proto in protocols:
923 s = self.dumps(x, proto)
924 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100925 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000926 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000927
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000928 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000929 # Map (proto, len(tuple)) to expected opcode.
930 expected_opcode = {(0, 0): pickle.TUPLE,
931 (0, 1): pickle.TUPLE,
932 (0, 2): pickle.TUPLE,
933 (0, 3): pickle.TUPLE,
934 (0, 4): pickle.TUPLE,
935
936 (1, 0): pickle.EMPTY_TUPLE,
937 (1, 1): pickle.TUPLE,
938 (1, 2): pickle.TUPLE,
939 (1, 3): pickle.TUPLE,
940 (1, 4): pickle.TUPLE,
941
942 (2, 0): pickle.EMPTY_TUPLE,
943 (2, 1): pickle.TUPLE1,
944 (2, 2): pickle.TUPLE2,
945 (2, 3): pickle.TUPLE3,
946 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000947
948 (3, 0): pickle.EMPTY_TUPLE,
949 (3, 1): pickle.TUPLE1,
950 (3, 2): pickle.TUPLE2,
951 (3, 3): pickle.TUPLE3,
952 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000953 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000954 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000955 b = (1,)
956 c = (1, 2)
957 d = (1, 2, 3)
958 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000959 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000960 for x in a, b, c, d, e:
961 s = self.dumps(x, proto)
962 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100963 self.assert_is_copy(x, y)
964 expected = expected_opcode[min(proto, 3), len(x)]
965 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000966
Guido van Rossum7d97d312003-01-28 04:25:27 +0000967 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000968 # Map (proto, singleton) to expected opcode.
969 expected_opcode = {(0, None): pickle.NONE,
970 (1, None): pickle.NONE,
971 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000972 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000973
974 (0, True): pickle.INT,
975 (1, True): pickle.INT,
976 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000977 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000978
979 (0, False): pickle.INT,
980 (1, False): pickle.INT,
981 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000982 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000983 }
Tim Peters4190fb82003-02-02 16:09:05 +0000984 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000985 for x in None, False, True:
986 s = self.dumps(x, proto)
987 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000988 self.assertTrue(x is y, (proto, x, s, y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100989 expected = expected_opcode[min(proto, 3), x]
990 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters3c67d792003-02-02 17:59:11 +0000991
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000992 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000993 x = MyTuple([1, 2, 3])
994 x.foo = 42
995 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000996 for proto in protocols:
997 s = self.dumps(x, proto)
998 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100999 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001000
1001 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001002 x = MyList([1, 2, 3])
1003 x.foo = 42
1004 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001005 for proto in protocols:
1006 s = self.dumps(x, proto)
1007 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001008 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001009
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001010 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001011 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001012 for C in myclasses:
1013 B = C.__base__
1014 x = C(C.sample)
1015 x.foo = 42
1016 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001017 y = self.loads(s)
1018 detail = (proto, C, B, x, y, type(y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001019 self.assert_is_copy(x, y) # XXX revisit
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001020 self.assertEqual(B(x), B(y), detail)
1021 self.assertEqual(x.__dict__, y.__dict__, detail)
1022
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01001023 def test_newobj_proxies(self):
1024 # NEWOBJ should use the __class__ rather than the raw type
1025 classes = myclasses[:]
1026 # Cannot create weakproxies to these classes
1027 for c in (MyInt, MyTuple):
1028 classes.remove(c)
1029 for proto in protocols:
1030 for C in classes:
1031 B = C.__base__
1032 x = C(C.sample)
1033 x.foo = 42
1034 p = weakref.proxy(x)
1035 s = self.dumps(p, proto)
1036 y = self.loads(s)
1037 self.assertEqual(type(y), type(x)) # rather than type(p)
1038 detail = (proto, C, B, x, y, type(y))
1039 self.assertEqual(B(x), B(y), detail)
1040 self.assertEqual(x.__dict__, y.__dict__, detail)
1041
Benjamin Peterson80f78a32015-07-02 16:18:38 -05001042 def test_newobj_not_class(self):
1043 # Issue 24552
1044 global SimpleNewObj
1045 save = SimpleNewObj
Benjamin Petersond3a2a952015-07-02 16:58:22 -05001046 o = SimpleNewObj.__new__(SimpleNewObj)
Benjamin Peterson80f78a32015-07-02 16:18:38 -05001047 b = self.dumps(o, 4)
1048 try:
1049 SimpleNewObj = 42
1050 self.assertRaises((TypeError, pickle.UnpicklingError), self.loads, b)
1051 finally:
1052 SimpleNewObj = save
1053
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001054 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001055 # an object of that type. Check that the resulting pickle uses opcode
1056 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001057
Tim Peters22e71712003-02-03 22:27:38 +00001058 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001059 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001060 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001061 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001062 x = MyList([1, 2, 3])
1063 x.foo = 42
1064 x.bar = "hello"
1065
Tim Peters22e71712003-02-03 22:27:38 +00001066 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001067 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001068 self.assertIn(__name__.encode("utf-8"), s1)
1069 self.assertIn(b"MyList", s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001070 self.assertFalse(opcode_in_pickle(opcode, s1))
Tim Peters3e667d52003-02-04 21:47:44 +00001071
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001072 y = self.loads(s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001073 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001074
Tim Peters22e71712003-02-03 22:27:38 +00001075 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001076 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001077 self.assertNotIn(__name__.encode("utf-8"), s2)
1078 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001079 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +00001080
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001081 y = self.loads(s2)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001082 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001083 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001084 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001085
1086 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001087 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1088 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001089
1090 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001091 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1092 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1093 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001094
1095 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001096 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1097 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1098 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1099
Tim Peters8d2613a2003-02-11 16:40:16 +00001100 def test_list_chunking(self):
1101 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +00001102 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001103 for proto in protocols:
1104 s = self.dumps(x, proto)
1105 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001106 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001107 num_appends = count_opcode(pickle.APPENDS, s)
1108 self.assertEqual(num_appends, proto > 0)
1109
1110 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001111 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001112 for proto in protocols:
1113 s = self.dumps(x, proto)
1114 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001115 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001116 num_appends = count_opcode(pickle.APPENDS, s)
1117 if proto == 0:
1118 self.assertEqual(num_appends, 0)
1119 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001120 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001121
1122 def test_dict_chunking(self):
1123 n = 10 # too small to chunk
1124 x = dict.fromkeys(range(n))
1125 for proto in protocols:
1126 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +00001127 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00001128 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001129 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001130 num_setitems = count_opcode(pickle.SETITEMS, s)
1131 self.assertEqual(num_setitems, proto > 0)
1132
1133 n = 2500 # expect at least two chunks when proto > 0
1134 x = dict.fromkeys(range(n))
1135 for proto in protocols:
1136 s = self.dumps(x, proto)
1137 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001138 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001139 num_setitems = count_opcode(pickle.SETITEMS, s)
1140 if proto == 0:
1141 self.assertEqual(num_setitems, 0)
1142 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001143 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001144
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001145 def test_set_chunking(self):
1146 n = 10 # too small to chunk
1147 x = set(range(n))
1148 for proto in protocols:
1149 s = self.dumps(x, proto)
1150 y = self.loads(s)
1151 self.assert_is_copy(x, y)
1152 num_additems = count_opcode(pickle.ADDITEMS, s)
1153 if proto < 4:
1154 self.assertEqual(num_additems, 0)
1155 else:
1156 self.assertEqual(num_additems, 1)
1157
1158 n = 2500 # expect at least two chunks when proto >= 4
1159 x = set(range(n))
1160 for proto in protocols:
1161 s = self.dumps(x, proto)
1162 y = self.loads(s)
1163 self.assert_is_copy(x, y)
1164 num_additems = count_opcode(pickle.ADDITEMS, s)
1165 if proto < 4:
1166 self.assertEqual(num_additems, 0)
1167 else:
1168 self.assertGreaterEqual(num_additems, 2)
1169
Tim Peterse9ef2032003-02-13 18:42:00 +00001170 def test_simple_newobj(self):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001171 x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__
Tim Peterse9ef2032003-02-13 18:42:00 +00001172 x.abc = 666
1173 for proto in protocols:
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001174 with self.subTest(proto=proto):
1175 s = self.dumps(x, proto)
1176 if proto < 1:
1177 self.assertIn(b'\nL64206', s) # LONG
1178 else:
1179 self.assertIn(b'M\xce\xfa', s) # BININT2
1180 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1181 2 <= proto)
1182 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1183 y = self.loads(s) # will raise TypeError if __init__ called
1184 self.assert_is_copy(x, y)
1185
1186 def test_complex_newobj(self):
1187 x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__
1188 x.abc = 666
1189 for proto in protocols:
1190 with self.subTest(proto=proto):
1191 s = self.dumps(x, proto)
1192 if proto < 1:
1193 self.assertIn(b'\nL64206', s) # LONG
1194 elif proto < 2:
1195 self.assertIn(b'M\xce\xfa', s) # BININT2
1196 elif proto < 4:
1197 self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
1198 else:
1199 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1200 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1201 2 <= proto)
1202 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1203 y = self.loads(s) # will raise TypeError if __init__ called
1204 self.assert_is_copy(x, y)
1205
1206 def test_complex_newobj_ex(self):
1207 x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__
1208 x.abc = 666
1209 for proto in protocols:
1210 with self.subTest(proto=proto):
1211 if 2 <= proto < 4:
1212 self.assertRaises(ValueError, self.dumps, x, proto)
1213 continue
1214 s = self.dumps(x, proto)
1215 if proto < 1:
1216 self.assertIn(b'\nL64206', s) # LONG
1217 elif proto < 2:
1218 self.assertIn(b'M\xce\xfa', s) # BININT2
1219 else:
1220 assert proto >= 4
1221 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1222 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s))
1223 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1224 4 <= proto)
1225 y = self.loads(s) # will raise TypeError if __init__ called
1226 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001227
Tim Peters42f08ac2003-02-11 22:43:24 +00001228 def test_newobj_list_slots(self):
1229 x = SlotList([1, 2, 3])
1230 x.foo = 42
1231 x.bar = "hello"
1232 s = self.dumps(x, 2)
1233 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001234 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001235
Guido van Rossum2a30b212003-02-18 22:41:24 +00001236 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001237 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001238 x = REX_one()
1239 self.assertEqual(x._reduce_called, 0)
1240 s = self.dumps(x, proto)
1241 self.assertEqual(x._reduce_called, 1)
1242 y = self.loads(s)
1243 self.assertEqual(y._reduce_called, 0)
1244
1245 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001246 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001247 x = REX_two()
1248 self.assertEqual(x._proto, None)
1249 s = self.dumps(x, proto)
1250 self.assertEqual(x._proto, proto)
1251 y = self.loads(s)
1252 self.assertEqual(y._proto, None)
1253
1254 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001255 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001256 x = REX_three()
1257 self.assertEqual(x._proto, None)
1258 s = self.dumps(x, proto)
1259 self.assertEqual(x._proto, proto)
1260 y = self.loads(s)
1261 self.assertEqual(y._proto, None)
1262
Guido van Rossumd8faa362007-04-27 19:54:29 +00001263 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001264 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001265 x = REX_four()
1266 self.assertEqual(x._proto, None)
1267 s = self.dumps(x, proto)
1268 self.assertEqual(x._proto, proto)
1269 y = self.loads(s)
1270 self.assertEqual(y._proto, proto)
1271
1272 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001273 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001274 x = REX_five()
1275 self.assertEqual(x._reduce_called, 0)
1276 s = self.dumps(x, proto)
1277 self.assertEqual(x._reduce_called, 1)
1278 y = self.loads(s)
1279 self.assertEqual(y._reduce_called, 1)
1280
Brett Cannon31f59292011-02-21 19:29:56 +00001281 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001282 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001283 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001284 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001285 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001286 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001287
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001288 def test_reduce_bad_iterator(self):
1289 # Issue4176: crash when 4th and 5th items of __reduce__()
1290 # are not iterators
1291 class C(object):
1292 def __reduce__(self):
1293 # 4th item is not an iterator
1294 return list, (), None, [], None
1295 class D(object):
1296 def __reduce__(self):
1297 # 5th item is not an iterator
1298 return dict, (), None, None, []
1299
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001300 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001301 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001302 try:
1303 self.dumps(C(), proto)
1304 except (pickle.PickleError):
1305 pass
1306 try:
1307 self.dumps(D(), proto)
1308 except (pickle.PickleError):
1309 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001310
Collin Winter771d8342009-04-16 03:18:06 +00001311 def test_many_puts_and_gets(self):
1312 # Test that internal data structures correctly deal with lots of
1313 # puts/gets.
1314 keys = ("aaa" + str(i) for i in range(100))
1315 large_dict = dict((k, [4, 5, 6]) for k in keys)
1316 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1317
1318 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001319 with self.subTest(proto=proto):
1320 dumped = self.dumps(obj, proto)
1321 loaded = self.loads(dumped)
1322 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00001323
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001324 def test_attribute_name_interning(self):
1325 # Test that attribute names of pickled objects are interned when
1326 # unpickling.
1327 for proto in protocols:
1328 x = C()
1329 x.foo = 42
1330 x.bar = "hello"
1331 s = self.dumps(x, proto)
1332 y = self.loads(s)
1333 x_keys = sorted(x.__dict__)
1334 y_keys = sorted(y.__dict__)
1335 for x_key, y_key in zip(x_keys, y_keys):
1336 self.assertIs(x_key, y_key)
1337
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001338 def test_unpickle_from_2x(self):
1339 # Unpickle non-trivial data from Python 2.x.
1340 loaded = self.loads(DATA3)
1341 self.assertEqual(loaded, set([1, 2]))
1342 loaded = self.loads(DATA4)
1343 self.assertEqual(type(loaded), type(range(0)))
1344 self.assertEqual(list(loaded), list(range(5)))
1345 loaded = self.loads(DATA5)
1346 self.assertEqual(type(loaded), SimpleCookie)
1347 self.assertEqual(list(loaded.keys()), ["key"])
Serhiy Storchaka8cf7c1c2014-11-02 22:18:25 +02001348 self.assertEqual(loaded["key"].value, "value")
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001349
Walter Doerwald9d1dbca2013-12-02 11:41:01 +01001350 for (exc, data) in DATA7.items():
1351 loaded = self.loads(data)
1352 self.assertIs(type(loaded), exc)
1353
1354 loaded = self.loads(DATA8)
1355 self.assertIs(type(loaded), Exception)
1356
1357 loaded = self.loads(DATA9)
1358 self.assertIs(type(loaded), UnicodeEncodeError)
1359 self.assertEqual(loaded.object, "foo")
1360 self.assertEqual(loaded.encoding, "ascii")
1361 self.assertEqual(loaded.start, 0)
1362 self.assertEqual(loaded.end, 1)
1363 self.assertEqual(loaded.reason, "bad")
1364
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001365 def test_pickle_to_2x(self):
1366 # Pickle non-trivial data with protocol 2, expecting that it yields
1367 # the same result as Python 2.x did.
1368 # NOTE: this test is a bit too strong since we can produce different
1369 # bytecode that 2.x will still understand.
1370 dumped = self.dumps(range(5), 2)
1371 self.assertEqual(dumped, DATA4)
1372 dumped = self.dumps(set([3]), 2)
1373 self.assertEqual(dumped, DATA6)
1374
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -08001375 def test_load_python2_str_as_bytes(self):
1376 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
1377 self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
1378 encoding="bytes"), b'a\x00\xa0')
1379 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
1380 self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
1381 encoding="bytes"), b'a\x00\xa0')
1382 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
1383 self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
1384 encoding="bytes"), b'a\x00\xa0')
1385
1386 def test_load_python2_unicode_as_str(self):
1387 # From Python 2: pickle.dumps(u'π', protocol=0)
1388 self.assertEqual(self.loads(b'V\\u03c0\n.',
1389 encoding='bytes'), 'π')
1390 # From Python 2: pickle.dumps(u'π', protocol=1)
1391 self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
1392 encoding="bytes"), 'π')
1393 # From Python 2: pickle.dumps(u'π', protocol=2)
1394 self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
1395 encoding="bytes"), 'π')
1396
1397 def test_load_long_python2_str_as_bytes(self):
1398 # From Python 2: pickle.dumps('x' * 300, protocol=1)
1399 self.assertEqual(self.loads(pickle.BINSTRING +
1400 struct.pack("<I", 300) +
1401 b'x' * 300 + pickle.STOP,
1402 encoding='bytes'), b'x' * 300)
1403
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001404 def test_large_pickles(self):
1405 # Test the correctness of internal buffering routines when handling
1406 # large data.
1407 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001408 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001409 dumped = self.dumps(data, proto)
1410 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001411 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001412 self.assertEqual(loaded, data)
1413
Alexander Belopolsky1ce92dc2011-02-24 19:40:09 +00001414 def test_empty_bytestring(self):
1415 # issue 11286
1416 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1417 self.assertEqual(empty, '')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001418
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001419 def test_int_pickling_efficiency(self):
1420 # Test compacity of int representation (see issue #12744)
1421 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001422 with self.subTest(proto=proto):
1423 pickles = [self.dumps(2**n, proto) for n in range(70)]
1424 sizes = list(map(len, pickles))
1425 # the size function is monotonic
1426 self.assertEqual(sorted(sizes), sizes)
1427 if proto >= 2:
1428 for p in pickles:
1429 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001430
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001431 def check_negative_32b_binXXX(self, dumped):
1432 if sys.maxsize > 2**32:
1433 self.skipTest("test is only meaningful on 32-bit builds")
1434 # XXX Pure Python pickle reads lengths as signed and passes
1435 # them directly to read() (hence the EOFError)
1436 with self.assertRaises((pickle.UnpicklingError, EOFError,
1437 ValueError, OverflowError)):
1438 self.loads(dumped)
1439
1440 def test_negative_32b_binbytes(self):
1441 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1442 self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.')
1443
1444 def test_negative_32b_binunicode(self):
1445 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1446 self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.')
1447
Antoine Pitrou55549ec2011-08-30 00:27:10 +02001448 def test_negative_put(self):
1449 # Issue #12847
1450 dumped = b'Va\np-1\n.'
1451 self.assertRaises(ValueError, self.loads, dumped)
1452
1453 def test_negative_32b_binput(self):
1454 # Issue #12847
1455 if sys.maxsize > 2**32:
1456 self.skipTest("test is only meaningful on 32-bit builds")
1457 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
1458 self.assertRaises(ValueError, self.loads, dumped)
1459
Alexandre Vassalotti7c5e0942013-04-15 23:14:55 -07001460 def test_badly_escaped_string(self):
1461 self.assertRaises(ValueError, self.loads, b"S'\\'\n.")
1462
1463 def test_badly_quoted_string(self):
1464 # Issue #17710
1465 badpickles = [b"S'\n.",
1466 b'S"\n.',
1467 b'S\' \n.',
1468 b'S" \n.',
1469 b'S\'"\n.',
1470 b'S"\'\n.',
1471 b"S' ' \n.",
1472 b'S" " \n.',
1473 b"S ''\n.",
1474 b'S ""\n.',
1475 b'S \n.',
1476 b'S\n.',
1477 b'S.']
1478 for p in badpickles:
1479 self.assertRaises(pickle.UnpicklingError, self.loads, p)
1480
1481 def test_correctly_quoted_string(self):
1482 goodpickles = [(b"S''\n.", ''),
1483 (b'S""\n.', ''),
1484 (b'S"\\n"\n.', '\n'),
1485 (b"S'\\n'\n.", '\n')]
1486 for p, expected in goodpickles:
1487 self.assertEqual(self.loads(p), expected)
1488
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001489 def _check_pickling_with_opcode(self, obj, opcode, proto):
1490 pickled = self.dumps(obj, proto)
1491 self.assertTrue(opcode_in_pickle(opcode, pickled))
1492 unpickled = self.loads(pickled)
1493 self.assertEqual(obj, unpickled)
1494
1495 def test_appends_on_non_lists(self):
1496 # Issue #17720
1497 obj = REX_six([1, 2, 3])
1498 for proto in protocols:
1499 if proto == 0:
1500 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1501 else:
1502 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1503
1504 def test_setitems_on_non_dicts(self):
1505 obj = REX_seven({1: -1, 2: -2, 3: -3})
1506 for proto in protocols:
1507 if proto == 0:
1508 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1509 else:
1510 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1511
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001512 # Exercise framing (proto >= 4) for significant workloads
1513
1514 FRAME_SIZE_TARGET = 64 * 1024
1515
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001516 def check_frame_opcodes(self, pickled):
1517 """
1518 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
1519 """
1520 frame_opcode_size = 9
1521 last_arg = last_pos = None
1522 for op, arg, pos in pickletools.genops(pickled):
1523 if op.name != 'FRAME':
1524 continue
1525 if last_pos is not None:
1526 # The previous frame's size should be equal to the number
1527 # of bytes up to the current frame.
1528 frame_size = pos - last_pos - frame_opcode_size
1529 self.assertEqual(frame_size, last_arg)
1530 last_arg, last_pos = arg, pos
1531 # The last frame's size should be equal to the number of bytes up
1532 # to the pickle's end.
1533 frame_size = len(pickled) - last_pos - frame_opcode_size
1534 self.assertEqual(frame_size, last_arg)
1535
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001536 def test_framing_many_objects(self):
1537 obj = list(range(10**5))
1538 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1539 with self.subTest(proto=proto):
1540 pickled = self.dumps(obj, proto)
1541 unpickled = self.loads(pickled)
1542 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001543 bytes_per_frame = (len(pickled) /
1544 count_opcode(pickle.FRAME, pickled))
1545 self.assertGreater(bytes_per_frame,
1546 self.FRAME_SIZE_TARGET / 2)
1547 self.assertLessEqual(bytes_per_frame,
1548 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001549 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001550
1551 def test_framing_large_objects(self):
1552 N = 1024 * 1024
1553 obj = [b'x' * N, b'y' * N, b'z' * N]
1554 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1555 with self.subTest(proto=proto):
1556 pickled = self.dumps(obj, proto)
1557 unpickled = self.loads(pickled)
1558 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001559 n_frames = count_opcode(pickle.FRAME, pickled)
Alexandre Vassalotti28d271e2013-12-01 16:27:46 -08001560 self.assertGreaterEqual(n_frames, len(obj))
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001561 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001562
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001563 def test_optional_frames(self):
1564 if pickle.HIGHEST_PROTOCOL < 4:
1565 return
1566
1567 def remove_frames(pickled, keep_frame=None):
1568 """Remove frame opcodes from the given pickle."""
1569 frame_starts = []
1570 # 1 byte for the opcode and 8 for the argument
1571 frame_opcode_size = 9
1572 for opcode, _, pos in pickletools.genops(pickled):
1573 if opcode.name == 'FRAME':
1574 frame_starts.append(pos)
1575
1576 newpickle = bytearray()
1577 last_frame_end = 0
1578 for i, pos in enumerate(frame_starts):
1579 if keep_frame and keep_frame(i):
1580 continue
1581 newpickle += pickled[last_frame_end:pos]
1582 last_frame_end = pos + frame_opcode_size
1583 newpickle += pickled[last_frame_end:]
1584 return newpickle
1585
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001586 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001587 num_frames = 20
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001588 obj = [bytes([i]) * frame_size for i in range(num_frames)]
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001589
1590 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1591 pickled = self.dumps(obj, proto)
1592
1593 frameless_pickle = remove_frames(pickled)
1594 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
1595 self.assertEqual(obj, self.loads(frameless_pickle))
1596
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001597 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001598 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
1599 count_opcode(pickle.FRAME, pickled))
1600 self.assertEqual(obj, self.loads(some_frames_pickle))
1601
Serhiy Storchaka21d75332015-01-26 10:37:01 +02001602 def test_frame_readline(self):
1603 pickled = b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00I42\n.'
1604 # 0: \x80 PROTO 4
1605 # 2: \x95 FRAME 5
1606 # 11: I INT 42
1607 # 15: . STOP
1608 self.assertEqual(self.loads(pickled), 42)
1609
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001610 def test_nested_names(self):
1611 global Nested
1612 class Nested:
1613 class A:
1614 class B:
1615 class C:
1616 pass
Serhiy Storchaka58e41342015-03-31 14:07:24 +03001617 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001618 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
1619 with self.subTest(proto=proto, obj=obj):
1620 unpickled = self.loads(self.dumps(obj, proto))
1621 self.assertIs(obj, unpickled)
1622
Serhiy Storchaka58e41342015-03-31 14:07:24 +03001623 def test_recursive_nested_names(self):
1624 global Recursive
1625 class Recursive:
1626 pass
1627 Recursive.mod = sys.modules[Recursive.__module__]
1628 Recursive.__qualname__ = 'Recursive.mod.Recursive'
1629 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1630 with self.subTest(proto=proto):
1631 unpickled = self.loads(self.dumps(Recursive, proto))
1632 self.assertIs(unpickled, Recursive)
1633 del Recursive.mod # break reference loop
1634
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001635 def test_py_methods(self):
1636 global PyMethodsTest
1637 class PyMethodsTest:
1638 @staticmethod
1639 def cheese():
1640 return "cheese"
1641 @classmethod
1642 def wine(cls):
1643 assert cls is PyMethodsTest
1644 return "wine"
1645 def biscuits(self):
1646 assert isinstance(self, PyMethodsTest)
1647 return "biscuits"
1648 class Nested:
1649 "Nested class"
1650 @staticmethod
1651 def ketchup():
1652 return "ketchup"
1653 @classmethod
1654 def maple(cls):
1655 assert cls is PyMethodsTest.Nested
1656 return "maple"
1657 def pie(self):
1658 assert isinstance(self, PyMethodsTest.Nested)
1659 return "pie"
1660
1661 py_methods = (
1662 PyMethodsTest.cheese,
1663 PyMethodsTest.wine,
1664 PyMethodsTest().biscuits,
1665 PyMethodsTest.Nested.ketchup,
1666 PyMethodsTest.Nested.maple,
1667 PyMethodsTest.Nested().pie
1668 )
1669 py_unbound_methods = (
1670 (PyMethodsTest.biscuits, PyMethodsTest),
1671 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
1672 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03001673 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001674 for method in py_methods:
1675 with self.subTest(proto=proto, method=method):
1676 unpickled = self.loads(self.dumps(method, proto))
1677 self.assertEqual(method(), unpickled())
1678 for method, cls in py_unbound_methods:
1679 obj = cls()
1680 with self.subTest(proto=proto, method=method):
1681 unpickled = self.loads(self.dumps(method, proto))
1682 self.assertEqual(method(obj), unpickled(obj))
1683
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001684 def test_c_methods(self):
1685 global Subclass
1686 class Subclass(tuple):
1687 class Nested(str):
1688 pass
1689
1690 c_methods = (
1691 # bound built-in method
1692 ("abcd".index, ("c",)),
1693 # unbound built-in method
1694 (str.index, ("abcd", "c")),
1695 # bound "slot" method
1696 ([1, 2, 3].__len__, ()),
1697 # unbound "slot" method
1698 (list.__len__, ([1, 2, 3],)),
1699 # bound "coexist" method
1700 ({1, 2}.__contains__, (2,)),
1701 # unbound "coexist" method
1702 (set.__contains__, ({1, 2}, 2)),
1703 # built-in class method
1704 (dict.fromkeys, (("a", 1), ("b", 2))),
1705 # built-in static method
1706 (bytearray.maketrans, (b"abc", b"xyz")),
1707 # subclass methods
1708 (Subclass([1,2,2]).count, (2,)),
1709 (Subclass.count, (Subclass([1,2,2]), 2)),
1710 (Subclass.Nested("sweet").count, ("e",)),
1711 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
1712 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03001713 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001714 for method, args in c_methods:
1715 with self.subTest(proto=proto, method=method):
1716 unpickled = self.loads(self.dumps(method, proto))
1717 self.assertEqual(method(*args), unpickled(*args))
1718
Serhiy Storchakabfe18242015-03-31 13:12:37 +03001719 def test_compat_pickle(self):
1720 tests = [
1721 (range(1, 7), '__builtin__', 'xrange'),
1722 (map(int, '123'), 'itertools', 'imap'),
1723 (functools.reduce, '__builtin__', 'reduce'),
1724 (dbm.whichdb, 'whichdb', 'whichdb'),
1725 (Exception(), 'exceptions', 'Exception'),
1726 (collections.UserDict(), 'UserDict', 'IterableUserDict'),
1727 (collections.UserList(), 'UserList', 'UserList'),
1728 (collections.defaultdict(), 'collections', 'defaultdict'),
1729 ]
1730 for val, mod, name in tests:
1731 for proto in range(3):
1732 with self.subTest(type=type(val), proto=proto):
1733 pickled = self.dumps(val, proto)
1734 self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled)
1735 self.assertIs(type(self.loads(pickled)), type(val))
1736
1737 def test_compat_unpickle(self):
1738 # xrange(1, 7)
1739 pickled = b'\x80\x02c__builtin__\nxrange\nK\x01K\x07K\x01\x87R.'
1740 unpickled = self.loads(pickled)
1741 self.assertIs(type(unpickled), range)
1742 self.assertEqual(unpickled, range(1, 7))
1743 self.assertEqual(list(unpickled), [1, 2, 3, 4, 5, 6])
1744 # reduce
1745 pickled = b'\x80\x02c__builtin__\nreduce\n.'
1746 self.assertIs(self.loads(pickled), functools.reduce)
1747 # whichdb.whichdb
1748 pickled = b'\x80\x02cwhichdb\nwhichdb\n.'
1749 self.assertIs(self.loads(pickled), dbm.whichdb)
1750 # Exception(), StandardError()
1751 for name in (b'Exception', b'StandardError'):
1752 pickled = (b'\x80\x02cexceptions\n' + name + b'\nU\x03ugh\x85R.')
1753 unpickled = self.loads(pickled)
1754 self.assertIs(type(unpickled), Exception)
1755 self.assertEqual(str(unpickled), 'ugh')
1756 # UserDict.UserDict({1: 2}), UserDict.IterableUserDict({1: 2})
1757 for name in (b'UserDict', b'IterableUserDict'):
1758 pickled = (b'\x80\x02(cUserDict\n' + name +
1759 b'\no}U\x04data}K\x01K\x02ssb.')
1760 unpickled = self.loads(pickled)
1761 self.assertIs(type(unpickled), collections.UserDict)
1762 self.assertEqual(unpickled, collections.UserDict({1: 2}))
1763
Antoine Pitrou6cd5eda2014-12-02 00:20:03 +01001764 def test_local_lookup_error(self):
1765 # Test that whichmodule() errors out cleanly when looking up
1766 # an assumed globally-reachable object fails.
1767 def f():
1768 pass
1769 # Since the function is local, lookup will fail
1770 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1771 with self.assertRaises((AttributeError, pickle.PicklingError)):
1772 pickletools.dis(self.dumps(f, proto))
1773 # Same without a __module__ attribute (exercises a different path
1774 # in _pickle.c).
1775 del f.__module__
1776 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1777 with self.assertRaises((AttributeError, pickle.PicklingError)):
1778 pickletools.dis(self.dumps(f, proto))
1779 # Yet a different path.
1780 f.__name__ = f.__qualname__
1781 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1782 with self.assertRaises((AttributeError, pickle.PicklingError)):
1783 pickletools.dis(self.dumps(f, proto))
1784
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001785
1786class BigmemPickleTests(unittest.TestCase):
1787
1788 # Binary protocols can serialize longs of up to 2GB-1
1789
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001790 @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001791 def test_huge_long_32b(self, size):
1792 data = 1 << (8 * size)
1793 try:
1794 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001795 if proto < 2:
1796 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001797 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001798 with self.assertRaises((ValueError, OverflowError)):
1799 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001800 finally:
1801 data = None
1802
1803 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1804 # (older protocols don't have a dedicated opcode for bytes and are
1805 # too inefficient)
1806
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001807 @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001808 def test_huge_bytes_32b(self, size):
1809 data = b"abcd" * (size // 4)
1810 try:
1811 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001812 if proto < 3:
1813 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001814 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001815 try:
1816 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001817 header = (pickle.BINBYTES +
1818 struct.pack("<I", len(data)))
1819 data_start = pickled.index(data)
1820 self.assertEqual(
1821 header,
1822 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001823 finally:
1824 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001825 finally:
1826 data = None
1827
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001828 @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001829 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001830 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001831 try:
1832 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001833 if proto < 3:
1834 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001835 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001836 if proto == 3:
1837 # Protocol 3 does not support large bytes objects.
1838 # Verify that we do not crash when processing one.
1839 with self.assertRaises((ValueError, OverflowError)):
1840 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001841 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001842 try:
1843 pickled = self.dumps(data, protocol=proto)
1844 header = (pickle.BINBYTES8 +
1845 struct.pack("<Q", len(data)))
1846 data_start = pickled.index(data)
1847 self.assertEqual(
1848 header,
1849 pickled[data_start-len(header):data_start])
1850 finally:
1851 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001852 finally:
1853 data = None
1854
1855 # All protocols use 1-byte per printable ASCII character; we add another
1856 # byte because the encoded form has to be copied into the internal buffer.
1857
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001858 @bigmemtest(size=_2G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001859 def test_huge_str_32b(self, size):
1860 data = "abcd" * (size // 4)
1861 try:
1862 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001863 if proto == 0:
1864 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001865 with self.subTest(proto=proto):
1866 try:
1867 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001868 header = (pickle.BINUNICODE +
1869 struct.pack("<I", len(data)))
1870 data_start = pickled.index(b'abcd')
1871 self.assertEqual(
1872 header,
1873 pickled[data_start-len(header):data_start])
1874 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1875 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001876 finally:
1877 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001878 finally:
1879 data = None
1880
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001881 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
1882 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
1883 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02001884
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001885 @bigmemtest(size=_4G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001886 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001887 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001888 try:
1889 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001890 if proto == 0:
1891 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001892 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001893 if proto < 4:
1894 with self.assertRaises((ValueError, OverflowError)):
1895 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001896 continue
1897 try:
1898 pickled = self.dumps(data, protocol=proto)
1899 header = (pickle.BINUNICODE8 +
1900 struct.pack("<Q", len(data)))
1901 data_start = pickled.index(b'abcd')
1902 self.assertEqual(
1903 header,
1904 pickled[data_start-len(header):data_start])
1905 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1906 pickled.index(b"abcd")), len(data))
1907 finally:
1908 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001909 finally:
1910 data = None
1911
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001912
Guido van Rossum2a30b212003-02-18 22:41:24 +00001913# Test classes for reduce_ex
1914
1915class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001916 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001917 _reduce_called = 0
1918 def __reduce__(self):
1919 self._reduce_called = 1
1920 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001921
1922class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001923 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001924 _proto = None
1925 def __reduce_ex__(self, proto):
1926 self._proto = proto
1927 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001928
1929class REX_three(object):
1930 _proto = None
1931 def __reduce_ex__(self, proto):
1932 self._proto = proto
1933 return REX_two, ()
1934 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001935 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001936
Guido van Rossumd8faa362007-04-27 19:54:29 +00001937class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001938 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001939 _proto = None
1940 def __reduce_ex__(self, proto):
1941 self._proto = proto
1942 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001943
1944class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001945 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001946 _reduce_called = 0
1947 def __reduce__(self):
1948 self._reduce_called = 1
1949 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001950
1951class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001952 """This class is used to check the 4th argument (list iterator) of
1953 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001954 """
1955 def __init__(self, items=None):
1956 self.items = items if items is not None else []
1957 def __eq__(self, other):
1958 return type(self) is type(other) and self.items == self.items
1959 def append(self, item):
1960 self.items.append(item)
1961 def __reduce__(self):
1962 return type(self), (), None, iter(self.items), None
1963
1964class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001965 """This class is used to check the 5th argument (dict iterator) of
1966 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001967 """
1968 def __init__(self, table=None):
1969 self.table = table if table is not None else {}
1970 def __eq__(self, other):
1971 return type(self) is type(other) and self.table == self.table
1972 def __setitem__(self, key, value):
1973 self.table[key] = value
1974 def __reduce__(self):
1975 return type(self), (), None, None, iter(self.table.items())
1976
Guido van Rossumd8faa362007-04-27 19:54:29 +00001977
Guido van Rossum2a30b212003-02-18 22:41:24 +00001978# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001979
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001980class MyInt(int):
1981 sample = 1
1982
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001983class MyFloat(float):
1984 sample = 1.0
1985
1986class MyComplex(complex):
1987 sample = 1.0 + 0.0j
1988
1989class MyStr(str):
1990 sample = "hello"
1991
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001992class MyUnicode(str):
1993 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001994
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001995class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001996 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001997
1998class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001999 sample = [1, 2, 3]
2000
2001class MyDict(dict):
2002 sample = {"a": 1, "b": 2}
2003
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002004class MySet(set):
2005 sample = {"a", "b"}
2006
2007class MyFrozenSet(frozenset):
2008 sample = frozenset({"a", "b"})
2009
Mark Dickinson5c2db372009-12-05 20:28:34 +00002010myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00002011 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002012 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002013 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002014
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002015
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00002016class SlotList(MyList):
2017 __slots__ = ["foo"]
2018
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002019class SimpleNewObj(int):
2020 def __init__(self, *args, **kwargs):
Tim Peterse9ef2032003-02-13 18:42:00 +00002021 # raise an error, to make sure this isn't called
2022 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002023 def __eq__(self, other):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002024 return int(self) == int(other) and self.__dict__ == other.__dict__
2025
2026class ComplexNewObj(SimpleNewObj):
2027 def __getnewargs__(self):
2028 return ('%X' % self, 16)
2029
2030class ComplexNewObjEx(SimpleNewObj):
2031 def __getnewargs_ex__(self):
2032 return ('%X' % self,), {'base': 16}
Tim Peterse9ef2032003-02-13 18:42:00 +00002033
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002034class BadGetattr:
2035 def __getattr__(self, key):
2036 self.foo
2037
Collin Winter771d8342009-04-16 03:18:06 +00002038
Jeremy Hylton66426532001-10-15 21:38:56 +00002039class AbstractPickleModuleTests(unittest.TestCase):
2040
2041 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002042 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00002043 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002044 try:
2045 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002046 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002047 finally:
2048 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00002049
2050 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002051 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00002052 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002053 try:
2054 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002055 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002056 finally:
2057 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002058
Collin Winter771d8342009-04-16 03:18:06 +00002059 def test_load_from_and_dump_to_file(self):
2060 stream = io.BytesIO()
2061 data = [123, {}, 124]
2062 pickle.dump(data, stream)
2063 stream.seek(0)
2064 unpickled = pickle.load(stream)
2065 self.assertEqual(unpickled, data)
2066
Tim Petersc0c93702003-02-13 19:30:57 +00002067 def test_highest_protocol(self):
2068 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002069 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00002070
Martin v. Löwis544f1192004-07-27 05:22:33 +00002071 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00002072 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00002073 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002074 pickle.dump(123, f, -1)
2075 pickle.dump(123, file=f, protocol=-1)
2076 pickle.dumps(123, -1)
2077 pickle.dumps(123, protocol=-1)
2078 pickle.Pickler(f, -1)
2079 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00002080
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002081 def test_bad_init(self):
2082 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002083 # Override initialization without calling __init__() of the superclass.
2084 class BadPickler(pickle.Pickler):
2085 def __init__(self): pass
2086
2087 class BadUnpickler(pickle.Unpickler):
2088 def __init__(self): pass
2089
2090 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
2091 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
2092
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00002093 def test_bad_input(self):
2094 # Test issue4298
2095 s = bytes([0x58, 0, 0, 0, 0x54])
2096 self.assertRaises(EOFError, pickle.loads, s)
2097
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002098
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002099class AbstractPersistentPicklerTests(unittest.TestCase):
2100
2101 # This class defines persistent_id() and persistent_load()
2102 # functions that should be used by the pickler. All even integers
2103 # are pickled using persistent ids.
2104
2105 def persistent_id(self, object):
2106 if isinstance(object, int) and object % 2 == 0:
2107 self.id_count += 1
2108 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002109 elif object == "test_false_value":
2110 self.false_count += 1
2111 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002112 else:
2113 return None
2114
2115 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002116 if not oid:
2117 self.load_false_count += 1
2118 return "test_false_value"
2119 else:
2120 self.load_count += 1
2121 object = int(oid)
2122 assert object % 2 == 0
2123 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002124
2125 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002126 L = list(range(10)) + ["test_false_value"]
2127 for proto in protocols:
2128 self.id_count = 0
2129 self.false_count = 0
2130 self.load_false_count = 0
2131 self.load_count = 0
2132 self.assertEqual(self.loads(self.dumps(L, proto)), L)
2133 self.assertEqual(self.id_count, 5)
2134 self.assertEqual(self.false_count, 1)
2135 self.assertEqual(self.load_count, 5)
2136 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00002137
Collin Winter771d8342009-04-16 03:18:06 +00002138
2139class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
2140
2141 pickler_class = None
2142 unpickler_class = None
2143
2144 def setUp(self):
2145 assert self.pickler_class
2146 assert self.unpickler_class
2147
2148 def test_clear_pickler_memo(self):
2149 # To test whether clear_memo() has any effect, we pickle an object,
2150 # then pickle it again without clearing the memo; the two serialized
2151 # forms should be different. If we clear_memo() and then pickle the
2152 # object again, the third serialized form should be identical to the
2153 # first one we obtained.
2154 data = ["abcdefg", "abcdefg", 44]
2155 f = io.BytesIO()
2156 pickler = self.pickler_class(f)
2157
2158 pickler.dump(data)
2159 first_pickled = f.getvalue()
2160
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002161 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00002162 f.seek(0)
2163 f.truncate()
2164
2165 pickler.dump(data)
2166 second_pickled = f.getvalue()
2167
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002168 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00002169 pickler.clear_memo()
2170 f.seek(0)
2171 f.truncate()
2172
2173 pickler.dump(data)
2174 third_pickled = f.getvalue()
2175
2176 self.assertNotEqual(first_pickled, second_pickled)
2177 self.assertEqual(first_pickled, third_pickled)
2178
2179 def test_priming_pickler_memo(self):
2180 # Verify that we can set the Pickler's memo attribute.
2181 data = ["abcdefg", "abcdefg", 44]
2182 f = io.BytesIO()
2183 pickler = self.pickler_class(f)
2184
2185 pickler.dump(data)
2186 first_pickled = f.getvalue()
2187
2188 f = io.BytesIO()
2189 primed = self.pickler_class(f)
2190 primed.memo = pickler.memo
2191
2192 primed.dump(data)
2193 primed_pickled = f.getvalue()
2194
2195 self.assertNotEqual(first_pickled, primed_pickled)
2196
2197 def test_priming_unpickler_memo(self):
2198 # Verify that we can set the Unpickler's memo attribute.
2199 data = ["abcdefg", "abcdefg", 44]
2200 f = io.BytesIO()
2201 pickler = self.pickler_class(f)
2202
2203 pickler.dump(data)
2204 first_pickled = f.getvalue()
2205
2206 f = io.BytesIO()
2207 primed = self.pickler_class(f)
2208 primed.memo = pickler.memo
2209
2210 primed.dump(data)
2211 primed_pickled = f.getvalue()
2212
2213 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2214 unpickled_data1 = unpickler.load()
2215
2216 self.assertEqual(unpickled_data1, data)
2217
2218 primed = self.unpickler_class(io.BytesIO(primed_pickled))
2219 primed.memo = unpickler.memo
2220 unpickled_data2 = primed.load()
2221
2222 primed.memo.clear()
2223
2224 self.assertEqual(unpickled_data2, data)
2225 self.assertTrue(unpickled_data2 is unpickled_data1)
2226
2227 def test_reusing_unpickler_objects(self):
2228 data1 = ["abcdefg", "abcdefg", 44]
2229 f = io.BytesIO()
2230 pickler = self.pickler_class(f)
2231 pickler.dump(data1)
2232 pickled1 = f.getvalue()
2233
2234 data2 = ["abcdefg", 44, 44]
2235 f = io.BytesIO()
2236 pickler = self.pickler_class(f)
2237 pickler.dump(data2)
2238 pickled2 = f.getvalue()
2239
2240 f = io.BytesIO()
2241 f.write(pickled1)
2242 f.seek(0)
2243 unpickler = self.unpickler_class(f)
2244 self.assertEqual(unpickler.load(), data1)
2245
2246 f.seek(0)
2247 f.truncate()
2248 f.write(pickled2)
2249 f.seek(0)
2250 self.assertEqual(unpickler.load(), data2)
2251
Antoine Pitrou04248a82010-10-12 20:51:21 +00002252 def _check_multiple_unpicklings(self, ioclass):
2253 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002254 with self.subTest(proto=proto):
2255 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2256 f = ioclass()
2257 pickler = self.pickler_class(f, protocol=proto)
2258 pickler.dump(data1)
2259 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002260
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002261 N = 5
2262 f = ioclass(pickled * N)
2263 unpickler = self.unpickler_class(f)
2264 for i in range(N):
2265 if f.seekable():
2266 pos = f.tell()
2267 self.assertEqual(unpickler.load(), data1)
2268 if f.seekable():
2269 self.assertEqual(f.tell(), pos + len(pickled))
2270 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002271
2272 def test_multiple_unpicklings_seekable(self):
2273 self._check_multiple_unpicklings(io.BytesIO)
2274
2275 def test_multiple_unpicklings_unseekable(self):
2276 self._check_multiple_unpicklings(UnseekableIO)
2277
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002278 def test_unpickling_buffering_readline(self):
2279 # Issue #12687: the unpickler's buffering logic could fail with
2280 # text mode opcodes.
2281 data = list(range(10))
2282 for proto in protocols:
2283 for buf_size in range(1, 11):
2284 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2285 pickler = self.pickler_class(f, protocol=proto)
2286 pickler.dump(data)
2287 f.seek(0)
2288 unpickler = self.unpickler_class(f)
2289 self.assertEqual(unpickler.load(), data)
2290
Collin Winter771d8342009-04-16 03:18:06 +00002291
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002292# Tests for dispatch_table attribute
2293
2294REDUCE_A = 'reduce_A'
2295
2296class AAA(object):
2297 def __reduce__(self):
2298 return str, (REDUCE_A,)
2299
2300class BBB(object):
2301 pass
2302
2303class AbstractDispatchTableTests(unittest.TestCase):
2304
2305 def test_default_dispatch_table(self):
2306 # No dispatch_table attribute by default
2307 f = io.BytesIO()
2308 p = self.pickler_class(f, 0)
2309 with self.assertRaises(AttributeError):
2310 p.dispatch_table
2311 self.assertFalse(hasattr(p, 'dispatch_table'))
2312
2313 def test_class_dispatch_table(self):
2314 # A dispatch_table attribute can be specified class-wide
2315 dt = self.get_dispatch_table()
2316
2317 class MyPickler(self.pickler_class):
2318 dispatch_table = dt
2319
2320 def dumps(obj, protocol=None):
2321 f = io.BytesIO()
2322 p = MyPickler(f, protocol)
2323 self.assertEqual(p.dispatch_table, dt)
2324 p.dump(obj)
2325 return f.getvalue()
2326
2327 self._test_dispatch_table(dumps, dt)
2328
2329 def test_instance_dispatch_table(self):
2330 # A dispatch_table attribute can also be specified instance-wide
2331 dt = self.get_dispatch_table()
2332
2333 def dumps(obj, protocol=None):
2334 f = io.BytesIO()
2335 p = self.pickler_class(f, protocol)
2336 p.dispatch_table = dt
2337 self.assertEqual(p.dispatch_table, dt)
2338 p.dump(obj)
2339 return f.getvalue()
2340
2341 self._test_dispatch_table(dumps, dt)
2342
2343 def _test_dispatch_table(self, dumps, dispatch_table):
2344 def custom_load_dump(obj):
2345 return pickle.loads(dumps(obj, 0))
2346
2347 def default_load_dump(obj):
2348 return pickle.loads(pickle.dumps(obj, 0))
2349
2350 # pickling complex numbers using protocol 0 relies on copyreg
2351 # so check pickling a complex number still works
2352 z = 1 + 2j
2353 self.assertEqual(custom_load_dump(z), z)
2354 self.assertEqual(default_load_dump(z), z)
2355
2356 # modify pickling of complex
2357 REDUCE_1 = 'reduce_1'
2358 def reduce_1(obj):
2359 return str, (REDUCE_1,)
2360 dispatch_table[complex] = reduce_1
2361 self.assertEqual(custom_load_dump(z), REDUCE_1)
2362 self.assertEqual(default_load_dump(z), z)
2363
2364 # check picklability of AAA and BBB
2365 a = AAA()
2366 b = BBB()
2367 self.assertEqual(custom_load_dump(a), REDUCE_A)
2368 self.assertIsInstance(custom_load_dump(b), BBB)
2369 self.assertEqual(default_load_dump(a), REDUCE_A)
2370 self.assertIsInstance(default_load_dump(b), BBB)
2371
2372 # modify pickling of BBB
2373 dispatch_table[BBB] = reduce_1
2374 self.assertEqual(custom_load_dump(a), REDUCE_A)
2375 self.assertEqual(custom_load_dump(b), REDUCE_1)
2376 self.assertEqual(default_load_dump(a), REDUCE_A)
2377 self.assertIsInstance(default_load_dump(b), BBB)
2378
2379 # revert pickling of BBB and modify pickling of AAA
2380 REDUCE_2 = 'reduce_2'
2381 def reduce_2(obj):
2382 return str, (REDUCE_2,)
2383 dispatch_table[AAA] = reduce_2
2384 del dispatch_table[BBB]
2385 self.assertEqual(custom_load_dump(a), REDUCE_2)
2386 self.assertIsInstance(custom_load_dump(b), BBB)
2387 self.assertEqual(default_load_dump(a), REDUCE_A)
2388 self.assertIsInstance(default_load_dump(b), BBB)
2389
2390
Guido van Rossum98297ee2007-11-06 21:34:58 +00002391if __name__ == "__main__":
2392 # Print some stuff that can be used to rewrite DATA{0,1,2}
2393 from pickletools import dis
2394 x = create_data()
2395 for i in range(3):
2396 p = pickle.dumps(x, i)
2397 print("DATA{0} = (".format(i))
2398 for j in range(0, len(p), 20):
2399 b = bytes(p[j:j+20])
2400 print(" {0!r}".format(b))
2401 print(")")
2402 print()
2403 print("# Disassembly of DATA{0}".format(i))
2404 print("DATA{0}_DIS = \"\"\"\\".format(i))
2405 dis(p)
2406 print("\"\"\"")
2407 print()