blob: 2c496d09592aac7ec70f90bcc01ae038835b5668 [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):
1159 x = object.__new__(SimpleNewObj) # avoid __init__
1160 x.abc = 666
1161 for proto in protocols:
1162 s = self.dumps(x, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001163 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1164 2 <= proto < 4)
1165 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1166 proto >= 4)
Tim Peterse9ef2032003-02-13 18:42:00 +00001167 y = self.loads(s) # will raise TypeError if __init__ called
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001168 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001169
Tim Peters42f08ac2003-02-11 22:43:24 +00001170 def test_newobj_list_slots(self):
1171 x = SlotList([1, 2, 3])
1172 x.foo = 42
1173 x.bar = "hello"
1174 s = self.dumps(x, 2)
1175 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001176 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001177
Guido van Rossum2a30b212003-02-18 22:41:24 +00001178 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001179 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001180 x = REX_one()
1181 self.assertEqual(x._reduce_called, 0)
1182 s = self.dumps(x, proto)
1183 self.assertEqual(x._reduce_called, 1)
1184 y = self.loads(s)
1185 self.assertEqual(y._reduce_called, 0)
1186
1187 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001188 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001189 x = REX_two()
1190 self.assertEqual(x._proto, None)
1191 s = self.dumps(x, proto)
1192 self.assertEqual(x._proto, proto)
1193 y = self.loads(s)
1194 self.assertEqual(y._proto, None)
1195
1196 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001197 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001198 x = REX_three()
1199 self.assertEqual(x._proto, None)
1200 s = self.dumps(x, proto)
1201 self.assertEqual(x._proto, proto)
1202 y = self.loads(s)
1203 self.assertEqual(y._proto, None)
1204
Guido van Rossumd8faa362007-04-27 19:54:29 +00001205 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001206 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001207 x = REX_four()
1208 self.assertEqual(x._proto, None)
1209 s = self.dumps(x, proto)
1210 self.assertEqual(x._proto, proto)
1211 y = self.loads(s)
1212 self.assertEqual(y._proto, proto)
1213
1214 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001215 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001216 x = REX_five()
1217 self.assertEqual(x._reduce_called, 0)
1218 s = self.dumps(x, proto)
1219 self.assertEqual(x._reduce_called, 1)
1220 y = self.loads(s)
1221 self.assertEqual(y._reduce_called, 1)
1222
Brett Cannon31f59292011-02-21 19:29:56 +00001223 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001224 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001225 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001226 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001227 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001228 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001229
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001230 def test_reduce_bad_iterator(self):
1231 # Issue4176: crash when 4th and 5th items of __reduce__()
1232 # are not iterators
1233 class C(object):
1234 def __reduce__(self):
1235 # 4th item is not an iterator
1236 return list, (), None, [], None
1237 class D(object):
1238 def __reduce__(self):
1239 # 5th item is not an iterator
1240 return dict, (), None, None, []
1241
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001242 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001243 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001244 try:
1245 self.dumps(C(), proto)
1246 except (pickle.PickleError):
1247 pass
1248 try:
1249 self.dumps(D(), proto)
1250 except (pickle.PickleError):
1251 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001252
Collin Winter771d8342009-04-16 03:18:06 +00001253 def test_many_puts_and_gets(self):
1254 # Test that internal data structures correctly deal with lots of
1255 # puts/gets.
1256 keys = ("aaa" + str(i) for i in range(100))
1257 large_dict = dict((k, [4, 5, 6]) for k in keys)
1258 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1259
1260 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001261 with self.subTest(proto=proto):
1262 dumped = self.dumps(obj, proto)
1263 loaded = self.loads(dumped)
1264 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00001265
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001266 def test_attribute_name_interning(self):
1267 # Test that attribute names of pickled objects are interned when
1268 # unpickling.
1269 for proto in protocols:
1270 x = C()
1271 x.foo = 42
1272 x.bar = "hello"
1273 s = self.dumps(x, proto)
1274 y = self.loads(s)
1275 x_keys = sorted(x.__dict__)
1276 y_keys = sorted(y.__dict__)
1277 for x_key, y_key in zip(x_keys, y_keys):
1278 self.assertIs(x_key, y_key)
1279
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001280 def test_unpickle_from_2x(self):
1281 # Unpickle non-trivial data from Python 2.x.
1282 loaded = self.loads(DATA3)
1283 self.assertEqual(loaded, set([1, 2]))
1284 loaded = self.loads(DATA4)
1285 self.assertEqual(type(loaded), type(range(0)))
1286 self.assertEqual(list(loaded), list(range(5)))
1287 loaded = self.loads(DATA5)
1288 self.assertEqual(type(loaded), SimpleCookie)
1289 self.assertEqual(list(loaded.keys()), ["key"])
Serhiy Storchaka8cf7c1c2014-11-02 22:18:25 +02001290 self.assertEqual(loaded["key"].value, "value")
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001291
Walter Doerwald9d1dbca2013-12-02 11:41:01 +01001292 for (exc, data) in DATA7.items():
1293 loaded = self.loads(data)
1294 self.assertIs(type(loaded), exc)
1295
1296 loaded = self.loads(DATA8)
1297 self.assertIs(type(loaded), Exception)
1298
1299 loaded = self.loads(DATA9)
1300 self.assertIs(type(loaded), UnicodeEncodeError)
1301 self.assertEqual(loaded.object, "foo")
1302 self.assertEqual(loaded.encoding, "ascii")
1303 self.assertEqual(loaded.start, 0)
1304 self.assertEqual(loaded.end, 1)
1305 self.assertEqual(loaded.reason, "bad")
1306
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001307 def test_pickle_to_2x(self):
1308 # Pickle non-trivial data with protocol 2, expecting that it yields
1309 # the same result as Python 2.x did.
1310 # NOTE: this test is a bit too strong since we can produce different
1311 # bytecode that 2.x will still understand.
1312 dumped = self.dumps(range(5), 2)
1313 self.assertEqual(dumped, DATA4)
1314 dumped = self.dumps(set([3]), 2)
1315 self.assertEqual(dumped, DATA6)
1316
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -08001317 def test_load_python2_str_as_bytes(self):
1318 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
1319 self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
1320 encoding="bytes"), b'a\x00\xa0')
1321 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
1322 self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
1323 encoding="bytes"), b'a\x00\xa0')
1324 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
1325 self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
1326 encoding="bytes"), b'a\x00\xa0')
1327
1328 def test_load_python2_unicode_as_str(self):
1329 # From Python 2: pickle.dumps(u'π', protocol=0)
1330 self.assertEqual(self.loads(b'V\\u03c0\n.',
1331 encoding='bytes'), 'π')
1332 # From Python 2: pickle.dumps(u'π', protocol=1)
1333 self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
1334 encoding="bytes"), 'π')
1335 # From Python 2: pickle.dumps(u'π', protocol=2)
1336 self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
1337 encoding="bytes"), 'π')
1338
1339 def test_load_long_python2_str_as_bytes(self):
1340 # From Python 2: pickle.dumps('x' * 300, protocol=1)
1341 self.assertEqual(self.loads(pickle.BINSTRING +
1342 struct.pack("<I", 300) +
1343 b'x' * 300 + pickle.STOP,
1344 encoding='bytes'), b'x' * 300)
1345
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001346 def test_large_pickles(self):
1347 # Test the correctness of internal buffering routines when handling
1348 # large data.
1349 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001350 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001351 dumped = self.dumps(data, proto)
1352 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001353 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001354 self.assertEqual(loaded, data)
1355
Alexander Belopolsky1ce92dc2011-02-24 19:40:09 +00001356 def test_empty_bytestring(self):
1357 # issue 11286
1358 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1359 self.assertEqual(empty, '')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001360
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001361 def test_int_pickling_efficiency(self):
1362 # Test compacity of int representation (see issue #12744)
1363 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001364 with self.subTest(proto=proto):
1365 pickles = [self.dumps(2**n, proto) for n in range(70)]
1366 sizes = list(map(len, pickles))
1367 # the size function is monotonic
1368 self.assertEqual(sorted(sizes), sizes)
1369 if proto >= 2:
1370 for p in pickles:
1371 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001372
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001373 def check_negative_32b_binXXX(self, dumped):
1374 if sys.maxsize > 2**32:
1375 self.skipTest("test is only meaningful on 32-bit builds")
1376 # XXX Pure Python pickle reads lengths as signed and passes
1377 # them directly to read() (hence the EOFError)
1378 with self.assertRaises((pickle.UnpicklingError, EOFError,
1379 ValueError, OverflowError)):
1380 self.loads(dumped)
1381
1382 def test_negative_32b_binbytes(self):
1383 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1384 self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.')
1385
1386 def test_negative_32b_binunicode(self):
1387 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1388 self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.')
1389
Antoine Pitrou55549ec2011-08-30 00:27:10 +02001390 def test_negative_put(self):
1391 # Issue #12847
1392 dumped = b'Va\np-1\n.'
1393 self.assertRaises(ValueError, self.loads, dumped)
1394
1395 def test_negative_32b_binput(self):
1396 # Issue #12847
1397 if sys.maxsize > 2**32:
1398 self.skipTest("test is only meaningful on 32-bit builds")
1399 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
1400 self.assertRaises(ValueError, self.loads, dumped)
1401
Alexandre Vassalotti7c5e0942013-04-15 23:14:55 -07001402 def test_badly_escaped_string(self):
1403 self.assertRaises(ValueError, self.loads, b"S'\\'\n.")
1404
1405 def test_badly_quoted_string(self):
1406 # Issue #17710
1407 badpickles = [b"S'\n.",
1408 b'S"\n.',
1409 b'S\' \n.',
1410 b'S" \n.',
1411 b'S\'"\n.',
1412 b'S"\'\n.',
1413 b"S' ' \n.",
1414 b'S" " \n.',
1415 b"S ''\n.",
1416 b'S ""\n.',
1417 b'S \n.',
1418 b'S\n.',
1419 b'S.']
1420 for p in badpickles:
1421 self.assertRaises(pickle.UnpicklingError, self.loads, p)
1422
1423 def test_correctly_quoted_string(self):
1424 goodpickles = [(b"S''\n.", ''),
1425 (b'S""\n.', ''),
1426 (b'S"\\n"\n.', '\n'),
1427 (b"S'\\n'\n.", '\n')]
1428 for p, expected in goodpickles:
1429 self.assertEqual(self.loads(p), expected)
1430
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001431 def _check_pickling_with_opcode(self, obj, opcode, proto):
1432 pickled = self.dumps(obj, proto)
1433 self.assertTrue(opcode_in_pickle(opcode, pickled))
1434 unpickled = self.loads(pickled)
1435 self.assertEqual(obj, unpickled)
1436
1437 def test_appends_on_non_lists(self):
1438 # Issue #17720
1439 obj = REX_six([1, 2, 3])
1440 for proto in protocols:
1441 if proto == 0:
1442 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1443 else:
1444 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1445
1446 def test_setitems_on_non_dicts(self):
1447 obj = REX_seven({1: -1, 2: -2, 3: -3})
1448 for proto in protocols:
1449 if proto == 0:
1450 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1451 else:
1452 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1453
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001454 # Exercise framing (proto >= 4) for significant workloads
1455
1456 FRAME_SIZE_TARGET = 64 * 1024
1457
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001458 def check_frame_opcodes(self, pickled):
1459 """
1460 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
1461 """
1462 frame_opcode_size = 9
1463 last_arg = last_pos = None
1464 for op, arg, pos in pickletools.genops(pickled):
1465 if op.name != 'FRAME':
1466 continue
1467 if last_pos is not None:
1468 # The previous frame's size should be equal to the number
1469 # of bytes up to the current frame.
1470 frame_size = pos - last_pos - frame_opcode_size
1471 self.assertEqual(frame_size, last_arg)
1472 last_arg, last_pos = arg, pos
1473 # The last frame's size should be equal to the number of bytes up
1474 # to the pickle's end.
1475 frame_size = len(pickled) - last_pos - frame_opcode_size
1476 self.assertEqual(frame_size, last_arg)
1477
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001478 def test_framing_many_objects(self):
1479 obj = list(range(10**5))
1480 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1481 with self.subTest(proto=proto):
1482 pickled = self.dumps(obj, proto)
1483 unpickled = self.loads(pickled)
1484 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001485 bytes_per_frame = (len(pickled) /
1486 count_opcode(pickle.FRAME, pickled))
1487 self.assertGreater(bytes_per_frame,
1488 self.FRAME_SIZE_TARGET / 2)
1489 self.assertLessEqual(bytes_per_frame,
1490 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001491 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001492
1493 def test_framing_large_objects(self):
1494 N = 1024 * 1024
1495 obj = [b'x' * N, b'y' * N, b'z' * N]
1496 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1497 with self.subTest(proto=proto):
1498 pickled = self.dumps(obj, proto)
1499 unpickled = self.loads(pickled)
1500 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001501 n_frames = count_opcode(pickle.FRAME, pickled)
Alexandre Vassalotti28d271e2013-12-01 16:27:46 -08001502 self.assertGreaterEqual(n_frames, len(obj))
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001503 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001504
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001505 def test_optional_frames(self):
1506 if pickle.HIGHEST_PROTOCOL < 4:
1507 return
1508
1509 def remove_frames(pickled, keep_frame=None):
1510 """Remove frame opcodes from the given pickle."""
1511 frame_starts = []
1512 # 1 byte for the opcode and 8 for the argument
1513 frame_opcode_size = 9
1514 for opcode, _, pos in pickletools.genops(pickled):
1515 if opcode.name == 'FRAME':
1516 frame_starts.append(pos)
1517
1518 newpickle = bytearray()
1519 last_frame_end = 0
1520 for i, pos in enumerate(frame_starts):
1521 if keep_frame and keep_frame(i):
1522 continue
1523 newpickle += pickled[last_frame_end:pos]
1524 last_frame_end = pos + frame_opcode_size
1525 newpickle += pickled[last_frame_end:]
1526 return newpickle
1527
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001528 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001529 num_frames = 20
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001530 obj = [bytes([i]) * frame_size for i in range(num_frames)]
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001531
1532 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1533 pickled = self.dumps(obj, proto)
1534
1535 frameless_pickle = remove_frames(pickled)
1536 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
1537 self.assertEqual(obj, self.loads(frameless_pickle))
1538
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001539 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001540 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
1541 count_opcode(pickle.FRAME, pickled))
1542 self.assertEqual(obj, self.loads(some_frames_pickle))
1543
Serhiy Storchaka21d75332015-01-26 10:37:01 +02001544 def test_frame_readline(self):
1545 pickled = b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00I42\n.'
1546 # 0: \x80 PROTO 4
1547 # 2: \x95 FRAME 5
1548 # 11: I INT 42
1549 # 15: . STOP
1550 self.assertEqual(self.loads(pickled), 42)
1551
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001552 def test_nested_names(self):
1553 global Nested
1554 class Nested:
1555 class A:
1556 class B:
1557 class C:
1558 pass
1559
1560 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1561 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
1562 with self.subTest(proto=proto, obj=obj):
1563 unpickled = self.loads(self.dumps(obj, proto))
1564 self.assertIs(obj, unpickled)
1565
1566 def test_py_methods(self):
1567 global PyMethodsTest
1568 class PyMethodsTest:
1569 @staticmethod
1570 def cheese():
1571 return "cheese"
1572 @classmethod
1573 def wine(cls):
1574 assert cls is PyMethodsTest
1575 return "wine"
1576 def biscuits(self):
1577 assert isinstance(self, PyMethodsTest)
1578 return "biscuits"
1579 class Nested:
1580 "Nested class"
1581 @staticmethod
1582 def ketchup():
1583 return "ketchup"
1584 @classmethod
1585 def maple(cls):
1586 assert cls is PyMethodsTest.Nested
1587 return "maple"
1588 def pie(self):
1589 assert isinstance(self, PyMethodsTest.Nested)
1590 return "pie"
1591
1592 py_methods = (
1593 PyMethodsTest.cheese,
1594 PyMethodsTest.wine,
1595 PyMethodsTest().biscuits,
1596 PyMethodsTest.Nested.ketchup,
1597 PyMethodsTest.Nested.maple,
1598 PyMethodsTest.Nested().pie
1599 )
1600 py_unbound_methods = (
1601 (PyMethodsTest.biscuits, PyMethodsTest),
1602 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
1603 )
1604 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1605 for method in py_methods:
1606 with self.subTest(proto=proto, method=method):
1607 unpickled = self.loads(self.dumps(method, proto))
1608 self.assertEqual(method(), unpickled())
1609 for method, cls in py_unbound_methods:
1610 obj = cls()
1611 with self.subTest(proto=proto, method=method):
1612 unpickled = self.loads(self.dumps(method, proto))
1613 self.assertEqual(method(obj), unpickled(obj))
1614
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001615 def test_c_methods(self):
1616 global Subclass
1617 class Subclass(tuple):
1618 class Nested(str):
1619 pass
1620
1621 c_methods = (
1622 # bound built-in method
1623 ("abcd".index, ("c",)),
1624 # unbound built-in method
1625 (str.index, ("abcd", "c")),
1626 # bound "slot" method
1627 ([1, 2, 3].__len__, ()),
1628 # unbound "slot" method
1629 (list.__len__, ([1, 2, 3],)),
1630 # bound "coexist" method
1631 ({1, 2}.__contains__, (2,)),
1632 # unbound "coexist" method
1633 (set.__contains__, ({1, 2}, 2)),
1634 # built-in class method
1635 (dict.fromkeys, (("a", 1), ("b", 2))),
1636 # built-in static method
1637 (bytearray.maketrans, (b"abc", b"xyz")),
1638 # subclass methods
1639 (Subclass([1,2,2]).count, (2,)),
1640 (Subclass.count, (Subclass([1,2,2]), 2)),
1641 (Subclass.Nested("sweet").count, ("e",)),
1642 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
1643 )
1644 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1645 for method, args in c_methods:
1646 with self.subTest(proto=proto, method=method):
1647 unpickled = self.loads(self.dumps(method, proto))
1648 self.assertEqual(method(*args), unpickled(*args))
1649
Serhiy Storchakabfe18242015-03-31 13:12:37 +03001650 def test_compat_pickle(self):
1651 tests = [
1652 (range(1, 7), '__builtin__', 'xrange'),
1653 (map(int, '123'), 'itertools', 'imap'),
1654 (functools.reduce, '__builtin__', 'reduce'),
1655 (dbm.whichdb, 'whichdb', 'whichdb'),
1656 (Exception(), 'exceptions', 'Exception'),
1657 (collections.UserDict(), 'UserDict', 'IterableUserDict'),
1658 (collections.UserList(), 'UserList', 'UserList'),
1659 (collections.defaultdict(), 'collections', 'defaultdict'),
1660 ]
1661 for val, mod, name in tests:
1662 for proto in range(3):
1663 with self.subTest(type=type(val), proto=proto):
1664 pickled = self.dumps(val, proto)
1665 self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled)
1666 self.assertIs(type(self.loads(pickled)), type(val))
1667
1668 def test_compat_unpickle(self):
1669 # xrange(1, 7)
1670 pickled = b'\x80\x02c__builtin__\nxrange\nK\x01K\x07K\x01\x87R.'
1671 unpickled = self.loads(pickled)
1672 self.assertIs(type(unpickled), range)
1673 self.assertEqual(unpickled, range(1, 7))
1674 self.assertEqual(list(unpickled), [1, 2, 3, 4, 5, 6])
1675 # reduce
1676 pickled = b'\x80\x02c__builtin__\nreduce\n.'
1677 self.assertIs(self.loads(pickled), functools.reduce)
1678 # whichdb.whichdb
1679 pickled = b'\x80\x02cwhichdb\nwhichdb\n.'
1680 self.assertIs(self.loads(pickled), dbm.whichdb)
1681 # Exception(), StandardError()
1682 for name in (b'Exception', b'StandardError'):
1683 pickled = (b'\x80\x02cexceptions\n' + name + b'\nU\x03ugh\x85R.')
1684 unpickled = self.loads(pickled)
1685 self.assertIs(type(unpickled), Exception)
1686 self.assertEqual(str(unpickled), 'ugh')
1687 # UserDict.UserDict({1: 2}), UserDict.IterableUserDict({1: 2})
1688 for name in (b'UserDict', b'IterableUserDict'):
1689 pickled = (b'\x80\x02(cUserDict\n' + name +
1690 b'\no}U\x04data}K\x01K\x02ssb.')
1691 unpickled = self.loads(pickled)
1692 self.assertIs(type(unpickled), collections.UserDict)
1693 self.assertEqual(unpickled, collections.UserDict({1: 2}))
1694
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001695
1696class BigmemPickleTests(unittest.TestCase):
1697
1698 # Binary protocols can serialize longs of up to 2GB-1
1699
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001700 @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001701 def test_huge_long_32b(self, size):
1702 data = 1 << (8 * size)
1703 try:
1704 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001705 if proto < 2:
1706 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001707 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001708 with self.assertRaises((ValueError, OverflowError)):
1709 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001710 finally:
1711 data = None
1712
1713 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1714 # (older protocols don't have a dedicated opcode for bytes and are
1715 # too inefficient)
1716
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001717 @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001718 def test_huge_bytes_32b(self, size):
1719 data = b"abcd" * (size // 4)
1720 try:
1721 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001722 if proto < 3:
1723 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001724 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001725 try:
1726 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001727 header = (pickle.BINBYTES +
1728 struct.pack("<I", len(data)))
1729 data_start = pickled.index(data)
1730 self.assertEqual(
1731 header,
1732 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001733 finally:
1734 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001735 finally:
1736 data = None
1737
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001738 @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001739 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001740 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001741 try:
1742 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001743 if proto < 3:
1744 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001745 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001746 if proto == 3:
1747 # Protocol 3 does not support large bytes objects.
1748 # Verify that we do not crash when processing one.
1749 with self.assertRaises((ValueError, OverflowError)):
1750 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001751 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001752 try:
1753 pickled = self.dumps(data, protocol=proto)
1754 header = (pickle.BINBYTES8 +
1755 struct.pack("<Q", len(data)))
1756 data_start = pickled.index(data)
1757 self.assertEqual(
1758 header,
1759 pickled[data_start-len(header):data_start])
1760 finally:
1761 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001762 finally:
1763 data = None
1764
1765 # All protocols use 1-byte per printable ASCII character; we add another
1766 # byte because the encoded form has to be copied into the internal buffer.
1767
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001768 @bigmemtest(size=_2G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001769 def test_huge_str_32b(self, size):
1770 data = "abcd" * (size // 4)
1771 try:
1772 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001773 if proto == 0:
1774 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001775 with self.subTest(proto=proto):
1776 try:
1777 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001778 header = (pickle.BINUNICODE +
1779 struct.pack("<I", len(data)))
1780 data_start = pickled.index(b'abcd')
1781 self.assertEqual(
1782 header,
1783 pickled[data_start-len(header):data_start])
1784 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1785 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001786 finally:
1787 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001788 finally:
1789 data = None
1790
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001791 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
1792 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
1793 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02001794
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001795 @bigmemtest(size=_4G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001796 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001797 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001798 try:
1799 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001800 if proto == 0:
1801 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001802 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001803 if proto < 4:
1804 with self.assertRaises((ValueError, OverflowError)):
1805 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001806 continue
1807 try:
1808 pickled = self.dumps(data, protocol=proto)
1809 header = (pickle.BINUNICODE8 +
1810 struct.pack("<Q", len(data)))
1811 data_start = pickled.index(b'abcd')
1812 self.assertEqual(
1813 header,
1814 pickled[data_start-len(header):data_start])
1815 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1816 pickled.index(b"abcd")), len(data))
1817 finally:
1818 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001819 finally:
1820 data = None
1821
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001822
Guido van Rossum2a30b212003-02-18 22:41:24 +00001823# Test classes for reduce_ex
1824
1825class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001826 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001827 _reduce_called = 0
1828 def __reduce__(self):
1829 self._reduce_called = 1
1830 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001831
1832class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001833 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001834 _proto = None
1835 def __reduce_ex__(self, proto):
1836 self._proto = proto
1837 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001838
1839class REX_three(object):
1840 _proto = None
1841 def __reduce_ex__(self, proto):
1842 self._proto = proto
1843 return REX_two, ()
1844 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001845 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001846
Guido van Rossumd8faa362007-04-27 19:54:29 +00001847class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001848 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001849 _proto = None
1850 def __reduce_ex__(self, proto):
1851 self._proto = proto
1852 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001853
1854class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001855 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001856 _reduce_called = 0
1857 def __reduce__(self):
1858 self._reduce_called = 1
1859 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001860
1861class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001862 """This class is used to check the 4th argument (list iterator) of
1863 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001864 """
1865 def __init__(self, items=None):
1866 self.items = items if items is not None else []
1867 def __eq__(self, other):
1868 return type(self) is type(other) and self.items == self.items
1869 def append(self, item):
1870 self.items.append(item)
1871 def __reduce__(self):
1872 return type(self), (), None, iter(self.items), None
1873
1874class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001875 """This class is used to check the 5th argument (dict iterator) of
1876 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001877 """
1878 def __init__(self, table=None):
1879 self.table = table if table is not None else {}
1880 def __eq__(self, other):
1881 return type(self) is type(other) and self.table == self.table
1882 def __setitem__(self, key, value):
1883 self.table[key] = value
1884 def __reduce__(self):
1885 return type(self), (), None, None, iter(self.table.items())
1886
Guido van Rossumd8faa362007-04-27 19:54:29 +00001887
Guido van Rossum2a30b212003-02-18 22:41:24 +00001888# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001889
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001890class MyInt(int):
1891 sample = 1
1892
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001893class MyFloat(float):
1894 sample = 1.0
1895
1896class MyComplex(complex):
1897 sample = 1.0 + 0.0j
1898
1899class MyStr(str):
1900 sample = "hello"
1901
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001902class MyUnicode(str):
1903 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001904
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001905class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001906 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001907
1908class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001909 sample = [1, 2, 3]
1910
1911class MyDict(dict):
1912 sample = {"a": 1, "b": 2}
1913
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001914class MySet(set):
1915 sample = {"a", "b"}
1916
1917class MyFrozenSet(frozenset):
1918 sample = frozenset({"a", "b"})
1919
Mark Dickinson5c2db372009-12-05 20:28:34 +00001920myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001921 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001922 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001923 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001924
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001925
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001926class SlotList(MyList):
1927 __slots__ = ["foo"]
1928
Tim Peterse9ef2032003-02-13 18:42:00 +00001929class SimpleNewObj(object):
1930 def __init__(self, a, b, c):
1931 # raise an error, to make sure this isn't called
1932 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001933 def __eq__(self, other):
1934 return self.__dict__ == other.__dict__
Tim Peterse9ef2032003-02-13 18:42:00 +00001935
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001936class BadGetattr:
1937 def __getattr__(self, key):
1938 self.foo
1939
Collin Winter771d8342009-04-16 03:18:06 +00001940
Jeremy Hylton66426532001-10-15 21:38:56 +00001941class AbstractPickleModuleTests(unittest.TestCase):
1942
1943 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001944 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001945 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001946 try:
1947 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001948 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001949 finally:
1950 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001951
1952 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001953 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001954 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001955 try:
1956 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001957 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001958 finally:
1959 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001960
Collin Winter771d8342009-04-16 03:18:06 +00001961 def test_load_from_and_dump_to_file(self):
1962 stream = io.BytesIO()
1963 data = [123, {}, 124]
1964 pickle.dump(data, stream)
1965 stream.seek(0)
1966 unpickled = pickle.load(stream)
1967 self.assertEqual(unpickled, data)
1968
Tim Petersc0c93702003-02-13 19:30:57 +00001969 def test_highest_protocol(self):
1970 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001971 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00001972
Martin v. Löwis544f1192004-07-27 05:22:33 +00001973 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001974 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001975 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001976 pickle.dump(123, f, -1)
1977 pickle.dump(123, file=f, protocol=-1)
1978 pickle.dumps(123, -1)
1979 pickle.dumps(123, protocol=-1)
1980 pickle.Pickler(f, -1)
1981 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001982
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001983 def test_bad_init(self):
1984 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001985 # Override initialization without calling __init__() of the superclass.
1986 class BadPickler(pickle.Pickler):
1987 def __init__(self): pass
1988
1989 class BadUnpickler(pickle.Unpickler):
1990 def __init__(self): pass
1991
1992 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1993 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1994
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001995 def test_bad_input(self):
1996 # Test issue4298
1997 s = bytes([0x58, 0, 0, 0, 0x54])
1998 self.assertRaises(EOFError, pickle.loads, s)
1999
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002000
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002001class AbstractPersistentPicklerTests(unittest.TestCase):
2002
2003 # This class defines persistent_id() and persistent_load()
2004 # functions that should be used by the pickler. All even integers
2005 # are pickled using persistent ids.
2006
2007 def persistent_id(self, object):
2008 if isinstance(object, int) and object % 2 == 0:
2009 self.id_count += 1
2010 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002011 elif object == "test_false_value":
2012 self.false_count += 1
2013 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002014 else:
2015 return None
2016
2017 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002018 if not oid:
2019 self.load_false_count += 1
2020 return "test_false_value"
2021 else:
2022 self.load_count += 1
2023 object = int(oid)
2024 assert object % 2 == 0
2025 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002026
2027 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002028 L = list(range(10)) + ["test_false_value"]
2029 for proto in protocols:
2030 self.id_count = 0
2031 self.false_count = 0
2032 self.load_false_count = 0
2033 self.load_count = 0
2034 self.assertEqual(self.loads(self.dumps(L, proto)), L)
2035 self.assertEqual(self.id_count, 5)
2036 self.assertEqual(self.false_count, 1)
2037 self.assertEqual(self.load_count, 5)
2038 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00002039
Collin Winter771d8342009-04-16 03:18:06 +00002040
2041class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
2042
2043 pickler_class = None
2044 unpickler_class = None
2045
2046 def setUp(self):
2047 assert self.pickler_class
2048 assert self.unpickler_class
2049
2050 def test_clear_pickler_memo(self):
2051 # To test whether clear_memo() has any effect, we pickle an object,
2052 # then pickle it again without clearing the memo; the two serialized
2053 # forms should be different. If we clear_memo() and then pickle the
2054 # object again, the third serialized form should be identical to the
2055 # first one we obtained.
2056 data = ["abcdefg", "abcdefg", 44]
2057 f = io.BytesIO()
2058 pickler = self.pickler_class(f)
2059
2060 pickler.dump(data)
2061 first_pickled = f.getvalue()
2062
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002063 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00002064 f.seek(0)
2065 f.truncate()
2066
2067 pickler.dump(data)
2068 second_pickled = f.getvalue()
2069
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002070 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00002071 pickler.clear_memo()
2072 f.seek(0)
2073 f.truncate()
2074
2075 pickler.dump(data)
2076 third_pickled = f.getvalue()
2077
2078 self.assertNotEqual(first_pickled, second_pickled)
2079 self.assertEqual(first_pickled, third_pickled)
2080
2081 def test_priming_pickler_memo(self):
2082 # Verify that we can set the Pickler's memo attribute.
2083 data = ["abcdefg", "abcdefg", 44]
2084 f = io.BytesIO()
2085 pickler = self.pickler_class(f)
2086
2087 pickler.dump(data)
2088 first_pickled = f.getvalue()
2089
2090 f = io.BytesIO()
2091 primed = self.pickler_class(f)
2092 primed.memo = pickler.memo
2093
2094 primed.dump(data)
2095 primed_pickled = f.getvalue()
2096
2097 self.assertNotEqual(first_pickled, primed_pickled)
2098
2099 def test_priming_unpickler_memo(self):
2100 # Verify that we can set the Unpickler's memo attribute.
2101 data = ["abcdefg", "abcdefg", 44]
2102 f = io.BytesIO()
2103 pickler = self.pickler_class(f)
2104
2105 pickler.dump(data)
2106 first_pickled = f.getvalue()
2107
2108 f = io.BytesIO()
2109 primed = self.pickler_class(f)
2110 primed.memo = pickler.memo
2111
2112 primed.dump(data)
2113 primed_pickled = f.getvalue()
2114
2115 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2116 unpickled_data1 = unpickler.load()
2117
2118 self.assertEqual(unpickled_data1, data)
2119
2120 primed = self.unpickler_class(io.BytesIO(primed_pickled))
2121 primed.memo = unpickler.memo
2122 unpickled_data2 = primed.load()
2123
2124 primed.memo.clear()
2125
2126 self.assertEqual(unpickled_data2, data)
2127 self.assertTrue(unpickled_data2 is unpickled_data1)
2128
2129 def test_reusing_unpickler_objects(self):
2130 data1 = ["abcdefg", "abcdefg", 44]
2131 f = io.BytesIO()
2132 pickler = self.pickler_class(f)
2133 pickler.dump(data1)
2134 pickled1 = f.getvalue()
2135
2136 data2 = ["abcdefg", 44, 44]
2137 f = io.BytesIO()
2138 pickler = self.pickler_class(f)
2139 pickler.dump(data2)
2140 pickled2 = f.getvalue()
2141
2142 f = io.BytesIO()
2143 f.write(pickled1)
2144 f.seek(0)
2145 unpickler = self.unpickler_class(f)
2146 self.assertEqual(unpickler.load(), data1)
2147
2148 f.seek(0)
2149 f.truncate()
2150 f.write(pickled2)
2151 f.seek(0)
2152 self.assertEqual(unpickler.load(), data2)
2153
Antoine Pitrou04248a82010-10-12 20:51:21 +00002154 def _check_multiple_unpicklings(self, ioclass):
2155 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002156 with self.subTest(proto=proto):
2157 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2158 f = ioclass()
2159 pickler = self.pickler_class(f, protocol=proto)
2160 pickler.dump(data1)
2161 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002162
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002163 N = 5
2164 f = ioclass(pickled * N)
2165 unpickler = self.unpickler_class(f)
2166 for i in range(N):
2167 if f.seekable():
2168 pos = f.tell()
2169 self.assertEqual(unpickler.load(), data1)
2170 if f.seekable():
2171 self.assertEqual(f.tell(), pos + len(pickled))
2172 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002173
2174 def test_multiple_unpicklings_seekable(self):
2175 self._check_multiple_unpicklings(io.BytesIO)
2176
2177 def test_multiple_unpicklings_unseekable(self):
2178 self._check_multiple_unpicklings(UnseekableIO)
2179
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002180 def test_unpickling_buffering_readline(self):
2181 # Issue #12687: the unpickler's buffering logic could fail with
2182 # text mode opcodes.
2183 data = list(range(10))
2184 for proto in protocols:
2185 for buf_size in range(1, 11):
2186 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2187 pickler = self.pickler_class(f, protocol=proto)
2188 pickler.dump(data)
2189 f.seek(0)
2190 unpickler = self.unpickler_class(f)
2191 self.assertEqual(unpickler.load(), data)
2192
Collin Winter771d8342009-04-16 03:18:06 +00002193
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002194# Tests for dispatch_table attribute
2195
2196REDUCE_A = 'reduce_A'
2197
2198class AAA(object):
2199 def __reduce__(self):
2200 return str, (REDUCE_A,)
2201
2202class BBB(object):
2203 pass
2204
2205class AbstractDispatchTableTests(unittest.TestCase):
2206
2207 def test_default_dispatch_table(self):
2208 # No dispatch_table attribute by default
2209 f = io.BytesIO()
2210 p = self.pickler_class(f, 0)
2211 with self.assertRaises(AttributeError):
2212 p.dispatch_table
2213 self.assertFalse(hasattr(p, 'dispatch_table'))
2214
2215 def test_class_dispatch_table(self):
2216 # A dispatch_table attribute can be specified class-wide
2217 dt = self.get_dispatch_table()
2218
2219 class MyPickler(self.pickler_class):
2220 dispatch_table = dt
2221
2222 def dumps(obj, protocol=None):
2223 f = io.BytesIO()
2224 p = MyPickler(f, protocol)
2225 self.assertEqual(p.dispatch_table, dt)
2226 p.dump(obj)
2227 return f.getvalue()
2228
2229 self._test_dispatch_table(dumps, dt)
2230
2231 def test_instance_dispatch_table(self):
2232 # A dispatch_table attribute can also be specified instance-wide
2233 dt = self.get_dispatch_table()
2234
2235 def dumps(obj, protocol=None):
2236 f = io.BytesIO()
2237 p = self.pickler_class(f, protocol)
2238 p.dispatch_table = dt
2239 self.assertEqual(p.dispatch_table, dt)
2240 p.dump(obj)
2241 return f.getvalue()
2242
2243 self._test_dispatch_table(dumps, dt)
2244
2245 def _test_dispatch_table(self, dumps, dispatch_table):
2246 def custom_load_dump(obj):
2247 return pickle.loads(dumps(obj, 0))
2248
2249 def default_load_dump(obj):
2250 return pickle.loads(pickle.dumps(obj, 0))
2251
2252 # pickling complex numbers using protocol 0 relies on copyreg
2253 # so check pickling a complex number still works
2254 z = 1 + 2j
2255 self.assertEqual(custom_load_dump(z), z)
2256 self.assertEqual(default_load_dump(z), z)
2257
2258 # modify pickling of complex
2259 REDUCE_1 = 'reduce_1'
2260 def reduce_1(obj):
2261 return str, (REDUCE_1,)
2262 dispatch_table[complex] = reduce_1
2263 self.assertEqual(custom_load_dump(z), REDUCE_1)
2264 self.assertEqual(default_load_dump(z), z)
2265
2266 # check picklability of AAA and BBB
2267 a = AAA()
2268 b = BBB()
2269 self.assertEqual(custom_load_dump(a), REDUCE_A)
2270 self.assertIsInstance(custom_load_dump(b), BBB)
2271 self.assertEqual(default_load_dump(a), REDUCE_A)
2272 self.assertIsInstance(default_load_dump(b), BBB)
2273
2274 # modify pickling of BBB
2275 dispatch_table[BBB] = reduce_1
2276 self.assertEqual(custom_load_dump(a), REDUCE_A)
2277 self.assertEqual(custom_load_dump(b), REDUCE_1)
2278 self.assertEqual(default_load_dump(a), REDUCE_A)
2279 self.assertIsInstance(default_load_dump(b), BBB)
2280
2281 # revert pickling of BBB and modify pickling of AAA
2282 REDUCE_2 = 'reduce_2'
2283 def reduce_2(obj):
2284 return str, (REDUCE_2,)
2285 dispatch_table[AAA] = reduce_2
2286 del dispatch_table[BBB]
2287 self.assertEqual(custom_load_dump(a), REDUCE_2)
2288 self.assertIsInstance(custom_load_dump(b), BBB)
2289 self.assertEqual(default_load_dump(a), REDUCE_A)
2290 self.assertIsInstance(default_load_dump(b), BBB)
2291
2292
Guido van Rossum98297ee2007-11-06 21:34:58 +00002293if __name__ == "__main__":
2294 # Print some stuff that can be used to rewrite DATA{0,1,2}
2295 from pickletools import dis
2296 x = create_data()
2297 for i in range(3):
2298 p = pickle.dumps(x, i)
2299 print("DATA{0} = (".format(i))
2300 for j in range(0, len(p), 20):
2301 b = bytes(p[j:j+20])
2302 print(" {0!r}".format(b))
2303 print(")")
2304 print()
2305 print("# Disassembly of DATA{0}".format(i))
2306 print("DATA{0}_DIS = \"\"\"\\".format(i))
2307 dis(p)
2308 print("\"\"\"")
2309 print()