blob: 1b08dbd8b5f31014459e7fefb50ed35f52f6a442 [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
Antoine Pitrou82be19f2011-08-29 23:09:33 +02006import sys
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01007import unittest
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01008import weakref
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00009from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +000010
Antoine Pitrou82be19f2011-08-29 23:09:33 +020011from test.support import (
Antoine Pitrouee763e22011-08-29 23:14:53 +020012 TestFailed, TESTFN, run_with_locale, no_tracing,
Antoine Pitrou94190bb2011-10-04 10:22:36 +020013 _2G, _4G, bigmemtest,
Antoine Pitrou82be19f2011-08-29 23:09:33 +020014 )
Tim Peterse089c682001-04-10 03:41:41 +000015
Guido van Rossum98297ee2007-11-06 21:34:58 +000016from pickle import bytes_types
17
Tim Petersee1a53c2003-02-02 02:57:53 +000018# Tests that try a number of pickle protocols should have a
19# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000020# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000021protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000022
Antoine Pitroub7591d42011-10-04 16:18:15 +020023ascii_char_size = 1
Antoine Pitrou82be19f2011-08-29 23:09:33 +020024
Tim Peters22e71712003-02-03 22:27:38 +000025
26# Return True if opcode code appears in the pickle, else False.
27def opcode_in_pickle(code, pickle):
28 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000029 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000030 return True
31 return False
32
Tim Peters8d2613a2003-02-11 16:40:16 +000033# Return the number of times opcode code appears in pickle.
34def count_opcode(code, pickle):
35 n = 0
36 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000037 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000038 n += 1
39 return n
40
Antoine Pitrou04248a82010-10-12 20:51:21 +000041
42class UnseekableIO(io.BytesIO):
43 def peek(self, *args):
44 raise NotImplementedError
45
46 def seekable(self):
47 return False
48
49 def seek(self, *args):
50 raise io.UnsupportedOperation
51
52 def tell(self):
53 raise io.UnsupportedOperation
54
55
Tim Peters3e667d52003-02-04 21:47:44 +000056# We can't very well test the extension registry without putting known stuff
57# in it, but we have to be careful to restore its original state. Code
58# should do this:
59#
60# e = ExtensionSaver(extension_code)
61# try:
62# fiddle w/ the extension registry's stuff for extension_code
63# finally:
64# e.restore()
65
66class ExtensionSaver:
67 # Remember current registration for code (if any), and remove it (if
68 # there is one).
69 def __init__(self, code):
70 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000071 if code in copyreg._inverted_registry:
72 self.pair = copyreg._inverted_registry[code]
73 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000074 else:
75 self.pair = None
76
77 # Restore previous registration for code.
78 def restore(self):
79 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000080 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000081 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000082 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000083 pair = self.pair
84 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000085 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000086
Jeremy Hylton66426532001-10-15 21:38:56 +000087class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000088 def __eq__(self, other):
89 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000090
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000091class D(C):
92 def __init__(self, arg):
93 pass
94
95class E(C):
96 def __getinitargs__(self):
97 return ()
98
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +010099class H(object):
100 pass
101
Jeremy Hylton66426532001-10-15 21:38:56 +0000102import __main__
103__main__.C = C
104C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000105__main__.D = D
106D.__module__ = "__main__"
107__main__.E = E
108E.__module__ = "__main__"
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100109__main__.H = H
110H.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000111
112class myint(int):
113 def __init__(self, x):
114 self.str = str(x)
115
116class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000117
Jeremy Hylton66426532001-10-15 21:38:56 +0000118 def __init__(self, a, b):
119 self.a = a
120 self.b = b
121
122 def __getinitargs__(self):
123 return self.a, self.b
124
Guido van Rossum04a86612001-12-19 16:58:54 +0000125class metaclass(type):
126 pass
127
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000128class use_metaclass(object, metaclass=metaclass):
129 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000130
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200131class pickling_metaclass(type):
132 def __eq__(self, other):
133 return (type(self) == type(other) and
134 self.reduce_args == other.reduce_args)
135
136 def __reduce__(self):
137 return (create_dynamic_class, self.reduce_args)
138
139def create_dynamic_class(name, bases):
140 result = pickling_metaclass(name, bases, dict())
141 result.reduce_args = (name, bases)
142 return result
143
Tim Peters70b02d72003-02-02 17:26:40 +0000144# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
145# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000146
Guido van Rossum98297ee2007-11-06 21:34:58 +0000147DATA0 = (
Mark Dickinson8dd05142009-01-20 20:43:58 +0000148 b'(lp0\nL0L\naL1L\naF2.0\nac'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000149 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000150 b'p1\n(F3.0\nF0.0\ntp2\nRp'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000151 b'3\naL1L\naL-1L\naL255L\naL-'
152 b'255L\naL-256L\naL65535L\na'
153 b'L-65535L\naL-65536L\naL2'
154 b'147483647L\naL-2147483'
155 b'647L\naL-2147483648L\na('
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000156 b'Vabc\np4\ng4\nccopyreg'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000157 b'\n_reconstructor\np5\n('
Georg Brandl1a3284e2007-12-02 09:40:06 +0000158 b'c__main__\nC\np6\ncbu'
159 b'iltins\nobject\np7\nNt'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000160 b'p8\nRp9\n(dp10\nVfoo\np1'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000161 b'1\nL1L\nsVbar\np12\nL2L\nsb'
162 b'g9\ntp13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000163)
Tim Peterse9358162001-01-22 22:05:20 +0000164
Guido van Rossum98297ee2007-11-06 21:34:58 +0000165# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000166DATA0_DIS = """\
167 0: ( MARK
168 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000169 2: p PUT 0
170 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000171 9: a APPEND
172 10: L LONG 1
173 14: a APPEND
174 15: F FLOAT 2.0
175 20: a APPEND
176 21: c GLOBAL 'builtins complex'
177 39: p PUT 1
178 42: ( MARK
179 43: F FLOAT 3.0
180 48: F FLOAT 0.0
181 53: t TUPLE (MARK at 42)
182 54: p PUT 2
183 57: R REDUCE
184 58: p PUT 3
185 61: a APPEND
186 62: L LONG 1
187 66: a APPEND
188 67: L LONG -1
189 72: a APPEND
190 73: L LONG 255
191 79: a APPEND
192 80: L LONG -255
193 87: a APPEND
194 88: L LONG -256
195 95: a APPEND
196 96: L LONG 65535
197 104: a APPEND
198 105: L LONG -65535
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000199 114: a APPEND
Mark Dickinson8dd05142009-01-20 20:43:58 +0000200 115: L LONG -65536
201 124: a APPEND
202 125: L LONG 2147483647
203 138: a APPEND
204 139: L LONG -2147483647
205 153: a APPEND
206 154: L LONG -2147483648
207 168: a APPEND
208 169: ( MARK
209 170: V UNICODE 'abc'
210 175: p PUT 4
211 178: g GET 4
212 181: c GLOBAL 'copyreg _reconstructor'
213 205: p PUT 5
214 208: ( MARK
215 209: c GLOBAL '__main__ C'
216 221: p PUT 6
217 224: c GLOBAL 'builtins object'
218 241: p PUT 7
219 244: N NONE
220 245: t TUPLE (MARK at 208)
221 246: p PUT 8
222 249: R REDUCE
223 250: p PUT 9
224 253: ( MARK
225 254: d DICT (MARK at 253)
226 255: p PUT 10
227 259: V UNICODE 'foo'
228 264: p PUT 11
229 268: L LONG 1
230 272: s SETITEM
231 273: V UNICODE 'bar'
232 278: p PUT 12
233 282: L LONG 2
234 286: s SETITEM
235 287: b BUILD
236 288: g GET 9
237 291: t TUPLE (MARK at 169)
238 292: p PUT 13
239 296: a APPEND
240 297: g GET 13
241 301: a APPEND
242 302: L LONG 5
243 306: a APPEND
244 307: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000245highest protocol among opcodes = 0
246"""
247
Guido van Rossum98297ee2007-11-06 21:34:58 +0000248DATA1 = (
Georg Brandl1a3284e2007-12-02 09:40:06 +0000249 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
250 b'builtins\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000251 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
252 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
253 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
254 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000255 b'cq\x04h\x04ccopyreg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000256 b'nstructor\nq\x05(c__main'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000257 b'__\nC\nq\x06cbuiltins\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000258 b'object\nq\x07Ntq\x08Rq\t}q\n('
259 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
260 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
261)
Tim Peters70b02d72003-02-02 17:26:40 +0000262
Guido van Rossum98297ee2007-11-06 21:34:58 +0000263# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000264DATA1_DIS = """\
265 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000266 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000267 3: ( MARK
268 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000269 6: K BININT1 1
270 8: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000271 17: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000272 35: q BINPUT 1
273 37: ( MARK
274 38: G BINFLOAT 3.0
275 47: G BINFLOAT 0.0
276 56: t TUPLE (MARK at 37)
277 57: q BINPUT 2
278 59: R REDUCE
279 60: q BINPUT 3
280 62: K BININT1 1
281 64: J BININT -1
282 69: K BININT1 255
283 71: J BININT -255
284 76: J BININT -256
285 81: M BININT2 65535
286 84: J BININT -65535
287 89: J BININT -65536
288 94: J BININT 2147483647
289 99: J BININT -2147483647
290 104: J BININT -2147483648
291 109: ( MARK
292 110: X BINUNICODE 'abc'
293 118: q BINPUT 4
294 120: h BINGET 4
295 122: c GLOBAL 'copyreg _reconstructor'
296 146: q BINPUT 5
297 148: ( MARK
298 149: c GLOBAL '__main__ C'
299 161: q BINPUT 6
300 163: c GLOBAL 'builtins object'
301 180: q BINPUT 7
302 182: N NONE
303 183: t TUPLE (MARK at 148)
304 184: q BINPUT 8
305 186: R REDUCE
306 187: q BINPUT 9
307 189: } EMPTY_DICT
308 190: q BINPUT 10
309 192: ( MARK
310 193: X BINUNICODE 'foo'
311 201: q BINPUT 11
312 203: K BININT1 1
313 205: X BINUNICODE 'bar'
314 213: q BINPUT 12
315 215: K BININT1 2
316 217: u SETITEMS (MARK at 192)
317 218: b BUILD
318 219: h BINGET 9
319 221: t TUPLE (MARK at 109)
320 222: q BINPUT 13
321 224: h BINGET 13
322 226: K BININT1 5
323 228: e APPENDS (MARK at 3)
324 229: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000325highest protocol among opcodes = 1
326"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000327
Guido van Rossum98297ee2007-11-06 21:34:58 +0000328DATA2 = (
329 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000330 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000331 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
332 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
333 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
334 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
335 b'bcq\x04h\x04c__main__\nC\nq\x05'
336 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
337 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
338 b'\nK\x05e.'
339)
Tim Petersfc273752003-03-02 04:54:24 +0000340
Guido van Rossum98297ee2007-11-06 21:34:58 +0000341# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000342DATA2_DIS = """\
343 0: \x80 PROTO 2
344 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000345 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000346 5: ( MARK
347 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000348 8: K BININT1 1
349 10: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000350 19: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000351 37: q BINPUT 1
352 39: G BINFLOAT 3.0
353 48: G BINFLOAT 0.0
354 57: \x86 TUPLE2
355 58: q BINPUT 2
356 60: R REDUCE
357 61: q BINPUT 3
358 63: K BININT1 1
359 65: J BININT -1
360 70: K BININT1 255
361 72: J BININT -255
362 77: J BININT -256
363 82: M BININT2 65535
364 85: J BININT -65535
365 90: J BININT -65536
366 95: J BININT 2147483647
367 100: J BININT -2147483647
368 105: J BININT -2147483648
369 110: ( MARK
370 111: X BINUNICODE 'abc'
371 119: q BINPUT 4
372 121: h BINGET 4
373 123: c GLOBAL '__main__ C'
374 135: q BINPUT 5
375 137: ) EMPTY_TUPLE
376 138: \x81 NEWOBJ
377 139: q BINPUT 6
378 141: } EMPTY_DICT
379 142: q BINPUT 7
380 144: ( MARK
381 145: X BINUNICODE 'foo'
382 153: q BINPUT 8
383 155: K BININT1 1
384 157: X BINUNICODE 'bar'
385 165: q BINPUT 9
386 167: K BININT1 2
387 169: u SETITEMS (MARK at 144)
388 170: b BUILD
389 171: h BINGET 6
390 173: t TUPLE (MARK at 110)
391 174: q BINPUT 10
392 176: h BINGET 10
393 178: K BININT1 5
394 180: e APPENDS (MARK at 5)
395 181: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000396highest protocol among opcodes = 2
397"""
398
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000399# set([1,2]) pickled from 2.x with protocol 2
400DATA3 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
401
402# xrange(5) pickled from 2.x with protocol 2
403DATA4 = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
404
405# a SimpleCookie() object pickled from 2.x with protocol 2
406DATA5 = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
407 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
408 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
409 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
410 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
411 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
412
413# set([3]) pickled from 2.x with protocol 2
414DATA6 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
415
Walter Doerwald9d1dbca2013-12-02 11:41:01 +0100416python2_exceptions_without_args = (
417 ArithmeticError,
418 AssertionError,
419 AttributeError,
420 BaseException,
421 BufferError,
422 BytesWarning,
423 DeprecationWarning,
424 EOFError,
425 EnvironmentError,
426 Exception,
427 FloatingPointError,
428 FutureWarning,
429 GeneratorExit,
430 IOError,
431 ImportError,
432 ImportWarning,
433 IndentationError,
434 IndexError,
435 KeyError,
436 KeyboardInterrupt,
437 LookupError,
438 MemoryError,
439 NameError,
440 NotImplementedError,
441 OSError,
442 OverflowError,
443 PendingDeprecationWarning,
444 ReferenceError,
445 RuntimeError,
446 RuntimeWarning,
447 # StandardError is gone in Python 3, we map it to Exception
448 StopIteration,
449 SyntaxError,
450 SyntaxWarning,
451 SystemError,
452 SystemExit,
453 TabError,
454 TypeError,
455 UnboundLocalError,
456 UnicodeError,
457 UnicodeWarning,
458 UserWarning,
459 ValueError,
460 Warning,
461 ZeroDivisionError,
462)
463
464exception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.'
465
466# Exception objects without arguments pickled from 2.x with protocol 2
467DATA7 = {
468 exception :
469 exception_pickle.replace(b'?', exception.__name__.encode("ascii"))
470 for exception in python2_exceptions_without_args
471}
472
473# StandardError is mapped to Exception, test that separately
474DATA8 = exception_pickle.replace(b'?', b'StandardError')
475
476# UnicodeEncodeError object pickled from 2.x with protocol 2
477DATA9 = (b'\x80\x02cexceptions\nUnicodeEncodeError\n'
478 b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01'
479 b'U\x03badq\x03tq\x04Rq\x05.')
480
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000481
Jeremy Hylton66426532001-10-15 21:38:56 +0000482def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000483 c = C()
484 c.foo = 1
485 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000486 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000487 # Append some integer test cases at cPickle.c's internal size
488 # cutoffs.
489 uint1max = 0xff
490 uint2max = 0xffff
491 int4max = 0x7fffffff
492 x.extend([1, -1,
493 uint1max, -uint1max, -uint1max-1,
494 uint2max, -uint2max, -uint2max-1,
495 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000496 y = ('abc', 'abc', c, c)
497 x.append(y)
498 x.append(y)
499 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000500 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000501
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100502
Jeremy Hylton66426532001-10-15 21:38:56 +0000503class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000504 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000505
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +0100506 optimized = False
507
Jeremy Hylton66426532001-10-15 21:38:56 +0000508 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000509
Jeremy Hylton66426532001-10-15 21:38:56 +0000510 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000511 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000512
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100513 def assert_is_copy(self, obj, objcopy, msg=None):
514 """Utility method to verify if two objects are copies of each others.
515 """
516 if msg is None:
517 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
518 self.assertEqual(obj, objcopy, msg=msg)
519 self.assertIs(type(obj), type(objcopy), msg=msg)
520 if hasattr(obj, '__dict__'):
521 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
522 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
523 if hasattr(obj, '__slots__'):
524 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
525 for slot in obj.__slots__:
526 self.assertEqual(
527 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
528 self.assertEqual(getattr(obj, slot, None),
529 getattr(objcopy, slot, None), msg=msg)
530
Jeremy Hylton66426532001-10-15 21:38:56 +0000531 def test_misc(self):
532 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000533 for proto in protocols:
534 x = myint(4)
535 s = self.dumps(x, proto)
536 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100537 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000538
Tim Peters70b02d72003-02-02 17:26:40 +0000539 x = (1, ())
540 s = self.dumps(x, proto)
541 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100542 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000543
Tim Peters70b02d72003-02-02 17:26:40 +0000544 x = initarg(1, x)
545 s = self.dumps(x, proto)
546 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100547 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000548
Jeremy Hylton66426532001-10-15 21:38:56 +0000549 # XXX test __reduce__ protocol?
550
Tim Peters70b02d72003-02-02 17:26:40 +0000551 def test_roundtrip_equality(self):
552 expected = self._testdata
553 for proto in protocols:
554 s = self.dumps(expected, proto)
555 got = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100556 self.assert_is_copy(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000557
Guido van Rossum98297ee2007-11-06 21:34:58 +0000558 def test_load_from_data0(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100559 self.assert_is_copy(self._testdata, self.loads(DATA0))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000560
561 def test_load_from_data1(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100562 self.assert_is_copy(self._testdata, self.loads(DATA1))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000563
564 def test_load_from_data2(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100565 self.assert_is_copy(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000566
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000567 def test_load_classic_instance(self):
568 # See issue5180. Test loading 2.x pickles that
569 # contain an instance of old style class.
570 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
571 xname = X.__name__.encode('ascii')
572 # Protocol 0 (text mode pickle):
573 """
574 0: ( MARK
575 1: i INST '__main__ X' (MARK at 0)
576 15: p PUT 0
577 18: ( MARK
578 19: d DICT (MARK at 18)
579 20: p PUT 1
580 23: b BUILD
581 24: . STOP
582 """
583 pickle0 = (b"(i__main__\n"
584 b"X\n"
585 b"p0\n"
586 b"(dp1\nb.").replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100587 self.assert_is_copy(X(*args), self.loads(pickle0))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000588
589 # Protocol 1 (binary mode pickle)
590 """
591 0: ( MARK
592 1: c GLOBAL '__main__ X'
593 15: q BINPUT 0
594 17: o OBJ (MARK at 0)
595 18: q BINPUT 1
596 20: } EMPTY_DICT
597 21: q BINPUT 2
598 23: b BUILD
599 24: . STOP
600 """
601 pickle1 = (b'(c__main__\n'
602 b'X\n'
603 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100604 self.assert_is_copy(X(*args), self.loads(pickle1))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000605
606 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
607 """
608 0: \x80 PROTO 2
609 2: ( MARK
610 3: c GLOBAL '__main__ X'
611 17: q BINPUT 0
612 19: o OBJ (MARK at 2)
613 20: q BINPUT 1
614 22: } EMPTY_DICT
615 23: q BINPUT 2
616 25: b BUILD
617 26: . STOP
618 """
619 pickle2 = (b'\x80\x02(c__main__\n'
620 b'X\n'
621 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100622 self.assert_is_copy(X(*args), self.loads(pickle2))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000623
Tim Peters70b02d72003-02-02 17:26:40 +0000624 # There are gratuitous differences between pickles produced by
625 # pickle and cPickle, largely because cPickle starts PUT indices at
626 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
627 # there's a comment with an exclamation point there whose meaning
628 # is a mystery. cPickle also suppresses PUT for objects with a refcount
629 # of 1.
630 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000631 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000632 from pickletools import dis
633
634 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
635 s = self.dumps(self._testdata, proto)
636 filelike = StringIO()
637 dis(s, out=filelike)
638 got = filelike.getvalue()
639 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000640
641 def test_recursive_list(self):
642 l = []
643 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000644 for proto in protocols:
645 s = self.dumps(l, proto)
646 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100647 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000648 self.assertEqual(len(x), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000649 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000650
Collin Winter8ca69de2009-05-26 16:53:41 +0000651 def test_recursive_tuple(self):
652 t = ([],)
653 t[0].append(t)
654 for proto in protocols:
655 s = self.dumps(t, proto)
656 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100657 self.assertIsInstance(x, tuple)
Collin Winter8ca69de2009-05-26 16:53:41 +0000658 self.assertEqual(len(x), 1)
659 self.assertEqual(len(x[0]), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000660 self.assertTrue(x is x[0][0])
Collin Winter8ca69de2009-05-26 16:53:41 +0000661
Jeremy Hylton66426532001-10-15 21:38:56 +0000662 def test_recursive_dict(self):
663 d = {}
664 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000665 for proto in protocols:
666 s = self.dumps(d, proto)
667 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100668 self.assertIsInstance(x, dict)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000669 self.assertEqual(list(x.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000670 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000671
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100672 def test_recursive_set(self):
673 h = H()
674 y = set({h})
675 h.attr = y
676 for proto in protocols:
677 s = self.dumps(y, proto)
678 x = self.loads(s)
679 self.assertIsInstance(x, set)
680 self.assertIs(list(x)[0].attr, x)
681 self.assertEqual(len(x), 1)
682
683 def test_recursive_frozenset(self):
684 h = H()
685 y = frozenset({h})
686 h.attr = y
687 for proto in protocols:
688 s = self.dumps(y, proto)
689 x = self.loads(s)
690 self.assertIsInstance(x, frozenset)
691 self.assertIs(list(x)[0].attr, x)
692 self.assertEqual(len(x), 1)
693
Jeremy Hylton66426532001-10-15 21:38:56 +0000694 def test_recursive_inst(self):
695 i = C()
696 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000697 for proto in protocols:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200698 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +0000699 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100700 self.assertIsInstance(x, C)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000701 self.assertEqual(dir(x), dir(i))
Ezio Melottiaaef3442013-03-04 15:17:56 +0200702 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000703
704 def test_recursive_multi(self):
705 l = []
706 d = {1:l}
707 i = C()
708 i.attr = d
709 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000710 for proto in protocols:
711 s = self.dumps(l, proto)
712 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100713 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000714 self.assertEqual(len(x), 1)
715 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000716 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000717 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000718
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000719 def test_get(self):
720 self.assertRaises(KeyError, self.loads, b'g0\np0')
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100721 self.assert_is_copy([(100,), (100,)],
722 self.loads(b'((Kdtp0\nh\x00l.))'))
Jeremy Hylton66426532001-10-15 21:38:56 +0000723
Walter Dörwald9b775532007-06-08 14:30:53 +0000724 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000725 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +0000726 '<\\>', '<\\\U00012345>',
727 # surrogates
728 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000729 for proto in protocols:
730 for u in endcases:
731 p = self.dumps(u, proto)
732 u2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100733 self.assert_is_copy(u, u2)
Tim Peterse089c682001-04-10 03:41:41 +0000734
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000735 def test_unicode_high_plane(self):
736 t = '\U00012345'
737 for proto in protocols:
738 p = self.dumps(t, proto)
739 t2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100740 self.assert_is_copy(t, t2)
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000741
Guido van Rossumf4169812008-03-17 22:56:06 +0000742 def test_bytes(self):
743 for proto in protocols:
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500744 for s in b'', b'xyz', b'xyz'*100:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200745 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100746 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500747 for s in [bytes([i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200748 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100749 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500750 for s in [bytes([i, i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200751 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100752 self.assert_is_copy(s, self.loads(p))
Guido van Rossumf4169812008-03-17 22:56:06 +0000753
Jeremy Hylton66426532001-10-15 21:38:56 +0000754 def test_ints(self):
755 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000756 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000757 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000758 while n:
759 for expected in (-n, n):
760 s = self.dumps(expected, proto)
761 n2 = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100762 self.assert_is_copy(expected, n2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000763 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000764
Jeremy Hylton66426532001-10-15 21:38:56 +0000765 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000766 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000767 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000768 got = self.loads(data)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100769 self.assert_is_copy(maxint64, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000770
771 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000772 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000773 self.assertRaises(ValueError, self.loads, data)
774
Tim Petersee1a53c2003-02-02 02:57:53 +0000775 def test_long(self):
776 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000777 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000778 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000779 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000780 for npos in nbase-1, nbase, nbase+1:
781 for n in npos, -npos:
782 pickle = self.dumps(n, proto)
783 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100784 self.assert_is_copy(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +0000785 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
786 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000787 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000788 nbase += nbase << 1000000
789 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000790 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000791 got = self.loads(p)
Antoine Pitroud5df1942013-11-23 21:20:49 +0100792 # assert_is_copy is very expensive here as it precomputes
793 # a failure message by computing the repr() of n and got,
794 # we just do the check ourselves.
795 self.assertIs(type(got), int)
796 self.assertEqual(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +0000797
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000798 def test_float(self):
799 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
800 3.14, 263.44582062374053, 6.022e23, 1e30]
801 test_values = test_values + [-x for x in test_values]
802 for proto in protocols:
803 for value in test_values:
804 pickle = self.dumps(value, proto)
805 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100806 self.assert_is_copy(value, got)
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000807
Thomas Wouters477c8d52006-05-27 19:21:47 +0000808 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
809 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000810 # make sure that floats are formatted locale independent with proto 0
811 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000812
Jeremy Hylton66426532001-10-15 21:38:56 +0000813 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000814 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000815
816 def test_getinitargs(self):
817 pass
818
Antoine Pitrou79035bd2012-06-26 23:04:48 +0200819 def test_pop_empty_stack(self):
820 # Test issue7455
821 s = b'0'
822 self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s)
823
Guido van Rossum04a86612001-12-19 16:58:54 +0000824 def test_metaclass(self):
825 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000826 for proto in protocols:
827 s = self.dumps(a, proto)
828 b = self.loads(s)
829 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000830
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200831 def test_dynamic_class(self):
832 a = create_dynamic_class("my_dynamic_class", (object,))
833 copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
834 for proto in protocols:
835 s = self.dumps(a, proto)
836 b = self.loads(s)
837 self.assertEqual(a, b)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100838 self.assertIs(type(a), type(b))
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200839
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000840 def test_structseq(self):
841 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000842 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000843
844 t = time.localtime()
845 for proto in protocols:
846 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000847 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100848 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000849 if hasattr(os, "stat"):
850 t = os.stat(os.curdir)
851 s = self.dumps(t, proto)
852 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100853 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000854 if hasattr(os, "statvfs"):
855 t = os.statvfs(os.curdir)
856 s = self.dumps(t, proto)
857 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100858 self.assert_is_copy(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000859
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100860 def test_ellipsis(self):
861 for proto in protocols:
862 s = self.dumps(..., proto)
863 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100864 self.assertIs(..., u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100865
866 def test_notimplemented(self):
867 for proto in protocols:
868 s = self.dumps(NotImplemented, proto)
869 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100870 self.assertIs(NotImplemented, u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100871
Alexandre Vassalotti19b6fa62013-11-30 16:06:39 -0800872 def test_singleton_types(self):
873 # Issue #6477: Test that types of built-in singletons can be pickled.
874 singletons = [None, ..., NotImplemented]
875 for singleton in singletons:
876 for proto in protocols:
877 s = self.dumps(type(singleton), proto)
878 u = self.loads(s)
879 self.assertIs(type(singleton), u)
880
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000881 # Tests for protocol 2
882
Tim Peters4190fb82003-02-02 16:09:05 +0000883 def test_proto(self):
Tim Peters4190fb82003-02-02 16:09:05 +0000884 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100885 pickled = self.dumps(None, proto)
Tim Peters4190fb82003-02-02 16:09:05 +0000886 if proto >= 2:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100887 proto_header = pickle.PROTO + bytes([proto])
888 self.assertTrue(pickled.startswith(proto_header))
889 else:
890 self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)
Tim Peters4190fb82003-02-02 16:09:05 +0000891
892 oob = protocols[-1] + 1 # a future protocol
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100893 build_none = pickle.NONE + pickle.STOP
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000894 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000895 try:
896 self.loads(badpickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100897 except ValueError as err:
898 self.assertIn("unsupported pickle protocol", str(err))
Tim Peters4190fb82003-02-02 16:09:05 +0000899 else:
900 self.fail("expected bad protocol number to raise ValueError")
901
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000902 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000903 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000904 for proto in protocols:
905 s = self.dumps(x, proto)
906 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100907 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000908 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000909
910 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000911 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000912 for proto in protocols:
913 s = self.dumps(x, proto)
914 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100915 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000916 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000917
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000918 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000919 # Map (proto, len(tuple)) to expected opcode.
920 expected_opcode = {(0, 0): pickle.TUPLE,
921 (0, 1): pickle.TUPLE,
922 (0, 2): pickle.TUPLE,
923 (0, 3): pickle.TUPLE,
924 (0, 4): pickle.TUPLE,
925
926 (1, 0): pickle.EMPTY_TUPLE,
927 (1, 1): pickle.TUPLE,
928 (1, 2): pickle.TUPLE,
929 (1, 3): pickle.TUPLE,
930 (1, 4): pickle.TUPLE,
931
932 (2, 0): pickle.EMPTY_TUPLE,
933 (2, 1): pickle.TUPLE1,
934 (2, 2): pickle.TUPLE2,
935 (2, 3): pickle.TUPLE3,
936 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000937
938 (3, 0): pickle.EMPTY_TUPLE,
939 (3, 1): pickle.TUPLE1,
940 (3, 2): pickle.TUPLE2,
941 (3, 3): pickle.TUPLE3,
942 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000943 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000944 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000945 b = (1,)
946 c = (1, 2)
947 d = (1, 2, 3)
948 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000949 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000950 for x in a, b, c, d, e:
951 s = self.dumps(x, proto)
952 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100953 self.assert_is_copy(x, y)
954 expected = expected_opcode[min(proto, 3), len(x)]
955 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000956
Guido van Rossum7d97d312003-01-28 04:25:27 +0000957 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000958 # Map (proto, singleton) to expected opcode.
959 expected_opcode = {(0, None): pickle.NONE,
960 (1, None): pickle.NONE,
961 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000962 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000963
964 (0, True): pickle.INT,
965 (1, True): pickle.INT,
966 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000967 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000968
969 (0, False): pickle.INT,
970 (1, False): pickle.INT,
971 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000972 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000973 }
Tim Peters4190fb82003-02-02 16:09:05 +0000974 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000975 for x in None, False, True:
976 s = self.dumps(x, proto)
977 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000978 self.assertTrue(x is y, (proto, x, s, y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100979 expected = expected_opcode[min(proto, 3), x]
980 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters3c67d792003-02-02 17:59:11 +0000981
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000982 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000983 x = MyTuple([1, 2, 3])
984 x.foo = 42
985 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000986 for proto in protocols:
987 s = self.dumps(x, proto)
988 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100989 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000990
991 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000992 x = MyList([1, 2, 3])
993 x.foo = 42
994 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000995 for proto in protocols:
996 s = self.dumps(x, proto)
997 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100998 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000999
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001000 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001001 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001002 for C in myclasses:
1003 B = C.__base__
1004 x = C(C.sample)
1005 x.foo = 42
1006 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001007 y = self.loads(s)
1008 detail = (proto, C, B, x, y, type(y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001009 self.assert_is_copy(x, y) # XXX revisit
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001010 self.assertEqual(B(x), B(y), detail)
1011 self.assertEqual(x.__dict__, y.__dict__, detail)
1012
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01001013 def test_newobj_proxies(self):
1014 # NEWOBJ should use the __class__ rather than the raw type
1015 classes = myclasses[:]
1016 # Cannot create weakproxies to these classes
1017 for c in (MyInt, MyTuple):
1018 classes.remove(c)
1019 for proto in protocols:
1020 for C in classes:
1021 B = C.__base__
1022 x = C(C.sample)
1023 x.foo = 42
1024 p = weakref.proxy(x)
1025 s = self.dumps(p, proto)
1026 y = self.loads(s)
1027 self.assertEqual(type(y), type(x)) # rather than type(p)
1028 detail = (proto, C, B, x, y, type(y))
1029 self.assertEqual(B(x), B(y), detail)
1030 self.assertEqual(x.__dict__, y.__dict__, detail)
1031
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001032 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001033 # an object of that type. Check that the resulting pickle uses opcode
1034 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001035
Tim Peters22e71712003-02-03 22:27:38 +00001036 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001037 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001038 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001039 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001040 x = MyList([1, 2, 3])
1041 x.foo = 42
1042 x.bar = "hello"
1043
Tim Peters22e71712003-02-03 22:27:38 +00001044 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001045 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001046 self.assertIn(__name__.encode("utf-8"), s1)
1047 self.assertIn(b"MyList", s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001048 self.assertFalse(opcode_in_pickle(opcode, s1))
Tim Peters3e667d52003-02-04 21:47:44 +00001049
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001050 y = self.loads(s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001051 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001052
Tim Peters22e71712003-02-03 22:27:38 +00001053 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001054 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001055 self.assertNotIn(__name__.encode("utf-8"), s2)
1056 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001057 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +00001058
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001059 y = self.loads(s2)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001060 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001061 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001062 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001063
1064 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001065 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1066 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001067
1068 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001069 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1070 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1071 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001072
1073 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001074 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1075 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1076 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1077
Tim Peters8d2613a2003-02-11 16:40:16 +00001078 def test_list_chunking(self):
1079 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +00001080 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001081 for proto in protocols:
1082 s = self.dumps(x, proto)
1083 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001084 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001085 num_appends = count_opcode(pickle.APPENDS, s)
1086 self.assertEqual(num_appends, proto > 0)
1087
1088 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001089 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001090 for proto in protocols:
1091 s = self.dumps(x, proto)
1092 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001093 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001094 num_appends = count_opcode(pickle.APPENDS, s)
1095 if proto == 0:
1096 self.assertEqual(num_appends, 0)
1097 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001098 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001099
1100 def test_dict_chunking(self):
1101 n = 10 # too small to chunk
1102 x = dict.fromkeys(range(n))
1103 for proto in protocols:
1104 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +00001105 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00001106 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001107 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001108 num_setitems = count_opcode(pickle.SETITEMS, s)
1109 self.assertEqual(num_setitems, proto > 0)
1110
1111 n = 2500 # expect at least two chunks when proto > 0
1112 x = dict.fromkeys(range(n))
1113 for proto in protocols:
1114 s = self.dumps(x, proto)
1115 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001116 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001117 num_setitems = count_opcode(pickle.SETITEMS, s)
1118 if proto == 0:
1119 self.assertEqual(num_setitems, 0)
1120 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001121 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001122
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001123 def test_set_chunking(self):
1124 n = 10 # too small to chunk
1125 x = set(range(n))
1126 for proto in protocols:
1127 s = self.dumps(x, proto)
1128 y = self.loads(s)
1129 self.assert_is_copy(x, y)
1130 num_additems = count_opcode(pickle.ADDITEMS, s)
1131 if proto < 4:
1132 self.assertEqual(num_additems, 0)
1133 else:
1134 self.assertEqual(num_additems, 1)
1135
1136 n = 2500 # expect at least two chunks when proto >= 4
1137 x = set(range(n))
1138 for proto in protocols:
1139 s = self.dumps(x, proto)
1140 y = self.loads(s)
1141 self.assert_is_copy(x, y)
1142 num_additems = count_opcode(pickle.ADDITEMS, s)
1143 if proto < 4:
1144 self.assertEqual(num_additems, 0)
1145 else:
1146 self.assertGreaterEqual(num_additems, 2)
1147
Tim Peterse9ef2032003-02-13 18:42:00 +00001148 def test_simple_newobj(self):
1149 x = object.__new__(SimpleNewObj) # avoid __init__
1150 x.abc = 666
1151 for proto in protocols:
1152 s = self.dumps(x, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001153 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1154 2 <= proto < 4)
1155 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1156 proto >= 4)
Tim Peterse9ef2032003-02-13 18:42:00 +00001157 y = self.loads(s) # will raise TypeError if __init__ called
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001158 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001159
Tim Peters42f08ac2003-02-11 22:43:24 +00001160 def test_newobj_list_slots(self):
1161 x = SlotList([1, 2, 3])
1162 x.foo = 42
1163 x.bar = "hello"
1164 s = self.dumps(x, 2)
1165 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001166 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001167
Guido van Rossum2a30b212003-02-18 22:41:24 +00001168 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001169 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001170 x = REX_one()
1171 self.assertEqual(x._reduce_called, 0)
1172 s = self.dumps(x, proto)
1173 self.assertEqual(x._reduce_called, 1)
1174 y = self.loads(s)
1175 self.assertEqual(y._reduce_called, 0)
1176
1177 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001178 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001179 x = REX_two()
1180 self.assertEqual(x._proto, None)
1181 s = self.dumps(x, proto)
1182 self.assertEqual(x._proto, proto)
1183 y = self.loads(s)
1184 self.assertEqual(y._proto, None)
1185
1186 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001187 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001188 x = REX_three()
1189 self.assertEqual(x._proto, None)
1190 s = self.dumps(x, proto)
1191 self.assertEqual(x._proto, proto)
1192 y = self.loads(s)
1193 self.assertEqual(y._proto, None)
1194
Guido van Rossumd8faa362007-04-27 19:54:29 +00001195 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001196 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001197 x = REX_four()
1198 self.assertEqual(x._proto, None)
1199 s = self.dumps(x, proto)
1200 self.assertEqual(x._proto, proto)
1201 y = self.loads(s)
1202 self.assertEqual(y._proto, proto)
1203
1204 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001205 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001206 x = REX_five()
1207 self.assertEqual(x._reduce_called, 0)
1208 s = self.dumps(x, proto)
1209 self.assertEqual(x._reduce_called, 1)
1210 y = self.loads(s)
1211 self.assertEqual(y._reduce_called, 1)
1212
Brett Cannon31f59292011-02-21 19:29:56 +00001213 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001214 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001215 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001216 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001217 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001218 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001219
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001220 def test_reduce_bad_iterator(self):
1221 # Issue4176: crash when 4th and 5th items of __reduce__()
1222 # are not iterators
1223 class C(object):
1224 def __reduce__(self):
1225 # 4th item is not an iterator
1226 return list, (), None, [], None
1227 class D(object):
1228 def __reduce__(self):
1229 # 5th item is not an iterator
1230 return dict, (), None, None, []
1231
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001232 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001233 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001234 try:
1235 self.dumps(C(), proto)
1236 except (pickle.PickleError):
1237 pass
1238 try:
1239 self.dumps(D(), proto)
1240 except (pickle.PickleError):
1241 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001242
Collin Winter771d8342009-04-16 03:18:06 +00001243 def test_many_puts_and_gets(self):
1244 # Test that internal data structures correctly deal with lots of
1245 # puts/gets.
1246 keys = ("aaa" + str(i) for i in range(100))
1247 large_dict = dict((k, [4, 5, 6]) for k in keys)
1248 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1249
1250 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001251 with self.subTest(proto=proto):
1252 dumped = self.dumps(obj, proto)
1253 loaded = self.loads(dumped)
1254 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00001255
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001256 def test_attribute_name_interning(self):
1257 # Test that attribute names of pickled objects are interned when
1258 # unpickling.
1259 for proto in protocols:
1260 x = C()
1261 x.foo = 42
1262 x.bar = "hello"
1263 s = self.dumps(x, proto)
1264 y = self.loads(s)
1265 x_keys = sorted(x.__dict__)
1266 y_keys = sorted(y.__dict__)
1267 for x_key, y_key in zip(x_keys, y_keys):
1268 self.assertIs(x_key, y_key)
1269
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001270 def test_unpickle_from_2x(self):
1271 # Unpickle non-trivial data from Python 2.x.
1272 loaded = self.loads(DATA3)
1273 self.assertEqual(loaded, set([1, 2]))
1274 loaded = self.loads(DATA4)
1275 self.assertEqual(type(loaded), type(range(0)))
1276 self.assertEqual(list(loaded), list(range(5)))
1277 loaded = self.loads(DATA5)
1278 self.assertEqual(type(loaded), SimpleCookie)
1279 self.assertEqual(list(loaded.keys()), ["key"])
1280 self.assertEqual(loaded["key"].value, "Set-Cookie: key=value")
1281
Walter Doerwald9d1dbca2013-12-02 11:41:01 +01001282 for (exc, data) in DATA7.items():
1283 loaded = self.loads(data)
1284 self.assertIs(type(loaded), exc)
1285
1286 loaded = self.loads(DATA8)
1287 self.assertIs(type(loaded), Exception)
1288
1289 loaded = self.loads(DATA9)
1290 self.assertIs(type(loaded), UnicodeEncodeError)
1291 self.assertEqual(loaded.object, "foo")
1292 self.assertEqual(loaded.encoding, "ascii")
1293 self.assertEqual(loaded.start, 0)
1294 self.assertEqual(loaded.end, 1)
1295 self.assertEqual(loaded.reason, "bad")
1296
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001297 def test_pickle_to_2x(self):
1298 # Pickle non-trivial data with protocol 2, expecting that it yields
1299 # the same result as Python 2.x did.
1300 # NOTE: this test is a bit too strong since we can produce different
1301 # bytecode that 2.x will still understand.
1302 dumped = self.dumps(range(5), 2)
1303 self.assertEqual(dumped, DATA4)
1304 dumped = self.dumps(set([3]), 2)
1305 self.assertEqual(dumped, DATA6)
1306
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001307 def test_large_pickles(self):
1308 # Test the correctness of internal buffering routines when handling
1309 # large data.
1310 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001311 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001312 dumped = self.dumps(data, proto)
1313 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001314 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001315 self.assertEqual(loaded, data)
1316
Alexander Belopolsky1ce92dc2011-02-24 19:40:09 +00001317 def test_empty_bytestring(self):
1318 # issue 11286
1319 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1320 self.assertEqual(empty, '')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001321
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001322 def test_int_pickling_efficiency(self):
1323 # Test compacity of int representation (see issue #12744)
1324 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001325 with self.subTest(proto=proto):
1326 pickles = [self.dumps(2**n, proto) for n in range(70)]
1327 sizes = list(map(len, pickles))
1328 # the size function is monotonic
1329 self.assertEqual(sorted(sizes), sizes)
1330 if proto >= 2:
1331 for p in pickles:
1332 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001333
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001334 def check_negative_32b_binXXX(self, dumped):
1335 if sys.maxsize > 2**32:
1336 self.skipTest("test is only meaningful on 32-bit builds")
1337 # XXX Pure Python pickle reads lengths as signed and passes
1338 # them directly to read() (hence the EOFError)
1339 with self.assertRaises((pickle.UnpicklingError, EOFError,
1340 ValueError, OverflowError)):
1341 self.loads(dumped)
1342
1343 def test_negative_32b_binbytes(self):
1344 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1345 self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.')
1346
1347 def test_negative_32b_binunicode(self):
1348 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1349 self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.')
1350
Antoine Pitrou55549ec2011-08-30 00:27:10 +02001351 def test_negative_put(self):
1352 # Issue #12847
1353 dumped = b'Va\np-1\n.'
1354 self.assertRaises(ValueError, self.loads, dumped)
1355
1356 def test_negative_32b_binput(self):
1357 # Issue #12847
1358 if sys.maxsize > 2**32:
1359 self.skipTest("test is only meaningful on 32-bit builds")
1360 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
1361 self.assertRaises(ValueError, self.loads, dumped)
1362
Alexandre Vassalotti7c5e0942013-04-15 23:14:55 -07001363 def test_badly_escaped_string(self):
1364 self.assertRaises(ValueError, self.loads, b"S'\\'\n.")
1365
1366 def test_badly_quoted_string(self):
1367 # Issue #17710
1368 badpickles = [b"S'\n.",
1369 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.']
1381 for p in badpickles:
1382 self.assertRaises(pickle.UnpicklingError, self.loads, p)
1383
1384 def test_correctly_quoted_string(self):
1385 goodpickles = [(b"S''\n.", ''),
1386 (b'S""\n.', ''),
1387 (b'S"\\n"\n.', '\n'),
1388 (b"S'\\n'\n.", '\n')]
1389 for p, expected in goodpickles:
1390 self.assertEqual(self.loads(p), expected)
1391
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001392 def _check_pickling_with_opcode(self, obj, opcode, proto):
1393 pickled = self.dumps(obj, proto)
1394 self.assertTrue(opcode_in_pickle(opcode, pickled))
1395 unpickled = self.loads(pickled)
1396 self.assertEqual(obj, unpickled)
1397
1398 def test_appends_on_non_lists(self):
1399 # Issue #17720
1400 obj = REX_six([1, 2, 3])
1401 for proto in protocols:
1402 if proto == 0:
1403 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1404 else:
1405 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1406
1407 def test_setitems_on_non_dicts(self):
1408 obj = REX_seven({1: -1, 2: -2, 3: -3})
1409 for proto in protocols:
1410 if proto == 0:
1411 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1412 else:
1413 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1414
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001415 # Exercise framing (proto >= 4) for significant workloads
1416
1417 FRAME_SIZE_TARGET = 64 * 1024
1418
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001419 def check_frame_opcodes(self, pickled):
1420 """
1421 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
1422 """
1423 frame_opcode_size = 9
1424 last_arg = last_pos = None
1425 for op, arg, pos in pickletools.genops(pickled):
1426 if op.name != 'FRAME':
1427 continue
1428 if last_pos is not None:
1429 # The previous frame's size should be equal to the number
1430 # of bytes up to the current frame.
1431 frame_size = pos - last_pos - frame_opcode_size
1432 self.assertEqual(frame_size, last_arg)
1433 last_arg, last_pos = arg, pos
1434 # The last frame's size should be equal to the number of bytes up
1435 # to the pickle's end.
1436 frame_size = len(pickled) - last_pos - frame_opcode_size
1437 self.assertEqual(frame_size, last_arg)
1438
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001439 def test_framing_many_objects(self):
1440 obj = list(range(10**5))
1441 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1442 with self.subTest(proto=proto):
1443 pickled = self.dumps(obj, proto)
1444 unpickled = self.loads(pickled)
1445 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001446 bytes_per_frame = (len(pickled) /
1447 count_opcode(pickle.FRAME, pickled))
1448 self.assertGreater(bytes_per_frame,
1449 self.FRAME_SIZE_TARGET / 2)
1450 self.assertLessEqual(bytes_per_frame,
1451 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001452 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001453
1454 def test_framing_large_objects(self):
1455 N = 1024 * 1024
1456 obj = [b'x' * N, b'y' * N, b'z' * N]
1457 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1458 with self.subTest(proto=proto):
1459 pickled = self.dumps(obj, proto)
1460 unpickled = self.loads(pickled)
1461 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001462 n_frames = count_opcode(pickle.FRAME, pickled)
Alexandre Vassalotti28d271e2013-12-01 16:27:46 -08001463 self.assertGreaterEqual(n_frames, len(obj))
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001464 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001465
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001466 def test_optional_frames(self):
1467 if pickle.HIGHEST_PROTOCOL < 4:
1468 return
1469
1470 def remove_frames(pickled, keep_frame=None):
1471 """Remove frame opcodes from the given pickle."""
1472 frame_starts = []
1473 # 1 byte for the opcode and 8 for the argument
1474 frame_opcode_size = 9
1475 for opcode, _, pos in pickletools.genops(pickled):
1476 if opcode.name == 'FRAME':
1477 frame_starts.append(pos)
1478
1479 newpickle = bytearray()
1480 last_frame_end = 0
1481 for i, pos in enumerate(frame_starts):
1482 if keep_frame and keep_frame(i):
1483 continue
1484 newpickle += pickled[last_frame_end:pos]
1485 last_frame_end = pos + frame_opcode_size
1486 newpickle += pickled[last_frame_end:]
1487 return newpickle
1488
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001489 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001490 num_frames = 20
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001491 obj = [bytes([i]) * frame_size for i in range(num_frames)]
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001492
1493 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1494 pickled = self.dumps(obj, proto)
1495
1496 frameless_pickle = remove_frames(pickled)
1497 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
1498 self.assertEqual(obj, self.loads(frameless_pickle))
1499
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001500 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001501 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
1502 count_opcode(pickle.FRAME, pickled))
1503 self.assertEqual(obj, self.loads(some_frames_pickle))
1504
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001505 def test_nested_names(self):
1506 global Nested
1507 class Nested:
1508 class A:
1509 class B:
1510 class C:
1511 pass
1512
1513 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1514 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
1515 with self.subTest(proto=proto, obj=obj):
1516 unpickled = self.loads(self.dumps(obj, proto))
1517 self.assertIs(obj, unpickled)
1518
1519 def test_py_methods(self):
1520 global PyMethodsTest
1521 class PyMethodsTest:
1522 @staticmethod
1523 def cheese():
1524 return "cheese"
1525 @classmethod
1526 def wine(cls):
1527 assert cls is PyMethodsTest
1528 return "wine"
1529 def biscuits(self):
1530 assert isinstance(self, PyMethodsTest)
1531 return "biscuits"
1532 class Nested:
1533 "Nested class"
1534 @staticmethod
1535 def ketchup():
1536 return "ketchup"
1537 @classmethod
1538 def maple(cls):
1539 assert cls is PyMethodsTest.Nested
1540 return "maple"
1541 def pie(self):
1542 assert isinstance(self, PyMethodsTest.Nested)
1543 return "pie"
1544
1545 py_methods = (
1546 PyMethodsTest.cheese,
1547 PyMethodsTest.wine,
1548 PyMethodsTest().biscuits,
1549 PyMethodsTest.Nested.ketchup,
1550 PyMethodsTest.Nested.maple,
1551 PyMethodsTest.Nested().pie
1552 )
1553 py_unbound_methods = (
1554 (PyMethodsTest.biscuits, PyMethodsTest),
1555 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
1556 )
1557 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1558 for method in py_methods:
1559 with self.subTest(proto=proto, method=method):
1560 unpickled = self.loads(self.dumps(method, proto))
1561 self.assertEqual(method(), unpickled())
1562 for method, cls in py_unbound_methods:
1563 obj = cls()
1564 with self.subTest(proto=proto, method=method):
1565 unpickled = self.loads(self.dumps(method, proto))
1566 self.assertEqual(method(obj), unpickled(obj))
1567
1568
1569 def test_c_methods(self):
1570 global Subclass
1571 class Subclass(tuple):
1572 class Nested(str):
1573 pass
1574
1575 c_methods = (
1576 # bound built-in method
1577 ("abcd".index, ("c",)),
1578 # unbound built-in method
1579 (str.index, ("abcd", "c")),
1580 # bound "slot" method
1581 ([1, 2, 3].__len__, ()),
1582 # unbound "slot" method
1583 (list.__len__, ([1, 2, 3],)),
1584 # bound "coexist" method
1585 ({1, 2}.__contains__, (2,)),
1586 # unbound "coexist" method
1587 (set.__contains__, ({1, 2}, 2)),
1588 # built-in class method
1589 (dict.fromkeys, (("a", 1), ("b", 2))),
1590 # built-in static method
1591 (bytearray.maketrans, (b"abc", b"xyz")),
1592 # subclass methods
1593 (Subclass([1,2,2]).count, (2,)),
1594 (Subclass.count, (Subclass([1,2,2]), 2)),
1595 (Subclass.Nested("sweet").count, ("e",)),
1596 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
1597 )
1598 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1599 for method, args in c_methods:
1600 with self.subTest(proto=proto, method=method):
1601 unpickled = self.loads(self.dumps(method, proto))
1602 self.assertEqual(method(*args), unpickled(*args))
1603
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001604
1605class BigmemPickleTests(unittest.TestCase):
1606
1607 # Binary protocols can serialize longs of up to 2GB-1
1608
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001609 @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001610 def test_huge_long_32b(self, size):
1611 data = 1 << (8 * size)
1612 try:
1613 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001614 with self.subTest(proto=proto):
1615 if proto < 2:
1616 continue
1617 with self.assertRaises((ValueError, OverflowError)):
1618 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001619 finally:
1620 data = None
1621
1622 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1623 # (older protocols don't have a dedicated opcode for bytes and are
1624 # too inefficient)
1625
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001626 @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001627 def test_huge_bytes_32b(self, size):
1628 data = b"abcd" * (size // 4)
1629 try:
1630 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001631 with self.subTest(proto=proto):
1632 if proto < 3:
1633 continue
1634 try:
1635 pickled = self.dumps(data, protocol=proto)
1636 self.assertTrue(b"abcd" in pickled[:19])
1637 self.assertTrue(b"abcd" in pickled[-18:])
1638 finally:
1639 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001640 finally:
1641 data = None
1642
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001643 @bigmemtest(size=_4G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001644 def test_huge_bytes_64b(self, size):
1645 data = b"a" * size
1646 try:
1647 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001648 with self.subTest(proto=proto):
1649 if proto < 3:
1650 continue
1651 with self.assertRaises((ValueError, OverflowError)):
1652 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001653 finally:
1654 data = None
1655
1656 # All protocols use 1-byte per printable ASCII character; we add another
1657 # byte because the encoded form has to be copied into the internal buffer.
1658
Antoine Pitroub7591d42011-10-04 16:18:15 +02001659 @bigmemtest(size=_2G, memuse=2 + ascii_char_size, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001660 def test_huge_str_32b(self, size):
1661 data = "abcd" * (size // 4)
1662 try:
1663 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001664 with self.subTest(proto=proto):
1665 try:
1666 pickled = self.dumps(data, protocol=proto)
1667 self.assertTrue(b"abcd" in pickled[:19])
1668 self.assertTrue(b"abcd" in pickled[-18:])
1669 finally:
1670 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001671 finally:
1672 data = None
1673
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001674 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
1675 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
1676 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02001677
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001678 @bigmemtest(size=_4G, memuse=2 + ascii_char_size, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001679 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001680 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001681 try:
1682 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001683 with self.subTest(proto=proto):
1684 if proto == 0:
1685 continue
1686 if proto < 4:
1687 with self.assertRaises((ValueError, OverflowError)):
1688 self.dumps(data, protocol=proto)
1689 else:
1690 try:
1691 pickled = self.dumps(data, protocol=proto)
1692 self.assertTrue(b"abcd" in pickled[:19])
1693 self.assertTrue(b"abcd" in pickled[-18:])
1694 finally:
1695 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001696 finally:
1697 data = None
1698
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001699
Guido van Rossum2a30b212003-02-18 22:41:24 +00001700# Test classes for reduce_ex
1701
1702class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001703 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001704 _reduce_called = 0
1705 def __reduce__(self):
1706 self._reduce_called = 1
1707 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001708
1709class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001710 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001711 _proto = None
1712 def __reduce_ex__(self, proto):
1713 self._proto = proto
1714 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001715
1716class REX_three(object):
1717 _proto = None
1718 def __reduce_ex__(self, proto):
1719 self._proto = proto
1720 return REX_two, ()
1721 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001722 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001723
Guido van Rossumd8faa362007-04-27 19:54:29 +00001724class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001725 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001726 _proto = None
1727 def __reduce_ex__(self, proto):
1728 self._proto = proto
1729 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001730
1731class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001732 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001733 _reduce_called = 0
1734 def __reduce__(self):
1735 self._reduce_called = 1
1736 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001737
1738class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001739 """This class is used to check the 4th argument (list iterator) of
1740 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001741 """
1742 def __init__(self, items=None):
1743 self.items = items if items is not None else []
1744 def __eq__(self, other):
1745 return type(self) is type(other) and self.items == self.items
1746 def append(self, item):
1747 self.items.append(item)
1748 def __reduce__(self):
1749 return type(self), (), None, iter(self.items), None
1750
1751class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001752 """This class is used to check the 5th argument (dict iterator) of
1753 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001754 """
1755 def __init__(self, table=None):
1756 self.table = table if table is not None else {}
1757 def __eq__(self, other):
1758 return type(self) is type(other) and self.table == self.table
1759 def __setitem__(self, key, value):
1760 self.table[key] = value
1761 def __reduce__(self):
1762 return type(self), (), None, None, iter(self.table.items())
1763
Guido van Rossumd8faa362007-04-27 19:54:29 +00001764
Guido van Rossum2a30b212003-02-18 22:41:24 +00001765# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001766
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001767class MyInt(int):
1768 sample = 1
1769
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001770class MyFloat(float):
1771 sample = 1.0
1772
1773class MyComplex(complex):
1774 sample = 1.0 + 0.0j
1775
1776class MyStr(str):
1777 sample = "hello"
1778
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001779class MyUnicode(str):
1780 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001781
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001782class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001783 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001784
1785class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001786 sample = [1, 2, 3]
1787
1788class MyDict(dict):
1789 sample = {"a": 1, "b": 2}
1790
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001791class MySet(set):
1792 sample = {"a", "b"}
1793
1794class MyFrozenSet(frozenset):
1795 sample = frozenset({"a", "b"})
1796
Mark Dickinson5c2db372009-12-05 20:28:34 +00001797myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001798 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001799 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001800 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001801
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001802
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001803class SlotList(MyList):
1804 __slots__ = ["foo"]
1805
Tim Peterse9ef2032003-02-13 18:42:00 +00001806class SimpleNewObj(object):
1807 def __init__(self, a, b, c):
1808 # raise an error, to make sure this isn't called
1809 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001810 def __eq__(self, other):
1811 return self.__dict__ == other.__dict__
Tim Peterse9ef2032003-02-13 18:42:00 +00001812
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001813class BadGetattr:
1814 def __getattr__(self, key):
1815 self.foo
1816
Collin Winter771d8342009-04-16 03:18:06 +00001817
Jeremy Hylton66426532001-10-15 21:38:56 +00001818class AbstractPickleModuleTests(unittest.TestCase):
1819
1820 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001821 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001822 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001823 try:
1824 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001825 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001826 finally:
1827 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001828
1829 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001830 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001831 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001832 try:
1833 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001834 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001835 finally:
1836 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001837
Collin Winter771d8342009-04-16 03:18:06 +00001838 def test_load_from_and_dump_to_file(self):
1839 stream = io.BytesIO()
1840 data = [123, {}, 124]
1841 pickle.dump(data, stream)
1842 stream.seek(0)
1843 unpickled = pickle.load(stream)
1844 self.assertEqual(unpickled, data)
1845
Tim Petersc0c93702003-02-13 19:30:57 +00001846 def test_highest_protocol(self):
1847 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001848 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00001849
Martin v. Löwis544f1192004-07-27 05:22:33 +00001850 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001851 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001852 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001853 pickle.dump(123, f, -1)
1854 pickle.dump(123, file=f, protocol=-1)
1855 pickle.dumps(123, -1)
1856 pickle.dumps(123, protocol=-1)
1857 pickle.Pickler(f, -1)
1858 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001859
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001860 def test_bad_init(self):
1861 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001862 # Override initialization without calling __init__() of the superclass.
1863 class BadPickler(pickle.Pickler):
1864 def __init__(self): pass
1865
1866 class BadUnpickler(pickle.Unpickler):
1867 def __init__(self): pass
1868
1869 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1870 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1871
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001872 def test_bad_input(self):
1873 # Test issue4298
1874 s = bytes([0x58, 0, 0, 0, 0x54])
1875 self.assertRaises(EOFError, pickle.loads, s)
1876
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001877
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001878class AbstractPersistentPicklerTests(unittest.TestCase):
1879
1880 # This class defines persistent_id() and persistent_load()
1881 # functions that should be used by the pickler. All even integers
1882 # are pickled using persistent ids.
1883
1884 def persistent_id(self, object):
1885 if isinstance(object, int) and object % 2 == 0:
1886 self.id_count += 1
1887 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001888 elif object == "test_false_value":
1889 self.false_count += 1
1890 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001891 else:
1892 return None
1893
1894 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001895 if not oid:
1896 self.load_false_count += 1
1897 return "test_false_value"
1898 else:
1899 self.load_count += 1
1900 object = int(oid)
1901 assert object % 2 == 0
1902 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001903
1904 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001905 L = list(range(10)) + ["test_false_value"]
1906 for proto in protocols:
1907 self.id_count = 0
1908 self.false_count = 0
1909 self.load_false_count = 0
1910 self.load_count = 0
1911 self.assertEqual(self.loads(self.dumps(L, proto)), L)
1912 self.assertEqual(self.id_count, 5)
1913 self.assertEqual(self.false_count, 1)
1914 self.assertEqual(self.load_count, 5)
1915 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001916
Collin Winter771d8342009-04-16 03:18:06 +00001917
1918class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1919
1920 pickler_class = None
1921 unpickler_class = None
1922
1923 def setUp(self):
1924 assert self.pickler_class
1925 assert self.unpickler_class
1926
1927 def test_clear_pickler_memo(self):
1928 # To test whether clear_memo() has any effect, we pickle an object,
1929 # then pickle it again without clearing the memo; the two serialized
1930 # forms should be different. If we clear_memo() and then pickle the
1931 # object again, the third serialized form should be identical to the
1932 # first one we obtained.
1933 data = ["abcdefg", "abcdefg", 44]
1934 f = io.BytesIO()
1935 pickler = self.pickler_class(f)
1936
1937 pickler.dump(data)
1938 first_pickled = f.getvalue()
1939
Serhiy Storchaka50254c52013-08-29 11:35:43 +03001940 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00001941 f.seek(0)
1942 f.truncate()
1943
1944 pickler.dump(data)
1945 second_pickled = f.getvalue()
1946
Serhiy Storchaka50254c52013-08-29 11:35:43 +03001947 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00001948 pickler.clear_memo()
1949 f.seek(0)
1950 f.truncate()
1951
1952 pickler.dump(data)
1953 third_pickled = f.getvalue()
1954
1955 self.assertNotEqual(first_pickled, second_pickled)
1956 self.assertEqual(first_pickled, third_pickled)
1957
1958 def test_priming_pickler_memo(self):
1959 # Verify that we can set the Pickler's memo attribute.
1960 data = ["abcdefg", "abcdefg", 44]
1961 f = io.BytesIO()
1962 pickler = self.pickler_class(f)
1963
1964 pickler.dump(data)
1965 first_pickled = f.getvalue()
1966
1967 f = io.BytesIO()
1968 primed = self.pickler_class(f)
1969 primed.memo = pickler.memo
1970
1971 primed.dump(data)
1972 primed_pickled = f.getvalue()
1973
1974 self.assertNotEqual(first_pickled, primed_pickled)
1975
1976 def test_priming_unpickler_memo(self):
1977 # Verify that we can set the Unpickler's memo attribute.
1978 data = ["abcdefg", "abcdefg", 44]
1979 f = io.BytesIO()
1980 pickler = self.pickler_class(f)
1981
1982 pickler.dump(data)
1983 first_pickled = f.getvalue()
1984
1985 f = io.BytesIO()
1986 primed = self.pickler_class(f)
1987 primed.memo = pickler.memo
1988
1989 primed.dump(data)
1990 primed_pickled = f.getvalue()
1991
1992 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
1993 unpickled_data1 = unpickler.load()
1994
1995 self.assertEqual(unpickled_data1, data)
1996
1997 primed = self.unpickler_class(io.BytesIO(primed_pickled))
1998 primed.memo = unpickler.memo
1999 unpickled_data2 = primed.load()
2000
2001 primed.memo.clear()
2002
2003 self.assertEqual(unpickled_data2, data)
2004 self.assertTrue(unpickled_data2 is unpickled_data1)
2005
2006 def test_reusing_unpickler_objects(self):
2007 data1 = ["abcdefg", "abcdefg", 44]
2008 f = io.BytesIO()
2009 pickler = self.pickler_class(f)
2010 pickler.dump(data1)
2011 pickled1 = f.getvalue()
2012
2013 data2 = ["abcdefg", 44, 44]
2014 f = io.BytesIO()
2015 pickler = self.pickler_class(f)
2016 pickler.dump(data2)
2017 pickled2 = f.getvalue()
2018
2019 f = io.BytesIO()
2020 f.write(pickled1)
2021 f.seek(0)
2022 unpickler = self.unpickler_class(f)
2023 self.assertEqual(unpickler.load(), data1)
2024
2025 f.seek(0)
2026 f.truncate()
2027 f.write(pickled2)
2028 f.seek(0)
2029 self.assertEqual(unpickler.load(), data2)
2030
Antoine Pitrou04248a82010-10-12 20:51:21 +00002031 def _check_multiple_unpicklings(self, ioclass):
2032 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002033 with self.subTest(proto=proto):
2034 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2035 f = ioclass()
2036 pickler = self.pickler_class(f, protocol=proto)
2037 pickler.dump(data1)
2038 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002039
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002040 N = 5
2041 f = ioclass(pickled * N)
2042 unpickler = self.unpickler_class(f)
2043 for i in range(N):
2044 if f.seekable():
2045 pos = f.tell()
2046 self.assertEqual(unpickler.load(), data1)
2047 if f.seekable():
2048 self.assertEqual(f.tell(), pos + len(pickled))
2049 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002050
2051 def test_multiple_unpicklings_seekable(self):
2052 self._check_multiple_unpicklings(io.BytesIO)
2053
2054 def test_multiple_unpicklings_unseekable(self):
2055 self._check_multiple_unpicklings(UnseekableIO)
2056
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002057 def test_unpickling_buffering_readline(self):
2058 # Issue #12687: the unpickler's buffering logic could fail with
2059 # text mode opcodes.
2060 data = list(range(10))
2061 for proto in protocols:
2062 for buf_size in range(1, 11):
2063 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2064 pickler = self.pickler_class(f, protocol=proto)
2065 pickler.dump(data)
2066 f.seek(0)
2067 unpickler = self.unpickler_class(f)
2068 self.assertEqual(unpickler.load(), data)
2069
Collin Winter771d8342009-04-16 03:18:06 +00002070
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002071# Tests for dispatch_table attribute
2072
2073REDUCE_A = 'reduce_A'
2074
2075class AAA(object):
2076 def __reduce__(self):
2077 return str, (REDUCE_A,)
2078
2079class BBB(object):
2080 pass
2081
2082class AbstractDispatchTableTests(unittest.TestCase):
2083
2084 def test_default_dispatch_table(self):
2085 # No dispatch_table attribute by default
2086 f = io.BytesIO()
2087 p = self.pickler_class(f, 0)
2088 with self.assertRaises(AttributeError):
2089 p.dispatch_table
2090 self.assertFalse(hasattr(p, 'dispatch_table'))
2091
2092 def test_class_dispatch_table(self):
2093 # A dispatch_table attribute can be specified class-wide
2094 dt = self.get_dispatch_table()
2095
2096 class MyPickler(self.pickler_class):
2097 dispatch_table = dt
2098
2099 def dumps(obj, protocol=None):
2100 f = io.BytesIO()
2101 p = MyPickler(f, protocol)
2102 self.assertEqual(p.dispatch_table, dt)
2103 p.dump(obj)
2104 return f.getvalue()
2105
2106 self._test_dispatch_table(dumps, dt)
2107
2108 def test_instance_dispatch_table(self):
2109 # A dispatch_table attribute can also be specified instance-wide
2110 dt = self.get_dispatch_table()
2111
2112 def dumps(obj, protocol=None):
2113 f = io.BytesIO()
2114 p = self.pickler_class(f, protocol)
2115 p.dispatch_table = dt
2116 self.assertEqual(p.dispatch_table, dt)
2117 p.dump(obj)
2118 return f.getvalue()
2119
2120 self._test_dispatch_table(dumps, dt)
2121
2122 def _test_dispatch_table(self, dumps, dispatch_table):
2123 def custom_load_dump(obj):
2124 return pickle.loads(dumps(obj, 0))
2125
2126 def default_load_dump(obj):
2127 return pickle.loads(pickle.dumps(obj, 0))
2128
2129 # pickling complex numbers using protocol 0 relies on copyreg
2130 # so check pickling a complex number still works
2131 z = 1 + 2j
2132 self.assertEqual(custom_load_dump(z), z)
2133 self.assertEqual(default_load_dump(z), z)
2134
2135 # modify pickling of complex
2136 REDUCE_1 = 'reduce_1'
2137 def reduce_1(obj):
2138 return str, (REDUCE_1,)
2139 dispatch_table[complex] = reduce_1
2140 self.assertEqual(custom_load_dump(z), REDUCE_1)
2141 self.assertEqual(default_load_dump(z), z)
2142
2143 # check picklability of AAA and BBB
2144 a = AAA()
2145 b = BBB()
2146 self.assertEqual(custom_load_dump(a), REDUCE_A)
2147 self.assertIsInstance(custom_load_dump(b), BBB)
2148 self.assertEqual(default_load_dump(a), REDUCE_A)
2149 self.assertIsInstance(default_load_dump(b), BBB)
2150
2151 # modify pickling of BBB
2152 dispatch_table[BBB] = reduce_1
2153 self.assertEqual(custom_load_dump(a), REDUCE_A)
2154 self.assertEqual(custom_load_dump(b), REDUCE_1)
2155 self.assertEqual(default_load_dump(a), REDUCE_A)
2156 self.assertIsInstance(default_load_dump(b), BBB)
2157
2158 # revert pickling of BBB and modify pickling of AAA
2159 REDUCE_2 = 'reduce_2'
2160 def reduce_2(obj):
2161 return str, (REDUCE_2,)
2162 dispatch_table[AAA] = reduce_2
2163 del dispatch_table[BBB]
2164 self.assertEqual(custom_load_dump(a), REDUCE_2)
2165 self.assertIsInstance(custom_load_dump(b), BBB)
2166 self.assertEqual(default_load_dump(a), REDUCE_A)
2167 self.assertIsInstance(default_load_dump(b), BBB)
2168
2169
Guido van Rossum98297ee2007-11-06 21:34:58 +00002170if __name__ == "__main__":
2171 # Print some stuff that can be used to rewrite DATA{0,1,2}
2172 from pickletools import dis
2173 x = create_data()
2174 for i in range(3):
2175 p = pickle.dumps(x, i)
2176 print("DATA{0} = (".format(i))
2177 for j in range(0, len(p), 20):
2178 b = bytes(p[j:j+20])
2179 print(" {0!r}".format(b))
2180 print(")")
2181 print()
2182 print("# Disassembly of DATA{0}".format(i))
2183 print("DATA{0}_DIS = \"\"\"\\".format(i))
2184 dis(p)
2185 print("\"\"\"")
2186 print()