blob: 021adcc408dbebdfd2948b3049957152287dea19 [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):
1156 x = object.__new__(SimpleNewObj) # avoid __init__
1157 x.abc = 666
1158 for proto in protocols:
1159 s = self.dumps(x, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001160 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1161 2 <= proto < 4)
1162 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1163 proto >= 4)
Tim Peterse9ef2032003-02-13 18:42:00 +00001164 y = self.loads(s) # will raise TypeError if __init__ called
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001165 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001166
Tim Peters42f08ac2003-02-11 22:43:24 +00001167 def test_newobj_list_slots(self):
1168 x = SlotList([1, 2, 3])
1169 x.foo = 42
1170 x.bar = "hello"
1171 s = self.dumps(x, 2)
1172 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001173 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001174
Guido van Rossum2a30b212003-02-18 22:41:24 +00001175 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001176 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001177 x = REX_one()
1178 self.assertEqual(x._reduce_called, 0)
1179 s = self.dumps(x, proto)
1180 self.assertEqual(x._reduce_called, 1)
1181 y = self.loads(s)
1182 self.assertEqual(y._reduce_called, 0)
1183
1184 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001185 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001186 x = REX_two()
1187 self.assertEqual(x._proto, None)
1188 s = self.dumps(x, proto)
1189 self.assertEqual(x._proto, proto)
1190 y = self.loads(s)
1191 self.assertEqual(y._proto, None)
1192
1193 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001194 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001195 x = REX_three()
1196 self.assertEqual(x._proto, None)
1197 s = self.dumps(x, proto)
1198 self.assertEqual(x._proto, proto)
1199 y = self.loads(s)
1200 self.assertEqual(y._proto, None)
1201
Guido van Rossumd8faa362007-04-27 19:54:29 +00001202 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001203 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001204 x = REX_four()
1205 self.assertEqual(x._proto, None)
1206 s = self.dumps(x, proto)
1207 self.assertEqual(x._proto, proto)
1208 y = self.loads(s)
1209 self.assertEqual(y._proto, proto)
1210
1211 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001212 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001213 x = REX_five()
1214 self.assertEqual(x._reduce_called, 0)
1215 s = self.dumps(x, proto)
1216 self.assertEqual(x._reduce_called, 1)
1217 y = self.loads(s)
1218 self.assertEqual(y._reduce_called, 1)
1219
Brett Cannon31f59292011-02-21 19:29:56 +00001220 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001221 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001222 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001223 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001224 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001225 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001226
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001227 def test_reduce_bad_iterator(self):
1228 # Issue4176: crash when 4th and 5th items of __reduce__()
1229 # are not iterators
1230 class C(object):
1231 def __reduce__(self):
1232 # 4th item is not an iterator
1233 return list, (), None, [], None
1234 class D(object):
1235 def __reduce__(self):
1236 # 5th item is not an iterator
1237 return dict, (), None, None, []
1238
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001239 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001240 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001241 try:
1242 self.dumps(C(), proto)
1243 except (pickle.PickleError):
1244 pass
1245 try:
1246 self.dumps(D(), proto)
1247 except (pickle.PickleError):
1248 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001249
Collin Winter771d8342009-04-16 03:18:06 +00001250 def test_many_puts_and_gets(self):
1251 # Test that internal data structures correctly deal with lots of
1252 # puts/gets.
1253 keys = ("aaa" + str(i) for i in range(100))
1254 large_dict = dict((k, [4, 5, 6]) for k in keys)
1255 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1256
1257 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001258 with self.subTest(proto=proto):
1259 dumped = self.dumps(obj, proto)
1260 loaded = self.loads(dumped)
1261 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00001262
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001263 def test_attribute_name_interning(self):
1264 # Test that attribute names of pickled objects are interned when
1265 # unpickling.
1266 for proto in protocols:
1267 x = C()
1268 x.foo = 42
1269 x.bar = "hello"
1270 s = self.dumps(x, proto)
1271 y = self.loads(s)
1272 x_keys = sorted(x.__dict__)
1273 y_keys = sorted(y.__dict__)
1274 for x_key, y_key in zip(x_keys, y_keys):
1275 self.assertIs(x_key, y_key)
1276
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001277 def test_unpickle_from_2x(self):
1278 # Unpickle non-trivial data from Python 2.x.
1279 loaded = self.loads(DATA3)
1280 self.assertEqual(loaded, set([1, 2]))
1281 loaded = self.loads(DATA4)
1282 self.assertEqual(type(loaded), type(range(0)))
1283 self.assertEqual(list(loaded), list(range(5)))
1284 loaded = self.loads(DATA5)
1285 self.assertEqual(type(loaded), SimpleCookie)
1286 self.assertEqual(list(loaded.keys()), ["key"])
Serhiy Storchaka8cf7c1c2014-11-02 22:18:25 +02001287 self.assertEqual(loaded["key"].value, "value")
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001288
Walter Doerwald9d1dbca2013-12-02 11:41:01 +01001289 for (exc, data) in DATA7.items():
1290 loaded = self.loads(data)
1291 self.assertIs(type(loaded), exc)
1292
1293 loaded = self.loads(DATA8)
1294 self.assertIs(type(loaded), Exception)
1295
1296 loaded = self.loads(DATA9)
1297 self.assertIs(type(loaded), UnicodeEncodeError)
1298 self.assertEqual(loaded.object, "foo")
1299 self.assertEqual(loaded.encoding, "ascii")
1300 self.assertEqual(loaded.start, 0)
1301 self.assertEqual(loaded.end, 1)
1302 self.assertEqual(loaded.reason, "bad")
1303
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001304 def test_pickle_to_2x(self):
1305 # Pickle non-trivial data with protocol 2, expecting that it yields
1306 # the same result as Python 2.x did.
1307 # NOTE: this test is a bit too strong since we can produce different
1308 # bytecode that 2.x will still understand.
1309 dumped = self.dumps(range(5), 2)
1310 self.assertEqual(dumped, DATA4)
1311 dumped = self.dumps(set([3]), 2)
1312 self.assertEqual(dumped, DATA6)
1313
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -08001314 def test_load_python2_str_as_bytes(self):
1315 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
1316 self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
1317 encoding="bytes"), b'a\x00\xa0')
1318 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
1319 self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
1320 encoding="bytes"), b'a\x00\xa0')
1321 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
1322 self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
1323 encoding="bytes"), b'a\x00\xa0')
1324
1325 def test_load_python2_unicode_as_str(self):
1326 # From Python 2: pickle.dumps(u'π', protocol=0)
1327 self.assertEqual(self.loads(b'V\\u03c0\n.',
1328 encoding='bytes'), 'π')
1329 # From Python 2: pickle.dumps(u'π', protocol=1)
1330 self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
1331 encoding="bytes"), 'π')
1332 # From Python 2: pickle.dumps(u'π', protocol=2)
1333 self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
1334 encoding="bytes"), 'π')
1335
1336 def test_load_long_python2_str_as_bytes(self):
1337 # From Python 2: pickle.dumps('x' * 300, protocol=1)
1338 self.assertEqual(self.loads(pickle.BINSTRING +
1339 struct.pack("<I", 300) +
1340 b'x' * 300 + pickle.STOP,
1341 encoding='bytes'), b'x' * 300)
1342
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001343 def test_large_pickles(self):
1344 # Test the correctness of internal buffering routines when handling
1345 # large data.
1346 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001347 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001348 dumped = self.dumps(data, proto)
1349 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001350 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001351 self.assertEqual(loaded, data)
1352
Alexander Belopolsky1ce92dc2011-02-24 19:40:09 +00001353 def test_empty_bytestring(self):
1354 # issue 11286
1355 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1356 self.assertEqual(empty, '')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001357
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001358 def test_int_pickling_efficiency(self):
1359 # Test compacity of int representation (see issue #12744)
1360 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001361 with self.subTest(proto=proto):
1362 pickles = [self.dumps(2**n, proto) for n in range(70)]
1363 sizes = list(map(len, pickles))
1364 # the size function is monotonic
1365 self.assertEqual(sorted(sizes), sizes)
1366 if proto >= 2:
1367 for p in pickles:
1368 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001369
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001370 def check_negative_32b_binXXX(self, dumped):
1371 if sys.maxsize > 2**32:
1372 self.skipTest("test is only meaningful on 32-bit builds")
1373 # XXX Pure Python pickle reads lengths as signed and passes
1374 # them directly to read() (hence the EOFError)
1375 with self.assertRaises((pickle.UnpicklingError, EOFError,
1376 ValueError, OverflowError)):
1377 self.loads(dumped)
1378
1379 def test_negative_32b_binbytes(self):
1380 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1381 self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.')
1382
1383 def test_negative_32b_binunicode(self):
1384 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1385 self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.')
1386
Antoine Pitrou55549ec2011-08-30 00:27:10 +02001387 def test_negative_put(self):
1388 # Issue #12847
1389 dumped = b'Va\np-1\n.'
1390 self.assertRaises(ValueError, self.loads, dumped)
1391
1392 def test_negative_32b_binput(self):
1393 # Issue #12847
1394 if sys.maxsize > 2**32:
1395 self.skipTest("test is only meaningful on 32-bit builds")
1396 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
1397 self.assertRaises(ValueError, self.loads, dumped)
1398
Alexandre Vassalotti7c5e0942013-04-15 23:14:55 -07001399 def test_badly_escaped_string(self):
1400 self.assertRaises(ValueError, self.loads, b"S'\\'\n.")
1401
1402 def test_badly_quoted_string(self):
1403 # Issue #17710
1404 badpickles = [b"S'\n.",
1405 b'S"\n.',
1406 b'S\' \n.',
1407 b'S" \n.',
1408 b'S\'"\n.',
1409 b'S"\'\n.',
1410 b"S' ' \n.",
1411 b'S" " \n.',
1412 b"S ''\n.",
1413 b'S ""\n.',
1414 b'S \n.',
1415 b'S\n.',
1416 b'S.']
1417 for p in badpickles:
1418 self.assertRaises(pickle.UnpicklingError, self.loads, p)
1419
1420 def test_correctly_quoted_string(self):
1421 goodpickles = [(b"S''\n.", ''),
1422 (b'S""\n.', ''),
1423 (b'S"\\n"\n.', '\n'),
1424 (b"S'\\n'\n.", '\n')]
1425 for p, expected in goodpickles:
1426 self.assertEqual(self.loads(p), expected)
1427
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001428 def _check_pickling_with_opcode(self, obj, opcode, proto):
1429 pickled = self.dumps(obj, proto)
1430 self.assertTrue(opcode_in_pickle(opcode, pickled))
1431 unpickled = self.loads(pickled)
1432 self.assertEqual(obj, unpickled)
1433
1434 def test_appends_on_non_lists(self):
1435 # Issue #17720
1436 obj = REX_six([1, 2, 3])
1437 for proto in protocols:
1438 if proto == 0:
1439 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1440 else:
1441 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1442
1443 def test_setitems_on_non_dicts(self):
1444 obj = REX_seven({1: -1, 2: -2, 3: -3})
1445 for proto in protocols:
1446 if proto == 0:
1447 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1448 else:
1449 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1450
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001451 # Exercise framing (proto >= 4) for significant workloads
1452
1453 FRAME_SIZE_TARGET = 64 * 1024
1454
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001455 def check_frame_opcodes(self, pickled):
1456 """
1457 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
1458 """
1459 frame_opcode_size = 9
1460 last_arg = last_pos = None
1461 for op, arg, pos in pickletools.genops(pickled):
1462 if op.name != 'FRAME':
1463 continue
1464 if last_pos is not None:
1465 # The previous frame's size should be equal to the number
1466 # of bytes up to the current frame.
1467 frame_size = pos - last_pos - frame_opcode_size
1468 self.assertEqual(frame_size, last_arg)
1469 last_arg, last_pos = arg, pos
1470 # The last frame's size should be equal to the number of bytes up
1471 # to the pickle's end.
1472 frame_size = len(pickled) - last_pos - frame_opcode_size
1473 self.assertEqual(frame_size, last_arg)
1474
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001475 def test_framing_many_objects(self):
1476 obj = list(range(10**5))
1477 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1478 with self.subTest(proto=proto):
1479 pickled = self.dumps(obj, proto)
1480 unpickled = self.loads(pickled)
1481 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001482 bytes_per_frame = (len(pickled) /
1483 count_opcode(pickle.FRAME, pickled))
1484 self.assertGreater(bytes_per_frame,
1485 self.FRAME_SIZE_TARGET / 2)
1486 self.assertLessEqual(bytes_per_frame,
1487 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001488 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001489
1490 def test_framing_large_objects(self):
1491 N = 1024 * 1024
1492 obj = [b'x' * N, b'y' * N, b'z' * N]
1493 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1494 with self.subTest(proto=proto):
1495 pickled = self.dumps(obj, proto)
1496 unpickled = self.loads(pickled)
1497 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001498 n_frames = count_opcode(pickle.FRAME, pickled)
Alexandre Vassalotti28d271e2013-12-01 16:27:46 -08001499 self.assertGreaterEqual(n_frames, len(obj))
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001500 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001501
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001502 def test_optional_frames(self):
1503 if pickle.HIGHEST_PROTOCOL < 4:
1504 return
1505
1506 def remove_frames(pickled, keep_frame=None):
1507 """Remove frame opcodes from the given pickle."""
1508 frame_starts = []
1509 # 1 byte for the opcode and 8 for the argument
1510 frame_opcode_size = 9
1511 for opcode, _, pos in pickletools.genops(pickled):
1512 if opcode.name == 'FRAME':
1513 frame_starts.append(pos)
1514
1515 newpickle = bytearray()
1516 last_frame_end = 0
1517 for i, pos in enumerate(frame_starts):
1518 if keep_frame and keep_frame(i):
1519 continue
1520 newpickle += pickled[last_frame_end:pos]
1521 last_frame_end = pos + frame_opcode_size
1522 newpickle += pickled[last_frame_end:]
1523 return newpickle
1524
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001525 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001526 num_frames = 20
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001527 obj = [bytes([i]) * frame_size for i in range(num_frames)]
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001528
1529 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1530 pickled = self.dumps(obj, proto)
1531
1532 frameless_pickle = remove_frames(pickled)
1533 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
1534 self.assertEqual(obj, self.loads(frameless_pickle))
1535
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001536 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001537 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
1538 count_opcode(pickle.FRAME, pickled))
1539 self.assertEqual(obj, self.loads(some_frames_pickle))
1540
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001541 def test_nested_names(self):
1542 global Nested
1543 class Nested:
1544 class A:
1545 class B:
1546 class C:
1547 pass
1548
1549 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1550 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
1551 with self.subTest(proto=proto, obj=obj):
1552 unpickled = self.loads(self.dumps(obj, proto))
1553 self.assertIs(obj, unpickled)
1554
1555 def test_py_methods(self):
1556 global PyMethodsTest
1557 class PyMethodsTest:
1558 @staticmethod
1559 def cheese():
1560 return "cheese"
1561 @classmethod
1562 def wine(cls):
1563 assert cls is PyMethodsTest
1564 return "wine"
1565 def biscuits(self):
1566 assert isinstance(self, PyMethodsTest)
1567 return "biscuits"
1568 class Nested:
1569 "Nested class"
1570 @staticmethod
1571 def ketchup():
1572 return "ketchup"
1573 @classmethod
1574 def maple(cls):
1575 assert cls is PyMethodsTest.Nested
1576 return "maple"
1577 def pie(self):
1578 assert isinstance(self, PyMethodsTest.Nested)
1579 return "pie"
1580
1581 py_methods = (
1582 PyMethodsTest.cheese,
1583 PyMethodsTest.wine,
1584 PyMethodsTest().biscuits,
1585 PyMethodsTest.Nested.ketchup,
1586 PyMethodsTest.Nested.maple,
1587 PyMethodsTest.Nested().pie
1588 )
1589 py_unbound_methods = (
1590 (PyMethodsTest.biscuits, PyMethodsTest),
1591 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
1592 )
1593 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1594 for method in py_methods:
1595 with self.subTest(proto=proto, method=method):
1596 unpickled = self.loads(self.dumps(method, proto))
1597 self.assertEqual(method(), unpickled())
1598 for method, cls in py_unbound_methods:
1599 obj = cls()
1600 with self.subTest(proto=proto, method=method):
1601 unpickled = self.loads(self.dumps(method, proto))
1602 self.assertEqual(method(obj), unpickled(obj))
1603
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001604 def test_c_methods(self):
1605 global Subclass
1606 class Subclass(tuple):
1607 class Nested(str):
1608 pass
1609
1610 c_methods = (
1611 # bound built-in method
1612 ("abcd".index, ("c",)),
1613 # unbound built-in method
1614 (str.index, ("abcd", "c")),
1615 # bound "slot" method
1616 ([1, 2, 3].__len__, ()),
1617 # unbound "slot" method
1618 (list.__len__, ([1, 2, 3],)),
1619 # bound "coexist" method
1620 ({1, 2}.__contains__, (2,)),
1621 # unbound "coexist" method
1622 (set.__contains__, ({1, 2}, 2)),
1623 # built-in class method
1624 (dict.fromkeys, (("a", 1), ("b", 2))),
1625 # built-in static method
1626 (bytearray.maketrans, (b"abc", b"xyz")),
1627 # subclass methods
1628 (Subclass([1,2,2]).count, (2,)),
1629 (Subclass.count, (Subclass([1,2,2]), 2)),
1630 (Subclass.Nested("sweet").count, ("e",)),
1631 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
1632 )
1633 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1634 for method, args in c_methods:
1635 with self.subTest(proto=proto, method=method):
1636 unpickled = self.loads(self.dumps(method, proto))
1637 self.assertEqual(method(*args), unpickled(*args))
1638
Antoine Pitrou6cd5eda2014-12-02 00:20:03 +01001639 def test_local_lookup_error(self):
1640 # Test that whichmodule() errors out cleanly when looking up
1641 # an assumed globally-reachable object fails.
1642 def f():
1643 pass
1644 # Since the function is local, lookup will fail
1645 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1646 with self.assertRaises((AttributeError, pickle.PicklingError)):
1647 pickletools.dis(self.dumps(f, proto))
1648 # Same without a __module__ attribute (exercises a different path
1649 # in _pickle.c).
1650 del f.__module__
1651 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1652 with self.assertRaises((AttributeError, pickle.PicklingError)):
1653 pickletools.dis(self.dumps(f, proto))
1654 # Yet a different path.
1655 f.__name__ = f.__qualname__
1656 for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
1657 with self.assertRaises((AttributeError, pickle.PicklingError)):
1658 pickletools.dis(self.dumps(f, proto))
1659
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001660
1661class BigmemPickleTests(unittest.TestCase):
1662
1663 # Binary protocols can serialize longs of up to 2GB-1
1664
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001665 @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001666 def test_huge_long_32b(self, size):
1667 data = 1 << (8 * size)
1668 try:
1669 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001670 if proto < 2:
1671 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001672 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001673 with self.assertRaises((ValueError, OverflowError)):
1674 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001675 finally:
1676 data = None
1677
1678 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1679 # (older protocols don't have a dedicated opcode for bytes and are
1680 # too inefficient)
1681
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001682 @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001683 def test_huge_bytes_32b(self, size):
1684 data = b"abcd" * (size // 4)
1685 try:
1686 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001687 if proto < 3:
1688 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001689 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001690 try:
1691 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001692 header = (pickle.BINBYTES +
1693 struct.pack("<I", len(data)))
1694 data_start = pickled.index(data)
1695 self.assertEqual(
1696 header,
1697 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001698 finally:
1699 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001700 finally:
1701 data = None
1702
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001703 @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001704 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001705 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001706 try:
1707 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001708 if proto < 3:
1709 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001710 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001711 if proto == 3:
1712 # Protocol 3 does not support large bytes objects.
1713 # Verify that we do not crash when processing one.
1714 with self.assertRaises((ValueError, OverflowError)):
1715 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001716 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001717 try:
1718 pickled = self.dumps(data, protocol=proto)
1719 header = (pickle.BINBYTES8 +
1720 struct.pack("<Q", len(data)))
1721 data_start = pickled.index(data)
1722 self.assertEqual(
1723 header,
1724 pickled[data_start-len(header):data_start])
1725 finally:
1726 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001727 finally:
1728 data = None
1729
1730 # All protocols use 1-byte per printable ASCII character; we add another
1731 # byte because the encoded form has to be copied into the internal buffer.
1732
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001733 @bigmemtest(size=_2G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001734 def test_huge_str_32b(self, size):
1735 data = "abcd" * (size // 4)
1736 try:
1737 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001738 if proto == 0:
1739 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001740 with self.subTest(proto=proto):
1741 try:
1742 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001743 header = (pickle.BINUNICODE +
1744 struct.pack("<I", len(data)))
1745 data_start = pickled.index(b'abcd')
1746 self.assertEqual(
1747 header,
1748 pickled[data_start-len(header):data_start])
1749 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1750 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001751 finally:
1752 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001753 finally:
1754 data = None
1755
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001756 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
1757 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
1758 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02001759
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001760 @bigmemtest(size=_4G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001761 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001762 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001763 try:
1764 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001765 if proto == 0:
1766 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001767 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001768 if proto < 4:
1769 with self.assertRaises((ValueError, OverflowError)):
1770 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001771 continue
1772 try:
1773 pickled = self.dumps(data, protocol=proto)
1774 header = (pickle.BINUNICODE8 +
1775 struct.pack("<Q", len(data)))
1776 data_start = pickled.index(b'abcd')
1777 self.assertEqual(
1778 header,
1779 pickled[data_start-len(header):data_start])
1780 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1781 pickled.index(b"abcd")), len(data))
1782 finally:
1783 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001784 finally:
1785 data = None
1786
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001787
Guido van Rossum2a30b212003-02-18 22:41:24 +00001788# Test classes for reduce_ex
1789
1790class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001791 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001792 _reduce_called = 0
1793 def __reduce__(self):
1794 self._reduce_called = 1
1795 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001796
1797class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001798 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001799 _proto = None
1800 def __reduce_ex__(self, proto):
1801 self._proto = proto
1802 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001803
1804class REX_three(object):
1805 _proto = None
1806 def __reduce_ex__(self, proto):
1807 self._proto = proto
1808 return REX_two, ()
1809 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001810 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001811
Guido van Rossumd8faa362007-04-27 19:54:29 +00001812class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001813 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001814 _proto = None
1815 def __reduce_ex__(self, proto):
1816 self._proto = proto
1817 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001818
1819class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001820 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001821 _reduce_called = 0
1822 def __reduce__(self):
1823 self._reduce_called = 1
1824 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001825
1826class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001827 """This class is used to check the 4th argument (list iterator) of
1828 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001829 """
1830 def __init__(self, items=None):
1831 self.items = items if items is not None else []
1832 def __eq__(self, other):
1833 return type(self) is type(other) and self.items == self.items
1834 def append(self, item):
1835 self.items.append(item)
1836 def __reduce__(self):
1837 return type(self), (), None, iter(self.items), None
1838
1839class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001840 """This class is used to check the 5th argument (dict iterator) of
1841 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001842 """
1843 def __init__(self, table=None):
1844 self.table = table if table is not None else {}
1845 def __eq__(self, other):
1846 return type(self) is type(other) and self.table == self.table
1847 def __setitem__(self, key, value):
1848 self.table[key] = value
1849 def __reduce__(self):
1850 return type(self), (), None, None, iter(self.table.items())
1851
Guido van Rossumd8faa362007-04-27 19:54:29 +00001852
Guido van Rossum2a30b212003-02-18 22:41:24 +00001853# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001854
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001855class MyInt(int):
1856 sample = 1
1857
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001858class MyFloat(float):
1859 sample = 1.0
1860
1861class MyComplex(complex):
1862 sample = 1.0 + 0.0j
1863
1864class MyStr(str):
1865 sample = "hello"
1866
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001867class MyUnicode(str):
1868 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001869
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001870class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001871 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001872
1873class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001874 sample = [1, 2, 3]
1875
1876class MyDict(dict):
1877 sample = {"a": 1, "b": 2}
1878
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001879class MySet(set):
1880 sample = {"a", "b"}
1881
1882class MyFrozenSet(frozenset):
1883 sample = frozenset({"a", "b"})
1884
Mark Dickinson5c2db372009-12-05 20:28:34 +00001885myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001886 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001887 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001888 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001889
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001890
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001891class SlotList(MyList):
1892 __slots__ = ["foo"]
1893
Tim Peterse9ef2032003-02-13 18:42:00 +00001894class SimpleNewObj(object):
1895 def __init__(self, a, b, c):
1896 # raise an error, to make sure this isn't called
1897 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001898 def __eq__(self, other):
1899 return self.__dict__ == other.__dict__
Tim Peterse9ef2032003-02-13 18:42:00 +00001900
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001901class BadGetattr:
1902 def __getattr__(self, key):
1903 self.foo
1904
Collin Winter771d8342009-04-16 03:18:06 +00001905
Jeremy Hylton66426532001-10-15 21:38:56 +00001906class AbstractPickleModuleTests(unittest.TestCase):
1907
1908 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001909 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001910 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001911 try:
1912 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001913 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001914 finally:
1915 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001916
1917 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001918 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001919 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001920 try:
1921 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001922 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001923 finally:
1924 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001925
Collin Winter771d8342009-04-16 03:18:06 +00001926 def test_load_from_and_dump_to_file(self):
1927 stream = io.BytesIO()
1928 data = [123, {}, 124]
1929 pickle.dump(data, stream)
1930 stream.seek(0)
1931 unpickled = pickle.load(stream)
1932 self.assertEqual(unpickled, data)
1933
Tim Petersc0c93702003-02-13 19:30:57 +00001934 def test_highest_protocol(self):
1935 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001936 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00001937
Martin v. Löwis544f1192004-07-27 05:22:33 +00001938 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001939 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001940 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001941 pickle.dump(123, f, -1)
1942 pickle.dump(123, file=f, protocol=-1)
1943 pickle.dumps(123, -1)
1944 pickle.dumps(123, protocol=-1)
1945 pickle.Pickler(f, -1)
1946 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001947
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001948 def test_bad_init(self):
1949 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001950 # Override initialization without calling __init__() of the superclass.
1951 class BadPickler(pickle.Pickler):
1952 def __init__(self): pass
1953
1954 class BadUnpickler(pickle.Unpickler):
1955 def __init__(self): pass
1956
1957 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1958 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1959
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001960 def test_bad_input(self):
1961 # Test issue4298
1962 s = bytes([0x58, 0, 0, 0, 0x54])
1963 self.assertRaises(EOFError, pickle.loads, s)
1964
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001965
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001966class AbstractPersistentPicklerTests(unittest.TestCase):
1967
1968 # This class defines persistent_id() and persistent_load()
1969 # functions that should be used by the pickler. All even integers
1970 # are pickled using persistent ids.
1971
1972 def persistent_id(self, object):
1973 if isinstance(object, int) and object % 2 == 0:
1974 self.id_count += 1
1975 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001976 elif object == "test_false_value":
1977 self.false_count += 1
1978 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001979 else:
1980 return None
1981
1982 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001983 if not oid:
1984 self.load_false_count += 1
1985 return "test_false_value"
1986 else:
1987 self.load_count += 1
1988 object = int(oid)
1989 assert object % 2 == 0
1990 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001991
1992 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001993 L = list(range(10)) + ["test_false_value"]
1994 for proto in protocols:
1995 self.id_count = 0
1996 self.false_count = 0
1997 self.load_false_count = 0
1998 self.load_count = 0
1999 self.assertEqual(self.loads(self.dumps(L, proto)), L)
2000 self.assertEqual(self.id_count, 5)
2001 self.assertEqual(self.false_count, 1)
2002 self.assertEqual(self.load_count, 5)
2003 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00002004
Collin Winter771d8342009-04-16 03:18:06 +00002005
2006class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
2007
2008 pickler_class = None
2009 unpickler_class = None
2010
2011 def setUp(self):
2012 assert self.pickler_class
2013 assert self.unpickler_class
2014
2015 def test_clear_pickler_memo(self):
2016 # To test whether clear_memo() has any effect, we pickle an object,
2017 # then pickle it again without clearing the memo; the two serialized
2018 # forms should be different. If we clear_memo() and then pickle the
2019 # object again, the third serialized form should be identical to the
2020 # first one we obtained.
2021 data = ["abcdefg", "abcdefg", 44]
2022 f = io.BytesIO()
2023 pickler = self.pickler_class(f)
2024
2025 pickler.dump(data)
2026 first_pickled = f.getvalue()
2027
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002028 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00002029 f.seek(0)
2030 f.truncate()
2031
2032 pickler.dump(data)
2033 second_pickled = f.getvalue()
2034
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002035 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00002036 pickler.clear_memo()
2037 f.seek(0)
2038 f.truncate()
2039
2040 pickler.dump(data)
2041 third_pickled = f.getvalue()
2042
2043 self.assertNotEqual(first_pickled, second_pickled)
2044 self.assertEqual(first_pickled, third_pickled)
2045
2046 def test_priming_pickler_memo(self):
2047 # Verify that we can set the Pickler's memo attribute.
2048 data = ["abcdefg", "abcdefg", 44]
2049 f = io.BytesIO()
2050 pickler = self.pickler_class(f)
2051
2052 pickler.dump(data)
2053 first_pickled = f.getvalue()
2054
2055 f = io.BytesIO()
2056 primed = self.pickler_class(f)
2057 primed.memo = pickler.memo
2058
2059 primed.dump(data)
2060 primed_pickled = f.getvalue()
2061
2062 self.assertNotEqual(first_pickled, primed_pickled)
2063
2064 def test_priming_unpickler_memo(self):
2065 # Verify that we can set the Unpickler's memo attribute.
2066 data = ["abcdefg", "abcdefg", 44]
2067 f = io.BytesIO()
2068 pickler = self.pickler_class(f)
2069
2070 pickler.dump(data)
2071 first_pickled = f.getvalue()
2072
2073 f = io.BytesIO()
2074 primed = self.pickler_class(f)
2075 primed.memo = pickler.memo
2076
2077 primed.dump(data)
2078 primed_pickled = f.getvalue()
2079
2080 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2081 unpickled_data1 = unpickler.load()
2082
2083 self.assertEqual(unpickled_data1, data)
2084
2085 primed = self.unpickler_class(io.BytesIO(primed_pickled))
2086 primed.memo = unpickler.memo
2087 unpickled_data2 = primed.load()
2088
2089 primed.memo.clear()
2090
2091 self.assertEqual(unpickled_data2, data)
2092 self.assertTrue(unpickled_data2 is unpickled_data1)
2093
2094 def test_reusing_unpickler_objects(self):
2095 data1 = ["abcdefg", "abcdefg", 44]
2096 f = io.BytesIO()
2097 pickler = self.pickler_class(f)
2098 pickler.dump(data1)
2099 pickled1 = f.getvalue()
2100
2101 data2 = ["abcdefg", 44, 44]
2102 f = io.BytesIO()
2103 pickler = self.pickler_class(f)
2104 pickler.dump(data2)
2105 pickled2 = f.getvalue()
2106
2107 f = io.BytesIO()
2108 f.write(pickled1)
2109 f.seek(0)
2110 unpickler = self.unpickler_class(f)
2111 self.assertEqual(unpickler.load(), data1)
2112
2113 f.seek(0)
2114 f.truncate()
2115 f.write(pickled2)
2116 f.seek(0)
2117 self.assertEqual(unpickler.load(), data2)
2118
Antoine Pitrou04248a82010-10-12 20:51:21 +00002119 def _check_multiple_unpicklings(self, ioclass):
2120 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002121 with self.subTest(proto=proto):
2122 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2123 f = ioclass()
2124 pickler = self.pickler_class(f, protocol=proto)
2125 pickler.dump(data1)
2126 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002127
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002128 N = 5
2129 f = ioclass(pickled * N)
2130 unpickler = self.unpickler_class(f)
2131 for i in range(N):
2132 if f.seekable():
2133 pos = f.tell()
2134 self.assertEqual(unpickler.load(), data1)
2135 if f.seekable():
2136 self.assertEqual(f.tell(), pos + len(pickled))
2137 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002138
2139 def test_multiple_unpicklings_seekable(self):
2140 self._check_multiple_unpicklings(io.BytesIO)
2141
2142 def test_multiple_unpicklings_unseekable(self):
2143 self._check_multiple_unpicklings(UnseekableIO)
2144
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002145 def test_unpickling_buffering_readline(self):
2146 # Issue #12687: the unpickler's buffering logic could fail with
2147 # text mode opcodes.
2148 data = list(range(10))
2149 for proto in protocols:
2150 for buf_size in range(1, 11):
2151 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2152 pickler = self.pickler_class(f, protocol=proto)
2153 pickler.dump(data)
2154 f.seek(0)
2155 unpickler = self.unpickler_class(f)
2156 self.assertEqual(unpickler.load(), data)
2157
Collin Winter771d8342009-04-16 03:18:06 +00002158
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002159# Tests for dispatch_table attribute
2160
2161REDUCE_A = 'reduce_A'
2162
2163class AAA(object):
2164 def __reduce__(self):
2165 return str, (REDUCE_A,)
2166
2167class BBB(object):
2168 pass
2169
2170class AbstractDispatchTableTests(unittest.TestCase):
2171
2172 def test_default_dispatch_table(self):
2173 # No dispatch_table attribute by default
2174 f = io.BytesIO()
2175 p = self.pickler_class(f, 0)
2176 with self.assertRaises(AttributeError):
2177 p.dispatch_table
2178 self.assertFalse(hasattr(p, 'dispatch_table'))
2179
2180 def test_class_dispatch_table(self):
2181 # A dispatch_table attribute can be specified class-wide
2182 dt = self.get_dispatch_table()
2183
2184 class MyPickler(self.pickler_class):
2185 dispatch_table = dt
2186
2187 def dumps(obj, protocol=None):
2188 f = io.BytesIO()
2189 p = MyPickler(f, protocol)
2190 self.assertEqual(p.dispatch_table, dt)
2191 p.dump(obj)
2192 return f.getvalue()
2193
2194 self._test_dispatch_table(dumps, dt)
2195
2196 def test_instance_dispatch_table(self):
2197 # A dispatch_table attribute can also be specified instance-wide
2198 dt = self.get_dispatch_table()
2199
2200 def dumps(obj, protocol=None):
2201 f = io.BytesIO()
2202 p = self.pickler_class(f, protocol)
2203 p.dispatch_table = dt
2204 self.assertEqual(p.dispatch_table, dt)
2205 p.dump(obj)
2206 return f.getvalue()
2207
2208 self._test_dispatch_table(dumps, dt)
2209
2210 def _test_dispatch_table(self, dumps, dispatch_table):
2211 def custom_load_dump(obj):
2212 return pickle.loads(dumps(obj, 0))
2213
2214 def default_load_dump(obj):
2215 return pickle.loads(pickle.dumps(obj, 0))
2216
2217 # pickling complex numbers using protocol 0 relies on copyreg
2218 # so check pickling a complex number still works
2219 z = 1 + 2j
2220 self.assertEqual(custom_load_dump(z), z)
2221 self.assertEqual(default_load_dump(z), z)
2222
2223 # modify pickling of complex
2224 REDUCE_1 = 'reduce_1'
2225 def reduce_1(obj):
2226 return str, (REDUCE_1,)
2227 dispatch_table[complex] = reduce_1
2228 self.assertEqual(custom_load_dump(z), REDUCE_1)
2229 self.assertEqual(default_load_dump(z), z)
2230
2231 # check picklability of AAA and BBB
2232 a = AAA()
2233 b = BBB()
2234 self.assertEqual(custom_load_dump(a), REDUCE_A)
2235 self.assertIsInstance(custom_load_dump(b), BBB)
2236 self.assertEqual(default_load_dump(a), REDUCE_A)
2237 self.assertIsInstance(default_load_dump(b), BBB)
2238
2239 # modify pickling of BBB
2240 dispatch_table[BBB] = reduce_1
2241 self.assertEqual(custom_load_dump(a), REDUCE_A)
2242 self.assertEqual(custom_load_dump(b), REDUCE_1)
2243 self.assertEqual(default_load_dump(a), REDUCE_A)
2244 self.assertIsInstance(default_load_dump(b), BBB)
2245
2246 # revert pickling of BBB and modify pickling of AAA
2247 REDUCE_2 = 'reduce_2'
2248 def reduce_2(obj):
2249 return str, (REDUCE_2,)
2250 dispatch_table[AAA] = reduce_2
2251 del dispatch_table[BBB]
2252 self.assertEqual(custom_load_dump(a), REDUCE_2)
2253 self.assertIsInstance(custom_load_dump(b), BBB)
2254 self.assertEqual(default_load_dump(a), REDUCE_A)
2255 self.assertIsInstance(default_load_dump(b), BBB)
2256
2257
Guido van Rossum98297ee2007-11-06 21:34:58 +00002258if __name__ == "__main__":
2259 # Print some stuff that can be used to rewrite DATA{0,1,2}
2260 from pickletools import dis
2261 x = create_data()
2262 for i in range(3):
2263 p = pickle.dumps(x, i)
2264 print("DATA{0} = (".format(i))
2265 for j in range(0, len(p), 20):
2266 b = bytes(p[j:j+20])
2267 print(" {0!r}".format(b))
2268 print(")")
2269 print()
2270 print("# Disassembly of DATA{0}".format(i))
2271 print("DATA{0}_DIS = \"\"\"\\".format(i))
2272 dis(p)
2273 print("\"\"\"")
2274 print()