blob: 1f59ab2dca5ab86641e0884449f19c6a6b350104 [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):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +0100815 for proto in protocols:
816 inst = AAA()
817 dumped = self.dumps(inst, proto)
818 loaded = self.loads(dumped)
819 self.assertEqual(loaded, REDUCE_A)
Jeremy Hylton66426532001-10-15 21:38:56 +0000820
821 def test_getinitargs(self):
Antoine Pitrouc1764dd2013-12-28 16:57:37 +0100822 for proto in protocols:
823 inst = initarg(1, 2)
824 dumped = self.dumps(inst, proto)
825 loaded = self.loads(dumped)
826 self.assert_is_copy(inst, loaded)
Jeremy Hylton66426532001-10-15 21:38:56 +0000827
Antoine Pitrou79035bd2012-06-26 23:04:48 +0200828 def test_pop_empty_stack(self):
829 # Test issue7455
830 s = b'0'
831 self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s)
832
Guido van Rossum04a86612001-12-19 16:58:54 +0000833 def test_metaclass(self):
834 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000835 for proto in protocols:
836 s = self.dumps(a, proto)
837 b = self.loads(s)
838 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000839
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200840 def test_dynamic_class(self):
841 a = create_dynamic_class("my_dynamic_class", (object,))
842 copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
843 for proto in protocols:
844 s = self.dumps(a, proto)
845 b = self.loads(s)
846 self.assertEqual(a, b)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100847 self.assertIs(type(a), type(b))
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200848
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000849 def test_structseq(self):
850 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000851 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000852
853 t = time.localtime()
854 for proto in protocols:
855 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000856 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100857 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000858 if hasattr(os, "stat"):
859 t = os.stat(os.curdir)
860 s = self.dumps(t, proto)
861 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100862 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000863 if hasattr(os, "statvfs"):
864 t = os.statvfs(os.curdir)
865 s = self.dumps(t, proto)
866 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100867 self.assert_is_copy(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000868
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100869 def test_ellipsis(self):
870 for proto in protocols:
871 s = self.dumps(..., proto)
872 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100873 self.assertIs(..., u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100874
875 def test_notimplemented(self):
876 for proto in protocols:
877 s = self.dumps(NotImplemented, proto)
878 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100879 self.assertIs(NotImplemented, u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100880
Alexandre Vassalotti19b6fa62013-11-30 16:06:39 -0800881 def test_singleton_types(self):
882 # Issue #6477: Test that types of built-in singletons can be pickled.
883 singletons = [None, ..., NotImplemented]
884 for singleton in singletons:
885 for proto in protocols:
886 s = self.dumps(type(singleton), proto)
887 u = self.loads(s)
888 self.assertIs(type(singleton), u)
889
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000890 # Tests for protocol 2
891
Tim Peters4190fb82003-02-02 16:09:05 +0000892 def test_proto(self):
Tim Peters4190fb82003-02-02 16:09:05 +0000893 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100894 pickled = self.dumps(None, proto)
Tim Peters4190fb82003-02-02 16:09:05 +0000895 if proto >= 2:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100896 proto_header = pickle.PROTO + bytes([proto])
897 self.assertTrue(pickled.startswith(proto_header))
898 else:
899 self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)
Tim Peters4190fb82003-02-02 16:09:05 +0000900
901 oob = protocols[-1] + 1 # a future protocol
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100902 build_none = pickle.NONE + pickle.STOP
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000903 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000904 try:
905 self.loads(badpickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100906 except ValueError as err:
907 self.assertIn("unsupported pickle protocol", str(err))
Tim Peters4190fb82003-02-02 16:09:05 +0000908 else:
909 self.fail("expected bad protocol number to raise ValueError")
910
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000911 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000912 x = 12345678910111213141516178920
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.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000918
919 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000920 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000921 for proto in protocols:
922 s = self.dumps(x, proto)
923 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100924 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000925 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000926
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000927 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000928 # Map (proto, len(tuple)) to expected opcode.
929 expected_opcode = {(0, 0): pickle.TUPLE,
930 (0, 1): pickle.TUPLE,
931 (0, 2): pickle.TUPLE,
932 (0, 3): pickle.TUPLE,
933 (0, 4): pickle.TUPLE,
934
935 (1, 0): pickle.EMPTY_TUPLE,
936 (1, 1): pickle.TUPLE,
937 (1, 2): pickle.TUPLE,
938 (1, 3): pickle.TUPLE,
939 (1, 4): pickle.TUPLE,
940
941 (2, 0): pickle.EMPTY_TUPLE,
942 (2, 1): pickle.TUPLE1,
943 (2, 2): pickle.TUPLE2,
944 (2, 3): pickle.TUPLE3,
945 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000946
947 (3, 0): pickle.EMPTY_TUPLE,
948 (3, 1): pickle.TUPLE1,
949 (3, 2): pickle.TUPLE2,
950 (3, 3): pickle.TUPLE3,
951 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000952 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000953 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000954 b = (1,)
955 c = (1, 2)
956 d = (1, 2, 3)
957 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000958 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000959 for x in a, b, c, d, e:
960 s = self.dumps(x, proto)
961 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100962 self.assert_is_copy(x, y)
963 expected = expected_opcode[min(proto, 3), len(x)]
964 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000965
Guido van Rossum7d97d312003-01-28 04:25:27 +0000966 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000967 # Map (proto, singleton) to expected opcode.
968 expected_opcode = {(0, None): pickle.NONE,
969 (1, None): pickle.NONE,
970 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000971 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000972
973 (0, True): pickle.INT,
974 (1, True): pickle.INT,
975 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000976 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000977
978 (0, False): pickle.INT,
979 (1, False): pickle.INT,
980 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000981 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000982 }
Tim Peters4190fb82003-02-02 16:09:05 +0000983 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000984 for x in None, False, True:
985 s = self.dumps(x, proto)
986 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000987 self.assertTrue(x is y, (proto, x, s, y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100988 expected = expected_opcode[min(proto, 3), x]
989 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters3c67d792003-02-02 17:59:11 +0000990
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000991 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000992 x = MyTuple([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
1000 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +00001001 x = MyList([1, 2, 3])
1002 x.foo = 42
1003 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +00001004 for proto in protocols:
1005 s = self.dumps(x, proto)
1006 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001007 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001008
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001009 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +00001010 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001011 for C in myclasses:
1012 B = C.__base__
1013 x = C(C.sample)
1014 x.foo = 42
1015 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001016 y = self.loads(s)
1017 detail = (proto, C, B, x, y, type(y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001018 self.assert_is_copy(x, y) # XXX revisit
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001019 self.assertEqual(B(x), B(y), detail)
1020 self.assertEqual(x.__dict__, y.__dict__, detail)
1021
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01001022 def test_newobj_proxies(self):
1023 # NEWOBJ should use the __class__ rather than the raw type
1024 classes = myclasses[:]
1025 # Cannot create weakproxies to these classes
1026 for c in (MyInt, MyTuple):
1027 classes.remove(c)
1028 for proto in protocols:
1029 for C in classes:
1030 B = C.__base__
1031 x = C(C.sample)
1032 x.foo = 42
1033 p = weakref.proxy(x)
1034 s = self.dumps(p, proto)
1035 y = self.loads(s)
1036 self.assertEqual(type(y), type(x)) # rather than type(p)
1037 detail = (proto, C, B, x, y, type(y))
1038 self.assertEqual(B(x), B(y), detail)
1039 self.assertEqual(x.__dict__, y.__dict__, detail)
1040
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001041 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +00001042 # an object of that type. Check that the resulting pickle uses opcode
1043 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +00001044
Tim Peters22e71712003-02-03 22:27:38 +00001045 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +00001046 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001047 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00001048 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001049 x = MyList([1, 2, 3])
1050 x.foo = 42
1051 x.bar = "hello"
1052
Tim Peters22e71712003-02-03 22:27:38 +00001053 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001054 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001055 self.assertIn(__name__.encode("utf-8"), s1)
1056 self.assertIn(b"MyList", s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001057 self.assertFalse(opcode_in_pickle(opcode, s1))
Tim Peters3e667d52003-02-04 21:47:44 +00001058
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001059 y = self.loads(s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001060 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001061
Tim Peters22e71712003-02-03 22:27:38 +00001062 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001063 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +00001064 self.assertNotIn(__name__.encode("utf-8"), s2)
1065 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +00001066 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +00001067
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001068 y = self.loads(s2)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001069 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001070 finally:
Tim Peters3e667d52003-02-04 21:47:44 +00001071 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +00001072
1073 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001074 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
1075 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001076
1077 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001078 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
1079 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
1080 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001081
1082 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +00001083 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
1084 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1085 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1086
Tim Peters8d2613a2003-02-11 16:40:16 +00001087 def test_list_chunking(self):
1088 n = 10 # too small to chunk
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 self.assertEqual(num_appends, proto > 0)
1096
1097 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001098 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001099 for proto in protocols:
1100 s = self.dumps(x, proto)
1101 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001102 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001103 num_appends = count_opcode(pickle.APPENDS, s)
1104 if proto == 0:
1105 self.assertEqual(num_appends, 0)
1106 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001107 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001108
1109 def test_dict_chunking(self):
1110 n = 10 # too small to chunk
1111 x = dict.fromkeys(range(n))
1112 for proto in protocols:
1113 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +00001114 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00001115 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 self.assertEqual(num_setitems, proto > 0)
1119
1120 n = 2500 # expect at least two chunks when proto > 0
1121 x = dict.fromkeys(range(n))
1122 for proto in protocols:
1123 s = self.dumps(x, proto)
1124 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001125 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001126 num_setitems = count_opcode(pickle.SETITEMS, s)
1127 if proto == 0:
1128 self.assertEqual(num_setitems, 0)
1129 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001130 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001131
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001132 def test_set_chunking(self):
1133 n = 10 # too small to chunk
1134 x = set(range(n))
1135 for proto in protocols:
1136 s = self.dumps(x, proto)
1137 y = self.loads(s)
1138 self.assert_is_copy(x, y)
1139 num_additems = count_opcode(pickle.ADDITEMS, s)
1140 if proto < 4:
1141 self.assertEqual(num_additems, 0)
1142 else:
1143 self.assertEqual(num_additems, 1)
1144
1145 n = 2500 # expect at least two chunks when proto >= 4
1146 x = set(range(n))
1147 for proto in protocols:
1148 s = self.dumps(x, proto)
1149 y = self.loads(s)
1150 self.assert_is_copy(x, y)
1151 num_additems = count_opcode(pickle.ADDITEMS, s)
1152 if proto < 4:
1153 self.assertEqual(num_additems, 0)
1154 else:
1155 self.assertGreaterEqual(num_additems, 2)
1156
Tim Peterse9ef2032003-02-13 18:42:00 +00001157 def test_simple_newobj(self):
1158 x = object.__new__(SimpleNewObj) # avoid __init__
1159 x.abc = 666
1160 for proto in protocols:
1161 s = self.dumps(x, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001162 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1163 2 <= proto < 4)
1164 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1165 proto >= 4)
Tim Peterse9ef2032003-02-13 18:42:00 +00001166 y = self.loads(s) # will raise TypeError if __init__ called
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001167 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001168
Tim Peters42f08ac2003-02-11 22:43:24 +00001169 def test_newobj_list_slots(self):
1170 x = SlotList([1, 2, 3])
1171 x.foo = 42
1172 x.bar = "hello"
1173 s = self.dumps(x, 2)
1174 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001175 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001176
Guido van Rossum2a30b212003-02-18 22:41:24 +00001177 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001178 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001179 x = REX_one()
1180 self.assertEqual(x._reduce_called, 0)
1181 s = self.dumps(x, proto)
1182 self.assertEqual(x._reduce_called, 1)
1183 y = self.loads(s)
1184 self.assertEqual(y._reduce_called, 0)
1185
1186 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001187 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001188 x = REX_two()
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
1195 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001196 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001197 x = REX_three()
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, None)
1203
Guido van Rossumd8faa362007-04-27 19:54:29 +00001204 def test_reduce_ex_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_four()
1207 self.assertEqual(x._proto, None)
1208 s = self.dumps(x, proto)
1209 self.assertEqual(x._proto, proto)
1210 y = self.loads(s)
1211 self.assertEqual(y._proto, proto)
1212
1213 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001214 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001215 x = REX_five()
1216 self.assertEqual(x._reduce_called, 0)
1217 s = self.dumps(x, proto)
1218 self.assertEqual(x._reduce_called, 1)
1219 y = self.loads(s)
1220 self.assertEqual(y._reduce_called, 1)
1221
Brett Cannon31f59292011-02-21 19:29:56 +00001222 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001223 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001224 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001225 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001226 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001227 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001228
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001229 def test_reduce_bad_iterator(self):
1230 # Issue4176: crash when 4th and 5th items of __reduce__()
1231 # are not iterators
1232 class C(object):
1233 def __reduce__(self):
1234 # 4th item is not an iterator
1235 return list, (), None, [], None
1236 class D(object):
1237 def __reduce__(self):
1238 # 5th item is not an iterator
1239 return dict, (), None, None, []
1240
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001241 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001242 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001243 try:
1244 self.dumps(C(), proto)
1245 except (pickle.PickleError):
1246 pass
1247 try:
1248 self.dumps(D(), proto)
1249 except (pickle.PickleError):
1250 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001251
Collin Winter771d8342009-04-16 03:18:06 +00001252 def test_many_puts_and_gets(self):
1253 # Test that internal data structures correctly deal with lots of
1254 # puts/gets.
1255 keys = ("aaa" + str(i) for i in range(100))
1256 large_dict = dict((k, [4, 5, 6]) for k in keys)
1257 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1258
1259 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001260 with self.subTest(proto=proto):
1261 dumped = self.dumps(obj, proto)
1262 loaded = self.loads(dumped)
1263 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00001264
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001265 def test_attribute_name_interning(self):
1266 # Test that attribute names of pickled objects are interned when
1267 # unpickling.
1268 for proto in protocols:
1269 x = C()
1270 x.foo = 42
1271 x.bar = "hello"
1272 s = self.dumps(x, proto)
1273 y = self.loads(s)
1274 x_keys = sorted(x.__dict__)
1275 y_keys = sorted(y.__dict__)
1276 for x_key, y_key in zip(x_keys, y_keys):
1277 self.assertIs(x_key, y_key)
1278
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001279 def test_unpickle_from_2x(self):
1280 # Unpickle non-trivial data from Python 2.x.
1281 loaded = self.loads(DATA3)
1282 self.assertEqual(loaded, set([1, 2]))
1283 loaded = self.loads(DATA4)
1284 self.assertEqual(type(loaded), type(range(0)))
1285 self.assertEqual(list(loaded), list(range(5)))
1286 loaded = self.loads(DATA5)
1287 self.assertEqual(type(loaded), SimpleCookie)
1288 self.assertEqual(list(loaded.keys()), ["key"])
1289 self.assertEqual(loaded["key"].value, "Set-Cookie: key=value")
1290
Walter Doerwald9d1dbca2013-12-02 11:41:01 +01001291 for (exc, data) in DATA7.items():
1292 loaded = self.loads(data)
1293 self.assertIs(type(loaded), exc)
1294
1295 loaded = self.loads(DATA8)
1296 self.assertIs(type(loaded), Exception)
1297
1298 loaded = self.loads(DATA9)
1299 self.assertIs(type(loaded), UnicodeEncodeError)
1300 self.assertEqual(loaded.object, "foo")
1301 self.assertEqual(loaded.encoding, "ascii")
1302 self.assertEqual(loaded.start, 0)
1303 self.assertEqual(loaded.end, 1)
1304 self.assertEqual(loaded.reason, "bad")
1305
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001306 def test_pickle_to_2x(self):
1307 # Pickle non-trivial data with protocol 2, expecting that it yields
1308 # the same result as Python 2.x did.
1309 # NOTE: this test is a bit too strong since we can produce different
1310 # bytecode that 2.x will still understand.
1311 dumped = self.dumps(range(5), 2)
1312 self.assertEqual(dumped, DATA4)
1313 dumped = self.dumps(set([3]), 2)
1314 self.assertEqual(dumped, DATA6)
1315
Alexandre Vassalottid05c9ff2013-12-07 01:09:27 -08001316 def test_load_python2_str_as_bytes(self):
1317 # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
1318 self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
1319 encoding="bytes"), b'a\x00\xa0')
1320 # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
1321 self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
1322 encoding="bytes"), b'a\x00\xa0')
1323 # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
1324 self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
1325 encoding="bytes"), b'a\x00\xa0')
1326
1327 def test_load_python2_unicode_as_str(self):
1328 # From Python 2: pickle.dumps(u'π', protocol=0)
1329 self.assertEqual(self.loads(b'V\\u03c0\n.',
1330 encoding='bytes'), 'π')
1331 # From Python 2: pickle.dumps(u'π', protocol=1)
1332 self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
1333 encoding="bytes"), 'π')
1334 # From Python 2: pickle.dumps(u'π', protocol=2)
1335 self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
1336 encoding="bytes"), 'π')
1337
1338 def test_load_long_python2_str_as_bytes(self):
1339 # From Python 2: pickle.dumps('x' * 300, protocol=1)
1340 self.assertEqual(self.loads(pickle.BINSTRING +
1341 struct.pack("<I", 300) +
1342 b'x' * 300 + pickle.STOP,
1343 encoding='bytes'), b'x' * 300)
1344
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001345 def test_large_pickles(self):
1346 # Test the correctness of internal buffering routines when handling
1347 # large data.
1348 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001349 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001350 dumped = self.dumps(data, proto)
1351 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001352 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001353 self.assertEqual(loaded, data)
1354
Alexander Belopolsky1ce92dc2011-02-24 19:40:09 +00001355 def test_empty_bytestring(self):
1356 # issue 11286
1357 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1358 self.assertEqual(empty, '')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001359
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001360 def test_int_pickling_efficiency(self):
1361 # Test compacity of int representation (see issue #12744)
1362 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001363 with self.subTest(proto=proto):
1364 pickles = [self.dumps(2**n, proto) for n in range(70)]
1365 sizes = list(map(len, pickles))
1366 # the size function is monotonic
1367 self.assertEqual(sorted(sizes), sizes)
1368 if proto >= 2:
1369 for p in pickles:
1370 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001371
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001372 def check_negative_32b_binXXX(self, dumped):
1373 if sys.maxsize > 2**32:
1374 self.skipTest("test is only meaningful on 32-bit builds")
1375 # XXX Pure Python pickle reads lengths as signed and passes
1376 # them directly to read() (hence the EOFError)
1377 with self.assertRaises((pickle.UnpicklingError, EOFError,
1378 ValueError, OverflowError)):
1379 self.loads(dumped)
1380
1381 def test_negative_32b_binbytes(self):
1382 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1383 self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.')
1384
1385 def test_negative_32b_binunicode(self):
1386 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1387 self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.')
1388
Antoine Pitrou55549ec2011-08-30 00:27:10 +02001389 def test_negative_put(self):
1390 # Issue #12847
1391 dumped = b'Va\np-1\n.'
1392 self.assertRaises(ValueError, self.loads, dumped)
1393
1394 def test_negative_32b_binput(self):
1395 # Issue #12847
1396 if sys.maxsize > 2**32:
1397 self.skipTest("test is only meaningful on 32-bit builds")
1398 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
1399 self.assertRaises(ValueError, self.loads, dumped)
1400
Alexandre Vassalotti7c5e0942013-04-15 23:14:55 -07001401 def test_badly_escaped_string(self):
1402 self.assertRaises(ValueError, self.loads, b"S'\\'\n.")
1403
1404 def test_badly_quoted_string(self):
1405 # Issue #17710
1406 badpickles = [b"S'\n.",
1407 b'S"\n.',
1408 b'S\' \n.',
1409 b'S" \n.',
1410 b'S\'"\n.',
1411 b'S"\'\n.',
1412 b"S' ' \n.",
1413 b'S" " \n.',
1414 b"S ''\n.",
1415 b'S ""\n.',
1416 b'S \n.',
1417 b'S\n.',
1418 b'S.']
1419 for p in badpickles:
1420 self.assertRaises(pickle.UnpicklingError, self.loads, p)
1421
1422 def test_correctly_quoted_string(self):
1423 goodpickles = [(b"S''\n.", ''),
1424 (b'S""\n.', ''),
1425 (b'S"\\n"\n.', '\n'),
1426 (b"S'\\n'\n.", '\n')]
1427 for p, expected in goodpickles:
1428 self.assertEqual(self.loads(p), expected)
1429
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001430 def _check_pickling_with_opcode(self, obj, opcode, proto):
1431 pickled = self.dumps(obj, proto)
1432 self.assertTrue(opcode_in_pickle(opcode, pickled))
1433 unpickled = self.loads(pickled)
1434 self.assertEqual(obj, unpickled)
1435
1436 def test_appends_on_non_lists(self):
1437 # Issue #17720
1438 obj = REX_six([1, 2, 3])
1439 for proto in protocols:
1440 if proto == 0:
1441 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1442 else:
1443 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1444
1445 def test_setitems_on_non_dicts(self):
1446 obj = REX_seven({1: -1, 2: -2, 3: -3})
1447 for proto in protocols:
1448 if proto == 0:
1449 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1450 else:
1451 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1452
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001453 # Exercise framing (proto >= 4) for significant workloads
1454
1455 FRAME_SIZE_TARGET = 64 * 1024
1456
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001457 def check_frame_opcodes(self, pickled):
1458 """
1459 Check the arguments of FRAME opcodes in a protocol 4+ pickle.
1460 """
1461 frame_opcode_size = 9
1462 last_arg = last_pos = None
1463 for op, arg, pos in pickletools.genops(pickled):
1464 if op.name != 'FRAME':
1465 continue
1466 if last_pos is not None:
1467 # The previous frame's size should be equal to the number
1468 # of bytes up to the current frame.
1469 frame_size = pos - last_pos - frame_opcode_size
1470 self.assertEqual(frame_size, last_arg)
1471 last_arg, last_pos = arg, pos
1472 # The last frame's size should be equal to the number of bytes up
1473 # to the pickle's end.
1474 frame_size = len(pickled) - last_pos - frame_opcode_size
1475 self.assertEqual(frame_size, last_arg)
1476
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001477 def test_framing_many_objects(self):
1478 obj = list(range(10**5))
1479 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1480 with self.subTest(proto=proto):
1481 pickled = self.dumps(obj, proto)
1482 unpickled = self.loads(pickled)
1483 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001484 bytes_per_frame = (len(pickled) /
1485 count_opcode(pickle.FRAME, pickled))
1486 self.assertGreater(bytes_per_frame,
1487 self.FRAME_SIZE_TARGET / 2)
1488 self.assertLessEqual(bytes_per_frame,
1489 self.FRAME_SIZE_TARGET * 1)
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001490 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001491
1492 def test_framing_large_objects(self):
1493 N = 1024 * 1024
1494 obj = [b'x' * N, b'y' * N, b'z' * N]
1495 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1496 with self.subTest(proto=proto):
1497 pickled = self.dumps(obj, proto)
1498 unpickled = self.loads(pickled)
1499 self.assertEqual(obj, unpickled)
Antoine Pitrou3ab9cfc2013-11-24 14:33:37 +01001500 n_frames = count_opcode(pickle.FRAME, pickled)
Alexandre Vassalotti28d271e2013-12-01 16:27:46 -08001501 self.assertGreaterEqual(n_frames, len(obj))
Antoine Pitrou6e8bc502013-12-03 09:51:40 +01001502 self.check_frame_opcodes(pickled)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001503
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001504 def test_optional_frames(self):
1505 if pickle.HIGHEST_PROTOCOL < 4:
1506 return
1507
1508 def remove_frames(pickled, keep_frame=None):
1509 """Remove frame opcodes from the given pickle."""
1510 frame_starts = []
1511 # 1 byte for the opcode and 8 for the argument
1512 frame_opcode_size = 9
1513 for opcode, _, pos in pickletools.genops(pickled):
1514 if opcode.name == 'FRAME':
1515 frame_starts.append(pos)
1516
1517 newpickle = bytearray()
1518 last_frame_end = 0
1519 for i, pos in enumerate(frame_starts):
1520 if keep_frame and keep_frame(i):
1521 continue
1522 newpickle += pickled[last_frame_end:pos]
1523 last_frame_end = pos + frame_opcode_size
1524 newpickle += pickled[last_frame_end:]
1525 return newpickle
1526
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001527 frame_size = self.FRAME_SIZE_TARGET
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001528 num_frames = 20
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001529 obj = [bytes([i]) * frame_size for i in range(num_frames)]
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001530
1531 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1532 pickled = self.dumps(obj, proto)
1533
1534 frameless_pickle = remove_frames(pickled)
1535 self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
1536 self.assertEqual(obj, self.loads(frameless_pickle))
1537
Alexandre Vassalotti5e411b72013-11-23 20:58:24 -08001538 some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
Alexandre Vassalottib6a2f2a2013-11-23 20:30:03 -08001539 self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
1540 count_opcode(pickle.FRAME, pickled))
1541 self.assertEqual(obj, self.loads(some_frames_pickle))
1542
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001543 def test_nested_names(self):
1544 global Nested
1545 class Nested:
1546 class A:
1547 class B:
1548 class C:
1549 pass
1550
1551 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1552 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
1553 with self.subTest(proto=proto, obj=obj):
1554 unpickled = self.loads(self.dumps(obj, proto))
1555 self.assertIs(obj, unpickled)
1556
1557 def test_py_methods(self):
1558 global PyMethodsTest
1559 class PyMethodsTest:
1560 @staticmethod
1561 def cheese():
1562 return "cheese"
1563 @classmethod
1564 def wine(cls):
1565 assert cls is PyMethodsTest
1566 return "wine"
1567 def biscuits(self):
1568 assert isinstance(self, PyMethodsTest)
1569 return "biscuits"
1570 class Nested:
1571 "Nested class"
1572 @staticmethod
1573 def ketchup():
1574 return "ketchup"
1575 @classmethod
1576 def maple(cls):
1577 assert cls is PyMethodsTest.Nested
1578 return "maple"
1579 def pie(self):
1580 assert isinstance(self, PyMethodsTest.Nested)
1581 return "pie"
1582
1583 py_methods = (
1584 PyMethodsTest.cheese,
1585 PyMethodsTest.wine,
1586 PyMethodsTest().biscuits,
1587 PyMethodsTest.Nested.ketchup,
1588 PyMethodsTest.Nested.maple,
1589 PyMethodsTest.Nested().pie
1590 )
1591 py_unbound_methods = (
1592 (PyMethodsTest.biscuits, PyMethodsTest),
1593 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
1594 )
1595 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1596 for method in py_methods:
1597 with self.subTest(proto=proto, method=method):
1598 unpickled = self.loads(self.dumps(method, proto))
1599 self.assertEqual(method(), unpickled())
1600 for method, cls in py_unbound_methods:
1601 obj = cls()
1602 with self.subTest(proto=proto, method=method):
1603 unpickled = self.loads(self.dumps(method, proto))
1604 self.assertEqual(method(obj), unpickled(obj))
1605
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001606 def test_c_methods(self):
1607 global Subclass
1608 class Subclass(tuple):
1609 class Nested(str):
1610 pass
1611
1612 c_methods = (
1613 # bound built-in method
1614 ("abcd".index, ("c",)),
1615 # unbound built-in method
1616 (str.index, ("abcd", "c")),
1617 # bound "slot" method
1618 ([1, 2, 3].__len__, ()),
1619 # unbound "slot" method
1620 (list.__len__, ([1, 2, 3],)),
1621 # bound "coexist" method
1622 ({1, 2}.__contains__, (2,)),
1623 # unbound "coexist" method
1624 (set.__contains__, ({1, 2}, 2)),
1625 # built-in class method
1626 (dict.fromkeys, (("a", 1), ("b", 2))),
1627 # built-in static method
1628 (bytearray.maketrans, (b"abc", b"xyz")),
1629 # subclass methods
1630 (Subclass([1,2,2]).count, (2,)),
1631 (Subclass.count, (Subclass([1,2,2]), 2)),
1632 (Subclass.Nested("sweet").count, ("e",)),
1633 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
1634 )
1635 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1636 for method, args in c_methods:
1637 with self.subTest(proto=proto, method=method):
1638 unpickled = self.loads(self.dumps(method, proto))
1639 self.assertEqual(method(*args), unpickled(*args))
1640
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001641
1642class BigmemPickleTests(unittest.TestCase):
1643
1644 # Binary protocols can serialize longs of up to 2GB-1
1645
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001646 @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001647 def test_huge_long_32b(self, size):
1648 data = 1 << (8 * size)
1649 try:
1650 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001651 if proto < 2:
1652 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001653 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001654 with self.assertRaises((ValueError, OverflowError)):
1655 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001656 finally:
1657 data = None
1658
1659 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1660 # (older protocols don't have a dedicated opcode for bytes and are
1661 # too inefficient)
1662
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001663 @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001664 def test_huge_bytes_32b(self, size):
1665 data = b"abcd" * (size // 4)
1666 try:
1667 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001668 if proto < 3:
1669 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001670 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001671 try:
1672 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001673 header = (pickle.BINBYTES +
1674 struct.pack("<I", len(data)))
1675 data_start = pickled.index(data)
1676 self.assertEqual(
1677 header,
1678 pickled[data_start-len(header):data_start])
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001679 finally:
1680 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001681 finally:
1682 data = None
1683
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001684 @bigmemtest(size=_4G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001685 def test_huge_bytes_64b(self, size):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001686 data = b"acbd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001687 try:
1688 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001689 if proto < 3:
1690 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001691 with self.subTest(proto=proto):
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001692 if proto == 3:
1693 # Protocol 3 does not support large bytes objects.
1694 # Verify that we do not crash when processing one.
1695 with self.assertRaises((ValueError, OverflowError)):
1696 self.dumps(data, protocol=proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001697 continue
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001698 try:
1699 pickled = self.dumps(data, protocol=proto)
1700 header = (pickle.BINBYTES8 +
1701 struct.pack("<Q", len(data)))
1702 data_start = pickled.index(data)
1703 self.assertEqual(
1704 header,
1705 pickled[data_start-len(header):data_start])
1706 finally:
1707 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001708 finally:
1709 data = None
1710
1711 # All protocols use 1-byte per printable ASCII character; we add another
1712 # byte because the encoded form has to be copied into the internal buffer.
1713
Antoine Pitroub7591d42011-10-04 16:18:15 +02001714 @bigmemtest(size=_2G, memuse=2 + ascii_char_size, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001715 def test_huge_str_32b(self, size):
1716 data = "abcd" * (size // 4)
1717 try:
1718 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001719 if proto == 0:
1720 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001721 with self.subTest(proto=proto):
1722 try:
1723 pickled = self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001724 header = (pickle.BINUNICODE +
1725 struct.pack("<I", len(data)))
1726 data_start = pickled.index(b'abcd')
1727 self.assertEqual(
1728 header,
1729 pickled[data_start-len(header):data_start])
1730 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1731 pickled.index(b"abcd")), len(data))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001732 finally:
1733 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001734 finally:
1735 data = None
1736
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001737 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
1738 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
1739 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02001740
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001741 @bigmemtest(size=_4G, memuse=2 + ascii_char_size, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001742 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001743 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001744 try:
1745 for proto in protocols:
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001746 if proto == 0:
1747 continue
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001748 with self.subTest(proto=proto):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001749 if proto < 4:
1750 with self.assertRaises((ValueError, OverflowError)):
1751 self.dumps(data, protocol=proto)
Alexandre Vassalotti6e73ff12013-12-05 19:29:32 -08001752 continue
1753 try:
1754 pickled = self.dumps(data, protocol=proto)
1755 header = (pickle.BINUNICODE8 +
1756 struct.pack("<Q", len(data)))
1757 data_start = pickled.index(b'abcd')
1758 self.assertEqual(
1759 header,
1760 pickled[data_start-len(header):data_start])
1761 self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
1762 pickled.index(b"abcd")), len(data))
1763 finally:
1764 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001765 finally:
1766 data = None
1767
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001768
Guido van Rossum2a30b212003-02-18 22:41:24 +00001769# Test classes for reduce_ex
1770
1771class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001772 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001773 _reduce_called = 0
1774 def __reduce__(self):
1775 self._reduce_called = 1
1776 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001777
1778class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001779 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001780 _proto = None
1781 def __reduce_ex__(self, proto):
1782 self._proto = proto
1783 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001784
1785class REX_three(object):
1786 _proto = None
1787 def __reduce_ex__(self, proto):
1788 self._proto = proto
1789 return REX_two, ()
1790 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001791 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001792
Guido van Rossumd8faa362007-04-27 19:54:29 +00001793class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001794 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001795 _proto = None
1796 def __reduce_ex__(self, proto):
1797 self._proto = proto
1798 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001799
1800class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001801 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001802 _reduce_called = 0
1803 def __reduce__(self):
1804 self._reduce_called = 1
1805 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001806
1807class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001808 """This class is used to check the 4th argument (list iterator) of
1809 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001810 """
1811 def __init__(self, items=None):
1812 self.items = items if items is not None else []
1813 def __eq__(self, other):
1814 return type(self) is type(other) and self.items == self.items
1815 def append(self, item):
1816 self.items.append(item)
1817 def __reduce__(self):
1818 return type(self), (), None, iter(self.items), None
1819
1820class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001821 """This class is used to check the 5th argument (dict iterator) of
1822 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001823 """
1824 def __init__(self, table=None):
1825 self.table = table if table is not None else {}
1826 def __eq__(self, other):
1827 return type(self) is type(other) and self.table == self.table
1828 def __setitem__(self, key, value):
1829 self.table[key] = value
1830 def __reduce__(self):
1831 return type(self), (), None, None, iter(self.table.items())
1832
Guido van Rossumd8faa362007-04-27 19:54:29 +00001833
Guido van Rossum2a30b212003-02-18 22:41:24 +00001834# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001835
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001836class MyInt(int):
1837 sample = 1
1838
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001839class MyFloat(float):
1840 sample = 1.0
1841
1842class MyComplex(complex):
1843 sample = 1.0 + 0.0j
1844
1845class MyStr(str):
1846 sample = "hello"
1847
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001848class MyUnicode(str):
1849 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001850
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001851class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001852 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001853
1854class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001855 sample = [1, 2, 3]
1856
1857class MyDict(dict):
1858 sample = {"a": 1, "b": 2}
1859
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001860class MySet(set):
1861 sample = {"a", "b"}
1862
1863class MyFrozenSet(frozenset):
1864 sample = frozenset({"a", "b"})
1865
Mark Dickinson5c2db372009-12-05 20:28:34 +00001866myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001867 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001868 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001869 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001870
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001871
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001872class SlotList(MyList):
1873 __slots__ = ["foo"]
1874
Tim Peterse9ef2032003-02-13 18:42:00 +00001875class SimpleNewObj(object):
1876 def __init__(self, a, b, c):
1877 # raise an error, to make sure this isn't called
1878 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001879 def __eq__(self, other):
1880 return self.__dict__ == other.__dict__
Tim Peterse9ef2032003-02-13 18:42:00 +00001881
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001882class BadGetattr:
1883 def __getattr__(self, key):
1884 self.foo
1885
Collin Winter771d8342009-04-16 03:18:06 +00001886
Jeremy Hylton66426532001-10-15 21:38:56 +00001887class AbstractPickleModuleTests(unittest.TestCase):
1888
1889 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001890 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001891 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001892 try:
1893 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001894 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001895 finally:
1896 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001897
1898 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001899 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001900 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001901 try:
1902 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001903 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001904 finally:
1905 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001906
Collin Winter771d8342009-04-16 03:18:06 +00001907 def test_load_from_and_dump_to_file(self):
1908 stream = io.BytesIO()
1909 data = [123, {}, 124]
1910 pickle.dump(data, stream)
1911 stream.seek(0)
1912 unpickled = pickle.load(stream)
1913 self.assertEqual(unpickled, data)
1914
Tim Petersc0c93702003-02-13 19:30:57 +00001915 def test_highest_protocol(self):
1916 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001917 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00001918
Martin v. Löwis544f1192004-07-27 05:22:33 +00001919 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001920 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001921 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001922 pickle.dump(123, f, -1)
1923 pickle.dump(123, file=f, protocol=-1)
1924 pickle.dumps(123, -1)
1925 pickle.dumps(123, protocol=-1)
1926 pickle.Pickler(f, -1)
1927 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001928
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001929 def test_bad_init(self):
1930 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001931 # Override initialization without calling __init__() of the superclass.
1932 class BadPickler(pickle.Pickler):
1933 def __init__(self): pass
1934
1935 class BadUnpickler(pickle.Unpickler):
1936 def __init__(self): pass
1937
1938 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1939 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1940
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001941 def test_bad_input(self):
1942 # Test issue4298
1943 s = bytes([0x58, 0, 0, 0, 0x54])
1944 self.assertRaises(EOFError, pickle.loads, s)
1945
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001946
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001947class AbstractPersistentPicklerTests(unittest.TestCase):
1948
1949 # This class defines persistent_id() and persistent_load()
1950 # functions that should be used by the pickler. All even integers
1951 # are pickled using persistent ids.
1952
1953 def persistent_id(self, object):
1954 if isinstance(object, int) and object % 2 == 0:
1955 self.id_count += 1
1956 return str(object)
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001957 elif object == "test_false_value":
1958 self.false_count += 1
1959 return ""
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001960 else:
1961 return None
1962
1963 def persistent_load(self, oid):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001964 if not oid:
1965 self.load_false_count += 1
1966 return "test_false_value"
1967 else:
1968 self.load_count += 1
1969 object = int(oid)
1970 assert object % 2 == 0
1971 return object
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001972
1973 def test_persistence(self):
Alexandre Vassalotti896414f2013-11-30 13:52:35 -08001974 L = list(range(10)) + ["test_false_value"]
1975 for proto in protocols:
1976 self.id_count = 0
1977 self.false_count = 0
1978 self.load_false_count = 0
1979 self.load_count = 0
1980 self.assertEqual(self.loads(self.dumps(L, proto)), L)
1981 self.assertEqual(self.id_count, 5)
1982 self.assertEqual(self.false_count, 1)
1983 self.assertEqual(self.load_count, 5)
1984 self.assertEqual(self.load_false_count, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001985
Collin Winter771d8342009-04-16 03:18:06 +00001986
1987class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1988
1989 pickler_class = None
1990 unpickler_class = None
1991
1992 def setUp(self):
1993 assert self.pickler_class
1994 assert self.unpickler_class
1995
1996 def test_clear_pickler_memo(self):
1997 # To test whether clear_memo() has any effect, we pickle an object,
1998 # then pickle it again without clearing the memo; the two serialized
1999 # forms should be different. If we clear_memo() and then pickle the
2000 # object again, the third serialized form should be identical to the
2001 # first one we obtained.
2002 data = ["abcdefg", "abcdefg", 44]
2003 f = io.BytesIO()
2004 pickler = self.pickler_class(f)
2005
2006 pickler.dump(data)
2007 first_pickled = f.getvalue()
2008
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002009 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00002010 f.seek(0)
2011 f.truncate()
2012
2013 pickler.dump(data)
2014 second_pickled = f.getvalue()
2015
Serhiy Storchaka50254c52013-08-29 11:35:43 +03002016 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00002017 pickler.clear_memo()
2018 f.seek(0)
2019 f.truncate()
2020
2021 pickler.dump(data)
2022 third_pickled = f.getvalue()
2023
2024 self.assertNotEqual(first_pickled, second_pickled)
2025 self.assertEqual(first_pickled, third_pickled)
2026
2027 def test_priming_pickler_memo(self):
2028 # Verify that we can set the Pickler's memo attribute.
2029 data = ["abcdefg", "abcdefg", 44]
2030 f = io.BytesIO()
2031 pickler = self.pickler_class(f)
2032
2033 pickler.dump(data)
2034 first_pickled = f.getvalue()
2035
2036 f = io.BytesIO()
2037 primed = self.pickler_class(f)
2038 primed.memo = pickler.memo
2039
2040 primed.dump(data)
2041 primed_pickled = f.getvalue()
2042
2043 self.assertNotEqual(first_pickled, primed_pickled)
2044
2045 def test_priming_unpickler_memo(self):
2046 # Verify that we can set the Unpickler's memo attribute.
2047 data = ["abcdefg", "abcdefg", 44]
2048 f = io.BytesIO()
2049 pickler = self.pickler_class(f)
2050
2051 pickler.dump(data)
2052 first_pickled = f.getvalue()
2053
2054 f = io.BytesIO()
2055 primed = self.pickler_class(f)
2056 primed.memo = pickler.memo
2057
2058 primed.dump(data)
2059 primed_pickled = f.getvalue()
2060
2061 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
2062 unpickled_data1 = unpickler.load()
2063
2064 self.assertEqual(unpickled_data1, data)
2065
2066 primed = self.unpickler_class(io.BytesIO(primed_pickled))
2067 primed.memo = unpickler.memo
2068 unpickled_data2 = primed.load()
2069
2070 primed.memo.clear()
2071
2072 self.assertEqual(unpickled_data2, data)
2073 self.assertTrue(unpickled_data2 is unpickled_data1)
2074
2075 def test_reusing_unpickler_objects(self):
2076 data1 = ["abcdefg", "abcdefg", 44]
2077 f = io.BytesIO()
2078 pickler = self.pickler_class(f)
2079 pickler.dump(data1)
2080 pickled1 = f.getvalue()
2081
2082 data2 = ["abcdefg", 44, 44]
2083 f = io.BytesIO()
2084 pickler = self.pickler_class(f)
2085 pickler.dump(data2)
2086 pickled2 = f.getvalue()
2087
2088 f = io.BytesIO()
2089 f.write(pickled1)
2090 f.seek(0)
2091 unpickler = self.unpickler_class(f)
2092 self.assertEqual(unpickler.load(), data1)
2093
2094 f.seek(0)
2095 f.truncate()
2096 f.write(pickled2)
2097 f.seek(0)
2098 self.assertEqual(unpickler.load(), data2)
2099
Antoine Pitrou04248a82010-10-12 20:51:21 +00002100 def _check_multiple_unpicklings(self, ioclass):
2101 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002102 with self.subTest(proto=proto):
2103 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
2104 f = ioclass()
2105 pickler = self.pickler_class(f, protocol=proto)
2106 pickler.dump(data1)
2107 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00002108
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01002109 N = 5
2110 f = ioclass(pickled * N)
2111 unpickler = self.unpickler_class(f)
2112 for i in range(N):
2113 if f.seekable():
2114 pos = f.tell()
2115 self.assertEqual(unpickler.load(), data1)
2116 if f.seekable():
2117 self.assertEqual(f.tell(), pos + len(pickled))
2118 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00002119
2120 def test_multiple_unpicklings_seekable(self):
2121 self._check_multiple_unpicklings(io.BytesIO)
2122
2123 def test_multiple_unpicklings_unseekable(self):
2124 self._check_multiple_unpicklings(UnseekableIO)
2125
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02002126 def test_unpickling_buffering_readline(self):
2127 # Issue #12687: the unpickler's buffering logic could fail with
2128 # text mode opcodes.
2129 data = list(range(10))
2130 for proto in protocols:
2131 for buf_size in range(1, 11):
2132 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
2133 pickler = self.pickler_class(f, protocol=proto)
2134 pickler.dump(data)
2135 f.seek(0)
2136 unpickler = self.unpickler_class(f)
2137 self.assertEqual(unpickler.load(), data)
2138
Collin Winter771d8342009-04-16 03:18:06 +00002139
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01002140# Tests for dispatch_table attribute
2141
2142REDUCE_A = 'reduce_A'
2143
2144class AAA(object):
2145 def __reduce__(self):
2146 return str, (REDUCE_A,)
2147
2148class BBB(object):
2149 pass
2150
2151class AbstractDispatchTableTests(unittest.TestCase):
2152
2153 def test_default_dispatch_table(self):
2154 # No dispatch_table attribute by default
2155 f = io.BytesIO()
2156 p = self.pickler_class(f, 0)
2157 with self.assertRaises(AttributeError):
2158 p.dispatch_table
2159 self.assertFalse(hasattr(p, 'dispatch_table'))
2160
2161 def test_class_dispatch_table(self):
2162 # A dispatch_table attribute can be specified class-wide
2163 dt = self.get_dispatch_table()
2164
2165 class MyPickler(self.pickler_class):
2166 dispatch_table = dt
2167
2168 def dumps(obj, protocol=None):
2169 f = io.BytesIO()
2170 p = MyPickler(f, protocol)
2171 self.assertEqual(p.dispatch_table, dt)
2172 p.dump(obj)
2173 return f.getvalue()
2174
2175 self._test_dispatch_table(dumps, dt)
2176
2177 def test_instance_dispatch_table(self):
2178 # A dispatch_table attribute can also be specified instance-wide
2179 dt = self.get_dispatch_table()
2180
2181 def dumps(obj, protocol=None):
2182 f = io.BytesIO()
2183 p = self.pickler_class(f, protocol)
2184 p.dispatch_table = dt
2185 self.assertEqual(p.dispatch_table, dt)
2186 p.dump(obj)
2187 return f.getvalue()
2188
2189 self._test_dispatch_table(dumps, dt)
2190
2191 def _test_dispatch_table(self, dumps, dispatch_table):
2192 def custom_load_dump(obj):
2193 return pickle.loads(dumps(obj, 0))
2194
2195 def default_load_dump(obj):
2196 return pickle.loads(pickle.dumps(obj, 0))
2197
2198 # pickling complex numbers using protocol 0 relies on copyreg
2199 # so check pickling a complex number still works
2200 z = 1 + 2j
2201 self.assertEqual(custom_load_dump(z), z)
2202 self.assertEqual(default_load_dump(z), z)
2203
2204 # modify pickling of complex
2205 REDUCE_1 = 'reduce_1'
2206 def reduce_1(obj):
2207 return str, (REDUCE_1,)
2208 dispatch_table[complex] = reduce_1
2209 self.assertEqual(custom_load_dump(z), REDUCE_1)
2210 self.assertEqual(default_load_dump(z), z)
2211
2212 # check picklability of AAA and BBB
2213 a = AAA()
2214 b = BBB()
2215 self.assertEqual(custom_load_dump(a), REDUCE_A)
2216 self.assertIsInstance(custom_load_dump(b), BBB)
2217 self.assertEqual(default_load_dump(a), REDUCE_A)
2218 self.assertIsInstance(default_load_dump(b), BBB)
2219
2220 # modify pickling of BBB
2221 dispatch_table[BBB] = reduce_1
2222 self.assertEqual(custom_load_dump(a), REDUCE_A)
2223 self.assertEqual(custom_load_dump(b), REDUCE_1)
2224 self.assertEqual(default_load_dump(a), REDUCE_A)
2225 self.assertIsInstance(default_load_dump(b), BBB)
2226
2227 # revert pickling of BBB and modify pickling of AAA
2228 REDUCE_2 = 'reduce_2'
2229 def reduce_2(obj):
2230 return str, (REDUCE_2,)
2231 dispatch_table[AAA] = reduce_2
2232 del dispatch_table[BBB]
2233 self.assertEqual(custom_load_dump(a), REDUCE_2)
2234 self.assertIsInstance(custom_load_dump(b), BBB)
2235 self.assertEqual(default_load_dump(a), REDUCE_A)
2236 self.assertIsInstance(default_load_dump(b), BBB)
2237
2238
Guido van Rossum98297ee2007-11-06 21:34:58 +00002239if __name__ == "__main__":
2240 # Print some stuff that can be used to rewrite DATA{0,1,2}
2241 from pickletools import dis
2242 x = create_data()
2243 for i in range(3):
2244 p = pickle.dumps(x, i)
2245 print("DATA{0} = (".format(i))
2246 for j in range(0, len(p), 20):
2247 b = bytes(p[j:j+20])
2248 print(" {0!r}".format(b))
2249 print(")")
2250 print()
2251 print("# Disassembly of DATA{0}".format(i))
2252 print("DATA{0}_DIS = \"\"\"\\".format(i))
2253 dis(p)
2254 print("\"\"\"")
2255 print()