blob: 040c26f2577985130d5a0ac54e4cbdee111b34fd [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
Antoine Pitroub7591d42011-10-04 16:18:15 +020024ascii_char_size = 1
Antoine Pitrou82be19f2011-08-29 23:09:33 +020025
Tim Peters22e71712003-02-03 22:27:38 +000026
27# Return True if opcode code appears in the pickle, else False.
28def opcode_in_pickle(code, pickle):
29 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000030 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000031 return True
32 return False
33
Tim Peters8d2613a2003-02-11 16:40:16 +000034# Return the number of times opcode code appears in pickle.
35def count_opcode(code, pickle):
36 n = 0
37 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000038 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000039 n += 1
40 return n
41
Antoine Pitrou04248a82010-10-12 20:51:21 +000042
43class UnseekableIO(io.BytesIO):
44 def peek(self, *args):
45 raise NotImplementedError
46
47 def seekable(self):
48 return False
49
50 def seek(self, *args):
51 raise io.UnsupportedOperation
52
53 def tell(self):
54 raise io.UnsupportedOperation
55
56
Tim Peters3e667d52003-02-04 21:47:44 +000057# We can't very well test the extension registry without putting known stuff
58# in it, but we have to be careful to restore its original state. Code
59# should do this:
60#
61# e = ExtensionSaver(extension_code)
62# try:
63# fiddle w/ the extension registry's stuff for extension_code
64# finally:
65# e.restore()
66
67class ExtensionSaver:
68 # Remember current registration for code (if any), and remove it (if
69 # there is one).
70 def __init__(self, code):
71 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000072 if code in copyreg._inverted_registry:
73 self.pair = copyreg._inverted_registry[code]
74 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000075 else:
76 self.pair = None
77
78 # Restore previous registration for code.
79 def restore(self):
80 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000081 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000082 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000083 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000084 pair = self.pair
85 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000086 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000087
Jeremy Hylton66426532001-10-15 21:38:56 +000088class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000089 def __eq__(self, other):
90 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000091
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000092class D(C):
93 def __init__(self, arg):
94 pass
95
96class E(C):
97 def __getinitargs__(self):
98 return ()
99
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100100class H(object):
101 pass
102
Jeremy Hylton66426532001-10-15 21:38:56 +0000103import __main__
104__main__.C = C
105C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000106__main__.D = D
107D.__module__ = "__main__"
108__main__.E = E
109E.__module__ = "__main__"
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100110__main__.H = H
111H.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000112
113class myint(int):
114 def __init__(self, x):
115 self.str = str(x)
116
117class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000118
Jeremy Hylton66426532001-10-15 21:38:56 +0000119 def __init__(self, a, b):
120 self.a = a
121 self.b = b
122
123 def __getinitargs__(self):
124 return self.a, self.b
125
Guido van Rossum04a86612001-12-19 16:58:54 +0000126class metaclass(type):
127 pass
128
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000129class use_metaclass(object, metaclass=metaclass):
130 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000131
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200132class pickling_metaclass(type):
133 def __eq__(self, other):
134 return (type(self) == type(other) and
135 self.reduce_args == other.reduce_args)
136
137 def __reduce__(self):
138 return (create_dynamic_class, self.reduce_args)
139
140def create_dynamic_class(name, bases):
141 result = pickling_metaclass(name, bases, dict())
142 result.reduce_args = (name, bases)
143 return result
144
Tim Peters70b02d72003-02-02 17:26:40 +0000145# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
146# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000147
Guido van Rossum98297ee2007-11-06 21:34:58 +0000148DATA0 = (
Mark Dickinson8dd05142009-01-20 20:43:58 +0000149 b'(lp0\nL0L\naL1L\naF2.0\nac'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000150 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000151 b'p1\n(F3.0\nF0.0\ntp2\nRp'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000152 b'3\naL1L\naL-1L\naL255L\naL-'
153 b'255L\naL-256L\naL65535L\na'
154 b'L-65535L\naL-65536L\naL2'
155 b'147483647L\naL-2147483'
156 b'647L\naL-2147483648L\na('
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000157 b'Vabc\np4\ng4\nccopyreg'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000158 b'\n_reconstructor\np5\n('
Georg Brandl1a3284e2007-12-02 09:40:06 +0000159 b'c__main__\nC\np6\ncbu'
160 b'iltins\nobject\np7\nNt'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000161 b'p8\nRp9\n(dp10\nVfoo\np1'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000162 b'1\nL1L\nsVbar\np12\nL2L\nsb'
163 b'g9\ntp13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000164)
Tim Peterse9358162001-01-22 22:05:20 +0000165
Guido van Rossum98297ee2007-11-06 21:34:58 +0000166# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000167DATA0_DIS = """\
168 0: ( MARK
169 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000170 2: p PUT 0
171 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000172 9: a APPEND
173 10: L LONG 1
174 14: a APPEND
175 15: F FLOAT 2.0
176 20: a APPEND
177 21: c GLOBAL 'builtins complex'
178 39: p PUT 1
179 42: ( MARK
180 43: F FLOAT 3.0
181 48: F FLOAT 0.0
182 53: t TUPLE (MARK at 42)
183 54: p PUT 2
184 57: R REDUCE
185 58: p PUT 3
186 61: a APPEND
187 62: L LONG 1
188 66: a APPEND
189 67: L LONG -1
190 72: a APPEND
191 73: L LONG 255
192 79: a APPEND
193 80: L LONG -255
194 87: a APPEND
195 88: L LONG -256
196 95: a APPEND
197 96: L LONG 65535
198 104: a APPEND
199 105: L LONG -65535
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000200 114: a APPEND
Mark Dickinson8dd05142009-01-20 20:43:58 +0000201 115: L LONG -65536
202 124: a APPEND
203 125: L LONG 2147483647
204 138: a APPEND
205 139: L LONG -2147483647
206 153: a APPEND
207 154: L LONG -2147483648
208 168: a APPEND
209 169: ( MARK
210 170: V UNICODE 'abc'
211 175: p PUT 4
212 178: g GET 4
213 181: c GLOBAL 'copyreg _reconstructor'
214 205: p PUT 5
215 208: ( MARK
216 209: c GLOBAL '__main__ C'
217 221: p PUT 6
218 224: c GLOBAL 'builtins object'
219 241: p PUT 7
220 244: N NONE
221 245: t TUPLE (MARK at 208)
222 246: p PUT 8
223 249: R REDUCE
224 250: p PUT 9
225 253: ( MARK
226 254: d DICT (MARK at 253)
227 255: p PUT 10
228 259: V UNICODE 'foo'
229 264: p PUT 11
230 268: L LONG 1
231 272: s SETITEM
232 273: V UNICODE 'bar'
233 278: p PUT 12
234 282: L LONG 2
235 286: s SETITEM
236 287: b BUILD
237 288: g GET 9
238 291: t TUPLE (MARK at 169)
239 292: p PUT 13
240 296: a APPEND
241 297: g GET 13
242 301: a APPEND
243 302: L LONG 5
244 306: a APPEND
245 307: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000246highest protocol among opcodes = 0
247"""
248
Guido van Rossum98297ee2007-11-06 21:34:58 +0000249DATA1 = (
Georg Brandl1a3284e2007-12-02 09:40:06 +0000250 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
251 b'builtins\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000252 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
253 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
254 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
255 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000256 b'cq\x04h\x04ccopyreg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000257 b'nstructor\nq\x05(c__main'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000258 b'__\nC\nq\x06cbuiltins\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000259 b'object\nq\x07Ntq\x08Rq\t}q\n('
260 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
261 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
262)
Tim Peters70b02d72003-02-02 17:26:40 +0000263
Guido van Rossum98297ee2007-11-06 21:34:58 +0000264# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000265DATA1_DIS = """\
266 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000267 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000268 3: ( MARK
269 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000270 6: K BININT1 1
271 8: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000272 17: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000273 35: q BINPUT 1
274 37: ( MARK
275 38: G BINFLOAT 3.0
276 47: G BINFLOAT 0.0
277 56: t TUPLE (MARK at 37)
278 57: q BINPUT 2
279 59: R REDUCE
280 60: q BINPUT 3
281 62: K BININT1 1
282 64: J BININT -1
283 69: K BININT1 255
284 71: J BININT -255
285 76: J BININT -256
286 81: M BININT2 65535
287 84: J BININT -65535
288 89: J BININT -65536
289 94: J BININT 2147483647
290 99: J BININT -2147483647
291 104: J BININT -2147483648
292 109: ( MARK
293 110: X BINUNICODE 'abc'
294 118: q BINPUT 4
295 120: h BINGET 4
296 122: c GLOBAL 'copyreg _reconstructor'
297 146: q BINPUT 5
298 148: ( MARK
299 149: c GLOBAL '__main__ C'
300 161: q BINPUT 6
301 163: c GLOBAL 'builtins object'
302 180: q BINPUT 7
303 182: N NONE
304 183: t TUPLE (MARK at 148)
305 184: q BINPUT 8
306 186: R REDUCE
307 187: q BINPUT 9
308 189: } EMPTY_DICT
309 190: q BINPUT 10
310 192: ( MARK
311 193: X BINUNICODE 'foo'
312 201: q BINPUT 11
313 203: K BININT1 1
314 205: X BINUNICODE 'bar'
315 213: q BINPUT 12
316 215: K BININT1 2
317 217: u SETITEMS (MARK at 192)
318 218: b BUILD
319 219: h BINGET 9
320 221: t TUPLE (MARK at 109)
321 222: q BINPUT 13
322 224: h BINGET 13
323 226: K BININT1 5
324 228: e APPENDS (MARK at 3)
325 229: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000326highest protocol among opcodes = 1
327"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000328
Guido van Rossum98297ee2007-11-06 21:34:58 +0000329DATA2 = (
330 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000331 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000332 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
333 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
334 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
335 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
336 b'bcq\x04h\x04c__main__\nC\nq\x05'
337 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
338 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
339 b'\nK\x05e.'
340)
Tim Petersfc273752003-03-02 04:54:24 +0000341
Guido van Rossum98297ee2007-11-06 21:34:58 +0000342# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000343DATA2_DIS = """\
344 0: \x80 PROTO 2
345 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000346 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000347 5: ( MARK
348 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000349 8: K BININT1 1
350 10: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000351 19: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000352 37: q BINPUT 1
353 39: G BINFLOAT 3.0
354 48: G BINFLOAT 0.0
355 57: \x86 TUPLE2
356 58: q BINPUT 2
357 60: R REDUCE
358 61: q BINPUT 3
359 63: K BININT1 1
360 65: J BININT -1
361 70: K BININT1 255
362 72: J BININT -255
363 77: J BININT -256
364 82: M BININT2 65535
365 85: J BININT -65535
366 90: J BININT -65536
367 95: J BININT 2147483647
368 100: J BININT -2147483647
369 105: J BININT -2147483648
370 110: ( MARK
371 111: X BINUNICODE 'abc'
372 119: q BINPUT 4
373 121: h BINGET 4
374 123: c GLOBAL '__main__ C'
375 135: q BINPUT 5
376 137: ) EMPTY_TUPLE
377 138: \x81 NEWOBJ
378 139: q BINPUT 6
379 141: } EMPTY_DICT
380 142: q BINPUT 7
381 144: ( MARK
382 145: X BINUNICODE 'foo'
383 153: q BINPUT 8
384 155: K BININT1 1
385 157: X BINUNICODE 'bar'
386 165: q BINPUT 9
387 167: K BININT1 2
388 169: u SETITEMS (MARK at 144)
389 170: b BUILD
390 171: h BINGET 6
391 173: t TUPLE (MARK at 110)
392 174: q BINPUT 10
393 176: h BINGET 10
394 178: K BININT1 5
395 180: e APPENDS (MARK at 5)
396 181: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000397highest protocol among opcodes = 2
398"""
399
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000400# set([1,2]) pickled from 2.x with protocol 2
401DATA3 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
402
403# xrange(5) pickled from 2.x with protocol 2
404DATA4 = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
405
406# a SimpleCookie() object pickled from 2.x with protocol 2
407DATA5 = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
408 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
409 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
410 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
411 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
412 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
413
414# set([3]) pickled from 2.x with protocol 2
415DATA6 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
416
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100417python2_exceptions_without_args = (
418 ArithmeticError,
419 AssertionError,
420 AttributeError,
421 BaseException,
422 BufferError,
423 BytesWarning,
424 DeprecationWarning,
425 EOFError,
426 EnvironmentError,
427 Exception,
428 FloatingPointError,
429 FutureWarning,
430 GeneratorExit,
431 IOError,
432 ImportError,
433 ImportWarning,
434 IndentationError,
435 IndexError,
436 KeyError,
437 KeyboardInterrupt,
438 LookupError,
439 MemoryError,
440 NameError,
441 NotImplementedError,
442 OSError,
443 OverflowError,
444 PendingDeprecationWarning,
445 ReferenceError,
446 RuntimeError,
447 RuntimeWarning,
448 # StandardError is gone in Python 3, we map it to Exception
449 StopIteration,
450 SyntaxError,
451 SyntaxWarning,
452 SystemError,
453 SystemExit,
454 TabError,
455 TypeError,
456 UnboundLocalError,
457 UnicodeError,
458 UnicodeWarning,
459 UserWarning,
460 ValueError,
461 Warning,
462 ZeroDivisionError,
463)
464
465exception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.'
466
467# Exception objects without arguments pickled from 2.x with protocol 2
468DATA7 = {
469 exception :
470 exception_pickle.replace(b'?', exception.__name__.encode("ascii"))
471 for exception in python2_exceptions_without_args
472}
473
474# StandardError is mapped to Exception, test that separately
475DATA8 = exception_pickle.replace(b'?', b'StandardError')
476
477# UnicodeEncodeError object pickled from 2.x with protocol 2
478DATA9 = (b'\x80\x02cexceptions\nUnicodeEncodeError\n'
479 b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01'
480 b'U\x03badq\x03tq\x04Rq\x05.')
481
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000482
Jeremy Hylton66426532001-10-15 21:38:56 +0000483def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000484 c = C()
485 c.foo = 1
486 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000487 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000488 # Append some integer test cases at cPickle.c's internal size
489 # cutoffs.
490 uint1max = 0xff
491 uint2max = 0xffff
492 int4max = 0x7fffffff
493 x.extend([1, -1,
494 uint1max, -uint1max, -uint1max-1,
495 uint2max, -uint2max, -uint2max-1,
496 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000497 y = ('abc', 'abc', c, c)
498 x.append(y)
499 x.append(y)
500 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000501 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000502
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100503
Jeremy Hylton66426532001-10-15 21:38:56 +0000504class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000505 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000506
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +0100507 optimized = False
508
Jeremy Hylton66426532001-10-15 21:38:56 +0000509 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000510
Jeremy Hylton66426532001-10-15 21:38:56 +0000511 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000512 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000513
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100514 def assert_is_copy(self, obj, objcopy, msg=None):
515 """Utility method to verify if two objects are copies of each others.
516 """
517 if msg is None:
518 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
519 self.assertEqual(obj, objcopy, msg=msg)
520 self.assertIs(type(obj), type(objcopy), msg=msg)
521 if hasattr(obj, '__dict__'):
522 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
523 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
524 if hasattr(obj, '__slots__'):
525 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
526 for slot in obj.__slots__:
527 self.assertEqual(
528 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
529 self.assertEqual(getattr(obj, slot, None),
530 getattr(objcopy, slot, None), msg=msg)
531
Jeremy Hylton66426532001-10-15 21:38:56 +0000532 def test_misc(self):
533 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000534 for proto in protocols:
535 x = myint(4)
536 s = self.dumps(x, proto)
537 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100538 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000539
Tim Peters70b02d72003-02-02 17:26:40 +0000540 x = (1, ())
541 s = self.dumps(x, proto)
542 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100543 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000544
Tim Peters70b02d72003-02-02 17:26:40 +0000545 x = initarg(1, x)
546 s = self.dumps(x, proto)
547 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100548 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000549
Jeremy Hylton66426532001-10-15 21:38:56 +0000550 # XXX test __reduce__ protocol?
551
Tim Peters70b02d72003-02-02 17:26:40 +0000552 def test_roundtrip_equality(self):
553 expected = self._testdata
554 for proto in protocols:
555 s = self.dumps(expected, proto)
556 got = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100557 self.assert_is_copy(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000558
Guido van Rossum98297ee2007-11-06 21:34:58 +0000559 def test_load_from_data0(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100560 self.assert_is_copy(self._testdata, self.loads(DATA0))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000561
562 def test_load_from_data1(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100563 self.assert_is_copy(self._testdata, self.loads(DATA1))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000564
565 def test_load_from_data2(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100566 self.assert_is_copy(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000567
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000568 def test_load_classic_instance(self):
569 # See issue5180. Test loading 2.x pickles that
570 # contain an instance of old style class.
571 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
572 xname = X.__name__.encode('ascii')
573 # Protocol 0 (text mode pickle):
574 """
575 0: ( MARK
576 1: i INST '__main__ X' (MARK at 0)
577 15: p PUT 0
578 18: ( MARK
579 19: d DICT (MARK at 18)
580 20: p PUT 1
581 23: b BUILD
582 24: . STOP
583 """
584 pickle0 = (b"(i__main__\n"
585 b"X\n"
586 b"p0\n"
587 b"(dp1\nb.").replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100588 self.assert_is_copy(X(*args), self.loads(pickle0))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000589
590 # Protocol 1 (binary mode pickle)
591 """
592 0: ( MARK
593 1: c GLOBAL '__main__ X'
594 15: q BINPUT 0
595 17: o OBJ (MARK at 0)
596 18: q BINPUT 1
597 20: } EMPTY_DICT
598 21: q BINPUT 2
599 23: b BUILD
600 24: . STOP
601 """
602 pickle1 = (b'(c__main__\n'
603 b'X\n'
604 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100605 self.assert_is_copy(X(*args), self.loads(pickle1))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000606
607 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
608 """
609 0: \x80 PROTO 2
610 2: ( MARK
611 3: c GLOBAL '__main__ X'
612 17: q BINPUT 0
613 19: o OBJ (MARK at 2)
614 20: q BINPUT 1
615 22: } EMPTY_DICT
616 23: q BINPUT 2
617 25: b BUILD
618 26: . STOP
619 """
620 pickle2 = (b'\x80\x02(c__main__\n'
621 b'X\n'
622 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100623 self.assert_is_copy(X(*args), self.loads(pickle2))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000624
Tim Peters70b02d72003-02-02 17:26:40 +0000625 # There are gratuitous differences between pickles produced by
626 # pickle and cPickle, largely because cPickle starts PUT indices at
627 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
628 # there's a comment with an exclamation point there whose meaning
629 # is a mystery. cPickle also suppresses PUT for objects with a refcount
630 # of 1.
631 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000632 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000633 from pickletools import dis
634
635 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
636 s = self.dumps(self._testdata, proto)
637 filelike = StringIO()
638 dis(s, out=filelike)
639 got = filelike.getvalue()
640 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000641
642 def test_recursive_list(self):
643 l = []
644 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000645 for proto in protocols:
646 s = self.dumps(l, proto)
647 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100648 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000649 self.assertEqual(len(x), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000650 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000651
Collin Winter8ca69de2009-05-26 16:53:41 +0000652 def test_recursive_tuple(self):
653 t = ([],)
654 t[0].append(t)
655 for proto in protocols:
656 s = self.dumps(t, proto)
657 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100658 self.assertIsInstance(x, tuple)
Collin Winter8ca69de2009-05-26 16:53:41 +0000659 self.assertEqual(len(x), 1)
660 self.assertEqual(len(x[0]), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000661 self.assertTrue(x is x[0][0])
Collin Winter8ca69de2009-05-26 16:53:41 +0000662
Jeremy Hylton66426532001-10-15 21:38:56 +0000663 def test_recursive_dict(self):
664 d = {}
665 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000666 for proto in protocols:
667 s = self.dumps(d, proto)
668 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100669 self.assertIsInstance(x, dict)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000670 self.assertEqual(list(x.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000671 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000672
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100673 def test_recursive_set(self):
674 h = H()
675 y = set({h})
676 h.attr = y
677 for proto in protocols:
678 s = self.dumps(y, proto)
679 x = self.loads(s)
680 self.assertIsInstance(x, set)
681 self.assertIs(list(x)[0].attr, x)
682 self.assertEqual(len(x), 1)
683
684 def test_recursive_frozenset(self):
685 h = H()
686 y = frozenset({h})
687 h.attr = y
688 for proto in protocols:
689 s = self.dumps(y, proto)
690 x = self.loads(s)
691 self.assertIsInstance(x, frozenset)
692 self.assertIs(list(x)[0].attr, x)
693 self.assertEqual(len(x), 1)
694
Jeremy Hylton66426532001-10-15 21:38:56 +0000695 def test_recursive_inst(self):
696 i = C()
697 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000698 for proto in protocols:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200699 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +0000700 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100701 self.assertIsInstance(x, C)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000702 self.assertEqual(dir(x), dir(i))
Ezio Melottiaaef3442013-03-04 15:17:56 +0200703 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000704
705 def test_recursive_multi(self):
706 l = []
707 d = {1:l}
708 i = C()
709 i.attr = d
710 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000711 for proto in protocols:
712 s = self.dumps(l, proto)
713 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100714 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000715 self.assertEqual(len(x), 1)
716 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000717 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000718 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000719
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000720 def test_get(self):
721 self.assertRaises(KeyError, self.loads, b'g0\np0')
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100722 self.assert_is_copy([(100,), (100,)],
723 self.loads(b'((Kdtp0\nh\x00l.))'))
Jeremy Hylton66426532001-10-15 21:38:56 +0000724
Walter Dörwald9b775532007-06-08 14:30:53 +0000725 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000726 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +0000727 '<\\>', '<\\\U00012345>',
728 # surrogates
729 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000730 for proto in protocols:
731 for u in endcases:
732 p = self.dumps(u, proto)
733 u2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100734 self.assert_is_copy(u, u2)
Tim Peterse089c682001-04-10 03:41:41 +0000735
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000736 def test_unicode_high_plane(self):
737 t = '\U00012345'
738 for proto in protocols:
739 p = self.dumps(t, proto)
740 t2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100741 self.assert_is_copy(t, t2)
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000742
Guido van Rossumf4169812008-03-17 22:56:06 +0000743 def test_bytes(self):
744 for proto in protocols:
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500745 for s in b'', b'xyz', b'xyz'*100:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200746 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100747 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500748 for s in [bytes([i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200749 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100750 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500751 for s in [bytes([i, i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200752 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100753 self.assert_is_copy(s, self.loads(p))
Guido van Rossumf4169812008-03-17 22:56:06 +0000754
Jeremy Hylton66426532001-10-15 21:38:56 +0000755 def test_ints(self):
756 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000757 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000758 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000759 while n:
760 for expected in (-n, n):
761 s = self.dumps(expected, proto)
762 n2 = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100763 self.assert_is_copy(expected, n2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000764 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000765
Jeremy Hylton66426532001-10-15 21:38:56 +0000766 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000767 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000768 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000769 got = self.loads(data)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100770 self.assert_is_copy(maxint64, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000771
772 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000773 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000774 self.assertRaises(ValueError, self.loads, data)
775
Tim Petersee1a53c2003-02-02 02:57:53 +0000776 def test_long(self):
777 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000778 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000779 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000780 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000781 for npos in nbase-1, nbase, nbase+1:
782 for n in npos, -npos:
783 pickle = self.dumps(n, proto)
784 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100785 self.assert_is_copy(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +0000786 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
787 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000788 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000789 nbase += nbase << 1000000
790 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000791 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000792 got = self.loads(p)
Antoine Pitroud5df1942013-11-23 21:20:49 +0100793 # assert_is_copy is very expensive here as it precomputes
794 # a failure message by computing the repr() of n and got,
795 # we just do the check ourselves.
796 self.assertIs(type(got), int)
797 self.assertEqual(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +0000798
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000799 def test_float(self):
800 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
801 3.14, 263.44582062374053, 6.022e23, 1e30]
802 test_values = test_values + [-x for x in test_values]
803 for proto in protocols:
804 for value in test_values:
805 pickle = self.dumps(value, proto)
806 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100807 self.assert_is_copy(value, got)
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000808
Thomas Wouters477c8d52006-05-27 19:21:47 +0000809 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
810 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000811 # make sure that floats are formatted locale independent with proto 0
812 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000813
Jeremy Hylton66426532001-10-15 21:38:56 +0000814 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000815 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000816
817 def test_getinitargs(self):
818 pass
819
Antoine Pitrou79035bd2012-06-26 23:04:48 +0200820 def test_pop_empty_stack(self):
821 # Test issue7455
822 s = b'0'
823 self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s)
824
Guido van Rossum04a86612001-12-19 16:58:54 +0000825 def test_metaclass(self):
826 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000827 for proto in protocols:
828 s = self.dumps(a, proto)
829 b = self.loads(s)
830 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000831
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200832 def test_dynamic_class(self):
833 a = create_dynamic_class("my_dynamic_class", (object,))
834 copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
835 for proto in protocols:
836 s = self.dumps(a, proto)
837 b = self.loads(s)
838 self.assertEqual(a, b)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100839 self.assertIs(type(a), type(b))
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200840
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000841 def test_structseq(self):
842 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000843 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000844
845 t = time.localtime()
846 for proto in protocols:
847 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000848 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100849 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000850 if hasattr(os, "stat"):
851 t = os.stat(os.curdir)
852 s = self.dumps(t, proto)
853 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100854 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000855 if hasattr(os, "statvfs"):
856 t = os.statvfs(os.curdir)
857 s = self.dumps(t, proto)
858 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100859 self.assert_is_copy(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000860
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100861 def test_ellipsis(self):
862 for proto in protocols:
863 s = self.dumps(..., proto)
864 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100865 self.assertIs(..., u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100866
867 def test_notimplemented(self):
868 for proto in protocols:
869 s = self.dumps(NotImplemented, proto)
870 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100871 self.assertIs(NotImplemented, u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100872
Alexandre Vassalotti19b6fa62013-11-30 16:06:39 -0800873 def test_singleton_types(self):
874 # Issue #6477: Test that types of built-in singletons can be pickled.
875 singletons = [None, ..., NotImplemented]
876 for singleton in singletons:
877 for proto in protocols:
878 s = self.dumps(type(singleton), proto)
879 u = self.loads(s)
880 self.assertIs(type(singleton), u)
881
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000882 # Tests for protocol 2
883
Tim Peters4190fb82003-02-02 16:09:05 +0000884 def test_proto(self):
Tim Peters4190fb82003-02-02 16:09:05 +0000885 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100886 pickled = self.dumps(None, proto)
Tim Peters4190fb82003-02-02 16:09:05 +0000887 if proto >= 2:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100888 proto_header = pickle.PROTO + bytes([proto])
889 self.assertTrue(pickled.startswith(proto_header))
890 else:
891 self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)
Tim Peters4190fb82003-02-02 16:09:05 +0000892
893 oob = protocols[-1] + 1 # a future protocol
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100894 build_none = pickle.NONE + pickle.STOP
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000895 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000896 try:
897 self.loads(badpickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100898 except ValueError as err:
899 self.assertIn("unsupported pickle protocol", str(err))
Tim Peters4190fb82003-02-02 16:09:05 +0000900 else:
901 self.fail("expected bad protocol number to raise ValueError")
902
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000903 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000904 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000905 for proto in protocols:
906 s = self.dumps(x, proto)
907 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100908 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000909 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000910
911 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000912 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000913 for proto in protocols:
914 s = self.dumps(x, proto)
915 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100916 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000917 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000918
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000919 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000920 # Map (proto, len(tuple)) to expected opcode.
921 expected_opcode = {(0, 0): pickle.TUPLE,
922 (0, 1): pickle.TUPLE,
923 (0, 2): pickle.TUPLE,
924 (0, 3): pickle.TUPLE,
925 (0, 4): pickle.TUPLE,
926
927 (1, 0): pickle.EMPTY_TUPLE,
928 (1, 1): pickle.TUPLE,
929 (1, 2): pickle.TUPLE,
930 (1, 3): pickle.TUPLE,
931 (1, 4): pickle.TUPLE,
932
933 (2, 0): pickle.EMPTY_TUPLE,
934 (2, 1): pickle.TUPLE1,
935 (2, 2): pickle.TUPLE2,
936 (2, 3): pickle.TUPLE3,
937 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000938
939 (3, 0): pickle.EMPTY_TUPLE,
940 (3, 1): pickle.TUPLE1,
941 (3, 2): pickle.TUPLE2,
942 (3, 3): pickle.TUPLE3,
943 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000944 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000945 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000946 b = (1,)
947 c = (1, 2)
948 d = (1, 2, 3)
949 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000950 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000951 for x in a, b, c, d, e:
952 s = self.dumps(x, proto)
953 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100954 self.assert_is_copy(x, y)
955 expected = expected_opcode[min(proto, 3), len(x)]
956 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000957
Guido van Rossum7d97d312003-01-28 04:25:27 +0000958 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000959 # Map (proto, singleton) to expected opcode.
960 expected_opcode = {(0, None): pickle.NONE,
961 (1, None): pickle.NONE,
962 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000963 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000964
965 (0, True): pickle.INT,
966 (1, True): pickle.INT,
967 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000968 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000969
970 (0, False): pickle.INT,
971 (1, False): pickle.INT,
972 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000973 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000974 }
Tim Peters4190fb82003-02-02 16:09:05 +0000975 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000976 for x in None, False, True:
977 s = self.dumps(x, proto)
978 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000979 self.assertTrue(x is y, (proto, x, s, y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100980 expected = expected_opcode[min(proto, 3), x]
981 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters3c67d792003-02-02 17:59:11 +0000982
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000983 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000984 x = MyTuple([1, 2, 3])
985 x.foo = 42
986 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000987 for proto in protocols:
988 s = self.dumps(x, proto)
989 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100990 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000991
992 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000993 x = MyList([1, 2, 3])
994 x.foo = 42
995 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000996 for proto in protocols:
997 s = self.dumps(x, proto)
998 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100999 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001000
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001001 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001002 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001003 for C in myclasses:
1004 B = C.__base__
1005 x = C(C.sample)
1006 x.foo = 42
1007 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001008 y = self.loads(s)
1009 detail = (proto, C, B, x, y, type(y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001010 self.assert_is_copy(x, y) # XXX revisit
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001011 self.assertEqual(B(x), B(y), detail)
1012 self.assertEqual(x.__dict__, y.__dict__, detail)
1013
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01001014 def test_newobj_proxies(self):
1015 # NEWOBJ should use the __class__ rather than the raw type
1016 classes = myclasses[:]
1017 # Cannot create weakproxies to these classes
1018 for c in (MyInt, MyTuple):
1019 classes.remove(c)
1020 for proto in protocols:
1021 for C in classes:
1022 B = C.__base__
1023 x = C(C.sample)
1024 x.foo = 42
1025 p = weakref.proxy(x)
1026 s = self.dumps(p, proto)
1027 y = self.loads(s)
1028 self.assertEqual(type(y), type(x)) # rather than type(p)
1029 detail = (proto, C, B, x, y, type(y))
1030 self.assertEqual(B(x), B(y), detail)
1031 self.assertEqual(x.__dict__, y.__dict__, detail)
1032
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001033 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001034 # an object of that type. Check that the resulting pickle uses opcode
1035 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001036
Tim Peters22e71712003-02-03 22:27:38 +00001037 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001038 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001039 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001040 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001041 x = MyList([1, 2, 3])
1042 x.foo = 42
1043 x.bar = "hello"
1044
Tim Peters22e71712003-02-03 22:27:38 +00001045 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001046 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001047 self.assertIn(__name__.encode("utf-8"), s1)
1048 self.assertIn(b"MyList", s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001049 self.assertFalse(opcode_in_pickle(opcode, s1))
Tim Peters3e667d52003-02-04 21:47:44 +00001050
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001051 y = self.loads(s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001052 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001053
Tim Peters22e71712003-02-03 22:27:38 +00001054 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001055 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001056 self.assertNotIn(__name__.encode("utf-8"), s2)
1057 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001058 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +00001059
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001060 y = self.loads(s2)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001061 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001062 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001063 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001064
1065 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001066 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1067 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001068
1069 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001070 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1071 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1072 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001073
1074 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001075 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1076 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1077 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1078
Tim Peters8d2613a2003-02-11 16:40:16 +00001079 def test_list_chunking(self):
1080 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +00001081 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001082 for proto in protocols:
1083 s = self.dumps(x, proto)
1084 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001085 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001086 num_appends = count_opcode(pickle.APPENDS, s)
1087 self.assertEqual(num_appends, proto > 0)
1088
1089 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001090 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001091 for proto in protocols:
1092 s = self.dumps(x, proto)
1093 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001094 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001095 num_appends = count_opcode(pickle.APPENDS, s)
1096 if proto == 0:
1097 self.assertEqual(num_appends, 0)
1098 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001099 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001100
1101 def test_dict_chunking(self):
1102 n = 10 # too small to chunk
1103 x = dict.fromkeys(range(n))
1104 for proto in protocols:
1105 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +00001106 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00001107 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001108 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001109 num_setitems = count_opcode(pickle.SETITEMS, s)
1110 self.assertEqual(num_setitems, proto > 0)
1111
1112 n = 2500 # expect at least two chunks when proto > 0
1113 x = dict.fromkeys(range(n))
1114 for proto in protocols:
1115 s = self.dumps(x, proto)
1116 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001117 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001118 num_setitems = count_opcode(pickle.SETITEMS, s)
1119 if proto == 0:
1120 self.assertEqual(num_setitems, 0)
1121 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001122 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001123
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001124 def test_set_chunking(self):
1125 n = 10 # too small to chunk
1126 x = set(range(n))
1127 for proto in protocols:
1128 s = self.dumps(x, proto)
1129 y = self.loads(s)
1130 self.assert_is_copy(x, y)
1131 num_additems = count_opcode(pickle.ADDITEMS, s)
1132 if proto < 4:
1133 self.assertEqual(num_additems, 0)
1134 else:
1135 self.assertEqual(num_additems, 1)
1136
1137 n = 2500 # expect at least two chunks when proto >= 4
1138 x = set(range(n))
1139 for proto in protocols:
1140 s = self.dumps(x, proto)
1141 y = self.loads(s)
1142 self.assert_is_copy(x, y)
1143 num_additems = count_opcode(pickle.ADDITEMS, s)
1144 if proto < 4:
1145 self.assertEqual(num_additems, 0)
1146 else:
1147 self.assertGreaterEqual(num_additems, 2)
1148
Tim Peterse9ef2032003-02-13 18:42:00 +00001149 def test_simple_newobj(self):
1150 x = object.__new__(SimpleNewObj) # avoid __init__
1151 x.abc = 666
1152 for proto in protocols:
1153 s = self.dumps(x, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001154 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1155 2 <= proto < 4)
1156 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1157 proto >= 4)
Tim Peterse9ef2032003-02-13 18:42:00 +00001158 y = self.loads(s) # will raise TypeError if __init__ called
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001159 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001160
Tim Peters42f08ac2003-02-11 22:43:24 +00001161 def test_newobj_list_slots(self):
1162 x = SlotList([1, 2, 3])
1163 x.foo = 42
1164 x.bar = "hello"
1165 s = self.dumps(x, 2)
1166 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001167 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001168
Guido van Rossum2a30b212003-02-18 22:41:24 +00001169 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001170 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001171 x = REX_one()
1172 self.assertEqual(x._reduce_called, 0)
1173 s = self.dumps(x, proto)
1174 self.assertEqual(x._reduce_called, 1)
1175 y = self.loads(s)
1176 self.assertEqual(y._reduce_called, 0)
1177
1178 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001179 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001180 x = REX_two()
1181 self.assertEqual(x._proto, None)
1182 s = self.dumps(x, proto)
1183 self.assertEqual(x._proto, proto)
1184 y = self.loads(s)
1185 self.assertEqual(y._proto, None)
1186
1187 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001188 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001189 x = REX_three()
1190 self.assertEqual(x._proto, None)
1191 s = self.dumps(x, proto)
1192 self.assertEqual(x._proto, proto)
1193 y = self.loads(s)
1194 self.assertEqual(y._proto, None)
1195
Guido van Rossumd8faa362007-04-27 19:54:29 +00001196 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001197 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001198 x = REX_four()
1199 self.assertEqual(x._proto, None)
1200 s = self.dumps(x, proto)
1201 self.assertEqual(x._proto, proto)
1202 y = self.loads(s)
1203 self.assertEqual(y._proto, proto)
1204
1205 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001206 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001207 x = REX_five()
1208 self.assertEqual(x._reduce_called, 0)
1209 s = self.dumps(x, proto)
1210 self.assertEqual(x._reduce_called, 1)
1211 y = self.loads(s)
1212 self.assertEqual(y._reduce_called, 1)
1213
Brett Cannon31f59292011-02-21 19:29:56 +00001214 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001215 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001216 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001217 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001218 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001219 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001220
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001221 def test_reduce_bad_iterator(self):
1222 # Issue4176: crash when 4th and 5th items of __reduce__()
1223 # are not iterators
1224 class C(object):
1225 def __reduce__(self):
1226 # 4th item is not an iterator
1227 return list, (), None, [], None
1228 class D(object):
1229 def __reduce__(self):
1230 # 5th item is not an iterator
1231 return dict, (), None, None, []
1232
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001233 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001234 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001235 try:
1236 self.dumps(C(), proto)
1237 except (pickle.PickleError):
1238 pass
1239 try:
1240 self.dumps(D(), proto)
1241 except (pickle.PickleError):
1242 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001243
Collin Winter771d8342009-04-16 03:18:06 +00001244 def test_many_puts_and_gets(self):
1245 # Test that internal data structures correctly deal with lots of
1246 # puts/gets.
1247 keys = ("aaa" + str(i) for i in range(100))
1248 large_dict = dict((k, [4, 5, 6]) for k in keys)
1249 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1250
1251 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001252 with self.subTest(proto=proto):
1253 dumped = self.dumps(obj, proto)
1254 loaded = self.loads(dumped)
1255 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00001256
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001257 def test_attribute_name_interning(self):
1258 # Test that attribute names of pickled objects are interned when
1259 # unpickling.
1260 for proto in protocols:
1261 x = C()
1262 x.foo = 42
1263 x.bar = "hello"
1264 s = self.dumps(x, proto)
1265 y = self.loads(s)
1266 x_keys = sorted(x.__dict__)
1267 y_keys = sorted(y.__dict__)
1268 for x_key, y_key in zip(x_keys, y_keys):
1269 self.assertIs(x_key, y_key)
1270
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001271 def test_unpickle_from_2x(self):
1272 # Unpickle non-trivial data from Python 2.x.
1273 loaded = self.loads(DATA3)
1274 self.assertEqual(loaded, set([1, 2]))
1275 loaded = self.loads(DATA4)
1276 self.assertEqual(type(loaded), type(range(0)))
1277 self.assertEqual(list(loaded), list(range(5)))
1278 loaded = self.loads(DATA5)
1279 self.assertEqual(type(loaded), SimpleCookie)
1280 self.assertEqual(list(loaded.keys()), ["key"])
1281 self.assertEqual(loaded["key"].value, "Set-Cookie: key=value")
1282
Walter Doerwald9d1dbca2013-12-02 11:41:01 +01001283 for (exc, data) in DATA7.items():
1284 loaded = self.loads(data)
1285 self.assertIs(type(loaded), exc)
1286
1287 loaded = self.loads(DATA8)
1288 self.assertIs(type(loaded), Exception)
1289
1290 loaded = self.loads(DATA9)
1291 self.assertIs(type(loaded), UnicodeEncodeError)
1292 self.assertEqual(loaded.object, "foo")
1293 self.assertEqual(loaded.encoding, "ascii")
1294 self.assertEqual(loaded.start, 0)
1295 self.assertEqual(loaded.end, 1)
1296 self.assertEqual(loaded.reason, "bad")
1297
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001298 def test_pickle_to_2x(self):
1299 # Pickle non-trivial data with protocol 2, expecting that it yields
1300 # the same result as Python 2.x did.
1301 # NOTE: this test is a bit too strong since we can produce different
1302 # bytecode that 2.x will still understand.
1303 dumped = self.dumps(range(5), 2)
1304 self.assertEqual(dumped, DATA4)
1305 dumped = self.dumps(set([3]), 2)
1306 self.assertEqual(dumped, DATA6)
1307
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001308 def test_large_pickles(self):
1309 # Test the correctness of internal buffering routines when handling
1310 # large data.
1311 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001312 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001313 dumped = self.dumps(data, proto)
1314 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001315 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001316 self.assertEqual(loaded, data)
1317
Alexander Belopolsky1ce92dc2011-02-24 19:40:09 +00001318 def test_empty_bytestring(self):
1319 # issue 11286
1320 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1321 self.assertEqual(empty, '')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001322
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001323 def test_int_pickling_efficiency(self):
1324 # Test compacity of int representation (see issue #12744)
1325 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001326 with self.subTest(proto=proto):
1327 pickles = [self.dumps(2**n, proto) for n in range(70)]
1328 sizes = list(map(len, pickles))
1329 # the size function is monotonic
1330 self.assertEqual(sorted(sizes), sizes)
1331 if proto >= 2:
1332 for p in pickles:
1333 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001334
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001335 def check_negative_32b_binXXX(self, dumped):
1336 if sys.maxsize > 2**32:
1337 self.skipTest("test is only meaningful on 32-bit builds")
1338 # XXX Pure Python pickle reads lengths as signed and passes
1339 # them directly to read() (hence the EOFError)
1340 with self.assertRaises((pickle.UnpicklingError, EOFError,
1341 ValueError, OverflowError)):
1342 self.loads(dumped)
1343
1344 def test_negative_32b_binbytes(self):
1345 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1346 self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.')
1347
1348 def test_negative_32b_binunicode(self):
1349 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1350 self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.')
1351
Antoine Pitrou55549ec2011-08-30 00:27:10 +02001352 def test_negative_put(self):
1353 # Issue #12847
1354 dumped = b'Va\np-1\n.'
1355 self.assertRaises(ValueError, self.loads, dumped)
1356
1357 def test_negative_32b_binput(self):
1358 # Issue #12847
1359 if sys.maxsize > 2**32:
1360 self.skipTest("test is only meaningful on 32-bit builds")
1361 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
1362 self.assertRaises(ValueError, self.loads, dumped)
1363
Alexandre Vassalotti7c5e0942013-04-15 23:14:55 -07001364 def test_badly_escaped_string(self):
1365 self.assertRaises(ValueError, self.loads, b"S'\\'\n.")
1366
1367 def test_badly_quoted_string(self):
1368 # Issue #17710
1369 badpickles = [b"S'\n.",
1370 b'S"\n.',
1371 b'S\' \n.',
1372 b'S" \n.',
1373 b'S\'"\n.',
1374 b'S"\'\n.',
1375 b"S' ' \n.",
1376 b'S" " \n.',
1377 b"S ''\n.",
1378 b'S ""\n.',
1379 b'S \n.',
1380 b'S\n.',
1381 b'S.']
1382 for p in badpickles:
1383 self.assertRaises(pickle.UnpicklingError, self.loads, p)
1384
1385 def test_correctly_quoted_string(self):
1386 goodpickles = [(b"S''\n.", ''),
1387 (b'S""\n.', ''),
1388 (b'S"\\n"\n.', '\n'),
1389 (b"S'\\n'\n.", '\n')]
1390 for p, expected in goodpickles:
1391 self.assertEqual(self.loads(p), expected)
1392
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001393 def _check_pickling_with_opcode(self, obj, opcode, proto):
1394 pickled = self.dumps(obj, proto)
1395 self.assertTrue(opcode_in_pickle(opcode, pickled))
1396 unpickled = self.loads(pickled)
1397 self.assertEqual(obj, unpickled)
1398
1399 def test_appends_on_non_lists(self):
1400 # Issue #17720
1401 obj = REX_six([1, 2, 3])
1402 for proto in protocols:
1403 if proto == 0:
1404 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1405 else:
1406 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1407
1408 def test_setitems_on_non_dicts(self):
1409 obj = REX_seven({1: -1, 2: -2, 3: -3})
1410 for proto in protocols:
1411 if proto == 0:
1412 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1413 else:
1414 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1415
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001416 # Exercise framing (proto >= 4) for significant workloads
1417
1418 FRAME_SIZE_TARGET = 64 * 1024
1419
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001420 def check_frame_opcodes(self, pickled):
1421 """
1422 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
1423 """
1424 frame_opcode_size = 9
1425 last_arg = last_pos = None
1426 for op, arg, pos in pickletools.genops(pickled):
1427 if op.name != 'FRAME':
1428 continue
1429 if last_pos is not None:
1430 # The previous frame's size should be equal to the number
1431 # of bytes up to the current frame.
1432 frame_size = pos - last_pos - frame_opcode_size
1433 self.assertEqual(frame_size, last_arg)
1434 last_arg, last_pos = arg, pos
1435 # The last frame's size should be equal to the number of bytes up
1436 # to the pickle's end.
1437 frame_size = len(pickled) - last_pos - frame_opcode_size
1438 self.assertEqual(frame_size, last_arg)
1439
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001440 def test_framing_many_objects(self):
1441 obj = list(range(10**5))
1442 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1443 with self.subTest(proto=proto):
1444 pickled = self.dumps(obj, proto)
1445 unpickled = self.loads(pickled)
1446 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001447 bytes_per_frame = (len(pickled) /
1448 count_opcode(pickle.FRAME, pickled))
1449 self.assertGreater(bytes_per_frame,
1450 self.FRAME_SIZE_TARGET / 2)
1451 self.assertLessEqual(bytes_per_frame,
1452 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001453 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001454
1455 def test_framing_large_objects(self):
1456 N = 1024 * 1024
1457 obj = [b'x' * N, b'y' * N, b'z' * N]
1458 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1459 with self.subTest(proto=proto):
1460 pickled = self.dumps(obj, proto)
1461 unpickled = self.loads(pickled)
1462 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001463 n_frames = count_opcode(pickle.FRAME, pickled)
Alexandre Vassalotti28d271e2013-12-01 16:27:46 -08001464 self.assertGreaterEqual(n_frames, len(obj))
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001465 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001466
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001467 def test_optional_frames(self):
1468 if pickle.HIGHEST_PROTOCOL < 4:
1469 return
1470
1471 def remove_frames(pickled, keep_frame=None):
1472 """Remove frame opcodes from the given pickle."""
1473 frame_starts = []
1474 # 1 byte for the opcode and 8 for the argument
1475 frame_opcode_size = 9
1476 for opcode, _, pos in pickletools.genops(pickled):
1477 if opcode.name == 'FRAME':
1478 frame_starts.append(pos)
1479
1480 newpickle = bytearray()
1481 last_frame_end = 0
1482 for i, pos in enumerate(frame_starts):
1483 if keep_frame and keep_frame(i):
1484 continue
1485 newpickle += pickled[last_frame_end:pos]
1486 last_frame_end = pos + frame_opcode_size
1487 newpickle += pickled[last_frame_end:]
1488 return newpickle
1489
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001490 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001491 num_frames = 20
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001492 obj = [bytes([i]) * frame_size for i in range(num_frames)]
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001493
1494 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1495 pickled = self.dumps(obj, proto)
1496
1497 frameless_pickle = remove_frames(pickled)
1498 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
1499 self.assertEqual(obj, self.loads(frameless_pickle))
1500
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001501 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001502 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
1503 count_opcode(pickle.FRAME, pickled))
1504 self.assertEqual(obj, self.loads(some_frames_pickle))
1505
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001506 def test_nested_names(self):
1507 global Nested
1508 class Nested:
1509 class A:
1510 class B:
1511 class C:
1512 pass
1513
1514 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1515 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
1516 with self.subTest(proto=proto, obj=obj):
1517 unpickled = self.loads(self.dumps(obj, proto))
1518 self.assertIs(obj, unpickled)
1519
1520 def test_py_methods(self):
1521 global PyMethodsTest
1522 class PyMethodsTest:
1523 @staticmethod
1524 def cheese():
1525 return "cheese"
1526 @classmethod
1527 def wine(cls):
1528 assert cls is PyMethodsTest
1529 return "wine"
1530 def biscuits(self):
1531 assert isinstance(self, PyMethodsTest)
1532 return "biscuits"
1533 class Nested:
1534 "Nested class"
1535 @staticmethod
1536 def ketchup():
1537 return "ketchup"
1538 @classmethod
1539 def maple(cls):
1540 assert cls is PyMethodsTest.Nested
1541 return "maple"
1542 def pie(self):
1543 assert isinstance(self, PyMethodsTest.Nested)
1544 return "pie"
1545
1546 py_methods = (
1547 PyMethodsTest.cheese,
1548 PyMethodsTest.wine,
1549 PyMethodsTest().biscuits,
1550 PyMethodsTest.Nested.ketchup,
1551 PyMethodsTest.Nested.maple,
1552 PyMethodsTest.Nested().pie
1553 )
1554 py_unbound_methods = (
1555 (PyMethodsTest.biscuits, PyMethodsTest),
1556 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
1557 )
1558 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1559 for method in py_methods:
1560 with self.subTest(proto=proto, method=method):
1561 unpickled = self.loads(self.dumps(method, proto))
1562 self.assertEqual(method(), unpickled())
1563 for method, cls in py_unbound_methods:
1564 obj = cls()
1565 with self.subTest(proto=proto, method=method):
1566 unpickled = self.loads(self.dumps(method, proto))
1567 self.assertEqual(method(obj), unpickled(obj))
1568
1569
1570 def test_c_methods(self):
1571 global Subclass
1572 class Subclass(tuple):
1573 class Nested(str):
1574 pass
1575
1576 c_methods = (
1577 # bound built-in method
1578 ("abcd".index, ("c",)),
1579 # unbound built-in method
1580 (str.index, ("abcd", "c")),
1581 # bound "slot" method
1582 ([1, 2, 3].__len__, ()),
1583 # unbound "slot" method
1584 (list.__len__, ([1, 2, 3],)),
1585 # bound "coexist" method
1586 ({1, 2}.__contains__, (2,)),
1587 # unbound "coexist" method
1588 (set.__contains__, ({1, 2}, 2)),
1589 # built-in class method
1590 (dict.fromkeys, (("a", 1), ("b", 2))),
1591 # built-in static method
1592 (bytearray.maketrans, (b"abc", b"xyz")),
1593 # subclass methods
1594 (Subclass([1,2,2]).count, (2,)),
1595 (Subclass.count, (Subclass([1,2,2]), 2)),
1596 (Subclass.Nested("sweet").count, ("e",)),
1597 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
1598 )
1599 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1600 for method, args in c_methods:
1601 with self.subTest(proto=proto, method=method):
1602 unpickled = self.loads(self.dumps(method, proto))
1603 self.assertEqual(method(*args), unpickled(*args))
1604
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001605
1606class BigmemPickleTests(unittest.TestCase):
1607
1608 # Binary protocols can serialize longs of up to 2GB-1
1609
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001610 @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001611 def test_huge_long_32b(self, size):
1612 data = 1 << (8 * size)
1613 try:
1614 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001615 if proto < 2:
1616 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001617 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001618 with self.assertRaises((ValueError, OverflowError)):
1619 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001620 finally:
1621 data = None
1622
1623 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1624 # (older protocols don't have a dedicated opcode for bytes and are
1625 # too inefficient)
1626
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001627 @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001628 def test_huge_bytes_32b(self, size):
1629 data = b"abcd" * (size // 4)
1630 try:
1631 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001632 if proto < 3:
1633 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001634 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001635 try:
1636 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001637 header = (pickle.BINBYTES +
1638 struct.pack("<I", len(data)))
1639 data_start = pickled.index(data)
1640 self.assertEqual(
1641 header,
1642 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001643 finally:
1644 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001645 finally:
1646 data = None
1647
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001648 @bigmemtest(size=_4G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001649 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001650 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001651 try:
1652 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001653 if proto < 3:
1654 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001655 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001656 if proto == 3:
1657 # Protocol 3 does not support large bytes objects.
1658 # Verify that we do not crash when processing one.
1659 with self.assertRaises((ValueError, OverflowError)):
1660 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001661 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001662 try:
1663 pickled = self.dumps(data, protocol=proto)
1664 header = (pickle.BINBYTES8 +
1665 struct.pack("<Q", len(data)))
1666 data_start = pickled.index(data)
1667 self.assertEqual(
1668 header,
1669 pickled[data_start-len(header):data_start])
1670 finally:
1671 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001672 finally:
1673 data = None
1674
1675 # All protocols use 1-byte per printable ASCII character; we add another
1676 # byte because the encoded form has to be copied into the internal buffer.
1677
Antoine Pitroub7591d42011-10-04 16:18:15 +02001678 @bigmemtest(size=_2G, memuse=2 + ascii_char_size, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001679 def test_huge_str_32b(self, size):
1680 data = "abcd" * (size // 4)
1681 try:
1682 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001683 if proto == 0:
1684 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001685 with self.subTest(proto=proto):
1686 try:
1687 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001688 header = (pickle.BINUNICODE +
1689 struct.pack("<I", len(data)))
1690 data_start = pickled.index(b'abcd')
1691 self.assertEqual(
1692 header,
1693 pickled[data_start-len(header):data_start])
1694 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1695 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001696 finally:
1697 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001698 finally:
1699 data = None
1700
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001701 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
1702 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
1703 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02001704
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001705 @bigmemtest(size=_4G, memuse=2 + ascii_char_size, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001706 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001707 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001708 try:
1709 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001710 if proto == 0:
1711 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001712 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001713 if proto < 4:
1714 with self.assertRaises((ValueError, OverflowError)):
1715 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001716 continue
1717 try:
1718 pickled = self.dumps(data, protocol=proto)
1719 header = (pickle.BINUNICODE8 +
1720 struct.pack("<Q", len(data)))
1721 data_start = pickled.index(b'abcd')
1722 self.assertEqual(
1723 header,
1724 pickled[data_start-len(header):data_start])
1725 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1726 pickled.index(b"abcd")), len(data))
1727 finally:
1728 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001729 finally:
1730 data = None
1731
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001732
Guido van Rossum2a30b212003-02-18 22:41:24 +00001733# Test classes for reduce_ex
1734
1735class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001736 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001737 _reduce_called = 0
1738 def __reduce__(self):
1739 self._reduce_called = 1
1740 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001741
1742class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001743 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001744 _proto = None
1745 def __reduce_ex__(self, proto):
1746 self._proto = proto
1747 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001748
1749class REX_three(object):
1750 _proto = None
1751 def __reduce_ex__(self, proto):
1752 self._proto = proto
1753 return REX_two, ()
1754 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001755 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001756
Guido van Rossumd8faa362007-04-27 19:54:29 +00001757class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001758 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001759 _proto = None
1760 def __reduce_ex__(self, proto):
1761 self._proto = proto
1762 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001763
1764class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001765 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001766 _reduce_called = 0
1767 def __reduce__(self):
1768 self._reduce_called = 1
1769 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001770
1771class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001772 """This class is used to check the 4th argument (list iterator) of
1773 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001774 """
1775 def __init__(self, items=None):
1776 self.items = items if items is not None else []
1777 def __eq__(self, other):
1778 return type(self) is type(other) and self.items == self.items
1779 def append(self, item):
1780 self.items.append(item)
1781 def __reduce__(self):
1782 return type(self), (), None, iter(self.items), None
1783
1784class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001785 """This class is used to check the 5th argument (dict iterator) of
1786 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001787 """
1788 def __init__(self, table=None):
1789 self.table = table if table is not None else {}
1790 def __eq__(self, other):
1791 return type(self) is type(other) and self.table == self.table
1792 def __setitem__(self, key, value):
1793 self.table[key] = value
1794 def __reduce__(self):
1795 return type(self), (), None, None, iter(self.table.items())
1796
Guido van Rossumd8faa362007-04-27 19:54:29 +00001797
Guido van Rossum2a30b212003-02-18 22:41:24 +00001798# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001799
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001800class MyInt(int):
1801 sample = 1
1802
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001803class MyFloat(float):
1804 sample = 1.0
1805
1806class MyComplex(complex):
1807 sample = 1.0 + 0.0j
1808
1809class MyStr(str):
1810 sample = "hello"
1811
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001812class MyUnicode(str):
1813 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001814
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001815class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001816 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001817
1818class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001819 sample = [1, 2, 3]
1820
1821class MyDict(dict):
1822 sample = {"a": 1, "b": 2}
1823
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001824class MySet(set):
1825 sample = {"a", "b"}
1826
1827class MyFrozenSet(frozenset):
1828 sample = frozenset({"a", "b"})
1829
Mark Dickinson5c2db372009-12-05 20:28:34 +00001830myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001831 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001832 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001833 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001834
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001835
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001836class SlotList(MyList):
1837 __slots__ = ["foo"]
1838
Tim Peterse9ef2032003-02-13 18:42:00 +00001839class SimpleNewObj(object):
1840 def __init__(self, a, b, c):
1841 # raise an error, to make sure this isn't called
1842 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001843 def __eq__(self, other):
1844 return self.__dict__ == other.__dict__
Tim Peterse9ef2032003-02-13 18:42:00 +00001845
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001846class BadGetattr:
1847 def __getattr__(self, key):
1848 self.foo
1849
Collin Winter771d8342009-04-16 03:18:06 +00001850
Jeremy Hylton66426532001-10-15 21:38:56 +00001851class AbstractPickleModuleTests(unittest.TestCase):
1852
1853 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001854 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001855 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001856 try:
1857 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001858 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001859 finally:
1860 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001861
1862 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001863 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001864 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001865 try:
1866 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001867 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001868 finally:
1869 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001870
Collin Winter771d8342009-04-16 03:18:06 +00001871 def test_load_from_and_dump_to_file(self):
1872 stream = io.BytesIO()
1873 data = [123, {}, 124]
1874 pickle.dump(data, stream)
1875 stream.seek(0)
1876 unpickled = pickle.load(stream)
1877 self.assertEqual(unpickled, data)
1878
Tim Petersc0c93702003-02-13 19:30:57 +00001879 def test_highest_protocol(self):
1880 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001881 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00001882
Martin v. Löwis544f1192004-07-27 05:22:33 +00001883 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001884 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001885 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001886 pickle.dump(123, f, -1)
1887 pickle.dump(123, file=f, protocol=-1)
1888 pickle.dumps(123, -1)
1889 pickle.dumps(123, protocol=-1)
1890 pickle.Pickler(f, -1)
1891 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001892
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001893 def test_bad_init(self):
1894 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001895 # Override initialization without calling __init__() of the superclass.
1896 class BadPickler(pickle.Pickler):
1897 def __init__(self): pass
1898
1899 class BadUnpickler(pickle.Unpickler):
1900 def __init__(self): pass
1901
1902 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1903 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1904
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001905 def test_bad_input(self):
1906 # Test issue4298
1907 s = bytes([0x58, 0, 0, 0, 0x54])
1908 self.assertRaises(EOFError, pickle.loads, s)
1909
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001910
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001911class AbstractPersistentPicklerTests(unittest.TestCase):
1912
1913 # This class defines persistent_id() and persistent_load()
1914 # functions that should be used by the pickler. All even integers
1915 # are pickled using persistent ids.
1916
1917 def persistent_id(self, object):
1918 if isinstance(object, int) and object % 2 == 0:
1919 self.id_count += 1
1920 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001921 elif object == "test_false_value":
1922 self.false_count += 1
1923 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001924 else:
1925 return None
1926
1927 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001928 if not oid:
1929 self.load_false_count += 1
1930 return "test_false_value"
1931 else:
1932 self.load_count += 1
1933 object = int(oid)
1934 assert object % 2 == 0
1935 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001936
1937 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001938 L = list(range(10)) + ["test_false_value"]
1939 for proto in protocols:
1940 self.id_count = 0
1941 self.false_count = 0
1942 self.load_false_count = 0
1943 self.load_count = 0
1944 self.assertEqual(self.loads(self.dumps(L, proto)), L)
1945 self.assertEqual(self.id_count, 5)
1946 self.assertEqual(self.false_count, 1)
1947 self.assertEqual(self.load_count, 5)
1948 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001949
Collin Winter771d8342009-04-16 03:18:06 +00001950
1951class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1952
1953 pickler_class = None
1954 unpickler_class = None
1955
1956 def setUp(self):
1957 assert self.pickler_class
1958 assert self.unpickler_class
1959
1960 def test_clear_pickler_memo(self):
1961 # To test whether clear_memo() has any effect, we pickle an object,
1962 # then pickle it again without clearing the memo; the two serialized
1963 # forms should be different. If we clear_memo() and then pickle the
1964 # object again, the third serialized form should be identical to the
1965 # first one we obtained.
1966 data = ["abcdefg", "abcdefg", 44]
1967 f = io.BytesIO()
1968 pickler = self.pickler_class(f)
1969
1970 pickler.dump(data)
1971 first_pickled = f.getvalue()
1972
Serhiy Storchaka50254c52013-08-29 11:35:43 +03001973 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00001974 f.seek(0)
1975 f.truncate()
1976
1977 pickler.dump(data)
1978 second_pickled = f.getvalue()
1979
Serhiy Storchaka50254c52013-08-29 11:35:43 +03001980 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00001981 pickler.clear_memo()
1982 f.seek(0)
1983 f.truncate()
1984
1985 pickler.dump(data)
1986 third_pickled = f.getvalue()
1987
1988 self.assertNotEqual(first_pickled, second_pickled)
1989 self.assertEqual(first_pickled, third_pickled)
1990
1991 def test_priming_pickler_memo(self):
1992 # Verify that we can set the Pickler's memo attribute.
1993 data = ["abcdefg", "abcdefg", 44]
1994 f = io.BytesIO()
1995 pickler = self.pickler_class(f)
1996
1997 pickler.dump(data)
1998 first_pickled = f.getvalue()
1999
2000 f = io.BytesIO()
2001 primed = self.pickler_class(f)
2002 primed.memo = pickler.memo
2003
2004 primed.dump(data)
2005 primed_pickled = f.getvalue()
2006
2007 self.assertNotEqual(first_pickled, primed_pickled)
2008
2009 def test_priming_unpickler_memo(self):
2010 # Verify that we can set the Unpickler's memo attribute.
2011 data = ["abcdefg", "abcdefg", 44]
2012 f = io.BytesIO()
2013 pickler = self.pickler_class(f)
2014
2015 pickler.dump(data)
2016 first_pickled = f.getvalue()
2017
2018 f = io.BytesIO()
2019 primed = self.pickler_class(f)
2020 primed.memo = pickler.memo
2021
2022 primed.dump(data)
2023 primed_pickled = f.getvalue()
2024
2025 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2026 unpickled_data1 = unpickler.load()
2027
2028 self.assertEqual(unpickled_data1, data)
2029
2030 primed = self.unpickler_class(io.BytesIO(primed_pickled))
2031 primed.memo = unpickler.memo
2032 unpickled_data2 = primed.load()
2033
2034 primed.memo.clear()
2035
2036 self.assertEqual(unpickled_data2, data)
2037 self.assertTrue(unpickled_data2 is unpickled_data1)
2038
2039 def test_reusing_unpickler_objects(self):
2040 data1 = ["abcdefg", "abcdefg", 44]
2041 f = io.BytesIO()
2042 pickler = self.pickler_class(f)
2043 pickler.dump(data1)
2044 pickled1 = f.getvalue()
2045
2046 data2 = ["abcdefg", 44, 44]
2047 f = io.BytesIO()
2048 pickler = self.pickler_class(f)
2049 pickler.dump(data2)
2050 pickled2 = f.getvalue()
2051
2052 f = io.BytesIO()
2053 f.write(pickled1)
2054 f.seek(0)
2055 unpickler = self.unpickler_class(f)
2056 self.assertEqual(unpickler.load(), data1)
2057
2058 f.seek(0)
2059 f.truncate()
2060 f.write(pickled2)
2061 f.seek(0)
2062 self.assertEqual(unpickler.load(), data2)
2063
Antoine Pitrou04248a82010-10-12 20:51:21 +00002064 def _check_multiple_unpicklings(self, ioclass):
2065 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002066 with self.subTest(proto=proto):
2067 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2068 f = ioclass()
2069 pickler = self.pickler_class(f, protocol=proto)
2070 pickler.dump(data1)
2071 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002072
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002073 N = 5
2074 f = ioclass(pickled * N)
2075 unpickler = self.unpickler_class(f)
2076 for i in range(N):
2077 if f.seekable():
2078 pos = f.tell()
2079 self.assertEqual(unpickler.load(), data1)
2080 if f.seekable():
2081 self.assertEqual(f.tell(), pos + len(pickled))
2082 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002083
2084 def test_multiple_unpicklings_seekable(self):
2085 self._check_multiple_unpicklings(io.BytesIO)
2086
2087 def test_multiple_unpicklings_unseekable(self):
2088 self._check_multiple_unpicklings(UnseekableIO)
2089
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002090 def test_unpickling_buffering_readline(self):
2091 # Issue #12687: the unpickler's buffering logic could fail with
2092 # text mode opcodes.
2093 data = list(range(10))
2094 for proto in protocols:
2095 for buf_size in range(1, 11):
2096 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2097 pickler = self.pickler_class(f, protocol=proto)
2098 pickler.dump(data)
2099 f.seek(0)
2100 unpickler = self.unpickler_class(f)
2101 self.assertEqual(unpickler.load(), data)
2102
Collin Winter771d8342009-04-16 03:18:06 +00002103
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002104# Tests for dispatch_table attribute
2105
2106REDUCE_A = 'reduce_A'
2107
2108class AAA(object):
2109 def __reduce__(self):
2110 return str, (REDUCE_A,)
2111
2112class BBB(object):
2113 pass
2114
2115class AbstractDispatchTableTests(unittest.TestCase):
2116
2117 def test_default_dispatch_table(self):
2118 # No dispatch_table attribute by default
2119 f = io.BytesIO()
2120 p = self.pickler_class(f, 0)
2121 with self.assertRaises(AttributeError):
2122 p.dispatch_table
2123 self.assertFalse(hasattr(p, 'dispatch_table'))
2124
2125 def test_class_dispatch_table(self):
2126 # A dispatch_table attribute can be specified class-wide
2127 dt = self.get_dispatch_table()
2128
2129 class MyPickler(self.pickler_class):
2130 dispatch_table = dt
2131
2132 def dumps(obj, protocol=None):
2133 f = io.BytesIO()
2134 p = MyPickler(f, protocol)
2135 self.assertEqual(p.dispatch_table, dt)
2136 p.dump(obj)
2137 return f.getvalue()
2138
2139 self._test_dispatch_table(dumps, dt)
2140
2141 def test_instance_dispatch_table(self):
2142 # A dispatch_table attribute can also be specified instance-wide
2143 dt = self.get_dispatch_table()
2144
2145 def dumps(obj, protocol=None):
2146 f = io.BytesIO()
2147 p = self.pickler_class(f, protocol)
2148 p.dispatch_table = dt
2149 self.assertEqual(p.dispatch_table, dt)
2150 p.dump(obj)
2151 return f.getvalue()
2152
2153 self._test_dispatch_table(dumps, dt)
2154
2155 def _test_dispatch_table(self, dumps, dispatch_table):
2156 def custom_load_dump(obj):
2157 return pickle.loads(dumps(obj, 0))
2158
2159 def default_load_dump(obj):
2160 return pickle.loads(pickle.dumps(obj, 0))
2161
2162 # pickling complex numbers using protocol 0 relies on copyreg
2163 # so check pickling a complex number still works
2164 z = 1 + 2j
2165 self.assertEqual(custom_load_dump(z), z)
2166 self.assertEqual(default_load_dump(z), z)
2167
2168 # modify pickling of complex
2169 REDUCE_1 = 'reduce_1'
2170 def reduce_1(obj):
2171 return str, (REDUCE_1,)
2172 dispatch_table[complex] = reduce_1
2173 self.assertEqual(custom_load_dump(z), REDUCE_1)
2174 self.assertEqual(default_load_dump(z), z)
2175
2176 # check picklability of AAA and BBB
2177 a = AAA()
2178 b = BBB()
2179 self.assertEqual(custom_load_dump(a), REDUCE_A)
2180 self.assertIsInstance(custom_load_dump(b), BBB)
2181 self.assertEqual(default_load_dump(a), REDUCE_A)
2182 self.assertIsInstance(default_load_dump(b), BBB)
2183
2184 # modify pickling of BBB
2185 dispatch_table[BBB] = reduce_1
2186 self.assertEqual(custom_load_dump(a), REDUCE_A)
2187 self.assertEqual(custom_load_dump(b), REDUCE_1)
2188 self.assertEqual(default_load_dump(a), REDUCE_A)
2189 self.assertIsInstance(default_load_dump(b), BBB)
2190
2191 # revert pickling of BBB and modify pickling of AAA
2192 REDUCE_2 = 'reduce_2'
2193 def reduce_2(obj):
2194 return str, (REDUCE_2,)
2195 dispatch_table[AAA] = reduce_2
2196 del dispatch_table[BBB]
2197 self.assertEqual(custom_load_dump(a), REDUCE_2)
2198 self.assertIsInstance(custom_load_dump(b), BBB)
2199 self.assertEqual(default_load_dump(a), REDUCE_A)
2200 self.assertIsInstance(default_load_dump(b), BBB)
2201
2202
Guido van Rossum98297ee2007-11-06 21:34:58 +00002203if __name__ == "__main__":
2204 # Print some stuff that can be used to rewrite DATA{0,1,2}
2205 from pickletools import dis
2206 x = create_data()
2207 for i in range(3):
2208 p = pickle.dumps(x, i)
2209 print("DATA{0} = (".format(i))
2210 for j in range(0, len(p), 20):
2211 b = bytes(p[j:j+20])
2212 print(" {0!r}".format(b))
2213 print(")")
2214 print()
2215 print("# Disassembly of DATA{0}".format(i))
2216 print("DATA{0}_DIS = \"\"\"\\".format(i))
2217 dis(p)
2218 print("\"\"\"")
2219 print()