blob: 5963175ddd1565602345b8e3c9228a948de3a6fb [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 Pitrou82be19f2011-08-29 23:09:33 +02001639
1640class BigmemPickleTests(unittest.TestCase):
1641
1642 # Binary protocols can serialize longs of up to 2GB-1
1643
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001644 @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001645 def test_huge_long_32b(self, size):
1646 data = 1 << (8 * size)
1647 try:
1648 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001649 if proto < 2:
1650 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001651 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001652 with self.assertRaises((ValueError, OverflowError)):
1653 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001654 finally:
1655 data = None
1656
1657 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1658 # (older protocols don't have a dedicated opcode for bytes and are
1659 # too inefficient)
1660
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001661 @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001662 def test_huge_bytes_32b(self, size):
1663 data = b"abcd" * (size // 4)
1664 try:
1665 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001666 if proto < 3:
1667 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001668 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001669 try:
1670 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001671 header = (pickle.BINBYTES +
1672 struct.pack("<I", len(data)))
1673 data_start = pickled.index(data)
1674 self.assertEqual(
1675 header,
1676 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001677 finally:
1678 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001679 finally:
1680 data = None
1681
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001682 @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001683 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001684 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001685 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):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001690 if proto == 3:
1691 # Protocol 3 does not support large bytes objects.
1692 # Verify that we do not crash when processing one.
1693 with self.assertRaises((ValueError, OverflowError)):
1694 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001695 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001696 try:
1697 pickled = self.dumps(data, protocol=proto)
1698 header = (pickle.BINBYTES8 +
1699 struct.pack("<Q", len(data)))
1700 data_start = pickled.index(data)
1701 self.assertEqual(
1702 header,
1703 pickled[data_start-len(header):data_start])
1704 finally:
1705 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001706 finally:
1707 data = None
1708
1709 # All protocols use 1-byte per printable ASCII character; we add another
1710 # byte because the encoded form has to be copied into the internal buffer.
1711
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001712 @bigmemtest(size=_2G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001713 def test_huge_str_32b(self, size):
1714 data = "abcd" * (size // 4)
1715 try:
1716 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001717 if proto == 0:
1718 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001719 with self.subTest(proto=proto):
1720 try:
1721 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001722 header = (pickle.BINUNICODE +
1723 struct.pack("<I", len(data)))
1724 data_start = pickled.index(b'abcd')
1725 self.assertEqual(
1726 header,
1727 pickled[data_start-len(header):data_start])
1728 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1729 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001730 finally:
1731 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001732 finally:
1733 data = None
1734
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001735 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
1736 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
1737 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02001738
Serhiy Storchaka4847e4e2014-01-10 13:37:54 +02001739 @bigmemtest(size=_4G, memuse=8, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001740 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001741 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001742 try:
1743 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001744 if proto == 0:
1745 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001746 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001747 if proto < 4:
1748 with self.assertRaises((ValueError, OverflowError)):
1749 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001750 continue
1751 try:
1752 pickled = self.dumps(data, protocol=proto)
1753 header = (pickle.BINUNICODE8 +
1754 struct.pack("<Q", len(data)))
1755 data_start = pickled.index(b'abcd')
1756 self.assertEqual(
1757 header,
1758 pickled[data_start-len(header):data_start])
1759 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1760 pickled.index(b"abcd")), len(data))
1761 finally:
1762 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001763 finally:
1764 data = None
1765
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001766
Guido van Rossum2a30b212003-02-18 22:41:24 +00001767# Test classes for reduce_ex
1768
1769class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001770 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001771 _reduce_called = 0
1772 def __reduce__(self):
1773 self._reduce_called = 1
1774 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001775
1776class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001777 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001778 _proto = None
1779 def __reduce_ex__(self, proto):
1780 self._proto = proto
1781 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001782
1783class REX_three(object):
1784 _proto = None
1785 def __reduce_ex__(self, proto):
1786 self._proto = proto
1787 return REX_two, ()
1788 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001789 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001790
Guido van Rossumd8faa362007-04-27 19:54:29 +00001791class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001792 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001793 _proto = None
1794 def __reduce_ex__(self, proto):
1795 self._proto = proto
1796 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001797
1798class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001799 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001800 _reduce_called = 0
1801 def __reduce__(self):
1802 self._reduce_called = 1
1803 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001804
1805class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001806 """This class is used to check the 4th argument (list iterator) of
1807 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001808 """
1809 def __init__(self, items=None):
1810 self.items = items if items is not None else []
1811 def __eq__(self, other):
1812 return type(self) is type(other) and self.items == self.items
1813 def append(self, item):
1814 self.items.append(item)
1815 def __reduce__(self):
1816 return type(self), (), None, iter(self.items), None
1817
1818class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001819 """This class is used to check the 5th argument (dict iterator) of
1820 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001821 """
1822 def __init__(self, table=None):
1823 self.table = table if table is not None else {}
1824 def __eq__(self, other):
1825 return type(self) is type(other) and self.table == self.table
1826 def __setitem__(self, key, value):
1827 self.table[key] = value
1828 def __reduce__(self):
1829 return type(self), (), None, None, iter(self.table.items())
1830
Guido van Rossumd8faa362007-04-27 19:54:29 +00001831
Guido van Rossum2a30b212003-02-18 22:41:24 +00001832# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001833
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001834class MyInt(int):
1835 sample = 1
1836
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001837class MyFloat(float):
1838 sample = 1.0
1839
1840class MyComplex(complex):
1841 sample = 1.0 + 0.0j
1842
1843class MyStr(str):
1844 sample = "hello"
1845
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001846class MyUnicode(str):
1847 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001848
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001849class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001850 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001851
1852class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001853 sample = [1, 2, 3]
1854
1855class MyDict(dict):
1856 sample = {"a": 1, "b": 2}
1857
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001858class MySet(set):
1859 sample = {"a", "b"}
1860
1861class MyFrozenSet(frozenset):
1862 sample = frozenset({"a", "b"})
1863
Mark Dickinson5c2db372009-12-05 20:28:34 +00001864myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001865 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001866 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001867 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001868
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001869
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001870class SlotList(MyList):
1871 __slots__ = ["foo"]
1872
Tim Peterse9ef2032003-02-13 18:42:00 +00001873class SimpleNewObj(object):
1874 def __init__(self, a, b, c):
1875 # raise an error, to make sure this isn't called
1876 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001877 def __eq__(self, other):
1878 return self.__dict__ == other.__dict__
Tim Peterse9ef2032003-02-13 18:42:00 +00001879
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001880class BadGetattr:
1881 def __getattr__(self, key):
1882 self.foo
1883
Collin Winter771d8342009-04-16 03:18:06 +00001884
Jeremy Hylton66426532001-10-15 21:38:56 +00001885class AbstractPickleModuleTests(unittest.TestCase):
1886
1887 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001888 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001889 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001890 try:
1891 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001892 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001893 finally:
1894 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001895
1896 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001897 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001898 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001899 try:
1900 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001901 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001902 finally:
1903 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001904
Collin Winter771d8342009-04-16 03:18:06 +00001905 def test_load_from_and_dump_to_file(self):
1906 stream = io.BytesIO()
1907 data = [123, {}, 124]
1908 pickle.dump(data, stream)
1909 stream.seek(0)
1910 unpickled = pickle.load(stream)
1911 self.assertEqual(unpickled, data)
1912
Tim Petersc0c93702003-02-13 19:30:57 +00001913 def test_highest_protocol(self):
1914 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001915 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00001916
Martin v. Löwis544f1192004-07-27 05:22:33 +00001917 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001918 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001919 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001920 pickle.dump(123, f, -1)
1921 pickle.dump(123, file=f, protocol=-1)
1922 pickle.dumps(123, -1)
1923 pickle.dumps(123, protocol=-1)
1924 pickle.Pickler(f, -1)
1925 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001926
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001927 def test_bad_init(self):
1928 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001929 # Override initialization without calling __init__() of the superclass.
1930 class BadPickler(pickle.Pickler):
1931 def __init__(self): pass
1932
1933 class BadUnpickler(pickle.Unpickler):
1934 def __init__(self): pass
1935
1936 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1937 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1938
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001939 def test_bad_input(self):
1940 # Test issue4298
1941 s = bytes([0x58, 0, 0, 0, 0x54])
1942 self.assertRaises(EOFError, pickle.loads, s)
1943
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001944
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001945class AbstractPersistentPicklerTests(unittest.TestCase):
1946
1947 # This class defines persistent_id() and persistent_load()
1948 # functions that should be used by the pickler. All even integers
1949 # are pickled using persistent ids.
1950
1951 def persistent_id(self, object):
1952 if isinstance(object, int) and object % 2 == 0:
1953 self.id_count += 1
1954 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001955 elif object == "test_false_value":
1956 self.false_count += 1
1957 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001958 else:
1959 return None
1960
1961 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001962 if not oid:
1963 self.load_false_count += 1
1964 return "test_false_value"
1965 else:
1966 self.load_count += 1
1967 object = int(oid)
1968 assert object % 2 == 0
1969 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001970
1971 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001972 L = list(range(10)) + ["test_false_value"]
1973 for proto in protocols:
1974 self.id_count = 0
1975 self.false_count = 0
1976 self.load_false_count = 0
1977 self.load_count = 0
1978 self.assertEqual(self.loads(self.dumps(L, proto)), L)
1979 self.assertEqual(self.id_count, 5)
1980 self.assertEqual(self.false_count, 1)
1981 self.assertEqual(self.load_count, 5)
1982 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001983
Collin Winter771d8342009-04-16 03:18:06 +00001984
1985class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1986
1987 pickler_class = None
1988 unpickler_class = None
1989
1990 def setUp(self):
1991 assert self.pickler_class
1992 assert self.unpickler_class
1993
1994 def test_clear_pickler_memo(self):
1995 # To test whether clear_memo() has any effect, we pickle an object,
1996 # then pickle it again without clearing the memo; the two serialized
1997 # forms should be different. If we clear_memo() and then pickle the
1998 # object again, the third serialized form should be identical to the
1999 # first one we obtained.
2000 data = ["abcdefg", "abcdefg", 44]
2001 f = io.BytesIO()
2002 pickler = self.pickler_class(f)
2003
2004 pickler.dump(data)
2005 first_pickled = f.getvalue()
2006
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002007 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00002008 f.seek(0)
2009 f.truncate()
2010
2011 pickler.dump(data)
2012 second_pickled = f.getvalue()
2013
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002014 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00002015 pickler.clear_memo()
2016 f.seek(0)
2017 f.truncate()
2018
2019 pickler.dump(data)
2020 third_pickled = f.getvalue()
2021
2022 self.assertNotEqual(first_pickled, second_pickled)
2023 self.assertEqual(first_pickled, third_pickled)
2024
2025 def test_priming_pickler_memo(self):
2026 # Verify that we can set the Pickler's memo attribute.
2027 data = ["abcdefg", "abcdefg", 44]
2028 f = io.BytesIO()
2029 pickler = self.pickler_class(f)
2030
2031 pickler.dump(data)
2032 first_pickled = f.getvalue()
2033
2034 f = io.BytesIO()
2035 primed = self.pickler_class(f)
2036 primed.memo = pickler.memo
2037
2038 primed.dump(data)
2039 primed_pickled = f.getvalue()
2040
2041 self.assertNotEqual(first_pickled, primed_pickled)
2042
2043 def test_priming_unpickler_memo(self):
2044 # Verify that we can set the Unpickler's memo attribute.
2045 data = ["abcdefg", "abcdefg", 44]
2046 f = io.BytesIO()
2047 pickler = self.pickler_class(f)
2048
2049 pickler.dump(data)
2050 first_pickled = f.getvalue()
2051
2052 f = io.BytesIO()
2053 primed = self.pickler_class(f)
2054 primed.memo = pickler.memo
2055
2056 primed.dump(data)
2057 primed_pickled = f.getvalue()
2058
2059 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2060 unpickled_data1 = unpickler.load()
2061
2062 self.assertEqual(unpickled_data1, data)
2063
2064 primed = self.unpickler_class(io.BytesIO(primed_pickled))
2065 primed.memo = unpickler.memo
2066 unpickled_data2 = primed.load()
2067
2068 primed.memo.clear()
2069
2070 self.assertEqual(unpickled_data2, data)
2071 self.assertTrue(unpickled_data2 is unpickled_data1)
2072
2073 def test_reusing_unpickler_objects(self):
2074 data1 = ["abcdefg", "abcdefg", 44]
2075 f = io.BytesIO()
2076 pickler = self.pickler_class(f)
2077 pickler.dump(data1)
2078 pickled1 = f.getvalue()
2079
2080 data2 = ["abcdefg", 44, 44]
2081 f = io.BytesIO()
2082 pickler = self.pickler_class(f)
2083 pickler.dump(data2)
2084 pickled2 = f.getvalue()
2085
2086 f = io.BytesIO()
2087 f.write(pickled1)
2088 f.seek(0)
2089 unpickler = self.unpickler_class(f)
2090 self.assertEqual(unpickler.load(), data1)
2091
2092 f.seek(0)
2093 f.truncate()
2094 f.write(pickled2)
2095 f.seek(0)
2096 self.assertEqual(unpickler.load(), data2)
2097
Antoine Pitrou04248a82010-10-12 20:51:21 +00002098 def _check_multiple_unpicklings(self, ioclass):
2099 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002100 with self.subTest(proto=proto):
2101 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2102 f = ioclass()
2103 pickler = self.pickler_class(f, protocol=proto)
2104 pickler.dump(data1)
2105 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002106
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002107 N = 5
2108 f = ioclass(pickled * N)
2109 unpickler = self.unpickler_class(f)
2110 for i in range(N):
2111 if f.seekable():
2112 pos = f.tell()
2113 self.assertEqual(unpickler.load(), data1)
2114 if f.seekable():
2115 self.assertEqual(f.tell(), pos + len(pickled))
2116 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002117
2118 def test_multiple_unpicklings_seekable(self):
2119 self._check_multiple_unpicklings(io.BytesIO)
2120
2121 def test_multiple_unpicklings_unseekable(self):
2122 self._check_multiple_unpicklings(UnseekableIO)
2123
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002124 def test_unpickling_buffering_readline(self):
2125 # Issue #12687: the unpickler's buffering logic could fail with
2126 # text mode opcodes.
2127 data = list(range(10))
2128 for proto in protocols:
2129 for buf_size in range(1, 11):
2130 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2131 pickler = self.pickler_class(f, protocol=proto)
2132 pickler.dump(data)
2133 f.seek(0)
2134 unpickler = self.unpickler_class(f)
2135 self.assertEqual(unpickler.load(), data)
2136
Collin Winter771d8342009-04-16 03:18:06 +00002137
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002138# Tests for dispatch_table attribute
2139
2140REDUCE_A = 'reduce_A'
2141
2142class AAA(object):
2143 def __reduce__(self):
2144 return str, (REDUCE_A,)
2145
2146class BBB(object):
2147 pass
2148
2149class AbstractDispatchTableTests(unittest.TestCase):
2150
2151 def test_default_dispatch_table(self):
2152 # No dispatch_table attribute by default
2153 f = io.BytesIO()
2154 p = self.pickler_class(f, 0)
2155 with self.assertRaises(AttributeError):
2156 p.dispatch_table
2157 self.assertFalse(hasattr(p, 'dispatch_table'))
2158
2159 def test_class_dispatch_table(self):
2160 # A dispatch_table attribute can be specified class-wide
2161 dt = self.get_dispatch_table()
2162
2163 class MyPickler(self.pickler_class):
2164 dispatch_table = dt
2165
2166 def dumps(obj, protocol=None):
2167 f = io.BytesIO()
2168 p = MyPickler(f, protocol)
2169 self.assertEqual(p.dispatch_table, dt)
2170 p.dump(obj)
2171 return f.getvalue()
2172
2173 self._test_dispatch_table(dumps, dt)
2174
2175 def test_instance_dispatch_table(self):
2176 # A dispatch_table attribute can also be specified instance-wide
2177 dt = self.get_dispatch_table()
2178
2179 def dumps(obj, protocol=None):
2180 f = io.BytesIO()
2181 p = self.pickler_class(f, protocol)
2182 p.dispatch_table = dt
2183 self.assertEqual(p.dispatch_table, dt)
2184 p.dump(obj)
2185 return f.getvalue()
2186
2187 self._test_dispatch_table(dumps, dt)
2188
2189 def _test_dispatch_table(self, dumps, dispatch_table):
2190 def custom_load_dump(obj):
2191 return pickle.loads(dumps(obj, 0))
2192
2193 def default_load_dump(obj):
2194 return pickle.loads(pickle.dumps(obj, 0))
2195
2196 # pickling complex numbers using protocol 0 relies on copyreg
2197 # so check pickling a complex number still works
2198 z = 1 + 2j
2199 self.assertEqual(custom_load_dump(z), z)
2200 self.assertEqual(default_load_dump(z), z)
2201
2202 # modify pickling of complex
2203 REDUCE_1 = 'reduce_1'
2204 def reduce_1(obj):
2205 return str, (REDUCE_1,)
2206 dispatch_table[complex] = reduce_1
2207 self.assertEqual(custom_load_dump(z), REDUCE_1)
2208 self.assertEqual(default_load_dump(z), z)
2209
2210 # check picklability of AAA and BBB
2211 a = AAA()
2212 b = BBB()
2213 self.assertEqual(custom_load_dump(a), REDUCE_A)
2214 self.assertIsInstance(custom_load_dump(b), BBB)
2215 self.assertEqual(default_load_dump(a), REDUCE_A)
2216 self.assertIsInstance(default_load_dump(b), BBB)
2217
2218 # modify pickling of BBB
2219 dispatch_table[BBB] = reduce_1
2220 self.assertEqual(custom_load_dump(a), REDUCE_A)
2221 self.assertEqual(custom_load_dump(b), REDUCE_1)
2222 self.assertEqual(default_load_dump(a), REDUCE_A)
2223 self.assertIsInstance(default_load_dump(b), BBB)
2224
2225 # revert pickling of BBB and modify pickling of AAA
2226 REDUCE_2 = 'reduce_2'
2227 def reduce_2(obj):
2228 return str, (REDUCE_2,)
2229 dispatch_table[AAA] = reduce_2
2230 del dispatch_table[BBB]
2231 self.assertEqual(custom_load_dump(a), REDUCE_2)
2232 self.assertIsInstance(custom_load_dump(b), BBB)
2233 self.assertEqual(default_load_dump(a), REDUCE_A)
2234 self.assertIsInstance(default_load_dump(b), BBB)
2235
2236
Guido van Rossum98297ee2007-11-06 21:34:58 +00002237if __name__ == "__main__":
2238 # Print some stuff that can be used to rewrite DATA{0,1,2}
2239 from pickletools import dis
2240 x = create_data()
2241 for i in range(3):
2242 p = pickle.dumps(x, i)
2243 print("DATA{0} = (".format(i))
2244 for j in range(0, len(p), 20):
2245 b = bytes(p[j:j+20])
2246 print(" {0!r}".format(b))
2247 print(")")
2248 print()
2249 print("# Disassembly of DATA{0}".format(i))
2250 print("DATA{0}_DIS = \"\"\"\\".format(i))
2251 dis(p)
2252 print("\"\"\"")
2253 print()