blob: 444a1036085939e6fe96477ec26f19ba57444614 [file] [log] [blame]
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001import copyreg
Collin Winter771d8342009-04-16 03:18:06 +00002import io
Tim Peters4190fb82003-02-02 16:09:05 +00003import pickle
Tim Peters31f119e2003-02-03 16:20:13 +00004import pickletools
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01005import random
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08006import struct
Antoine Pitrou82be19f2011-08-29 23:09:33 +02007import sys
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01008import unittest
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01009import weakref
Antoine Pitroud9dfaa92009-06-04 20:32:06 +000010from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +000011
Antoine Pitrou82be19f2011-08-29 23:09:33 +020012from test.support import (
Antoine Pitrouee763e22011-08-29 23:14:53 +020013 TestFailed, TESTFN, run_with_locale, no_tracing,
Antoine Pitrou94190bb2011-10-04 10:22:36 +020014 _2G, _4G, bigmemtest,
Antoine Pitrou82be19f2011-08-29 23:09:33 +020015 )
Tim Peterse089c682001-04-10 03:41:41 +000016
Guido van Rossum98297ee2007-11-06 21:34:58 +000017from pickle import bytes_types
18
Tim Petersee1a53c2003-02-02 02:57:53 +000019# Tests that try a number of pickle protocols should have a
20# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000021# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000022protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000023
Tim Peters22e71712003-02-03 22:27:38 +000024
25# Return True if opcode code appears in the pickle, else False.
26def opcode_in_pickle(code, pickle):
27 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000028 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000029 return True
30 return False
31
Tim Peters8d2613a2003-02-11 16:40:16 +000032# Return the number of times opcode code appears in pickle.
33def count_opcode(code, pickle):
34 n = 0
35 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000036 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000037 n += 1
38 return n
39
Antoine Pitrou04248a82010-10-12 20:51:21 +000040
41class UnseekableIO(io.BytesIO):
42 def peek(self, *args):
43 raise NotImplementedError
44
45 def seekable(self):
46 return False
47
48 def seek(self, *args):
49 raise io.UnsupportedOperation
50
51 def tell(self):
52 raise io.UnsupportedOperation
53
54
Tim Peters3e667d52003-02-04 21:47:44 +000055# We can't very well test the extension registry without putting known stuff
56# in it, but we have to be careful to restore its original state. Code
57# should do this:
58#
59# e = ExtensionSaver(extension_code)
60# try:
61# fiddle w/ the extension registry's stuff for extension_code
62# finally:
63# e.restore()
64
65class ExtensionSaver:
66 # Remember current registration for code (if any), and remove it (if
67 # there is one).
68 def __init__(self, code):
69 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000070 if code in copyreg._inverted_registry:
71 self.pair = copyreg._inverted_registry[code]
72 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000073 else:
74 self.pair = None
75
76 # Restore previous registration for code.
77 def restore(self):
78 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000079 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000080 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000081 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000082 pair = self.pair
83 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000084 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000085
Jeremy Hylton66426532001-10-15 21:38:56 +000086class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000087 def __eq__(self, other):
88 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000089
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000090class D(C):
91 def __init__(self, arg):
92 pass
93
94class E(C):
95 def __getinitargs__(self):
96 return ()
97
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +010098class H(object):
99 pass
100
Jeremy Hylton66426532001-10-15 21:38:56 +0000101import __main__
102__main__.C = C
103C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000104__main__.D = D
105D.__module__ = "__main__"
106__main__.E = E
107E.__module__ = "__main__"
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100108__main__.H = H
109H.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000110
111class myint(int):
112 def __init__(self, x):
113 self.str = str(x)
114
115class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000116
Jeremy Hylton66426532001-10-15 21:38:56 +0000117 def __init__(self, a, b):
118 self.a = a
119 self.b = b
120
121 def __getinitargs__(self):
122 return self.a, self.b
123
Guido van Rossum04a86612001-12-19 16:58:54 +0000124class metaclass(type):
125 pass
126
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000127class use_metaclass(object, metaclass=metaclass):
128 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000129
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200130class pickling_metaclass(type):
131 def __eq__(self, other):
132 return (type(self) == type(other) and
133 self.reduce_args == other.reduce_args)
134
135 def __reduce__(self):
136 return (create_dynamic_class, self.reduce_args)
137
138def create_dynamic_class(name, bases):
139 result = pickling_metaclass(name, bases, dict())
140 result.reduce_args = (name, bases)
141 return result
142
Tim Peters70b02d72003-02-02 17:26:40 +0000143# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
144# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000145
Guido van Rossum98297ee2007-11-06 21:34:58 +0000146DATA0 = (
Mark Dickinson8dd05142009-01-20 20:43:58 +0000147 b'(lp0\nL0L\naL1L\naF2.0\nac'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000148 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000149 b'p1\n(F3.0\nF0.0\ntp2\nRp'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000150 b'3\naL1L\naL-1L\naL255L\naL-'
151 b'255L\naL-256L\naL65535L\na'
152 b'L-65535L\naL-65536L\naL2'
153 b'147483647L\naL-2147483'
154 b'647L\naL-2147483648L\na('
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000155 b'Vabc\np4\ng4\nccopyreg'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000156 b'\n_reconstructor\np5\n('
Georg Brandl1a3284e2007-12-02 09:40:06 +0000157 b'c__main__\nC\np6\ncbu'
158 b'iltins\nobject\np7\nNt'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000159 b'p8\nRp9\n(dp10\nVfoo\np1'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000160 b'1\nL1L\nsVbar\np12\nL2L\nsb'
161 b'g9\ntp13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000162)
Tim Peterse9358162001-01-22 22:05:20 +0000163
Guido van Rossum98297ee2007-11-06 21:34:58 +0000164# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000165DATA0_DIS = """\
166 0: ( MARK
167 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000168 2: p PUT 0
169 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000170 9: a APPEND
171 10: L LONG 1
172 14: a APPEND
173 15: F FLOAT 2.0
174 20: a APPEND
175 21: c GLOBAL 'builtins complex'
176 39: p PUT 1
177 42: ( MARK
178 43: F FLOAT 3.0
179 48: F FLOAT 0.0
180 53: t TUPLE (MARK at 42)
181 54: p PUT 2
182 57: R REDUCE
183 58: p PUT 3
184 61: a APPEND
185 62: L LONG 1
186 66: a APPEND
187 67: L LONG -1
188 72: a APPEND
189 73: L LONG 255
190 79: a APPEND
191 80: L LONG -255
192 87: a APPEND
193 88: L LONG -256
194 95: a APPEND
195 96: L LONG 65535
196 104: a APPEND
197 105: L LONG -65535
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000198 114: a APPEND
Mark Dickinson8dd05142009-01-20 20:43:58 +0000199 115: L LONG -65536
200 124: a APPEND
201 125: L LONG 2147483647
202 138: a APPEND
203 139: L LONG -2147483647
204 153: a APPEND
205 154: L LONG -2147483648
206 168: a APPEND
207 169: ( MARK
208 170: V UNICODE 'abc'
209 175: p PUT 4
210 178: g GET 4
211 181: c GLOBAL 'copyreg _reconstructor'
212 205: p PUT 5
213 208: ( MARK
214 209: c GLOBAL '__main__ C'
215 221: p PUT 6
216 224: c GLOBAL 'builtins object'
217 241: p PUT 7
218 244: N NONE
219 245: t TUPLE (MARK at 208)
220 246: p PUT 8
221 249: R REDUCE
222 250: p PUT 9
223 253: ( MARK
224 254: d DICT (MARK at 253)
225 255: p PUT 10
226 259: V UNICODE 'foo'
227 264: p PUT 11
228 268: L LONG 1
229 272: s SETITEM
230 273: V UNICODE 'bar'
231 278: p PUT 12
232 282: L LONG 2
233 286: s SETITEM
234 287: b BUILD
235 288: g GET 9
236 291: t TUPLE (MARK at 169)
237 292: p PUT 13
238 296: a APPEND
239 297: g GET 13
240 301: a APPEND
241 302: L LONG 5
242 306: a APPEND
243 307: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000244highest protocol among opcodes = 0
245"""
246
Guido van Rossum98297ee2007-11-06 21:34:58 +0000247DATA1 = (
Georg Brandl1a3284e2007-12-02 09:40:06 +0000248 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
249 b'builtins\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000250 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
251 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
252 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
253 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000254 b'cq\x04h\x04ccopyreg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000255 b'nstructor\nq\x05(c__main'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000256 b'__\nC\nq\x06cbuiltins\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000257 b'object\nq\x07Ntq\x08Rq\t}q\n('
258 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
259 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
260)
Tim Peters70b02d72003-02-02 17:26:40 +0000261
Guido van Rossum98297ee2007-11-06 21:34:58 +0000262# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000263DATA1_DIS = """\
264 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000265 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000266 3: ( MARK
267 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000268 6: K BININT1 1
269 8: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000270 17: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000271 35: q BINPUT 1
272 37: ( MARK
273 38: G BINFLOAT 3.0
274 47: G BINFLOAT 0.0
275 56: t TUPLE (MARK at 37)
276 57: q BINPUT 2
277 59: R REDUCE
278 60: q BINPUT 3
279 62: K BININT1 1
280 64: J BININT -1
281 69: K BININT1 255
282 71: J BININT -255
283 76: J BININT -256
284 81: M BININT2 65535
285 84: J BININT -65535
286 89: J BININT -65536
287 94: J BININT 2147483647
288 99: J BININT -2147483647
289 104: J BININT -2147483648
290 109: ( MARK
291 110: X BINUNICODE 'abc'
292 118: q BINPUT 4
293 120: h BINGET 4
294 122: c GLOBAL 'copyreg _reconstructor'
295 146: q BINPUT 5
296 148: ( MARK
297 149: c GLOBAL '__main__ C'
298 161: q BINPUT 6
299 163: c GLOBAL 'builtins object'
300 180: q BINPUT 7
301 182: N NONE
302 183: t TUPLE (MARK at 148)
303 184: q BINPUT 8
304 186: R REDUCE
305 187: q BINPUT 9
306 189: } EMPTY_DICT
307 190: q BINPUT 10
308 192: ( MARK
309 193: X BINUNICODE 'foo'
310 201: q BINPUT 11
311 203: K BININT1 1
312 205: X BINUNICODE 'bar'
313 213: q BINPUT 12
314 215: K BININT1 2
315 217: u SETITEMS (MARK at 192)
316 218: b BUILD
317 219: h BINGET 9
318 221: t TUPLE (MARK at 109)
319 222: q BINPUT 13
320 224: h BINGET 13
321 226: K BININT1 5
322 228: e APPENDS (MARK at 3)
323 229: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000324highest protocol among opcodes = 1
325"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000326
Guido van Rossum98297ee2007-11-06 21:34:58 +0000327DATA2 = (
328 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000329 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000330 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
331 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
332 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
333 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
334 b'bcq\x04h\x04c__main__\nC\nq\x05'
335 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
336 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
337 b'\nK\x05e.'
338)
Tim Petersfc273752003-03-02 04:54:24 +0000339
Guido van Rossum98297ee2007-11-06 21:34:58 +0000340# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000341DATA2_DIS = """\
342 0: \x80 PROTO 2
343 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000344 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000345 5: ( MARK
346 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000347 8: K BININT1 1
348 10: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000349 19: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000350 37: q BINPUT 1
351 39: G BINFLOAT 3.0
352 48: G BINFLOAT 0.0
353 57: \x86 TUPLE2
354 58: q BINPUT 2
355 60: R REDUCE
356 61: q BINPUT 3
357 63: K BININT1 1
358 65: J BININT -1
359 70: K BININT1 255
360 72: J BININT -255
361 77: J BININT -256
362 82: M BININT2 65535
363 85: J BININT -65535
364 90: J BININT -65536
365 95: J BININT 2147483647
366 100: J BININT -2147483647
367 105: J BININT -2147483648
368 110: ( MARK
369 111: X BINUNICODE 'abc'
370 119: q BINPUT 4
371 121: h BINGET 4
372 123: c GLOBAL '__main__ C'
373 135: q BINPUT 5
374 137: ) EMPTY_TUPLE
375 138: \x81 NEWOBJ
376 139: q BINPUT 6
377 141: } EMPTY_DICT
378 142: q BINPUT 7
379 144: ( MARK
380 145: X BINUNICODE 'foo'
381 153: q BINPUT 8
382 155: K BININT1 1
383 157: X BINUNICODE 'bar'
384 165: q BINPUT 9
385 167: K BININT1 2
386 169: u SETITEMS (MARK at 144)
387 170: b BUILD
388 171: h BINGET 6
389 173: t TUPLE (MARK at 110)
390 174: q BINPUT 10
391 176: h BINGET 10
392 178: K BININT1 5
393 180: e APPENDS (MARK at 5)
394 181: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000395highest protocol among opcodes = 2
396"""
397
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000398# set([1,2]) pickled from 2.x with protocol 2
399DATA3 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
400
401# xrange(5) pickled from 2.x with protocol 2
402DATA4 = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
403
404# a SimpleCookie() object pickled from 2.x with protocol 2
405DATA5 = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
406 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
407 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
408 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
409 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
410 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
411
412# set([3]) pickled from 2.x with protocol 2
413DATA6 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
414
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100415python2_exceptions_without_args = (
416 ArithmeticError,
417 AssertionError,
418 AttributeError,
419 BaseException,
420 BufferError,
421 BytesWarning,
422 DeprecationWarning,
423 EOFError,
424 EnvironmentError,
425 Exception,
426 FloatingPointError,
427 FutureWarning,
428 GeneratorExit,
429 IOError,
430 ImportError,
431 ImportWarning,
432 IndentationError,
433 IndexError,
434 KeyError,
435 KeyboardInterrupt,
436 LookupError,
437 MemoryError,
438 NameError,
439 NotImplementedError,
440 OSError,
441 OverflowError,
442 PendingDeprecationWarning,
443 ReferenceError,
444 RuntimeError,
445 RuntimeWarning,
446 # StandardError is gone in Python 3, we map it to Exception
447 StopIteration,
448 SyntaxError,
449 SyntaxWarning,
450 SystemError,
451 SystemExit,
452 TabError,
453 TypeError,
454 UnboundLocalError,
455 UnicodeError,
456 UnicodeWarning,
457 UserWarning,
458 ValueError,
459 Warning,
460 ZeroDivisionError,
461)
462
463exception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.'
464
465# Exception objects without arguments pickled from 2.x with protocol 2
466DATA7 = {
467 exception :
468 exception_pickle.replace(b'?', exception.__name__.encode("ascii"))
469 for exception in python2_exceptions_without_args
470}
471
472# StandardError is mapped to Exception, test that separately
473DATA8 = exception_pickle.replace(b'?', b'StandardError')
474
475# UnicodeEncodeError object pickled from 2.x with protocol 2
476DATA9 = (b'\x80\x02cexceptions\nUnicodeEncodeError\n'
477 b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01'
478 b'U\x03badq\x03tq\x04Rq\x05.')
479
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000480
Jeremy Hylton66426532001-10-15 21:38:56 +0000481def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000482 c = C()
483 c.foo = 1
484 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000485 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000486 # Append some integer test cases at cPickle.c's internal size
487 # cutoffs.
488 uint1max = 0xff
489 uint2max = 0xffff
490 int4max = 0x7fffffff
491 x.extend([1, -1,
492 uint1max, -uint1max, -uint1max-1,
493 uint2max, -uint2max, -uint2max-1,
494 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000495 y = ('abc', 'abc', c, c)
496 x.append(y)
497 x.append(y)
498 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000499 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000500
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100501
Jeremy Hylton66426532001-10-15 21:38:56 +0000502class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000503 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000504
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +0100505 optimized = False
506
Jeremy Hylton66426532001-10-15 21:38:56 +0000507 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000508
Jeremy Hylton66426532001-10-15 21:38:56 +0000509 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000510 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000511
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100512 def assert_is_copy(self, obj, objcopy, msg=None):
513 """Utility method to verify if two objects are copies of each others.
514 """
515 if msg is None:
516 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
517 self.assertEqual(obj, objcopy, msg=msg)
518 self.assertIs(type(obj), type(objcopy), msg=msg)
519 if hasattr(obj, '__dict__'):
520 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
521 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
522 if hasattr(obj, '__slots__'):
523 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
524 for slot in obj.__slots__:
525 self.assertEqual(
526 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
527 self.assertEqual(getattr(obj, slot, None),
528 getattr(objcopy, slot, None), msg=msg)
529
Jeremy Hylton66426532001-10-15 21:38:56 +0000530 def test_misc(self):
531 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000532 for proto in protocols:
533 x = myint(4)
534 s = self.dumps(x, proto)
535 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100536 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000537
Tim Peters70b02d72003-02-02 17:26:40 +0000538 x = (1, ())
539 s = self.dumps(x, proto)
540 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100541 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000542
Tim Peters70b02d72003-02-02 17:26:40 +0000543 x = initarg(1, x)
544 s = self.dumps(x, proto)
545 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100546 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000547
Jeremy Hylton66426532001-10-15 21:38:56 +0000548 # XXX test __reduce__ protocol?
549
Tim Peters70b02d72003-02-02 17:26:40 +0000550 def test_roundtrip_equality(self):
551 expected = self._testdata
552 for proto in protocols:
553 s = self.dumps(expected, proto)
554 got = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100555 self.assert_is_copy(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000556
Guido van Rossum98297ee2007-11-06 21:34:58 +0000557 def test_load_from_data0(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100558 self.assert_is_copy(self._testdata, self.loads(DATA0))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000559
560 def test_load_from_data1(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100561 self.assert_is_copy(self._testdata, self.loads(DATA1))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000562
563 def test_load_from_data2(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100564 self.assert_is_copy(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000565
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000566 def test_load_classic_instance(self):
567 # See issue5180. Test loading 2.x pickles that
568 # contain an instance of old style class.
569 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
570 xname = X.__name__.encode('ascii')
571 # Protocol 0 (text mode pickle):
572 """
573 0: ( MARK
574 1: i INST '__main__ X' (MARK at 0)
575 15: p PUT 0
576 18: ( MARK
577 19: d DICT (MARK at 18)
578 20: p PUT 1
579 23: b BUILD
580 24: . STOP
581 """
582 pickle0 = (b"(i__main__\n"
583 b"X\n"
584 b"p0\n"
585 b"(dp1\nb.").replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100586 self.assert_is_copy(X(*args), self.loads(pickle0))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000587
588 # Protocol 1 (binary mode pickle)
589 """
590 0: ( MARK
591 1: c GLOBAL '__main__ X'
592 15: q BINPUT 0
593 17: o OBJ (MARK at 0)
594 18: q BINPUT 1
595 20: } EMPTY_DICT
596 21: q BINPUT 2
597 23: b BUILD
598 24: . STOP
599 """
600 pickle1 = (b'(c__main__\n'
601 b'X\n'
602 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100603 self.assert_is_copy(X(*args), self.loads(pickle1))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000604
605 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
606 """
607 0: \x80 PROTO 2
608 2: ( MARK
609 3: c GLOBAL '__main__ X'
610 17: q BINPUT 0
611 19: o OBJ (MARK at 2)
612 20: q BINPUT 1
613 22: } EMPTY_DICT
614 23: q BINPUT 2
615 25: b BUILD
616 26: . STOP
617 """
618 pickle2 = (b'\x80\x02(c__main__\n'
619 b'X\n'
620 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100621 self.assert_is_copy(X(*args), self.loads(pickle2))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000622
Tim Peters70b02d72003-02-02 17:26:40 +0000623 # There are gratuitous differences between pickles produced by
624 # pickle and cPickle, largely because cPickle starts PUT indices at
625 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
626 # there's a comment with an exclamation point there whose meaning
627 # is a mystery. cPickle also suppresses PUT for objects with a refcount
628 # of 1.
629 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000630 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000631 from pickletools import dis
632
633 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
634 s = self.dumps(self._testdata, proto)
635 filelike = StringIO()
636 dis(s, out=filelike)
637 got = filelike.getvalue()
638 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000639
640 def test_recursive_list(self):
641 l = []
642 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000643 for proto in protocols:
644 s = self.dumps(l, proto)
645 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100646 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000647 self.assertEqual(len(x), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000648 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000649
Collin Winter8ca69de2009-05-26 16:53:41 +0000650 def test_recursive_tuple(self):
651 t = ([],)
652 t[0].append(t)
653 for proto in protocols:
654 s = self.dumps(t, proto)
655 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100656 self.assertIsInstance(x, tuple)
Collin Winter8ca69de2009-05-26 16:53:41 +0000657 self.assertEqual(len(x), 1)
658 self.assertEqual(len(x[0]), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000659 self.assertTrue(x is x[0][0])
Collin Winter8ca69de2009-05-26 16:53:41 +0000660
Jeremy Hylton66426532001-10-15 21:38:56 +0000661 def test_recursive_dict(self):
662 d = {}
663 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000664 for proto in protocols:
665 s = self.dumps(d, proto)
666 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100667 self.assertIsInstance(x, dict)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000668 self.assertEqual(list(x.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000669 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000670
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100671 def test_recursive_set(self):
672 h = H()
673 y = set({h})
674 h.attr = y
675 for proto in protocols:
676 s = self.dumps(y, proto)
677 x = self.loads(s)
678 self.assertIsInstance(x, set)
679 self.assertIs(list(x)[0].attr, x)
680 self.assertEqual(len(x), 1)
681
682 def test_recursive_frozenset(self):
683 h = H()
684 y = frozenset({h})
685 h.attr = y
686 for proto in protocols:
687 s = self.dumps(y, proto)
688 x = self.loads(s)
689 self.assertIsInstance(x, frozenset)
690 self.assertIs(list(x)[0].attr, x)
691 self.assertEqual(len(x), 1)
692
Jeremy Hylton66426532001-10-15 21:38:56 +0000693 def test_recursive_inst(self):
694 i = C()
695 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000696 for proto in protocols:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200697 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +0000698 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100699 self.assertIsInstance(x, C)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000700 self.assertEqual(dir(x), dir(i))
Ezio Melottiaaef3442013-03-04 15:17:56 +0200701 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000702
703 def test_recursive_multi(self):
704 l = []
705 d = {1:l}
706 i = C()
707 i.attr = d
708 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000709 for proto in protocols:
710 s = self.dumps(l, proto)
711 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100712 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000713 self.assertEqual(len(x), 1)
714 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000715 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000716 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000717
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000718 def test_get(self):
719 self.assertRaises(KeyError, self.loads, b'g0\np0')
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100720 self.assert_is_copy([(100,), (100,)],
721 self.loads(b'((Kdtp0\nh\x00l.))'))
Jeremy Hylton66426532001-10-15 21:38:56 +0000722
Walter Dörwald9b775532007-06-08 14:30:53 +0000723 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000724 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +0000725 '<\\>', '<\\\U00012345>',
726 # surrogates
727 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000728 for proto in protocols:
729 for u in endcases:
730 p = self.dumps(u, proto)
731 u2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100732 self.assert_is_copy(u, u2)
Tim Peterse089c682001-04-10 03:41:41 +0000733
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000734 def test_unicode_high_plane(self):
735 t = '\U00012345'
736 for proto in protocols:
737 p = self.dumps(t, proto)
738 t2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100739 self.assert_is_copy(t, t2)
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000740
Guido van Rossumf4169812008-03-17 22:56:06 +0000741 def test_bytes(self):
742 for proto in protocols:
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500743 for s in b'', b'xyz', b'xyz'*100:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200744 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100745 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500746 for s in [bytes([i]) for i in range(256)]:
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, 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))
Guido van Rossumf4169812008-03-17 22:56:06 +0000752
Jeremy Hylton66426532001-10-15 21:38:56 +0000753 def test_ints(self):
754 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000755 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000756 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000757 while n:
758 for expected in (-n, n):
759 s = self.dumps(expected, proto)
760 n2 = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100761 self.assert_is_copy(expected, n2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000762 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000763
Jeremy Hylton66426532001-10-15 21:38:56 +0000764 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000765 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000766 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000767 got = self.loads(data)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100768 self.assert_is_copy(maxint64, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000769
770 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000771 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000772 self.assertRaises(ValueError, self.loads, data)
773
Tim Petersee1a53c2003-02-02 02:57:53 +0000774 def test_long(self):
775 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000776 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000777 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000778 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000779 for npos in nbase-1, nbase, nbase+1:
780 for n in npos, -npos:
781 pickle = self.dumps(n, proto)
782 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100783 self.assert_is_copy(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +0000784 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
785 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000786 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000787 nbase += nbase << 1000000
788 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000789 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000790 got = self.loads(p)
Antoine Pitroud5df1942013-11-23 21:20:49 +0100791 # assert_is_copy is very expensive here as it precomputes
792 # a failure message by computing the repr() of n and got,
793 # we just do the check ourselves.
794 self.assertIs(type(got), int)
795 self.assertEqual(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +0000796
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000797 def test_float(self):
798 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
799 3.14, 263.44582062374053, 6.022e23, 1e30]
800 test_values = test_values + [-x for x in test_values]
801 for proto in protocols:
802 for value in test_values:
803 pickle = self.dumps(value, proto)
804 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100805 self.assert_is_copy(value, got)
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000806
Thomas Wouters477c8d52006-05-27 19:21:47 +0000807 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
808 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000809 # make sure that floats are formatted locale independent with proto 0
810 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000811
Jeremy Hylton66426532001-10-15 21:38:56 +0000812 def test_reduce(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +0100813 for proto in protocols:
814 inst = AAA()
815 dumped = self.dumps(inst, proto)
816 loaded = self.loads(dumped)
817 self.assertEqual(loaded, REDUCE_A)
Jeremy Hylton66426532001-10-15 21:38:56 +0000818
819 def test_getinitargs(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +0100820 for proto in protocols:
821 inst = initarg(1, 2)
822 dumped = self.dumps(inst, proto)
823 loaded = self.loads(dumped)
824 self.assert_is_copy(inst, loaded)
Jeremy Hylton66426532001-10-15 21:38:56 +0000825
Antoine Pitrou79035bd2012-06-26 23:04:48 +0200826 def test_pop_empty_stack(self):
827 # Test issue7455
828 s = b'0'
829 self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s)
830
Guido van Rossum04a86612001-12-19 16:58:54 +0000831 def test_metaclass(self):
832 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000833 for proto in protocols:
834 s = self.dumps(a, proto)
835 b = self.loads(s)
836 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000837
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200838 def test_dynamic_class(self):
839 a = create_dynamic_class("my_dynamic_class", (object,))
840 copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
841 for proto in protocols:
842 s = self.dumps(a, proto)
843 b = self.loads(s)
844 self.assertEqual(a, b)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100845 self.assertIs(type(a), type(b))
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200846
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000847 def test_structseq(self):
848 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000849 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000850
851 t = time.localtime()
852 for proto in protocols:
853 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000854 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100855 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000856 if hasattr(os, "stat"):
857 t = os.stat(os.curdir)
858 s = self.dumps(t, proto)
859 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100860 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000861 if hasattr(os, "statvfs"):
862 t = os.statvfs(os.curdir)
863 s = self.dumps(t, proto)
864 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100865 self.assert_is_copy(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000866
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100867 def test_ellipsis(self):
868 for proto in protocols:
869 s = self.dumps(..., proto)
870 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100871 self.assertIs(..., u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100872
873 def test_notimplemented(self):
874 for proto in protocols:
875 s = self.dumps(NotImplemented, proto)
876 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100877 self.assertIs(NotImplemented, u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100878
Alexandre Vassalotti19b6fa62013-11-30 16:06:39 -0800879 def test_singleton_types(self):
880 # Issue #6477: Test that types of built-in singletons can be pickled.
881 singletons = [None, ..., NotImplemented]
882 for singleton in singletons:
883 for proto in protocols:
884 s = self.dumps(type(singleton), proto)
885 u = self.loads(s)
886 self.assertIs(type(singleton), u)
887
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000888 # Tests for protocol 2
889
Tim Peters4190fb82003-02-02 16:09:05 +0000890 def test_proto(self):
Tim Peters4190fb82003-02-02 16:09:05 +0000891 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100892 pickled = self.dumps(None, proto)
Tim Peters4190fb82003-02-02 16:09:05 +0000893 if proto >= 2:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100894 proto_header = pickle.PROTO + bytes([proto])
895 self.assertTrue(pickled.startswith(proto_header))
896 else:
897 self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)
Tim Peters4190fb82003-02-02 16:09:05 +0000898
899 oob = protocols[-1] + 1 # a future protocol
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100900 build_none = pickle.NONE + pickle.STOP
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000901 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000902 try:
903 self.loads(badpickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100904 except ValueError as err:
905 self.assertIn("unsupported pickle protocol", str(err))
Tim Peters4190fb82003-02-02 16:09:05 +0000906 else:
907 self.fail("expected bad protocol number to raise ValueError")
908
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000909 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000910 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000911 for proto in protocols:
912 s = self.dumps(x, proto)
913 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100914 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000915 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000916
917 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000918 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000919 for proto in protocols:
920 s = self.dumps(x, proto)
921 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100922 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000923 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000924
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000925 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000926 # Map (proto, len(tuple)) to expected opcode.
927 expected_opcode = {(0, 0): pickle.TUPLE,
928 (0, 1): pickle.TUPLE,
929 (0, 2): pickle.TUPLE,
930 (0, 3): pickle.TUPLE,
931 (0, 4): pickle.TUPLE,
932
933 (1, 0): pickle.EMPTY_TUPLE,
934 (1, 1): pickle.TUPLE,
935 (1, 2): pickle.TUPLE,
936 (1, 3): pickle.TUPLE,
937 (1, 4): pickle.TUPLE,
938
939 (2, 0): pickle.EMPTY_TUPLE,
940 (2, 1): pickle.TUPLE1,
941 (2, 2): pickle.TUPLE2,
942 (2, 3): pickle.TUPLE3,
943 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000944
945 (3, 0): pickle.EMPTY_TUPLE,
946 (3, 1): pickle.TUPLE1,
947 (3, 2): pickle.TUPLE2,
948 (3, 3): pickle.TUPLE3,
949 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000950 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000951 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000952 b = (1,)
953 c = (1, 2)
954 d = (1, 2, 3)
955 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000956 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000957 for x in a, b, c, d, e:
958 s = self.dumps(x, proto)
959 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100960 self.assert_is_copy(x, y)
961 expected = expected_opcode[min(proto, 3), len(x)]
962 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000963
Guido van Rossum7d97d312003-01-28 04:25:27 +0000964 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000965 # Map (proto, singleton) to expected opcode.
966 expected_opcode = {(0, None): pickle.NONE,
967 (1, None): pickle.NONE,
968 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000969 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000970
971 (0, True): pickle.INT,
972 (1, True): pickle.INT,
973 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000974 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000975
976 (0, False): pickle.INT,
977 (1, False): pickle.INT,
978 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000979 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000980 }
Tim Peters4190fb82003-02-02 16:09:05 +0000981 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000982 for x in None, False, True:
983 s = self.dumps(x, proto)
984 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000985 self.assertTrue(x is y, (proto, x, s, y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100986 expected = expected_opcode[min(proto, 3), x]
987 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters3c67d792003-02-02 17:59:11 +0000988
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000989 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000990 x = MyTuple([1, 2, 3])
991 x.foo = 42
992 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000993 for proto in protocols:
994 s = self.dumps(x, proto)
995 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100996 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000997
998 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000999 x = MyList([1, 2, 3])
1000 x.foo = 42
1001 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001002 for proto in protocols:
1003 s = self.dumps(x, proto)
1004 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001005 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001006
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001007 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001008 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001009 for C in myclasses:
1010 B = C.__base__
1011 x = C(C.sample)
1012 x.foo = 42
1013 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001014 y = self.loads(s)
1015 detail = (proto, C, B, x, y, type(y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001016 self.assert_is_copy(x, y) # XXX revisit
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001017 self.assertEqual(B(x), B(y), detail)
1018 self.assertEqual(x.__dict__, y.__dict__, detail)
1019
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01001020 def test_newobj_proxies(self):
1021 # NEWOBJ should use the __class__ rather than the raw type
1022 classes = myclasses[:]
1023 # Cannot create weakproxies to these classes
1024 for c in (MyInt, MyTuple):
1025 classes.remove(c)
1026 for proto in protocols:
1027 for C in classes:
1028 B = C.__base__
1029 x = C(C.sample)
1030 x.foo = 42
1031 p = weakref.proxy(x)
1032 s = self.dumps(p, proto)
1033 y = self.loads(s)
1034 self.assertEqual(type(y), type(x)) # rather than type(p)
1035 detail = (proto, C, B, x, y, type(y))
1036 self.assertEqual(B(x), B(y), detail)
1037 self.assertEqual(x.__dict__, y.__dict__, detail)
1038
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001039 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001040 # an object of that type. Check that the resulting pickle uses opcode
1041 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001042
Tim Peters22e71712003-02-03 22:27:38 +00001043 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001044 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001045 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001046 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001047 x = MyList([1, 2, 3])
1048 x.foo = 42
1049 x.bar = "hello"
1050
Tim Peters22e71712003-02-03 22:27:38 +00001051 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001052 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001053 self.assertIn(__name__.encode("utf-8"), s1)
1054 self.assertIn(b"MyList", s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001055 self.assertFalse(opcode_in_pickle(opcode, s1))
Tim Peters3e667d52003-02-04 21:47:44 +00001056
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001057 y = self.loads(s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001058 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001059
Tim Peters22e71712003-02-03 22:27:38 +00001060 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001061 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001062 self.assertNotIn(__name__.encode("utf-8"), s2)
1063 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001064 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +00001065
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001066 y = self.loads(s2)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001067 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001068 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001069 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001070
1071 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001072 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1073 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001074
1075 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001076 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1077 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1078 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001079
1080 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001081 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1082 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1083 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1084
Tim Peters8d2613a2003-02-11 16:40:16 +00001085 def test_list_chunking(self):
1086 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +00001087 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001088 for proto in protocols:
1089 s = self.dumps(x, proto)
1090 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001091 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001092 num_appends = count_opcode(pickle.APPENDS, s)
1093 self.assertEqual(num_appends, proto > 0)
1094
1095 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001096 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001097 for proto in protocols:
1098 s = self.dumps(x, proto)
1099 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001100 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001101 num_appends = count_opcode(pickle.APPENDS, s)
1102 if proto == 0:
1103 self.assertEqual(num_appends, 0)
1104 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001105 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001106
1107 def test_dict_chunking(self):
1108 n = 10 # too small to chunk
1109 x = dict.fromkeys(range(n))
1110 for proto in protocols:
1111 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +00001112 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00001113 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001114 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001115 num_setitems = count_opcode(pickle.SETITEMS, s)
1116 self.assertEqual(num_setitems, proto > 0)
1117
1118 n = 2500 # expect at least two chunks when proto > 0
1119 x = dict.fromkeys(range(n))
1120 for proto in protocols:
1121 s = self.dumps(x, proto)
1122 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001123 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001124 num_setitems = count_opcode(pickle.SETITEMS, s)
1125 if proto == 0:
1126 self.assertEqual(num_setitems, 0)
1127 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001128 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001129
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001130 def test_set_chunking(self):
1131 n = 10 # too small to chunk
1132 x = set(range(n))
1133 for proto in protocols:
1134 s = self.dumps(x, proto)
1135 y = self.loads(s)
1136 self.assert_is_copy(x, y)
1137 num_additems = count_opcode(pickle.ADDITEMS, s)
1138 if proto < 4:
1139 self.assertEqual(num_additems, 0)
1140 else:
1141 self.assertEqual(num_additems, 1)
1142
1143 n = 2500 # expect at least two chunks when proto >= 4
1144 x = set(range(n))
1145 for proto in protocols:
1146 s = self.dumps(x, proto)
1147 y = self.loads(s)
1148 self.assert_is_copy(x, y)
1149 num_additems = count_opcode(pickle.ADDITEMS, s)
1150 if proto < 4:
1151 self.assertEqual(num_additems, 0)
1152 else:
1153 self.assertGreaterEqual(num_additems, 2)
1154
Tim Peterse9ef2032003-02-13 18:42:00 +00001155 def test_simple_newobj(self):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001156 x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__
Tim Peterse9ef2032003-02-13 18:42:00 +00001157 x.abc = 666
1158 for proto in protocols:
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001159 with self.subTest(proto=proto):
1160 s = self.dumps(x, proto)
1161 if proto < 1:
1162 self.assertIn(b'\nL64206', s) # LONG
1163 else:
1164 self.assertIn(b'M\xce\xfa', s) # BININT2
1165 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1166 2 <= proto)
1167 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1168 y = self.loads(s) # will raise TypeError if __init__ called
1169 self.assert_is_copy(x, y)
1170
1171 def test_complex_newobj(self):
1172 x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__
1173 x.abc = 666
1174 for proto in protocols:
1175 with self.subTest(proto=proto):
1176 s = self.dumps(x, proto)
1177 if proto < 1:
1178 self.assertIn(b'\nL64206', s) # LONG
1179 elif proto < 2:
1180 self.assertIn(b'M\xce\xfa', s) # BININT2
1181 elif proto < 4:
1182 self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE
1183 else:
1184 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1185 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1186 2 <= proto)
1187 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
1188 y = self.loads(s) # will raise TypeError if __init__ called
1189 self.assert_is_copy(x, y)
1190
1191 def test_complex_newobj_ex(self):
1192 x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__
1193 x.abc = 666
1194 for proto in protocols:
1195 with self.subTest(proto=proto):
1196 if 2 <= proto < 4:
1197 self.assertRaises(ValueError, self.dumps, x, proto)
1198 continue
1199 s = self.dumps(x, proto)
1200 if proto < 1:
1201 self.assertIn(b'\nL64206', s) # LONG
1202 elif proto < 2:
1203 self.assertIn(b'M\xce\xfa', s) # BININT2
1204 else:
1205 assert proto >= 4
1206 self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE
1207 self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s))
1208 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1209 4 <= proto)
1210 y = self.loads(s) # will raise TypeError if __init__ called
1211 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001212
Tim Peters42f08ac2003-02-11 22:43:24 +00001213 def test_newobj_list_slots(self):
1214 x = SlotList([1, 2, 3])
1215 x.foo = 42
1216 x.bar = "hello"
1217 s = self.dumps(x, 2)
1218 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001219 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001220
Guido van Rossum2a30b212003-02-18 22:41:24 +00001221 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001222 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001223 x = REX_one()
1224 self.assertEqual(x._reduce_called, 0)
1225 s = self.dumps(x, proto)
1226 self.assertEqual(x._reduce_called, 1)
1227 y = self.loads(s)
1228 self.assertEqual(y._reduce_called, 0)
1229
1230 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001231 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001232 x = REX_two()
1233 self.assertEqual(x._proto, None)
1234 s = self.dumps(x, proto)
1235 self.assertEqual(x._proto, proto)
1236 y = self.loads(s)
1237 self.assertEqual(y._proto, None)
1238
1239 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001240 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001241 x = REX_three()
1242 self.assertEqual(x._proto, None)
1243 s = self.dumps(x, proto)
1244 self.assertEqual(x._proto, proto)
1245 y = self.loads(s)
1246 self.assertEqual(y._proto, None)
1247
Guido van Rossumd8faa362007-04-27 19:54:29 +00001248 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001249 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001250 x = REX_four()
1251 self.assertEqual(x._proto, None)
1252 s = self.dumps(x, proto)
1253 self.assertEqual(x._proto, proto)
1254 y = self.loads(s)
1255 self.assertEqual(y._proto, proto)
1256
1257 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001258 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001259 x = REX_five()
1260 self.assertEqual(x._reduce_called, 0)
1261 s = self.dumps(x, proto)
1262 self.assertEqual(x._reduce_called, 1)
1263 y = self.loads(s)
1264 self.assertEqual(y._reduce_called, 1)
1265
Brett Cannon31f59292011-02-21 19:29:56 +00001266 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001267 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001268 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001269 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001270 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001271 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001272
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001273 def test_reduce_bad_iterator(self):
1274 # Issue4176: crash when 4th and 5th items of __reduce__()
1275 # are not iterators
1276 class C(object):
1277 def __reduce__(self):
1278 # 4th item is not an iterator
1279 return list, (), None, [], None
1280 class D(object):
1281 def __reduce__(self):
1282 # 5th item is not an iterator
1283 return dict, (), None, None, []
1284
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001285 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001286 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001287 try:
1288 self.dumps(C(), proto)
1289 except (pickle.PickleError):
1290 pass
1291 try:
1292 self.dumps(D(), proto)
1293 except (pickle.PickleError):
1294 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001295
Collin Winter771d8342009-04-16 03:18:06 +00001296 def test_many_puts_and_gets(self):
1297 # Test that internal data structures correctly deal with lots of
1298 # puts/gets.
1299 keys = ("aaa" + str(i) for i in range(100))
1300 large_dict = dict((k, [4, 5, 6]) for k in keys)
1301 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1302
1303 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001304 with self.subTest(proto=proto):
1305 dumped = self.dumps(obj, proto)
1306 loaded = self.loads(dumped)
1307 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00001308
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001309 def test_attribute_name_interning(self):
1310 # Test that attribute names of pickled objects are interned when
1311 # unpickling.
1312 for proto in protocols:
1313 x = C()
1314 x.foo = 42
1315 x.bar = "hello"
1316 s = self.dumps(x, proto)
1317 y = self.loads(s)
1318 x_keys = sorted(x.__dict__)
1319 y_keys = sorted(y.__dict__)
1320 for x_key, y_key in zip(x_keys, y_keys):
1321 self.assertIs(x_key, y_key)
1322
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001323 def test_unpickle_from_2x(self):
1324 # Unpickle non-trivial data from Python 2.x.
1325 loaded = self.loads(DATA3)
1326 self.assertEqual(loaded, set([1, 2]))
1327 loaded = self.loads(DATA4)
1328 self.assertEqual(type(loaded), type(range(0)))
1329 self.assertEqual(list(loaded), list(range(5)))
1330 loaded = self.loads(DATA5)
1331 self.assertEqual(type(loaded), SimpleCookie)
1332 self.assertEqual(list(loaded.keys()), ["key"])
Serhiy Storchaka8cf7c1c2014-11-02 22:18:25 +02001333 self.assertEqual(loaded["key"].value, "value")
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001334
Walter Doerwald9d1dbca2013-12-02 11:41:01 +01001335 for (exc, data) in DATA7.items():
1336 loaded = self.loads(data)
1337 self.assertIs(type(loaded), exc)
1338
1339 loaded = self.loads(DATA8)
1340 self.assertIs(type(loaded), Exception)
1341
1342 loaded = self.loads(DATA9)
1343 self.assertIs(type(loaded), UnicodeEncodeError)
1344 self.assertEqual(loaded.object, "foo")
1345 self.assertEqual(loaded.encoding, "ascii")
1346 self.assertEqual(loaded.start, 0)
1347 self.assertEqual(loaded.end, 1)
1348 self.assertEqual(loaded.reason, "bad")
1349
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001350 def test_pickle_to_2x(self):
1351 # Pickle non-trivial data with protocol 2, expecting that it yields
1352 # the same result as Python 2.x did.
1353 # NOTE: this test is a bit too strong since we can produce different
1354 # bytecode that 2.x will still understand.
1355 dumped = self.dumps(range(5), 2)
1356 self.assertEqual(dumped, DATA4)
1357 dumped = self.dumps(set([3]), 2)
1358 self.assertEqual(dumped, DATA6)
1359
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -08001360 def test_load_python2_str_as_bytes(self):
1361 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
1362 self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
1363 encoding="bytes"), b'a\x00\xa0')
1364 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
1365 self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
1366 encoding="bytes"), b'a\x00\xa0')
1367 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
1368 self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
1369 encoding="bytes"), b'a\x00\xa0')
1370
1371 def test_load_python2_unicode_as_str(self):
1372 # From Python 2: pickle.dumps(u'π', protocol=0)
1373 self.assertEqual(self.loads(b'V\\u03c0\n.',
1374 encoding='bytes'), 'π')
1375 # From Python 2: pickle.dumps(u'π', protocol=1)
1376 self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
1377 encoding="bytes"), 'π')
1378 # From Python 2: pickle.dumps(u'π', protocol=2)
1379 self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
1380 encoding="bytes"), 'π')
1381
1382 def test_load_long_python2_str_as_bytes(self):
1383 # From Python 2: pickle.dumps('x' * 300, protocol=1)
1384 self.assertEqual(self.loads(pickle.BINSTRING +
1385 struct.pack("<I", 300) +
1386 b'x' * 300 + pickle.STOP,
1387 encoding='bytes'), b'x' * 300)
1388
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001389 def test_large_pickles(self):
1390 # Test the correctness of internal buffering routines when handling
1391 # large data.
1392 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001393 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001394 dumped = self.dumps(data, proto)
1395 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001396 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001397 self.assertEqual(loaded, data)
1398
Alexander Belopolsky1ce92dc2011-02-24 19:40:09 +00001399 def test_empty_bytestring(self):
1400 # issue 11286
1401 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1402 self.assertEqual(empty, '')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001403
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001404 def test_int_pickling_efficiency(self):
1405 # Test compacity of int representation (see issue #12744)
1406 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001407 with self.subTest(proto=proto):
1408 pickles = [self.dumps(2**n, proto) for n in range(70)]
1409 sizes = list(map(len, pickles))
1410 # the size function is monotonic
1411 self.assertEqual(sorted(sizes), sizes)
1412 if proto >= 2:
1413 for p in pickles:
1414 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001415
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001416 def check_negative_32b_binXXX(self, dumped):
1417 if sys.maxsize > 2**32:
1418 self.skipTest("test is only meaningful on 32-bit builds")
1419 # XXX Pure Python pickle reads lengths as signed and passes
1420 # them directly to read() (hence the EOFError)
1421 with self.assertRaises((pickle.UnpicklingError, EOFError,
1422 ValueError, OverflowError)):
1423 self.loads(dumped)
1424
1425 def test_negative_32b_binbytes(self):
1426 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1427 self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.')
1428
1429 def test_negative_32b_binunicode(self):
1430 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1431 self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.')
1432
Antoine Pitrou55549ec2011-08-30 00:27:10 +02001433 def test_negative_put(self):
1434 # Issue #12847
1435 dumped = b'Va\np-1\n.'
1436 self.assertRaises(ValueError, self.loads, dumped)
1437
1438 def test_negative_32b_binput(self):
1439 # Issue #12847
1440 if sys.maxsize > 2**32:
1441 self.skipTest("test is only meaningful on 32-bit builds")
1442 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
1443 self.assertRaises(ValueError, self.loads, dumped)
1444
Alexandre Vassalotti7c5e0942013-04-15 23:14:55 -07001445 def test_badly_escaped_string(self):
1446 self.assertRaises(ValueError, self.loads, b"S'\\'\n.")
1447
1448 def test_badly_quoted_string(self):
1449 # Issue #17710
1450 badpickles = [b"S'\n.",
1451 b'S"\n.',
1452 b'S\' \n.',
1453 b'S" \n.',
1454 b'S\'"\n.',
1455 b'S"\'\n.',
1456 b"S' ' \n.",
1457 b'S" " \n.',
1458 b"S ''\n.",
1459 b'S ""\n.',
1460 b'S \n.',
1461 b'S\n.',
1462 b'S.']
1463 for p in badpickles:
1464 self.assertRaises(pickle.UnpicklingError, self.loads, p)
1465
1466 def test_correctly_quoted_string(self):
1467 goodpickles = [(b"S''\n.", ''),
1468 (b'S""\n.', ''),
1469 (b'S"\\n"\n.', '\n'),
1470 (b"S'\\n'\n.", '\n')]
1471 for p, expected in goodpickles:
1472 self.assertEqual(self.loads(p), expected)
1473
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001474 def _check_pickling_with_opcode(self, obj, opcode, proto):
1475 pickled = self.dumps(obj, proto)
1476 self.assertTrue(opcode_in_pickle(opcode, pickled))
1477 unpickled = self.loads(pickled)
1478 self.assertEqual(obj, unpickled)
1479
1480 def test_appends_on_non_lists(self):
1481 # Issue #17720
1482 obj = REX_six([1, 2, 3])
1483 for proto in protocols:
1484 if proto == 0:
1485 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1486 else:
1487 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1488
1489 def test_setitems_on_non_dicts(self):
1490 obj = REX_seven({1: -1, 2: -2, 3: -3})
1491 for proto in protocols:
1492 if proto == 0:
1493 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1494 else:
1495 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1496
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001497 # Exercise framing (proto >= 4) for significant workloads
1498
1499 FRAME_SIZE_TARGET = 64 * 1024
1500
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001501 def check_frame_opcodes(self, pickled):
1502 """
1503 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
1504 """
1505 frame_opcode_size = 9
1506 last_arg = last_pos = None
1507 for op, arg, pos in pickletools.genops(pickled):
1508 if op.name != 'FRAME':
1509 continue
1510 if last_pos is not None:
1511 # The previous frame's size should be equal to the number
1512 # of bytes up to the current frame.
1513 frame_size = pos - last_pos - frame_opcode_size
1514 self.assertEqual(frame_size, last_arg)
1515 last_arg, last_pos = arg, pos
1516 # The last frame's size should be equal to the number of bytes up
1517 # to the pickle's end.
1518 frame_size = len(pickled) - last_pos - frame_opcode_size
1519 self.assertEqual(frame_size, last_arg)
1520
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001521 def test_framing_many_objects(self):
1522 obj = list(range(10**5))
1523 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1524 with self.subTest(proto=proto):
1525 pickled = self.dumps(obj, proto)
1526 unpickled = self.loads(pickled)
1527 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001528 bytes_per_frame = (len(pickled) /
1529 count_opcode(pickle.FRAME, pickled))
1530 self.assertGreater(bytes_per_frame,
1531 self.FRAME_SIZE_TARGET / 2)
1532 self.assertLessEqual(bytes_per_frame,
1533 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001534 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001535
1536 def test_framing_large_objects(self):
1537 N = 1024 * 1024
1538 obj = [b'x' * N, b'y' * N, b'z' * N]
1539 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1540 with self.subTest(proto=proto):
1541 pickled = self.dumps(obj, proto)
1542 unpickled = self.loads(pickled)
1543 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001544 n_frames = count_opcode(pickle.FRAME, pickled)
Alexandre Vassalotti28d271e2013-12-01 16:27:46 -08001545 self.assertGreaterEqual(n_frames, len(obj))
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001546 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001547
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001548 def test_optional_frames(self):
1549 if pickle.HIGHEST_PROTOCOL < 4:
1550 return
1551
1552 def remove_frames(pickled, keep_frame=None):
1553 """Remove frame opcodes from the given pickle."""
1554 frame_starts = []
1555 # 1 byte for the opcode and 8 for the argument
1556 frame_opcode_size = 9
1557 for opcode, _, pos in pickletools.genops(pickled):
1558 if opcode.name == 'FRAME':
1559 frame_starts.append(pos)
1560
1561 newpickle = bytearray()
1562 last_frame_end = 0
1563 for i, pos in enumerate(frame_starts):
1564 if keep_frame and keep_frame(i):
1565 continue
1566 newpickle += pickled[last_frame_end:pos]
1567 last_frame_end = pos + frame_opcode_size
1568 newpickle += pickled[last_frame_end:]
1569 return newpickle
1570
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001571 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001572 num_frames = 20
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001573 obj = [bytes([i]) * frame_size for i in range(num_frames)]
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001574
1575 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1576 pickled = self.dumps(obj, proto)
1577
1578 frameless_pickle = remove_frames(pickled)
1579 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
1580 self.assertEqual(obj, self.loads(frameless_pickle))
1581
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001582 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001583 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
1584 count_opcode(pickle.FRAME, pickled))
1585 self.assertEqual(obj, self.loads(some_frames_pickle))
1586
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001587 def test_nested_names(self):
1588 global Nested
1589 class Nested:
1590 class A:
1591 class B:
1592 class C:
1593 pass
1594
1595 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1596 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
1597 with self.subTest(proto=proto, obj=obj):
1598 unpickled = self.loads(self.dumps(obj, proto))
1599 self.assertIs(obj, unpickled)
1600
1601 def test_py_methods(self):
1602 global PyMethodsTest
1603 class PyMethodsTest:
1604 @staticmethod
1605 def cheese():
1606 return "cheese"
1607 @classmethod
1608 def wine(cls):
1609 assert cls is PyMethodsTest
1610 return "wine"
1611 def biscuits(self):
1612 assert isinstance(self, PyMethodsTest)
1613 return "biscuits"
1614 class Nested:
1615 "Nested class"
1616 @staticmethod
1617 def ketchup():
1618 return "ketchup"
1619 @classmethod
1620 def maple(cls):
1621 assert cls is PyMethodsTest.Nested
1622 return "maple"
1623 def pie(self):
1624 assert isinstance(self, PyMethodsTest.Nested)
1625 return "pie"
1626
1627 py_methods = (
1628 PyMethodsTest.cheese,
1629 PyMethodsTest.wine,
1630 PyMethodsTest().biscuits,
1631 PyMethodsTest.Nested.ketchup,
1632 PyMethodsTest.Nested.maple,
1633 PyMethodsTest.Nested().pie
1634 )
1635 py_unbound_methods = (
1636 (PyMethodsTest.biscuits, PyMethodsTest),
1637 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
1638 )
1639 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1640 for method in py_methods:
1641 with self.subTest(proto=proto, method=method):
1642 unpickled = self.loads(self.dumps(method, proto))
1643 self.assertEqual(method(), unpickled())
1644 for method, cls in py_unbound_methods:
1645 obj = cls()
1646 with self.subTest(proto=proto, method=method):
1647 unpickled = self.loads(self.dumps(method, proto))
1648 self.assertEqual(method(obj), unpickled(obj))
1649
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001650 def test_c_methods(self):
1651 global Subclass
1652 class Subclass(tuple):
1653 class Nested(str):
1654 pass
1655
1656 c_methods = (
1657 # bound built-in method
1658 ("abcd".index, ("c",)),
1659 # unbound built-in method
1660 (str.index, ("abcd", "c")),
1661 # bound "slot" method
1662 ([1, 2, 3].__len__, ()),
1663 # unbound "slot" method
1664 (list.__len__, ([1, 2, 3],)),
1665 # bound "coexist" method
1666 ({1, 2}.__contains__, (2,)),
1667 # unbound "coexist" method
1668 (set.__contains__, ({1, 2}, 2)),
1669 # built-in class method
1670 (dict.fromkeys, (("a", 1), ("b", 2))),
1671 # built-in static method
1672 (bytearray.maketrans, (b"abc", b"xyz")),
1673 # subclass methods
1674 (Subclass([1,2,2]).count, (2,)),
1675 (Subclass.count, (Subclass([1,2,2]), 2)),
1676 (Subclass.Nested("sweet").count, ("e",)),
1677 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
1678 )
1679 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1680 for method, args in c_methods:
1681 with self.subTest(proto=proto, method=method):
1682 unpickled = self.loads(self.dumps(method, proto))
1683 self.assertEqual(method(*args), unpickled(*args))
1684
Antoine Pitrou6cd5eda2014-12-02 00:20:03 +01001685 def test_local_lookup_error(self):
1686 # Test that whichmodule() errors out cleanly when looking up
1687 # an assumed globally-reachable object fails.
1688 def f():
1689 pass
1690 # Since the function is local, lookup will fail
1691 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1692 with self.assertRaises((AttributeError, pickle.PicklingError)):
1693 pickletools.dis(self.dumps(f, proto))
1694 # Same without a __module__ attribute (exercises a different path
1695 # in _pickle.c).
1696 del f.__module__
1697 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1698 with self.assertRaises((AttributeError, pickle.PicklingError)):
1699 pickletools.dis(self.dumps(f, proto))
1700 # Yet a different path.
1701 f.__name__ = f.__qualname__
1702 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1703 with self.assertRaises((AttributeError, pickle.PicklingError)):
1704 pickletools.dis(self.dumps(f, proto))
1705
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001706
1707class BigmemPickleTests(unittest.TestCase):
1708
1709 # Binary protocols can serialize longs of up to 2GB-1
1710
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001711 @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001712 def test_huge_long_32b(self, size):
1713 data = 1 << (8 * size)
1714 try:
1715 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001716 if proto < 2:
1717 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001718 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001719 with self.assertRaises((ValueError, OverflowError)):
1720 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001721 finally:
1722 data = None
1723
1724 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1725 # (older protocols don't have a dedicated opcode for bytes and are
1726 # too inefficient)
1727
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001728 @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001729 def test_huge_bytes_32b(self, size):
1730 data = b"abcd" * (size // 4)
1731 try:
1732 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001733 if proto < 3:
1734 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001735 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001736 try:
1737 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001738 header = (pickle.BINBYTES +
1739 struct.pack("<I", len(data)))
1740 data_start = pickled.index(data)
1741 self.assertEqual(
1742 header,
1743 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001744 finally:
1745 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001746 finally:
1747 data = None
1748
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001749 @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001750 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001751 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001752 try:
1753 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001754 if proto < 3:
1755 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001756 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001757 if proto == 3:
1758 # Protocol 3 does not support large bytes objects.
1759 # Verify that we do not crash when processing one.
1760 with self.assertRaises((ValueError, OverflowError)):
1761 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001762 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001763 try:
1764 pickled = self.dumps(data, protocol=proto)
1765 header = (pickle.BINBYTES8 +
1766 struct.pack("<Q", len(data)))
1767 data_start = pickled.index(data)
1768 self.assertEqual(
1769 header,
1770 pickled[data_start-len(header):data_start])
1771 finally:
1772 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001773 finally:
1774 data = None
1775
1776 # All protocols use 1-byte per printable ASCII character; we add another
1777 # byte because the encoded form has to be copied into the internal buffer.
1778
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001779 @bigmemtest(size=_2G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001780 def test_huge_str_32b(self, size):
1781 data = "abcd" * (size // 4)
1782 try:
1783 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001784 if proto == 0:
1785 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001786 with self.subTest(proto=proto):
1787 try:
1788 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001789 header = (pickle.BINUNICODE +
1790 struct.pack("<I", len(data)))
1791 data_start = pickled.index(b'abcd')
1792 self.assertEqual(
1793 header,
1794 pickled[data_start-len(header):data_start])
1795 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1796 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001797 finally:
1798 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001799 finally:
1800 data = None
1801
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001802 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
1803 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
1804 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02001805
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001806 @bigmemtest(size=_4G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001807 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001808 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001809 try:
1810 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001811 if proto == 0:
1812 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001813 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001814 if proto < 4:
1815 with self.assertRaises((ValueError, OverflowError)):
1816 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001817 continue
1818 try:
1819 pickled = self.dumps(data, protocol=proto)
1820 header = (pickle.BINUNICODE8 +
1821 struct.pack("<Q", len(data)))
1822 data_start = pickled.index(b'abcd')
1823 self.assertEqual(
1824 header,
1825 pickled[data_start-len(header):data_start])
1826 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1827 pickled.index(b"abcd")), len(data))
1828 finally:
1829 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001830 finally:
1831 data = None
1832
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001833
Guido van Rossum2a30b212003-02-18 22:41:24 +00001834# Test classes for reduce_ex
1835
1836class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001837 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001838 _reduce_called = 0
1839 def __reduce__(self):
1840 self._reduce_called = 1
1841 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001842
1843class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001844 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001845 _proto = None
1846 def __reduce_ex__(self, proto):
1847 self._proto = proto
1848 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001849
1850class REX_three(object):
1851 _proto = None
1852 def __reduce_ex__(self, proto):
1853 self._proto = proto
1854 return REX_two, ()
1855 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001856 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001857
Guido van Rossumd8faa362007-04-27 19:54:29 +00001858class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001859 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001860 _proto = None
1861 def __reduce_ex__(self, proto):
1862 self._proto = proto
1863 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001864
1865class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001866 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001867 _reduce_called = 0
1868 def __reduce__(self):
1869 self._reduce_called = 1
1870 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001871
1872class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001873 """This class is used to check the 4th argument (list iterator) of
1874 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001875 """
1876 def __init__(self, items=None):
1877 self.items = items if items is not None else []
1878 def __eq__(self, other):
1879 return type(self) is type(other) and self.items == self.items
1880 def append(self, item):
1881 self.items.append(item)
1882 def __reduce__(self):
1883 return type(self), (), None, iter(self.items), None
1884
1885class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001886 """This class is used to check the 5th argument (dict iterator) of
1887 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001888 """
1889 def __init__(self, table=None):
1890 self.table = table if table is not None else {}
1891 def __eq__(self, other):
1892 return type(self) is type(other) and self.table == self.table
1893 def __setitem__(self, key, value):
1894 self.table[key] = value
1895 def __reduce__(self):
1896 return type(self), (), None, None, iter(self.table.items())
1897
Guido van Rossumd8faa362007-04-27 19:54:29 +00001898
Guido van Rossum2a30b212003-02-18 22:41:24 +00001899# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001900
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001901class MyInt(int):
1902 sample = 1
1903
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001904class MyFloat(float):
1905 sample = 1.0
1906
1907class MyComplex(complex):
1908 sample = 1.0 + 0.0j
1909
1910class MyStr(str):
1911 sample = "hello"
1912
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001913class MyUnicode(str):
1914 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001915
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001916class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001917 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001918
1919class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001920 sample = [1, 2, 3]
1921
1922class MyDict(dict):
1923 sample = {"a": 1, "b": 2}
1924
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001925class MySet(set):
1926 sample = {"a", "b"}
1927
1928class MyFrozenSet(frozenset):
1929 sample = frozenset({"a", "b"})
1930
Mark Dickinson5c2db372009-12-05 20:28:34 +00001931myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001932 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001933 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001934 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001935
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001936
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001937class SlotList(MyList):
1938 __slots__ = ["foo"]
1939
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001940class SimpleNewObj(int):
1941 def __init__(self, *args, **kwargs):
Tim Peterse9ef2032003-02-13 18:42:00 +00001942 # raise an error, to make sure this isn't called
1943 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001944 def __eq__(self, other):
Serhiy Storchaka707b5cc2014-12-16 19:43:46 +02001945 return int(self) == int(other) and self.__dict__ == other.__dict__
1946
1947class ComplexNewObj(SimpleNewObj):
1948 def __getnewargs__(self):
1949 return ('%X' % self, 16)
1950
1951class ComplexNewObjEx(SimpleNewObj):
1952 def __getnewargs_ex__(self):
1953 return ('%X' % self,), {'base': 16}
Tim Peterse9ef2032003-02-13 18:42:00 +00001954
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001955class BadGetattr:
1956 def __getattr__(self, key):
1957 self.foo
1958
Collin Winter771d8342009-04-16 03:18:06 +00001959
Jeremy Hylton66426532001-10-15 21:38:56 +00001960class AbstractPickleModuleTests(unittest.TestCase):
1961
1962 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001963 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001964 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001965 try:
1966 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001967 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001968 finally:
1969 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001970
1971 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001972 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001973 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001974 try:
1975 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001976 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001977 finally:
1978 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001979
Collin Winter771d8342009-04-16 03:18:06 +00001980 def test_load_from_and_dump_to_file(self):
1981 stream = io.BytesIO()
1982 data = [123, {}, 124]
1983 pickle.dump(data, stream)
1984 stream.seek(0)
1985 unpickled = pickle.load(stream)
1986 self.assertEqual(unpickled, data)
1987
Tim Petersc0c93702003-02-13 19:30:57 +00001988 def test_highest_protocol(self):
1989 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001990 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00001991
Martin v. Löwis544f1192004-07-27 05:22:33 +00001992 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001993 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001994 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001995 pickle.dump(123, f, -1)
1996 pickle.dump(123, file=f, protocol=-1)
1997 pickle.dumps(123, -1)
1998 pickle.dumps(123, protocol=-1)
1999 pickle.Pickler(f, -1)
2000 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00002001
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002002 def test_bad_init(self):
2003 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002004 # Override initialization without calling __init__() of the superclass.
2005 class BadPickler(pickle.Pickler):
2006 def __init__(self): pass
2007
2008 class BadUnpickler(pickle.Unpickler):
2009 def __init__(self): pass
2010
2011 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
2012 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
2013
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00002014 def test_bad_input(self):
2015 # Test issue4298
2016 s = bytes([0x58, 0, 0, 0, 0x54])
2017 self.assertRaises(EOFError, pickle.loads, s)
2018
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00002019
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002020class AbstractPersistentPicklerTests(unittest.TestCase):
2021
2022 # This class defines persistent_id() and persistent_load()
2023 # functions that should be used by the pickler. All even integers
2024 # are pickled using persistent ids.
2025
2026 def persistent_id(self, object):
2027 if isinstance(object, int) and object % 2 == 0:
2028 self.id_count += 1
2029 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002030 elif object == "test_false_value":
2031 self.false_count += 1
2032 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002033 else:
2034 return None
2035
2036 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002037 if not oid:
2038 self.load_false_count += 1
2039 return "test_false_value"
2040 else:
2041 self.load_count += 1
2042 object = int(oid)
2043 assert object % 2 == 0
2044 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00002045
2046 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08002047 L = list(range(10)) + ["test_false_value"]
2048 for proto in protocols:
2049 self.id_count = 0
2050 self.false_count = 0
2051 self.load_false_count = 0
2052 self.load_count = 0
2053 self.assertEqual(self.loads(self.dumps(L, proto)), L)
2054 self.assertEqual(self.id_count, 5)
2055 self.assertEqual(self.false_count, 1)
2056 self.assertEqual(self.load_count, 5)
2057 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00002058
Collin Winter771d8342009-04-16 03:18:06 +00002059
2060class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
2061
2062 pickler_class = None
2063 unpickler_class = None
2064
2065 def setUp(self):
2066 assert self.pickler_class
2067 assert self.unpickler_class
2068
2069 def test_clear_pickler_memo(self):
2070 # To test whether clear_memo() has any effect, we pickle an object,
2071 # then pickle it again without clearing the memo; the two serialized
2072 # forms should be different. If we clear_memo() and then pickle the
2073 # object again, the third serialized form should be identical to the
2074 # first one we obtained.
2075 data = ["abcdefg", "abcdefg", 44]
2076 f = io.BytesIO()
2077 pickler = self.pickler_class(f)
2078
2079 pickler.dump(data)
2080 first_pickled = f.getvalue()
2081
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002082 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00002083 f.seek(0)
2084 f.truncate()
2085
2086 pickler.dump(data)
2087 second_pickled = f.getvalue()
2088
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002089 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00002090 pickler.clear_memo()
2091 f.seek(0)
2092 f.truncate()
2093
2094 pickler.dump(data)
2095 third_pickled = f.getvalue()
2096
2097 self.assertNotEqual(first_pickled, second_pickled)
2098 self.assertEqual(first_pickled, third_pickled)
2099
2100 def test_priming_pickler_memo(self):
2101 # Verify that we can set the Pickler's memo attribute.
2102 data = ["abcdefg", "abcdefg", 44]
2103 f = io.BytesIO()
2104 pickler = self.pickler_class(f)
2105
2106 pickler.dump(data)
2107 first_pickled = f.getvalue()
2108
2109 f = io.BytesIO()
2110 primed = self.pickler_class(f)
2111 primed.memo = pickler.memo
2112
2113 primed.dump(data)
2114 primed_pickled = f.getvalue()
2115
2116 self.assertNotEqual(first_pickled, primed_pickled)
2117
2118 def test_priming_unpickler_memo(self):
2119 # Verify that we can set the Unpickler's memo attribute.
2120 data = ["abcdefg", "abcdefg", 44]
2121 f = io.BytesIO()
2122 pickler = self.pickler_class(f)
2123
2124 pickler.dump(data)
2125 first_pickled = f.getvalue()
2126
2127 f = io.BytesIO()
2128 primed = self.pickler_class(f)
2129 primed.memo = pickler.memo
2130
2131 primed.dump(data)
2132 primed_pickled = f.getvalue()
2133
2134 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2135 unpickled_data1 = unpickler.load()
2136
2137 self.assertEqual(unpickled_data1, data)
2138
2139 primed = self.unpickler_class(io.BytesIO(primed_pickled))
2140 primed.memo = unpickler.memo
2141 unpickled_data2 = primed.load()
2142
2143 primed.memo.clear()
2144
2145 self.assertEqual(unpickled_data2, data)
2146 self.assertTrue(unpickled_data2 is unpickled_data1)
2147
2148 def test_reusing_unpickler_objects(self):
2149 data1 = ["abcdefg", "abcdefg", 44]
2150 f = io.BytesIO()
2151 pickler = self.pickler_class(f)
2152 pickler.dump(data1)
2153 pickled1 = f.getvalue()
2154
2155 data2 = ["abcdefg", 44, 44]
2156 f = io.BytesIO()
2157 pickler = self.pickler_class(f)
2158 pickler.dump(data2)
2159 pickled2 = f.getvalue()
2160
2161 f = io.BytesIO()
2162 f.write(pickled1)
2163 f.seek(0)
2164 unpickler = self.unpickler_class(f)
2165 self.assertEqual(unpickler.load(), data1)
2166
2167 f.seek(0)
2168 f.truncate()
2169 f.write(pickled2)
2170 f.seek(0)
2171 self.assertEqual(unpickler.load(), data2)
2172
Antoine Pitrou04248a82010-10-12 20:51:21 +00002173 def _check_multiple_unpicklings(self, ioclass):
2174 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002175 with self.subTest(proto=proto):
2176 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2177 f = ioclass()
2178 pickler = self.pickler_class(f, protocol=proto)
2179 pickler.dump(data1)
2180 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002181
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002182 N = 5
2183 f = ioclass(pickled * N)
2184 unpickler = self.unpickler_class(f)
2185 for i in range(N):
2186 if f.seekable():
2187 pos = f.tell()
2188 self.assertEqual(unpickler.load(), data1)
2189 if f.seekable():
2190 self.assertEqual(f.tell(), pos + len(pickled))
2191 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002192
2193 def test_multiple_unpicklings_seekable(self):
2194 self._check_multiple_unpicklings(io.BytesIO)
2195
2196 def test_multiple_unpicklings_unseekable(self):
2197 self._check_multiple_unpicklings(UnseekableIO)
2198
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002199 def test_unpickling_buffering_readline(self):
2200 # Issue #12687: the unpickler's buffering logic could fail with
2201 # text mode opcodes.
2202 data = list(range(10))
2203 for proto in protocols:
2204 for buf_size in range(1, 11):
2205 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2206 pickler = self.pickler_class(f, protocol=proto)
2207 pickler.dump(data)
2208 f.seek(0)
2209 unpickler = self.unpickler_class(f)
2210 self.assertEqual(unpickler.load(), data)
2211
Collin Winter771d8342009-04-16 03:18:06 +00002212
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002213# Tests for dispatch_table attribute
2214
2215REDUCE_A = 'reduce_A'
2216
2217class AAA(object):
2218 def __reduce__(self):
2219 return str, (REDUCE_A,)
2220
2221class BBB(object):
2222 pass
2223
2224class AbstractDispatchTableTests(unittest.TestCase):
2225
2226 def test_default_dispatch_table(self):
2227 # No dispatch_table attribute by default
2228 f = io.BytesIO()
2229 p = self.pickler_class(f, 0)
2230 with self.assertRaises(AttributeError):
2231 p.dispatch_table
2232 self.assertFalse(hasattr(p, 'dispatch_table'))
2233
2234 def test_class_dispatch_table(self):
2235 # A dispatch_table attribute can be specified class-wide
2236 dt = self.get_dispatch_table()
2237
2238 class MyPickler(self.pickler_class):
2239 dispatch_table = dt
2240
2241 def dumps(obj, protocol=None):
2242 f = io.BytesIO()
2243 p = MyPickler(f, protocol)
2244 self.assertEqual(p.dispatch_table, dt)
2245 p.dump(obj)
2246 return f.getvalue()
2247
2248 self._test_dispatch_table(dumps, dt)
2249
2250 def test_instance_dispatch_table(self):
2251 # A dispatch_table attribute can also be specified instance-wide
2252 dt = self.get_dispatch_table()
2253
2254 def dumps(obj, protocol=None):
2255 f = io.BytesIO()
2256 p = self.pickler_class(f, protocol)
2257 p.dispatch_table = dt
2258 self.assertEqual(p.dispatch_table, dt)
2259 p.dump(obj)
2260 return f.getvalue()
2261
2262 self._test_dispatch_table(dumps, dt)
2263
2264 def _test_dispatch_table(self, dumps, dispatch_table):
2265 def custom_load_dump(obj):
2266 return pickle.loads(dumps(obj, 0))
2267
2268 def default_load_dump(obj):
2269 return pickle.loads(pickle.dumps(obj, 0))
2270
2271 # pickling complex numbers using protocol 0 relies on copyreg
2272 # so check pickling a complex number still works
2273 z = 1 + 2j
2274 self.assertEqual(custom_load_dump(z), z)
2275 self.assertEqual(default_load_dump(z), z)
2276
2277 # modify pickling of complex
2278 REDUCE_1 = 'reduce_1'
2279 def reduce_1(obj):
2280 return str, (REDUCE_1,)
2281 dispatch_table[complex] = reduce_1
2282 self.assertEqual(custom_load_dump(z), REDUCE_1)
2283 self.assertEqual(default_load_dump(z), z)
2284
2285 # check picklability of AAA and BBB
2286 a = AAA()
2287 b = BBB()
2288 self.assertEqual(custom_load_dump(a), REDUCE_A)
2289 self.assertIsInstance(custom_load_dump(b), BBB)
2290 self.assertEqual(default_load_dump(a), REDUCE_A)
2291 self.assertIsInstance(default_load_dump(b), BBB)
2292
2293 # modify pickling of BBB
2294 dispatch_table[BBB] = reduce_1
2295 self.assertEqual(custom_load_dump(a), REDUCE_A)
2296 self.assertEqual(custom_load_dump(b), REDUCE_1)
2297 self.assertEqual(default_load_dump(a), REDUCE_A)
2298 self.assertIsInstance(default_load_dump(b), BBB)
2299
2300 # revert pickling of BBB and modify pickling of AAA
2301 REDUCE_2 = 'reduce_2'
2302 def reduce_2(obj):
2303 return str, (REDUCE_2,)
2304 dispatch_table[AAA] = reduce_2
2305 del dispatch_table[BBB]
2306 self.assertEqual(custom_load_dump(a), REDUCE_2)
2307 self.assertIsInstance(custom_load_dump(b), BBB)
2308 self.assertEqual(default_load_dump(a), REDUCE_A)
2309 self.assertIsInstance(default_load_dump(b), BBB)
2310
2311
Guido van Rossum98297ee2007-11-06 21:34:58 +00002312if __name__ == "__main__":
2313 # Print some stuff that can be used to rewrite DATA{0,1,2}
2314 from pickletools import dis
2315 x = create_data()
2316 for i in range(3):
2317 p = pickle.dumps(x, i)
2318 print("DATA{0} = (".format(i))
2319 for j in range(0, len(p), 20):
2320 b = bytes(p[j:j+20])
2321 print(" {0!r}".format(b))
2322 print(")")
2323 print()
2324 print("# Disassembly of DATA{0}".format(i))
2325 print("DATA{0}_DIS = \"\"\"\\".format(i))
2326 dis(p)
2327 print("\"\"\"")
2328 print()