blob: a0c7a0ab69076e16dec14a6d58a176741fb2830c [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
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001042 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001043 # an object of that type. Check that the resulting pickle uses opcode
1044 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001045
Tim Peters22e71712003-02-03 22:27:38 +00001046 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001047 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001048 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001049 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001050 x = MyList([1, 2, 3])
1051 x.foo = 42
1052 x.bar = "hello"
1053
Tim Peters22e71712003-02-03 22:27:38 +00001054 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001055 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001056 self.assertIn(__name__.encode("utf-8"), s1)
1057 self.assertIn(b"MyList", s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001058 self.assertFalse(opcode_in_pickle(opcode, s1))
Tim Peters3e667d52003-02-04 21:47:44 +00001059
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001060 y = self.loads(s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001061 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001062
Tim Peters22e71712003-02-03 22:27:38 +00001063 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001064 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001065 self.assertNotIn(__name__.encode("utf-8"), s2)
1066 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001067 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +00001068
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001069 y = self.loads(s2)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001070 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001071 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001072 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001073
1074 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001075 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1076 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001077
1078 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001079 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1080 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1081 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001082
1083 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001084 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1085 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1086 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1087
Tim Peters8d2613a2003-02-11 16:40:16 +00001088 def test_list_chunking(self):
1089 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +00001090 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001091 for proto in protocols:
1092 s = self.dumps(x, proto)
1093 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001094 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001095 num_appends = count_opcode(pickle.APPENDS, s)
1096 self.assertEqual(num_appends, proto > 0)
1097
1098 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001099 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001100 for proto in protocols:
1101 s = self.dumps(x, proto)
1102 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001103 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001104 num_appends = count_opcode(pickle.APPENDS, s)
1105 if proto == 0:
1106 self.assertEqual(num_appends, 0)
1107 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001108 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001109
1110 def test_dict_chunking(self):
1111 n = 10 # too small to chunk
1112 x = dict.fromkeys(range(n))
1113 for proto in protocols:
1114 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +00001115 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00001116 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001117 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001118 num_setitems = count_opcode(pickle.SETITEMS, s)
1119 self.assertEqual(num_setitems, proto > 0)
1120
1121 n = 2500 # expect at least two chunks when proto > 0
1122 x = dict.fromkeys(range(n))
1123 for proto in protocols:
1124 s = self.dumps(x, proto)
1125 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001126 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001127 num_setitems = count_opcode(pickle.SETITEMS, s)
1128 if proto == 0:
1129 self.assertEqual(num_setitems, 0)
1130 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001131 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001132
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001133 def test_set_chunking(self):
1134 n = 10 # too small to chunk
1135 x = set(range(n))
1136 for proto in protocols:
1137 s = self.dumps(x, proto)
1138 y = self.loads(s)
1139 self.assert_is_copy(x, y)
1140 num_additems = count_opcode(pickle.ADDITEMS, s)
1141 if proto < 4:
1142 self.assertEqual(num_additems, 0)
1143 else:
1144 self.assertEqual(num_additems, 1)
1145
1146 n = 2500 # expect at least two chunks when proto >= 4
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.assertGreaterEqual(num_additems, 2)
1157
Tim Peterse9ef2032003-02-13 18:42:00 +00001158 def test_simple_newobj(self):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001159 x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__
Tim Peterse9ef2032003-02-13 18:42:00 +00001160 x.abc = 666
1161 for proto in protocols:
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001162 with self.subTest(proto=proto):
1163 s = self.dumps(x, proto)
1164 if proto < 1:
1165 self.assertIn(b'\nL64206', s) # LONG
1166 else:
1167 self.assertIn(b'M\xce\xfa', s) # BININT2
1168 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1169 2 <= proto)
1170 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1171 y = self.loads(s) # will raise TypeError if __init__ called
1172 self.assert_is_copy(x, y)
1173
1174 def test_complex_newobj(self):
1175 x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__
1176 x.abc = 666
1177 for proto in protocols:
1178 with self.subTest(proto=proto):
1179 s = self.dumps(x, proto)
1180 if proto < 1:
1181 self.assertIn(b'\nL64206', s) # LONG
1182 elif proto < 2:
1183 self.assertIn(b'M\xce\xfa', s) # BININT2
1184 elif proto < 4:
1185 self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
1186 else:
1187 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1188 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1189 2 <= proto)
1190 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1191 y = self.loads(s) # will raise TypeError if __init__ called
1192 self.assert_is_copy(x, y)
1193
1194 def test_complex_newobj_ex(self):
1195 x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__
1196 x.abc = 666
1197 for proto in protocols:
1198 with self.subTest(proto=proto):
1199 if 2 <= proto < 4:
1200 self.assertRaises(ValueError, self.dumps, x, proto)
1201 continue
1202 s = self.dumps(x, proto)
1203 if proto < 1:
1204 self.assertIn(b'\nL64206', s) # LONG
1205 elif proto < 2:
1206 self.assertIn(b'M\xce\xfa', s) # BININT2
1207 else:
1208 assert proto >= 4
1209 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1210 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s))
1211 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1212 4 <= proto)
1213 y = self.loads(s) # will raise TypeError if __init__ called
1214 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001215
Tim Peters42f08ac2003-02-11 22:43:24 +00001216 def test_newobj_list_slots(self):
1217 x = SlotList([1, 2, 3])
1218 x.foo = 42
1219 x.bar = "hello"
1220 s = self.dumps(x, 2)
1221 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001222 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001223
Guido van Rossum2a30b212003-02-18 22:41:24 +00001224 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001225 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001226 x = REX_one()
1227 self.assertEqual(x._reduce_called, 0)
1228 s = self.dumps(x, proto)
1229 self.assertEqual(x._reduce_called, 1)
1230 y = self.loads(s)
1231 self.assertEqual(y._reduce_called, 0)
1232
1233 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001234 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001235 x = REX_two()
1236 self.assertEqual(x._proto, None)
1237 s = self.dumps(x, proto)
1238 self.assertEqual(x._proto, proto)
1239 y = self.loads(s)
1240 self.assertEqual(y._proto, None)
1241
1242 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001243 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001244 x = REX_three()
1245 self.assertEqual(x._proto, None)
1246 s = self.dumps(x, proto)
1247 self.assertEqual(x._proto, proto)
1248 y = self.loads(s)
1249 self.assertEqual(y._proto, None)
1250
Guido van Rossumd8faa362007-04-27 19:54:29 +00001251 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001252 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001253 x = REX_four()
1254 self.assertEqual(x._proto, None)
1255 s = self.dumps(x, proto)
1256 self.assertEqual(x._proto, proto)
1257 y = self.loads(s)
1258 self.assertEqual(y._proto, proto)
1259
1260 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001261 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001262 x = REX_five()
1263 self.assertEqual(x._reduce_called, 0)
1264 s = self.dumps(x, proto)
1265 self.assertEqual(x._reduce_called, 1)
1266 y = self.loads(s)
1267 self.assertEqual(y._reduce_called, 1)
1268
Brett Cannon31f59292011-02-21 19:29:56 +00001269 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001270 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001271 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001272 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001273 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001274 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001275
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001276 def test_reduce_bad_iterator(self):
1277 # Issue4176: crash when 4th and 5th items of __reduce__()
1278 # are not iterators
1279 class C(object):
1280 def __reduce__(self):
1281 # 4th item is not an iterator
1282 return list, (), None, [], None
1283 class D(object):
1284 def __reduce__(self):
1285 # 5th item is not an iterator
1286 return dict, (), None, None, []
1287
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001288 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001289 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001290 try:
1291 self.dumps(C(), proto)
1292 except (pickle.PickleError):
1293 pass
1294 try:
1295 self.dumps(D(), proto)
1296 except (pickle.PickleError):
1297 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001298
Collin Winter771d8342009-04-16 03:18:06 +00001299 def test_many_puts_and_gets(self):
1300 # Test that internal data structures correctly deal with lots of
1301 # puts/gets.
1302 keys = ("aaa" + str(i) for i in range(100))
1303 large_dict = dict((k, [4, 5, 6]) for k in keys)
1304 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1305
1306 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001307 with self.subTest(proto=proto):
1308 dumped = self.dumps(obj, proto)
1309 loaded = self.loads(dumped)
1310 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00001311
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001312 def test_attribute_name_interning(self):
1313 # Test that attribute names of pickled objects are interned when
1314 # unpickling.
1315 for proto in protocols:
1316 x = C()
1317 x.foo = 42
1318 x.bar = "hello"
1319 s = self.dumps(x, proto)
1320 y = self.loads(s)
1321 x_keys = sorted(x.__dict__)
1322 y_keys = sorted(y.__dict__)
1323 for x_key, y_key in zip(x_keys, y_keys):
1324 self.assertIs(x_key, y_key)
1325
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001326 def test_unpickle_from_2x(self):
1327 # Unpickle non-trivial data from Python 2.x.
1328 loaded = self.loads(DATA3)
1329 self.assertEqual(loaded, set([1, 2]))
1330 loaded = self.loads(DATA4)
1331 self.assertEqual(type(loaded), type(range(0)))
1332 self.assertEqual(list(loaded), list(range(5)))
1333 loaded = self.loads(DATA5)
1334 self.assertEqual(type(loaded), SimpleCookie)
1335 self.assertEqual(list(loaded.keys()), ["key"])
Serhiy Storchaka8cf7c1c2014-11-02 22:18:25 +02001336 self.assertEqual(loaded["key"].value, "value")
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001337
Walter Doerwald9d1dbca2013-12-02 11:41:01 +01001338 for (exc, data) in DATA7.items():
1339 loaded = self.loads(data)
1340 self.assertIs(type(loaded), exc)
1341
1342 loaded = self.loads(DATA8)
1343 self.assertIs(type(loaded), Exception)
1344
1345 loaded = self.loads(DATA9)
1346 self.assertIs(type(loaded), UnicodeEncodeError)
1347 self.assertEqual(loaded.object, "foo")
1348 self.assertEqual(loaded.encoding, "ascii")
1349 self.assertEqual(loaded.start, 0)
1350 self.assertEqual(loaded.end, 1)
1351 self.assertEqual(loaded.reason, "bad")
1352
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001353 def test_pickle_to_2x(self):
1354 # Pickle non-trivial data with protocol 2, expecting that it yields
1355 # the same result as Python 2.x did.
1356 # NOTE: this test is a bit too strong since we can produce different
1357 # bytecode that 2.x will still understand.
1358 dumped = self.dumps(range(5), 2)
1359 self.assertEqual(dumped, DATA4)
1360 dumped = self.dumps(set([3]), 2)
1361 self.assertEqual(dumped, DATA6)
1362
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -08001363 def test_load_python2_str_as_bytes(self):
1364 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
1365 self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
1366 encoding="bytes"), b'a\x00\xa0')
1367 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
1368 self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
1369 encoding="bytes"), b'a\x00\xa0')
1370 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
1371 self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
1372 encoding="bytes"), b'a\x00\xa0')
1373
1374 def test_load_python2_unicode_as_str(self):
1375 # From Python 2: pickle.dumps(u'π', protocol=0)
1376 self.assertEqual(self.loads(b'V\\u03c0\n.',
1377 encoding='bytes'), 'π')
1378 # From Python 2: pickle.dumps(u'π', protocol=1)
1379 self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
1380 encoding="bytes"), 'π')
1381 # From Python 2: pickle.dumps(u'π', protocol=2)
1382 self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
1383 encoding="bytes"), 'π')
1384
1385 def test_load_long_python2_str_as_bytes(self):
1386 # From Python 2: pickle.dumps('x' * 300, protocol=1)
1387 self.assertEqual(self.loads(pickle.BINSTRING +
1388 struct.pack("<I", 300) +
1389 b'x' * 300 + pickle.STOP,
1390 encoding='bytes'), b'x' * 300)
1391
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001392 def test_large_pickles(self):
1393 # Test the correctness of internal buffering routines when handling
1394 # large data.
1395 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001396 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001397 dumped = self.dumps(data, proto)
1398 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001399 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001400 self.assertEqual(loaded, data)
1401
Alexander Belopolsky1ce92dc2011-02-24 19:40:09 +00001402 def test_empty_bytestring(self):
1403 # issue 11286
1404 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1405 self.assertEqual(empty, '')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001406
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001407 def test_int_pickling_efficiency(self):
1408 # Test compacity of int representation (see issue #12744)
1409 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001410 with self.subTest(proto=proto):
1411 pickles = [self.dumps(2**n, proto) for n in range(70)]
1412 sizes = list(map(len, pickles))
1413 # the size function is monotonic
1414 self.assertEqual(sorted(sizes), sizes)
1415 if proto >= 2:
1416 for p in pickles:
1417 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001418
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001419 def check_negative_32b_binXXX(self, dumped):
1420 if sys.maxsize > 2**32:
1421 self.skipTest("test is only meaningful on 32-bit builds")
1422 # XXX Pure Python pickle reads lengths as signed and passes
1423 # them directly to read() (hence the EOFError)
1424 with self.assertRaises((pickle.UnpicklingError, EOFError,
1425 ValueError, OverflowError)):
1426 self.loads(dumped)
1427
1428 def test_negative_32b_binbytes(self):
1429 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1430 self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.')
1431
1432 def test_negative_32b_binunicode(self):
1433 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1434 self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.')
1435
Antoine Pitrou55549ec2011-08-30 00:27:10 +02001436 def test_negative_put(self):
1437 # Issue #12847
1438 dumped = b'Va\np-1\n.'
1439 self.assertRaises(ValueError, self.loads, dumped)
1440
1441 def test_negative_32b_binput(self):
1442 # Issue #12847
1443 if sys.maxsize > 2**32:
1444 self.skipTest("test is only meaningful on 32-bit builds")
1445 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
1446 self.assertRaises(ValueError, self.loads, dumped)
1447
Alexandre Vassalotti7c5e0942013-04-15 23:14:55 -07001448 def test_badly_escaped_string(self):
1449 self.assertRaises(ValueError, self.loads, b"S'\\'\n.")
1450
1451 def test_badly_quoted_string(self):
1452 # Issue #17710
1453 badpickles = [b"S'\n.",
1454 b'S"\n.',
1455 b'S\' \n.',
1456 b'S" \n.',
1457 b'S\'"\n.',
1458 b'S"\'\n.',
1459 b"S' ' \n.",
1460 b'S" " \n.',
1461 b"S ''\n.",
1462 b'S ""\n.',
1463 b'S \n.',
1464 b'S\n.',
1465 b'S.']
1466 for p in badpickles:
1467 self.assertRaises(pickle.UnpicklingError, self.loads, p)
1468
1469 def test_correctly_quoted_string(self):
1470 goodpickles = [(b"S''\n.", ''),
1471 (b'S""\n.', ''),
1472 (b'S"\\n"\n.', '\n'),
1473 (b"S'\\n'\n.", '\n')]
1474 for p, expected in goodpickles:
1475 self.assertEqual(self.loads(p), expected)
1476
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001477 def _check_pickling_with_opcode(self, obj, opcode, proto):
1478 pickled = self.dumps(obj, proto)
1479 self.assertTrue(opcode_in_pickle(opcode, pickled))
1480 unpickled = self.loads(pickled)
1481 self.assertEqual(obj, unpickled)
1482
1483 def test_appends_on_non_lists(self):
1484 # Issue #17720
1485 obj = REX_six([1, 2, 3])
1486 for proto in protocols:
1487 if proto == 0:
1488 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1489 else:
1490 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1491
1492 def test_setitems_on_non_dicts(self):
1493 obj = REX_seven({1: -1, 2: -2, 3: -3})
1494 for proto in protocols:
1495 if proto == 0:
1496 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1497 else:
1498 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1499
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001500 # Exercise framing (proto >= 4) for significant workloads
1501
1502 FRAME_SIZE_TARGET = 64 * 1024
1503
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001504 def check_frame_opcodes(self, pickled):
1505 """
1506 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
1507 """
1508 frame_opcode_size = 9
1509 last_arg = last_pos = None
1510 for op, arg, pos in pickletools.genops(pickled):
1511 if op.name != 'FRAME':
1512 continue
1513 if last_pos is not None:
1514 # The previous frame's size should be equal to the number
1515 # of bytes up to the current frame.
1516 frame_size = pos - last_pos - frame_opcode_size
1517 self.assertEqual(frame_size, last_arg)
1518 last_arg, last_pos = arg, pos
1519 # The last frame's size should be equal to the number of bytes up
1520 # to the pickle's end.
1521 frame_size = len(pickled) - last_pos - frame_opcode_size
1522 self.assertEqual(frame_size, last_arg)
1523
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001524 def test_framing_many_objects(self):
1525 obj = list(range(10**5))
1526 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1527 with self.subTest(proto=proto):
1528 pickled = self.dumps(obj, proto)
1529 unpickled = self.loads(pickled)
1530 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001531 bytes_per_frame = (len(pickled) /
1532 count_opcode(pickle.FRAME, pickled))
1533 self.assertGreater(bytes_per_frame,
1534 self.FRAME_SIZE_TARGET / 2)
1535 self.assertLessEqual(bytes_per_frame,
1536 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001537 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001538
1539 def test_framing_large_objects(self):
1540 N = 1024 * 1024
1541 obj = [b'x' * N, b'y' * N, b'z' * N]
1542 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1543 with self.subTest(proto=proto):
1544 pickled = self.dumps(obj, proto)
1545 unpickled = self.loads(pickled)
1546 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001547 n_frames = count_opcode(pickle.FRAME, pickled)
Alexandre Vassalotti28d271e2013-12-01 16:27:46 -08001548 self.assertGreaterEqual(n_frames, len(obj))
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001549 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001550
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001551 def test_optional_frames(self):
1552 if pickle.HIGHEST_PROTOCOL < 4:
1553 return
1554
1555 def remove_frames(pickled, keep_frame=None):
1556 """Remove frame opcodes from the given pickle."""
1557 frame_starts = []
1558 # 1 byte for the opcode and 8 for the argument
1559 frame_opcode_size = 9
1560 for opcode, _, pos in pickletools.genops(pickled):
1561 if opcode.name == 'FRAME':
1562 frame_starts.append(pos)
1563
1564 newpickle = bytearray()
1565 last_frame_end = 0
1566 for i, pos in enumerate(frame_starts):
1567 if keep_frame and keep_frame(i):
1568 continue
1569 newpickle += pickled[last_frame_end:pos]
1570 last_frame_end = pos + frame_opcode_size
1571 newpickle += pickled[last_frame_end:]
1572 return newpickle
1573
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001574 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001575 num_frames = 20
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001576 obj = [bytes([i]) * frame_size for i in range(num_frames)]
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001577
1578 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1579 pickled = self.dumps(obj, proto)
1580
1581 frameless_pickle = remove_frames(pickled)
1582 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
1583 self.assertEqual(obj, self.loads(frameless_pickle))
1584
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001585 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001586 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
1587 count_opcode(pickle.FRAME, pickled))
1588 self.assertEqual(obj, self.loads(some_frames_pickle))
1589
Serhiy Storchaka21d75332015-01-26 10:37:01 +02001590 def test_frame_readline(self):
1591 pickled = b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00I42\n.'
1592 # 0: \x80 PROTO 4
1593 # 2: \x95 FRAME 5
1594 # 11: I INT 42
1595 # 15: . STOP
1596 self.assertEqual(self.loads(pickled), 42)
1597
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001598 def test_nested_names(self):
1599 global Nested
1600 class Nested:
1601 class A:
1602 class B:
1603 class C:
1604 pass
Serhiy Storchaka58e41342015-03-31 14:07:24 +03001605 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001606 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
1607 with self.subTest(proto=proto, obj=obj):
1608 unpickled = self.loads(self.dumps(obj, proto))
1609 self.assertIs(obj, unpickled)
1610
Serhiy Storchaka58e41342015-03-31 14:07:24 +03001611 def test_recursive_nested_names(self):
1612 global Recursive
1613 class Recursive:
1614 pass
1615 Recursive.mod = sys.modules[Recursive.__module__]
1616 Recursive.__qualname__ = 'Recursive.mod.Recursive'
1617 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1618 with self.subTest(proto=proto):
1619 unpickled = self.loads(self.dumps(Recursive, proto))
1620 self.assertIs(unpickled, Recursive)
1621 del Recursive.mod # break reference loop
1622
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001623 def test_py_methods(self):
1624 global PyMethodsTest
1625 class PyMethodsTest:
1626 @staticmethod
1627 def cheese():
1628 return "cheese"
1629 @classmethod
1630 def wine(cls):
1631 assert cls is PyMethodsTest
1632 return "wine"
1633 def biscuits(self):
1634 assert isinstance(self, PyMethodsTest)
1635 return "biscuits"
1636 class Nested:
1637 "Nested class"
1638 @staticmethod
1639 def ketchup():
1640 return "ketchup"
1641 @classmethod
1642 def maple(cls):
1643 assert cls is PyMethodsTest.Nested
1644 return "maple"
1645 def pie(self):
1646 assert isinstance(self, PyMethodsTest.Nested)
1647 return "pie"
1648
1649 py_methods = (
1650 PyMethodsTest.cheese,
1651 PyMethodsTest.wine,
1652 PyMethodsTest().biscuits,
1653 PyMethodsTest.Nested.ketchup,
1654 PyMethodsTest.Nested.maple,
1655 PyMethodsTest.Nested().pie
1656 )
1657 py_unbound_methods = (
1658 (PyMethodsTest.biscuits, PyMethodsTest),
1659 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
1660 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03001661 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001662 for method in py_methods:
1663 with self.subTest(proto=proto, method=method):
1664 unpickled = self.loads(self.dumps(method, proto))
1665 self.assertEqual(method(), unpickled())
1666 for method, cls in py_unbound_methods:
1667 obj = cls()
1668 with self.subTest(proto=proto, method=method):
1669 unpickled = self.loads(self.dumps(method, proto))
1670 self.assertEqual(method(obj), unpickled(obj))
1671
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001672 def test_c_methods(self):
1673 global Subclass
1674 class Subclass(tuple):
1675 class Nested(str):
1676 pass
1677
1678 c_methods = (
1679 # bound built-in method
1680 ("abcd".index, ("c",)),
1681 # unbound built-in method
1682 (str.index, ("abcd", "c")),
1683 # bound "slot" method
1684 ([1, 2, 3].__len__, ()),
1685 # unbound "slot" method
1686 (list.__len__, ([1, 2, 3],)),
1687 # bound "coexist" method
1688 ({1, 2}.__contains__, (2,)),
1689 # unbound "coexist" method
1690 (set.__contains__, ({1, 2}, 2)),
1691 # built-in class method
1692 (dict.fromkeys, (("a", 1), ("b", 2))),
1693 # built-in static method
1694 (bytearray.maketrans, (b"abc", b"xyz")),
1695 # subclass methods
1696 (Subclass([1,2,2]).count, (2,)),
1697 (Subclass.count, (Subclass([1,2,2]), 2)),
1698 (Subclass.Nested("sweet").count, ("e",)),
1699 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
1700 )
Serhiy Storchaka58e41342015-03-31 14:07:24 +03001701 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001702 for method, args in c_methods:
1703 with self.subTest(proto=proto, method=method):
1704 unpickled = self.loads(self.dumps(method, proto))
1705 self.assertEqual(method(*args), unpickled(*args))
1706
Serhiy Storchakabfe18242015-03-31 13:12:37 +03001707 def test_compat_pickle(self):
1708 tests = [
1709 (range(1, 7), '__builtin__', 'xrange'),
1710 (map(int, '123'), 'itertools', 'imap'),
1711 (functools.reduce, '__builtin__', 'reduce'),
1712 (dbm.whichdb, 'whichdb', 'whichdb'),
1713 (Exception(), 'exceptions', 'Exception'),
1714 (collections.UserDict(), 'UserDict', 'IterableUserDict'),
1715 (collections.UserList(), 'UserList', 'UserList'),
1716 (collections.defaultdict(), 'collections', 'defaultdict'),
1717 ]
1718 for val, mod, name in tests:
1719 for proto in range(3):
1720 with self.subTest(type=type(val), proto=proto):
1721 pickled = self.dumps(val, proto)
1722 self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled)
1723 self.assertIs(type(self.loads(pickled)), type(val))
1724
1725 def test_compat_unpickle(self):
1726 # xrange(1, 7)
1727 pickled = b'\x80\x02c__builtin__\nxrange\nK\x01K\x07K\x01\x87R.'
1728 unpickled = self.loads(pickled)
1729 self.assertIs(type(unpickled), range)
1730 self.assertEqual(unpickled, range(1, 7))
1731 self.assertEqual(list(unpickled), [1, 2, 3, 4, 5, 6])
1732 # reduce
1733 pickled = b'\x80\x02c__builtin__\nreduce\n.'
1734 self.assertIs(self.loads(pickled), functools.reduce)
1735 # whichdb.whichdb
1736 pickled = b'\x80\x02cwhichdb\nwhichdb\n.'
1737 self.assertIs(self.loads(pickled), dbm.whichdb)
1738 # Exception(), StandardError()
1739 for name in (b'Exception', b'StandardError'):
1740 pickled = (b'\x80\x02cexceptions\n' + name + b'\nU\x03ugh\x85R.')
1741 unpickled = self.loads(pickled)
1742 self.assertIs(type(unpickled), Exception)
1743 self.assertEqual(str(unpickled), 'ugh')
1744 # UserDict.UserDict({1: 2}), UserDict.IterableUserDict({1: 2})
1745 for name in (b'UserDict', b'IterableUserDict'):
1746 pickled = (b'\x80\x02(cUserDict\n' + name +
1747 b'\no}U\x04data}K\x01K\x02ssb.')
1748 unpickled = self.loads(pickled)
1749 self.assertIs(type(unpickled), collections.UserDict)
1750 self.assertEqual(unpickled, collections.UserDict({1: 2}))
1751
Antoine Pitrou6cd5eda2014-12-02 00:20:03 +01001752 def test_local_lookup_error(self):
1753 # Test that whichmodule() errors out cleanly when looking up
1754 # an assumed globally-reachable object fails.
1755 def f():
1756 pass
1757 # Since the function is local, lookup will fail
1758 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1759 with self.assertRaises((AttributeError, pickle.PicklingError)):
1760 pickletools.dis(self.dumps(f, proto))
1761 # Same without a __module__ attribute (exercises a different path
1762 # in _pickle.c).
1763 del f.__module__
1764 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1765 with self.assertRaises((AttributeError, pickle.PicklingError)):
1766 pickletools.dis(self.dumps(f, proto))
1767 # Yet a different path.
1768 f.__name__ = f.__qualname__
1769 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1770 with self.assertRaises((AttributeError, pickle.PicklingError)):
1771 pickletools.dis(self.dumps(f, proto))
1772
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001773
1774class BigmemPickleTests(unittest.TestCase):
1775
1776 # Binary protocols can serialize longs of up to 2GB-1
1777
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001778 @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001779 def test_huge_long_32b(self, size):
1780 data = 1 << (8 * size)
1781 try:
1782 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001783 if proto < 2:
1784 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001785 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001786 with self.assertRaises((ValueError, OverflowError)):
1787 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001788 finally:
1789 data = None
1790
1791 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1792 # (older protocols don't have a dedicated opcode for bytes and are
1793 # too inefficient)
1794
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001795 @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001796 def test_huge_bytes_32b(self, size):
1797 data = b"abcd" * (size // 4)
1798 try:
1799 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001800 if proto < 3:
1801 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001802 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001803 try:
1804 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001805 header = (pickle.BINBYTES +
1806 struct.pack("<I", len(data)))
1807 data_start = pickled.index(data)
1808 self.assertEqual(
1809 header,
1810 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001811 finally:
1812 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001813 finally:
1814 data = None
1815
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001816 @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001817 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001818 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001819 try:
1820 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001821 if proto < 3:
1822 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001823 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001824 if proto == 3:
1825 # Protocol 3 does not support large bytes objects.
1826 # Verify that we do not crash when processing one.
1827 with self.assertRaises((ValueError, OverflowError)):
1828 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001829 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001830 try:
1831 pickled = self.dumps(data, protocol=proto)
1832 header = (pickle.BINBYTES8 +
1833 struct.pack("<Q", len(data)))
1834 data_start = pickled.index(data)
1835 self.assertEqual(
1836 header,
1837 pickled[data_start-len(header):data_start])
1838 finally:
1839 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001840 finally:
1841 data = None
1842
1843 # All protocols use 1-byte per printable ASCII character; we add another
1844 # byte because the encoded form has to be copied into the internal buffer.
1845
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001846 @bigmemtest(size=_2G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001847 def test_huge_str_32b(self, size):
1848 data = "abcd" * (size // 4)
1849 try:
1850 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001851 if proto == 0:
1852 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001853 with self.subTest(proto=proto):
1854 try:
1855 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001856 header = (pickle.BINUNICODE +
1857 struct.pack("<I", len(data)))
1858 data_start = pickled.index(b'abcd')
1859 self.assertEqual(
1860 header,
1861 pickled[data_start-len(header):data_start])
1862 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1863 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001864 finally:
1865 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001866 finally:
1867 data = None
1868
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001869 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
1870 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
1871 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02001872
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001873 @bigmemtest(size=_4G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001874 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001875 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001876 try:
1877 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001878 if proto == 0:
1879 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001880 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001881 if proto < 4:
1882 with self.assertRaises((ValueError, OverflowError)):
1883 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001884 continue
1885 try:
1886 pickled = self.dumps(data, protocol=proto)
1887 header = (pickle.BINUNICODE8 +
1888 struct.pack("<Q", len(data)))
1889 data_start = pickled.index(b'abcd')
1890 self.assertEqual(
1891 header,
1892 pickled[data_start-len(header):data_start])
1893 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1894 pickled.index(b"abcd")), len(data))
1895 finally:
1896 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001897 finally:
1898 data = None
1899
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001900
Guido van Rossum2a30b212003-02-18 22:41:24 +00001901# Test classes for reduce_ex
1902
1903class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001904 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001905 _reduce_called = 0
1906 def __reduce__(self):
1907 self._reduce_called = 1
1908 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001909
1910class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001911 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001912 _proto = None
1913 def __reduce_ex__(self, proto):
1914 self._proto = proto
1915 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001916
1917class REX_three(object):
1918 _proto = None
1919 def __reduce_ex__(self, proto):
1920 self._proto = proto
1921 return REX_two, ()
1922 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001923 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001924
Guido van Rossumd8faa362007-04-27 19:54:29 +00001925class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001926 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001927 _proto = None
1928 def __reduce_ex__(self, proto):
1929 self._proto = proto
1930 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001931
1932class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001933 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001934 _reduce_called = 0
1935 def __reduce__(self):
1936 self._reduce_called = 1
1937 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001938
1939class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001940 """This class is used to check the 4th argument (list iterator) of
1941 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001942 """
1943 def __init__(self, items=None):
1944 self.items = items if items is not None else []
1945 def __eq__(self, other):
1946 return type(self) is type(other) and self.items == self.items
1947 def append(self, item):
1948 self.items.append(item)
1949 def __reduce__(self):
1950 return type(self), (), None, iter(self.items), None
1951
1952class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001953 """This class is used to check the 5th argument (dict iterator) of
1954 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001955 """
1956 def __init__(self, table=None):
1957 self.table = table if table is not None else {}
1958 def __eq__(self, other):
1959 return type(self) is type(other) and self.table == self.table
1960 def __setitem__(self, key, value):
1961 self.table[key] = value
1962 def __reduce__(self):
1963 return type(self), (), None, None, iter(self.table.items())
1964
Guido van Rossumd8faa362007-04-27 19:54:29 +00001965
Guido van Rossum2a30b212003-02-18 22:41:24 +00001966# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001967
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001968class MyInt(int):
1969 sample = 1
1970
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001971class MyFloat(float):
1972 sample = 1.0
1973
1974class MyComplex(complex):
1975 sample = 1.0 + 0.0j
1976
1977class MyStr(str):
1978 sample = "hello"
1979
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001980class MyUnicode(str):
1981 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001982
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001983class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001984 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001985
1986class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001987 sample = [1, 2, 3]
1988
1989class MyDict(dict):
1990 sample = {"a": 1, "b": 2}
1991
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001992class MySet(set):
1993 sample = {"a", "b"}
1994
1995class MyFrozenSet(frozenset):
1996 sample = frozenset({"a", "b"})
1997
Mark Dickinson5c2db372009-12-05 20:28:34 +00001998myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001999 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002000 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002001 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00002002
Guido van Rossum533dbcf2003-01-28 17:55:05 +00002003
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00002004class SlotList(MyList):
2005 __slots__ = ["foo"]
2006
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002007class SimpleNewObj(int):
2008 def __init__(self, *args, **kwargs):
Tim Peterse9ef2032003-02-13 18:42:00 +00002009 # raise an error, to make sure this isn't called
2010 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002011 def __eq__(self, other):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02002012 return int(self) == int(other) and self.__dict__ == other.__dict__
2013
2014class ComplexNewObj(SimpleNewObj):
2015 def __getnewargs__(self):
2016 return ('%X' % self, 16)
2017
2018class ComplexNewObjEx(SimpleNewObj):
2019 def __getnewargs_ex__(self):
2020 return ('%X' % self,), {'base': 16}
Tim Peterse9ef2032003-02-13 18:42:00 +00002021
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00002022class BadGetattr:
2023 def __getattr__(self, key):
2024 self.foo
2025
Collin Winter771d8342009-04-16 03:18:06 +00002026
Jeremy Hylton66426532001-10-15 21:38:56 +00002027class AbstractPickleModuleTests(unittest.TestCase):
2028
2029 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002030 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00002031 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002032 try:
2033 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002034 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002035 finally:
2036 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00002037
2038 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002039 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00002040 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002041 try:
2042 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002043 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00002044 finally:
2045 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002046
Collin Winter771d8342009-04-16 03:18:06 +00002047 def test_load_from_and_dump_to_file(self):
2048 stream = io.BytesIO()
2049 data = [123, {}, 124]
2050 pickle.dump(data, stream)
2051 stream.seek(0)
2052 unpickled = pickle.load(stream)
2053 self.assertEqual(unpickled, data)
2054
Tim Petersc0c93702003-02-13 19:30:57 +00002055 def test_highest_protocol(self):
2056 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002057 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00002058
Martin v. Löwis544f1192004-07-27 05:22:33 +00002059 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00002060 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00002061 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00002062 pickle.dump(123, f, -1)
2063 pickle.dump(123, file=f, protocol=-1)
2064 pickle.dumps(123, -1)
2065 pickle.dumps(123, protocol=-1)
2066 pickle.Pickler(f, -1)
2067 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00002068
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002069 def test_bad_init(self):
2070 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002071 # Override initialization without calling __init__() of the superclass.
2072 class BadPickler(pickle.Pickler):
2073 def __init__(self): pass
2074
2075 class BadUnpickler(pickle.Unpickler):
2076 def __init__(self): pass
2077
2078 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
2079 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
2080
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00002081 def test_bad_input(self):
2082 # Test issue4298
2083 s = bytes([0x58, 0, 0, 0, 0x54])
2084 self.assertRaises(EOFError, pickle.loads, s)
2085
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002086
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002087class AbstractPersistentPicklerTests(unittest.TestCase):
2088
2089 # This class defines persistent_id() and persistent_load()
2090 # functions that should be used by the pickler. All even integers
2091 # are pickled using persistent ids.
2092
2093 def persistent_id(self, object):
2094 if isinstance(object, int) and object % 2 == 0:
2095 self.id_count += 1
2096 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002097 elif object == "test_false_value":
2098 self.false_count += 1
2099 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002100 else:
2101 return None
2102
2103 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002104 if not oid:
2105 self.load_false_count += 1
2106 return "test_false_value"
2107 else:
2108 self.load_count += 1
2109 object = int(oid)
2110 assert object % 2 == 0
2111 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002112
2113 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002114 L = list(range(10)) + ["test_false_value"]
2115 for proto in protocols:
2116 self.id_count = 0
2117 self.false_count = 0
2118 self.load_false_count = 0
2119 self.load_count = 0
2120 self.assertEqual(self.loads(self.dumps(L, proto)), L)
2121 self.assertEqual(self.id_count, 5)
2122 self.assertEqual(self.false_count, 1)
2123 self.assertEqual(self.load_count, 5)
2124 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00002125
Collin Winter771d8342009-04-16 03:18:06 +00002126
2127class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
2128
2129 pickler_class = None
2130 unpickler_class = None
2131
2132 def setUp(self):
2133 assert self.pickler_class
2134 assert self.unpickler_class
2135
2136 def test_clear_pickler_memo(self):
2137 # To test whether clear_memo() has any effect, we pickle an object,
2138 # then pickle it again without clearing the memo; the two serialized
2139 # forms should be different. If we clear_memo() and then pickle the
2140 # object again, the third serialized form should be identical to the
2141 # first one we obtained.
2142 data = ["abcdefg", "abcdefg", 44]
2143 f = io.BytesIO()
2144 pickler = self.pickler_class(f)
2145
2146 pickler.dump(data)
2147 first_pickled = f.getvalue()
2148
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002149 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00002150 f.seek(0)
2151 f.truncate()
2152
2153 pickler.dump(data)
2154 second_pickled = f.getvalue()
2155
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002156 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00002157 pickler.clear_memo()
2158 f.seek(0)
2159 f.truncate()
2160
2161 pickler.dump(data)
2162 third_pickled = f.getvalue()
2163
2164 self.assertNotEqual(first_pickled, second_pickled)
2165 self.assertEqual(first_pickled, third_pickled)
2166
2167 def test_priming_pickler_memo(self):
2168 # Verify that we can set the Pickler's memo attribute.
2169 data = ["abcdefg", "abcdefg", 44]
2170 f = io.BytesIO()
2171 pickler = self.pickler_class(f)
2172
2173 pickler.dump(data)
2174 first_pickled = f.getvalue()
2175
2176 f = io.BytesIO()
2177 primed = self.pickler_class(f)
2178 primed.memo = pickler.memo
2179
2180 primed.dump(data)
2181 primed_pickled = f.getvalue()
2182
2183 self.assertNotEqual(first_pickled, primed_pickled)
2184
2185 def test_priming_unpickler_memo(self):
2186 # Verify that we can set the Unpickler's memo attribute.
2187 data = ["abcdefg", "abcdefg", 44]
2188 f = io.BytesIO()
2189 pickler = self.pickler_class(f)
2190
2191 pickler.dump(data)
2192 first_pickled = f.getvalue()
2193
2194 f = io.BytesIO()
2195 primed = self.pickler_class(f)
2196 primed.memo = pickler.memo
2197
2198 primed.dump(data)
2199 primed_pickled = f.getvalue()
2200
2201 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2202 unpickled_data1 = unpickler.load()
2203
2204 self.assertEqual(unpickled_data1, data)
2205
2206 primed = self.unpickler_class(io.BytesIO(primed_pickled))
2207 primed.memo = unpickler.memo
2208 unpickled_data2 = primed.load()
2209
2210 primed.memo.clear()
2211
2212 self.assertEqual(unpickled_data2, data)
2213 self.assertTrue(unpickled_data2 is unpickled_data1)
2214
2215 def test_reusing_unpickler_objects(self):
2216 data1 = ["abcdefg", "abcdefg", 44]
2217 f = io.BytesIO()
2218 pickler = self.pickler_class(f)
2219 pickler.dump(data1)
2220 pickled1 = f.getvalue()
2221
2222 data2 = ["abcdefg", 44, 44]
2223 f = io.BytesIO()
2224 pickler = self.pickler_class(f)
2225 pickler.dump(data2)
2226 pickled2 = f.getvalue()
2227
2228 f = io.BytesIO()
2229 f.write(pickled1)
2230 f.seek(0)
2231 unpickler = self.unpickler_class(f)
2232 self.assertEqual(unpickler.load(), data1)
2233
2234 f.seek(0)
2235 f.truncate()
2236 f.write(pickled2)
2237 f.seek(0)
2238 self.assertEqual(unpickler.load(), data2)
2239
Antoine Pitrou04248a82010-10-12 20:51:21 +00002240 def _check_multiple_unpicklings(self, ioclass):
2241 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002242 with self.subTest(proto=proto):
2243 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2244 f = ioclass()
2245 pickler = self.pickler_class(f, protocol=proto)
2246 pickler.dump(data1)
2247 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002248
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002249 N = 5
2250 f = ioclass(pickled * N)
2251 unpickler = self.unpickler_class(f)
2252 for i in range(N):
2253 if f.seekable():
2254 pos = f.tell()
2255 self.assertEqual(unpickler.load(), data1)
2256 if f.seekable():
2257 self.assertEqual(f.tell(), pos + len(pickled))
2258 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002259
2260 def test_multiple_unpicklings_seekable(self):
2261 self._check_multiple_unpicklings(io.BytesIO)
2262
2263 def test_multiple_unpicklings_unseekable(self):
2264 self._check_multiple_unpicklings(UnseekableIO)
2265
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002266 def test_unpickling_buffering_readline(self):
2267 # Issue #12687: the unpickler's buffering logic could fail with
2268 # text mode opcodes.
2269 data = list(range(10))
2270 for proto in protocols:
2271 for buf_size in range(1, 11):
2272 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2273 pickler = self.pickler_class(f, protocol=proto)
2274 pickler.dump(data)
2275 f.seek(0)
2276 unpickler = self.unpickler_class(f)
2277 self.assertEqual(unpickler.load(), data)
2278
Collin Winter771d8342009-04-16 03:18:06 +00002279
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002280# Tests for dispatch_table attribute
2281
2282REDUCE_A = 'reduce_A'
2283
2284class AAA(object):
2285 def __reduce__(self):
2286 return str, (REDUCE_A,)
2287
2288class BBB(object):
2289 pass
2290
2291class AbstractDispatchTableTests(unittest.TestCase):
2292
2293 def test_default_dispatch_table(self):
2294 # No dispatch_table attribute by default
2295 f = io.BytesIO()
2296 p = self.pickler_class(f, 0)
2297 with self.assertRaises(AttributeError):
2298 p.dispatch_table
2299 self.assertFalse(hasattr(p, 'dispatch_table'))
2300
2301 def test_class_dispatch_table(self):
2302 # A dispatch_table attribute can be specified class-wide
2303 dt = self.get_dispatch_table()
2304
2305 class MyPickler(self.pickler_class):
2306 dispatch_table = dt
2307
2308 def dumps(obj, protocol=None):
2309 f = io.BytesIO()
2310 p = MyPickler(f, protocol)
2311 self.assertEqual(p.dispatch_table, dt)
2312 p.dump(obj)
2313 return f.getvalue()
2314
2315 self._test_dispatch_table(dumps, dt)
2316
2317 def test_instance_dispatch_table(self):
2318 # A dispatch_table attribute can also be specified instance-wide
2319 dt = self.get_dispatch_table()
2320
2321 def dumps(obj, protocol=None):
2322 f = io.BytesIO()
2323 p = self.pickler_class(f, protocol)
2324 p.dispatch_table = dt
2325 self.assertEqual(p.dispatch_table, dt)
2326 p.dump(obj)
2327 return f.getvalue()
2328
2329 self._test_dispatch_table(dumps, dt)
2330
2331 def _test_dispatch_table(self, dumps, dispatch_table):
2332 def custom_load_dump(obj):
2333 return pickle.loads(dumps(obj, 0))
2334
2335 def default_load_dump(obj):
2336 return pickle.loads(pickle.dumps(obj, 0))
2337
2338 # pickling complex numbers using protocol 0 relies on copyreg
2339 # so check pickling a complex number still works
2340 z = 1 + 2j
2341 self.assertEqual(custom_load_dump(z), z)
2342 self.assertEqual(default_load_dump(z), z)
2343
2344 # modify pickling of complex
2345 REDUCE_1 = 'reduce_1'
2346 def reduce_1(obj):
2347 return str, (REDUCE_1,)
2348 dispatch_table[complex] = reduce_1
2349 self.assertEqual(custom_load_dump(z), REDUCE_1)
2350 self.assertEqual(default_load_dump(z), z)
2351
2352 # check picklability of AAA and BBB
2353 a = AAA()
2354 b = BBB()
2355 self.assertEqual(custom_load_dump(a), REDUCE_A)
2356 self.assertIsInstance(custom_load_dump(b), BBB)
2357 self.assertEqual(default_load_dump(a), REDUCE_A)
2358 self.assertIsInstance(default_load_dump(b), BBB)
2359
2360 # modify pickling of BBB
2361 dispatch_table[BBB] = reduce_1
2362 self.assertEqual(custom_load_dump(a), REDUCE_A)
2363 self.assertEqual(custom_load_dump(b), REDUCE_1)
2364 self.assertEqual(default_load_dump(a), REDUCE_A)
2365 self.assertIsInstance(default_load_dump(b), BBB)
2366
2367 # revert pickling of BBB and modify pickling of AAA
2368 REDUCE_2 = 'reduce_2'
2369 def reduce_2(obj):
2370 return str, (REDUCE_2,)
2371 dispatch_table[AAA] = reduce_2
2372 del dispatch_table[BBB]
2373 self.assertEqual(custom_load_dump(a), REDUCE_2)
2374 self.assertIsInstance(custom_load_dump(b), BBB)
2375 self.assertEqual(default_load_dump(a), REDUCE_A)
2376 self.assertIsInstance(default_load_dump(b), BBB)
2377
2378
Guido van Rossum98297ee2007-11-06 21:34:58 +00002379if __name__ == "__main__":
2380 # Print some stuff that can be used to rewrite DATA{0,1,2}
2381 from pickletools import dis
2382 x = create_data()
2383 for i in range(3):
2384 p = pickle.dumps(x, i)
2385 print("DATA{0} = (".format(i))
2386 for j in range(0, len(p), 20):
2387 b = bytes(p[j:j+20])
2388 print(" {0!r}".format(b))
2389 print(")")
2390 print()
2391 print("# Disassembly of DATA{0}".format(i))
2392 print("DATA{0}_DIS = \"\"\"\\".format(i))
2393 dis(p)
2394 print("\"\"\"")
2395 print()