blob: 34e46f686c1dd731acbb00b4733396f4898ed4dd [file] [log] [blame]
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001import copyreg
Collin Winter771d8342009-04-16 03:18:06 +00002import io
Tim Peters4190fb82003-02-02 16:09:05 +00003import pickle
Tim Peters31f119e2003-02-03 16:20:13 +00004import pickletools
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01005import random
Antoine Pitrou82be19f2011-08-29 23:09:33 +02006import sys
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01007import unittest
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01008import weakref
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00009from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +000010
Antoine Pitrou82be19f2011-08-29 23:09:33 +020011from test.support import (
Antoine Pitrouee763e22011-08-29 23:14:53 +020012 TestFailed, TESTFN, run_with_locale, no_tracing,
Antoine Pitrou94190bb2011-10-04 10:22:36 +020013 _2G, _4G, bigmemtest,
Antoine Pitrou82be19f2011-08-29 23:09:33 +020014 )
Tim Peterse089c682001-04-10 03:41:41 +000015
Guido van Rossum98297ee2007-11-06 21:34:58 +000016from pickle import bytes_types
17
Tim Petersee1a53c2003-02-02 02:57:53 +000018# Tests that try a number of pickle protocols should have a
19# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000020# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000021protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000022
Antoine Pitroub7591d42011-10-04 16:18:15 +020023ascii_char_size = 1
Antoine Pitrou82be19f2011-08-29 23:09:33 +020024
Tim Peters22e71712003-02-03 22:27:38 +000025
26# Return True if opcode code appears in the pickle, else False.
27def opcode_in_pickle(code, pickle):
28 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000029 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000030 return True
31 return False
32
Tim Peters8d2613a2003-02-11 16:40:16 +000033# Return the number of times opcode code appears in pickle.
34def count_opcode(code, pickle):
35 n = 0
36 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000037 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000038 n += 1
39 return n
40
Antoine Pitrou04248a82010-10-12 20:51:21 +000041
42class UnseekableIO(io.BytesIO):
43 def peek(self, *args):
44 raise NotImplementedError
45
46 def seekable(self):
47 return False
48
49 def seek(self, *args):
50 raise io.UnsupportedOperation
51
52 def tell(self):
53 raise io.UnsupportedOperation
54
55
Tim Peters3e667d52003-02-04 21:47:44 +000056# We can't very well test the extension registry without putting known stuff
57# in it, but we have to be careful to restore its original state. Code
58# should do this:
59#
60# e = ExtensionSaver(extension_code)
61# try:
62# fiddle w/ the extension registry's stuff for extension_code
63# finally:
64# e.restore()
65
66class ExtensionSaver:
67 # Remember current registration for code (if any), and remove it (if
68 # there is one).
69 def __init__(self, code):
70 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000071 if code in copyreg._inverted_registry:
72 self.pair = copyreg._inverted_registry[code]
73 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000074 else:
75 self.pair = None
76
77 # Restore previous registration for code.
78 def restore(self):
79 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000080 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000081 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000082 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000083 pair = self.pair
84 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000085 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000086
Jeremy Hylton66426532001-10-15 21:38:56 +000087class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000088 def __eq__(self, other):
89 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000090
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000091class D(C):
92 def __init__(self, arg):
93 pass
94
95class E(C):
96 def __getinitargs__(self):
97 return ()
98
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +010099class H(object):
100 pass
101
Jeremy Hylton66426532001-10-15 21:38:56 +0000102import __main__
103__main__.C = C
104C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000105__main__.D = D
106D.__module__ = "__main__"
107__main__.E = E
108E.__module__ = "__main__"
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100109__main__.H = H
110H.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000111
112class myint(int):
113 def __init__(self, x):
114 self.str = str(x)
115
116class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000117
Jeremy Hylton66426532001-10-15 21:38:56 +0000118 def __init__(self, a, b):
119 self.a = a
120 self.b = b
121
122 def __getinitargs__(self):
123 return self.a, self.b
124
Guido van Rossum04a86612001-12-19 16:58:54 +0000125class metaclass(type):
126 pass
127
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000128class use_metaclass(object, metaclass=metaclass):
129 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000130
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200131class pickling_metaclass(type):
132 def __eq__(self, other):
133 return (type(self) == type(other) and
134 self.reduce_args == other.reduce_args)
135
136 def __reduce__(self):
137 return (create_dynamic_class, self.reduce_args)
138
139def create_dynamic_class(name, bases):
140 result = pickling_metaclass(name, bases, dict())
141 result.reduce_args = (name, bases)
142 return result
143
Tim Peters70b02d72003-02-02 17:26:40 +0000144# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
145# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000146
Guido van Rossum98297ee2007-11-06 21:34:58 +0000147DATA0 = (
Mark Dickinson8dd05142009-01-20 20:43:58 +0000148 b'(lp0\nL0L\naL1L\naF2.0\nac'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000149 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000150 b'p1\n(F3.0\nF0.0\ntp2\nRp'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000151 b'3\naL1L\naL-1L\naL255L\naL-'
152 b'255L\naL-256L\naL65535L\na'
153 b'L-65535L\naL-65536L\naL2'
154 b'147483647L\naL-2147483'
155 b'647L\naL-2147483648L\na('
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000156 b'Vabc\np4\ng4\nccopyreg'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000157 b'\n_reconstructor\np5\n('
Georg Brandl1a3284e2007-12-02 09:40:06 +0000158 b'c__main__\nC\np6\ncbu'
159 b'iltins\nobject\np7\nNt'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000160 b'p8\nRp9\n(dp10\nVfoo\np1'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000161 b'1\nL1L\nsVbar\np12\nL2L\nsb'
162 b'g9\ntp13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000163)
Tim Peterse9358162001-01-22 22:05:20 +0000164
Guido van Rossum98297ee2007-11-06 21:34:58 +0000165# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000166DATA0_DIS = """\
167 0: ( MARK
168 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000169 2: p PUT 0
170 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000171 9: a APPEND
172 10: L LONG 1
173 14: a APPEND
174 15: F FLOAT 2.0
175 20: a APPEND
176 21: c GLOBAL 'builtins complex'
177 39: p PUT 1
178 42: ( MARK
179 43: F FLOAT 3.0
180 48: F FLOAT 0.0
181 53: t TUPLE (MARK at 42)
182 54: p PUT 2
183 57: R REDUCE
184 58: p PUT 3
185 61: a APPEND
186 62: L LONG 1
187 66: a APPEND
188 67: L LONG -1
189 72: a APPEND
190 73: L LONG 255
191 79: a APPEND
192 80: L LONG -255
193 87: a APPEND
194 88: L LONG -256
195 95: a APPEND
196 96: L LONG 65535
197 104: a APPEND
198 105: L LONG -65535
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000199 114: a APPEND
Mark Dickinson8dd05142009-01-20 20:43:58 +0000200 115: L LONG -65536
201 124: a APPEND
202 125: L LONG 2147483647
203 138: a APPEND
204 139: L LONG -2147483647
205 153: a APPEND
206 154: L LONG -2147483648
207 168: a APPEND
208 169: ( MARK
209 170: V UNICODE 'abc'
210 175: p PUT 4
211 178: g GET 4
212 181: c GLOBAL 'copyreg _reconstructor'
213 205: p PUT 5
214 208: ( MARK
215 209: c GLOBAL '__main__ C'
216 221: p PUT 6
217 224: c GLOBAL 'builtins object'
218 241: p PUT 7
219 244: N NONE
220 245: t TUPLE (MARK at 208)
221 246: p PUT 8
222 249: R REDUCE
223 250: p PUT 9
224 253: ( MARK
225 254: d DICT (MARK at 253)
226 255: p PUT 10
227 259: V UNICODE 'foo'
228 264: p PUT 11
229 268: L LONG 1
230 272: s SETITEM
231 273: V UNICODE 'bar'
232 278: p PUT 12
233 282: L LONG 2
234 286: s SETITEM
235 287: b BUILD
236 288: g GET 9
237 291: t TUPLE (MARK at 169)
238 292: p PUT 13
239 296: a APPEND
240 297: g GET 13
241 301: a APPEND
242 302: L LONG 5
243 306: a APPEND
244 307: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000245highest protocol among opcodes = 0
246"""
247
Guido van Rossum98297ee2007-11-06 21:34:58 +0000248DATA1 = (
Georg Brandl1a3284e2007-12-02 09:40:06 +0000249 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
250 b'builtins\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000251 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
252 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
253 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
254 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000255 b'cq\x04h\x04ccopyreg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000256 b'nstructor\nq\x05(c__main'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000257 b'__\nC\nq\x06cbuiltins\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000258 b'object\nq\x07Ntq\x08Rq\t}q\n('
259 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
260 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
261)
Tim Peters70b02d72003-02-02 17:26:40 +0000262
Guido van Rossum98297ee2007-11-06 21:34:58 +0000263# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000264DATA1_DIS = """\
265 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000266 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000267 3: ( MARK
268 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000269 6: K BININT1 1
270 8: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000271 17: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000272 35: q BINPUT 1
273 37: ( MARK
274 38: G BINFLOAT 3.0
275 47: G BINFLOAT 0.0
276 56: t TUPLE (MARK at 37)
277 57: q BINPUT 2
278 59: R REDUCE
279 60: q BINPUT 3
280 62: K BININT1 1
281 64: J BININT -1
282 69: K BININT1 255
283 71: J BININT -255
284 76: J BININT -256
285 81: M BININT2 65535
286 84: J BININT -65535
287 89: J BININT -65536
288 94: J BININT 2147483647
289 99: J BININT -2147483647
290 104: J BININT -2147483648
291 109: ( MARK
292 110: X BINUNICODE 'abc'
293 118: q BINPUT 4
294 120: h BINGET 4
295 122: c GLOBAL 'copyreg _reconstructor'
296 146: q BINPUT 5
297 148: ( MARK
298 149: c GLOBAL '__main__ C'
299 161: q BINPUT 6
300 163: c GLOBAL 'builtins object'
301 180: q BINPUT 7
302 182: N NONE
303 183: t TUPLE (MARK at 148)
304 184: q BINPUT 8
305 186: R REDUCE
306 187: q BINPUT 9
307 189: } EMPTY_DICT
308 190: q BINPUT 10
309 192: ( MARK
310 193: X BINUNICODE 'foo'
311 201: q BINPUT 11
312 203: K BININT1 1
313 205: X BINUNICODE 'bar'
314 213: q BINPUT 12
315 215: K BININT1 2
316 217: u SETITEMS (MARK at 192)
317 218: b BUILD
318 219: h BINGET 9
319 221: t TUPLE (MARK at 109)
320 222: q BINPUT 13
321 224: h BINGET 13
322 226: K BININT1 5
323 228: e APPENDS (MARK at 3)
324 229: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000325highest protocol among opcodes = 1
326"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000327
Guido van Rossum98297ee2007-11-06 21:34:58 +0000328DATA2 = (
329 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000330 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000331 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
332 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
333 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
334 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
335 b'bcq\x04h\x04c__main__\nC\nq\x05'
336 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
337 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
338 b'\nK\x05e.'
339)
Tim Petersfc273752003-03-02 04:54:24 +0000340
Guido van Rossum98297ee2007-11-06 21:34:58 +0000341# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000342DATA2_DIS = """\
343 0: \x80 PROTO 2
344 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000345 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000346 5: ( MARK
347 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000348 8: K BININT1 1
349 10: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000350 19: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000351 37: q BINPUT 1
352 39: G BINFLOAT 3.0
353 48: G BINFLOAT 0.0
354 57: \x86 TUPLE2
355 58: q BINPUT 2
356 60: R REDUCE
357 61: q BINPUT 3
358 63: K BININT1 1
359 65: J BININT -1
360 70: K BININT1 255
361 72: J BININT -255
362 77: J BININT -256
363 82: M BININT2 65535
364 85: J BININT -65535
365 90: J BININT -65536
366 95: J BININT 2147483647
367 100: J BININT -2147483647
368 105: J BININT -2147483648
369 110: ( MARK
370 111: X BINUNICODE 'abc'
371 119: q BINPUT 4
372 121: h BINGET 4
373 123: c GLOBAL '__main__ C'
374 135: q BINPUT 5
375 137: ) EMPTY_TUPLE
376 138: \x81 NEWOBJ
377 139: q BINPUT 6
378 141: } EMPTY_DICT
379 142: q BINPUT 7
380 144: ( MARK
381 145: X BINUNICODE 'foo'
382 153: q BINPUT 8
383 155: K BININT1 1
384 157: X BINUNICODE 'bar'
385 165: q BINPUT 9
386 167: K BININT1 2
387 169: u SETITEMS (MARK at 144)
388 170: b BUILD
389 171: h BINGET 6
390 173: t TUPLE (MARK at 110)
391 174: q BINPUT 10
392 176: h BINGET 10
393 178: K BININT1 5
394 180: e APPENDS (MARK at 5)
395 181: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000396highest protocol among opcodes = 2
397"""
398
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000399# set([1,2]) pickled from 2.x with protocol 2
400DATA3 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
401
402# xrange(5) pickled from 2.x with protocol 2
403DATA4 = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
404
405# a SimpleCookie() object pickled from 2.x with protocol 2
406DATA5 = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
407 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
408 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
409 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
410 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
411 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
412
413# set([3]) pickled from 2.x with protocol 2
414DATA6 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
415
416
Jeremy Hylton66426532001-10-15 21:38:56 +0000417def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000418 c = C()
419 c.foo = 1
420 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000421 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000422 # Append some integer test cases at cPickle.c's internal size
423 # cutoffs.
424 uint1max = 0xff
425 uint2max = 0xffff
426 int4max = 0x7fffffff
427 x.extend([1, -1,
428 uint1max, -uint1max, -uint1max-1,
429 uint2max, -uint2max, -uint2max-1,
430 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000431 y = ('abc', 'abc', c, c)
432 x.append(y)
433 x.append(y)
434 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000435 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000436
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100437
Jeremy Hylton66426532001-10-15 21:38:56 +0000438class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000439 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000440
Jeremy Hylton66426532001-10-15 21:38:56 +0000441 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000442
Jeremy Hylton66426532001-10-15 21:38:56 +0000443 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000444 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000445
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100446 def assert_is_copy(self, obj, objcopy, msg=None):
447 """Utility method to verify if two objects are copies of each others.
448 """
449 if msg is None:
450 msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
451 self.assertEqual(obj, objcopy, msg=msg)
452 self.assertIs(type(obj), type(objcopy), msg=msg)
453 if hasattr(obj, '__dict__'):
454 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
455 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
456 if hasattr(obj, '__slots__'):
457 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
458 for slot in obj.__slots__:
459 self.assertEqual(
460 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
461 self.assertEqual(getattr(obj, slot, None),
462 getattr(objcopy, slot, None), msg=msg)
463
Jeremy Hylton66426532001-10-15 21:38:56 +0000464 def test_misc(self):
465 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000466 for proto in protocols:
467 x = myint(4)
468 s = self.dumps(x, proto)
469 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100470 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000471
Tim Peters70b02d72003-02-02 17:26:40 +0000472 x = (1, ())
473 s = self.dumps(x, proto)
474 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100475 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000476
Tim Peters70b02d72003-02-02 17:26:40 +0000477 x = initarg(1, x)
478 s = self.dumps(x, proto)
479 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100480 self.assert_is_copy(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000481
Jeremy Hylton66426532001-10-15 21:38:56 +0000482 # XXX test __reduce__ protocol?
483
Tim Peters70b02d72003-02-02 17:26:40 +0000484 def test_roundtrip_equality(self):
485 expected = self._testdata
486 for proto in protocols:
487 s = self.dumps(expected, proto)
488 got = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100489 self.assert_is_copy(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000490
Guido van Rossum98297ee2007-11-06 21:34:58 +0000491 def test_load_from_data0(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100492 self.assert_is_copy(self._testdata, self.loads(DATA0))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000493
494 def test_load_from_data1(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100495 self.assert_is_copy(self._testdata, self.loads(DATA1))
Guido van Rossum98297ee2007-11-06 21:34:58 +0000496
497 def test_load_from_data2(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100498 self.assert_is_copy(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000499
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000500 def test_load_classic_instance(self):
501 # See issue5180. Test loading 2.x pickles that
502 # contain an instance of old style class.
503 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
504 xname = X.__name__.encode('ascii')
505 # Protocol 0 (text mode pickle):
506 """
507 0: ( MARK
508 1: i INST '__main__ X' (MARK at 0)
509 15: p PUT 0
510 18: ( MARK
511 19: d DICT (MARK at 18)
512 20: p PUT 1
513 23: b BUILD
514 24: . STOP
515 """
516 pickle0 = (b"(i__main__\n"
517 b"X\n"
518 b"p0\n"
519 b"(dp1\nb.").replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100520 self.assert_is_copy(X(*args), self.loads(pickle0))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000521
522 # Protocol 1 (binary mode pickle)
523 """
524 0: ( MARK
525 1: c GLOBAL '__main__ X'
526 15: q BINPUT 0
527 17: o OBJ (MARK at 0)
528 18: q BINPUT 1
529 20: } EMPTY_DICT
530 21: q BINPUT 2
531 23: b BUILD
532 24: . STOP
533 """
534 pickle1 = (b'(c__main__\n'
535 b'X\n'
536 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100537 self.assert_is_copy(X(*args), self.loads(pickle1))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000538
539 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
540 """
541 0: \x80 PROTO 2
542 2: ( MARK
543 3: c GLOBAL '__main__ X'
544 17: q BINPUT 0
545 19: o OBJ (MARK at 2)
546 20: q BINPUT 1
547 22: } EMPTY_DICT
548 23: q BINPUT 2
549 25: b BUILD
550 26: . STOP
551 """
552 pickle2 = (b'\x80\x02(c__main__\n'
553 b'X\n'
554 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100555 self.assert_is_copy(X(*args), self.loads(pickle2))
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000556
Tim Peters70b02d72003-02-02 17:26:40 +0000557 # There are gratuitous differences between pickles produced by
558 # pickle and cPickle, largely because cPickle starts PUT indices at
559 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
560 # there's a comment with an exclamation point there whose meaning
561 # is a mystery. cPickle also suppresses PUT for objects with a refcount
562 # of 1.
563 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000564 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000565 from pickletools import dis
566
567 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
568 s = self.dumps(self._testdata, proto)
569 filelike = StringIO()
570 dis(s, out=filelike)
571 got = filelike.getvalue()
572 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000573
574 def test_recursive_list(self):
575 l = []
576 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000577 for proto in protocols:
578 s = self.dumps(l, proto)
579 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100580 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000581 self.assertEqual(len(x), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000582 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000583
Collin Winter8ca69de2009-05-26 16:53:41 +0000584 def test_recursive_tuple(self):
585 t = ([],)
586 t[0].append(t)
587 for proto in protocols:
588 s = self.dumps(t, proto)
589 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100590 self.assertIsInstance(x, tuple)
Collin Winter8ca69de2009-05-26 16:53:41 +0000591 self.assertEqual(len(x), 1)
592 self.assertEqual(len(x[0]), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000593 self.assertTrue(x is x[0][0])
Collin Winter8ca69de2009-05-26 16:53:41 +0000594
Jeremy Hylton66426532001-10-15 21:38:56 +0000595 def test_recursive_dict(self):
596 d = {}
597 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000598 for proto in protocols:
599 s = self.dumps(d, proto)
600 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100601 self.assertIsInstance(x, dict)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000602 self.assertEqual(list(x.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000603 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000604
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100605 def test_recursive_set(self):
606 h = H()
607 y = set({h})
608 h.attr = y
609 for proto in protocols:
610 s = self.dumps(y, proto)
611 x = self.loads(s)
612 self.assertIsInstance(x, set)
613 self.assertIs(list(x)[0].attr, x)
614 self.assertEqual(len(x), 1)
615
616 def test_recursive_frozenset(self):
617 h = H()
618 y = frozenset({h})
619 h.attr = y
620 for proto in protocols:
621 s = self.dumps(y, proto)
622 x = self.loads(s)
623 self.assertIsInstance(x, frozenset)
624 self.assertIs(list(x)[0].attr, x)
625 self.assertEqual(len(x), 1)
626
Jeremy Hylton66426532001-10-15 21:38:56 +0000627 def test_recursive_inst(self):
628 i = C()
629 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000630 for proto in protocols:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200631 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +0000632 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100633 self.assertIsInstance(x, C)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000634 self.assertEqual(dir(x), dir(i))
Ezio Melottiaaef3442013-03-04 15:17:56 +0200635 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000636
637 def test_recursive_multi(self):
638 l = []
639 d = {1:l}
640 i = C()
641 i.attr = d
642 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000643 for proto in protocols:
644 s = self.dumps(l, proto)
645 x = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100646 self.assertIsInstance(x, list)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000647 self.assertEqual(len(x), 1)
648 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000649 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000650 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000651
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000652 def test_get(self):
653 self.assertRaises(KeyError, self.loads, b'g0\np0')
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100654 self.assert_is_copy([(100,), (100,)],
655 self.loads(b'((Kdtp0\nh\x00l.))'))
Jeremy Hylton66426532001-10-15 21:38:56 +0000656
Walter Dörwald9b775532007-06-08 14:30:53 +0000657 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000658 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +0000659 '<\\>', '<\\\U00012345>',
660 # surrogates
661 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000662 for proto in protocols:
663 for u in endcases:
664 p = self.dumps(u, proto)
665 u2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100666 self.assert_is_copy(u, u2)
Tim Peterse089c682001-04-10 03:41:41 +0000667
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000668 def test_unicode_high_plane(self):
669 t = '\U00012345'
670 for proto in protocols:
671 p = self.dumps(t, proto)
672 t2 = self.loads(p)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100673 self.assert_is_copy(t, t2)
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000674
Guido van Rossumf4169812008-03-17 22:56:06 +0000675 def test_bytes(self):
676 for proto in protocols:
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500677 for s in b'', b'xyz', b'xyz'*100:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200678 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100679 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500680 for s in [bytes([i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200681 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100682 self.assert_is_copy(s, self.loads(p))
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500683 for s in [bytes([i, i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200684 p = self.dumps(s, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100685 self.assert_is_copy(s, self.loads(p))
Guido van Rossumf4169812008-03-17 22:56:06 +0000686
Jeremy Hylton66426532001-10-15 21:38:56 +0000687 def test_ints(self):
688 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000689 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000690 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000691 while n:
692 for expected in (-n, n):
693 s = self.dumps(expected, proto)
694 n2 = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100695 self.assert_is_copy(expected, n2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000696 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000697
Jeremy Hylton66426532001-10-15 21:38:56 +0000698 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000699 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000700 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000701 got = self.loads(data)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100702 self.assert_is_copy(maxint64, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000703
704 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000705 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000706 self.assertRaises(ValueError, self.loads, data)
707
Tim Petersee1a53c2003-02-02 02:57:53 +0000708 def test_long(self):
709 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000710 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000711 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000712 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000713 for npos in nbase-1, nbase, nbase+1:
714 for n in npos, -npos:
715 pickle = self.dumps(n, proto)
716 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100717 self.assert_is_copy(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +0000718 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
719 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000720 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000721 nbase += nbase << 1000000
722 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000723 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000724 got = self.loads(p)
Antoine Pitroud5df1942013-11-23 21:20:49 +0100725 # assert_is_copy is very expensive here as it precomputes
726 # a failure message by computing the repr() of n and got,
727 # we just do the check ourselves.
728 self.assertIs(type(got), int)
729 self.assertEqual(n, got)
Tim Petersee1a53c2003-02-02 02:57:53 +0000730
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000731 def test_float(self):
732 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
733 3.14, 263.44582062374053, 6.022e23, 1e30]
734 test_values = test_values + [-x for x in test_values]
735 for proto in protocols:
736 for value in test_values:
737 pickle = self.dumps(value, proto)
738 got = self.loads(pickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100739 self.assert_is_copy(value, got)
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000740
Thomas Wouters477c8d52006-05-27 19:21:47 +0000741 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
742 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000743 # make sure that floats are formatted locale independent with proto 0
744 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000745
Jeremy Hylton66426532001-10-15 21:38:56 +0000746 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000747 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000748
749 def test_getinitargs(self):
750 pass
751
Antoine Pitrou79035bd2012-06-26 23:04:48 +0200752 def test_pop_empty_stack(self):
753 # Test issue7455
754 s = b'0'
755 self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s)
756
Guido van Rossum04a86612001-12-19 16:58:54 +0000757 def test_metaclass(self):
758 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000759 for proto in protocols:
760 s = self.dumps(a, proto)
761 b = self.loads(s)
762 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000763
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200764 def test_dynamic_class(self):
765 a = create_dynamic_class("my_dynamic_class", (object,))
766 copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
767 for proto in protocols:
768 s = self.dumps(a, proto)
769 b = self.loads(s)
770 self.assertEqual(a, b)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100771 self.assertIs(type(a), type(b))
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200772
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000773 def test_structseq(self):
774 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000775 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000776
777 t = time.localtime()
778 for proto in protocols:
779 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000780 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100781 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000782 if hasattr(os, "stat"):
783 t = os.stat(os.curdir)
784 s = self.dumps(t, proto)
785 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100786 self.assert_is_copy(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000787 if hasattr(os, "statvfs"):
788 t = os.statvfs(os.curdir)
789 s = self.dumps(t, proto)
790 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100791 self.assert_is_copy(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000792
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100793 def test_ellipsis(self):
794 for proto in protocols:
795 s = self.dumps(..., proto)
796 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100797 self.assertIs(..., u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100798
799 def test_notimplemented(self):
800 for proto in protocols:
801 s = self.dumps(NotImplemented, proto)
802 u = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100803 self.assertIs(NotImplemented, u)
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100804
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000805 # Tests for protocol 2
806
Tim Peters4190fb82003-02-02 16:09:05 +0000807 def test_proto(self):
Tim Peters4190fb82003-02-02 16:09:05 +0000808 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100809 pickled = self.dumps(None, proto)
Tim Peters4190fb82003-02-02 16:09:05 +0000810 if proto >= 2:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100811 proto_header = pickle.PROTO + bytes([proto])
812 self.assertTrue(pickled.startswith(proto_header))
813 else:
814 self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)
Tim Peters4190fb82003-02-02 16:09:05 +0000815
816 oob = protocols[-1] + 1 # a future protocol
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100817 build_none = pickle.NONE + pickle.STOP
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000818 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000819 try:
820 self.loads(badpickle)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100821 except ValueError as err:
822 self.assertIn("unsupported pickle protocol", str(err))
Tim Peters4190fb82003-02-02 16:09:05 +0000823 else:
824 self.fail("expected bad protocol number to raise ValueError")
825
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000826 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000827 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000828 for proto in protocols:
829 s = self.dumps(x, proto)
830 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100831 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000832 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000833
834 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000835 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000836 for proto in protocols:
837 s = self.dumps(x, proto)
838 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100839 self.assert_is_copy(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000840 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000841
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000842 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000843 # Map (proto, len(tuple)) to expected opcode.
844 expected_opcode = {(0, 0): pickle.TUPLE,
845 (0, 1): pickle.TUPLE,
846 (0, 2): pickle.TUPLE,
847 (0, 3): pickle.TUPLE,
848 (0, 4): pickle.TUPLE,
849
850 (1, 0): pickle.EMPTY_TUPLE,
851 (1, 1): pickle.TUPLE,
852 (1, 2): pickle.TUPLE,
853 (1, 3): pickle.TUPLE,
854 (1, 4): pickle.TUPLE,
855
856 (2, 0): pickle.EMPTY_TUPLE,
857 (2, 1): pickle.TUPLE1,
858 (2, 2): pickle.TUPLE2,
859 (2, 3): pickle.TUPLE3,
860 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000861
862 (3, 0): pickle.EMPTY_TUPLE,
863 (3, 1): pickle.TUPLE1,
864 (3, 2): pickle.TUPLE2,
865 (3, 3): pickle.TUPLE3,
866 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000867 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000868 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000869 b = (1,)
870 c = (1, 2)
871 d = (1, 2, 3)
872 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000873 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000874 for x in a, b, c, d, e:
875 s = self.dumps(x, proto)
876 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100877 self.assert_is_copy(x, y)
878 expected = expected_opcode[min(proto, 3), len(x)]
879 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000880
Guido van Rossum7d97d312003-01-28 04:25:27 +0000881 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000882 # Map (proto, singleton) to expected opcode.
883 expected_opcode = {(0, None): pickle.NONE,
884 (1, None): pickle.NONE,
885 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000886 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000887
888 (0, True): pickle.INT,
889 (1, True): pickle.INT,
890 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000891 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000892
893 (0, False): pickle.INT,
894 (1, False): pickle.INT,
895 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000896 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000897 }
Tim Peters4190fb82003-02-02 16:09:05 +0000898 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000899 for x in None, False, True:
900 s = self.dumps(x, proto)
901 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000902 self.assertTrue(x is y, (proto, x, s, y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100903 expected = expected_opcode[min(proto, 3), x]
904 self.assertTrue(opcode_in_pickle(expected, s))
Tim Peters3c67d792003-02-02 17:59:11 +0000905
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000906 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000907 x = MyTuple([1, 2, 3])
908 x.foo = 42
909 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000910 for proto in protocols:
911 s = self.dumps(x, proto)
912 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100913 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000914
915 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000916 x = MyList([1, 2, 3])
917 x.foo = 42
918 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000919 for proto in protocols:
920 s = self.dumps(x, proto)
921 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100922 self.assert_is_copy(x, y)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000923
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000924 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +0000925 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000926 for C in myclasses:
927 B = C.__base__
928 x = C(C.sample)
929 x.foo = 42
930 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000931 y = self.loads(s)
932 detail = (proto, C, B, x, y, type(y))
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100933 self.assert_is_copy(x, y) # XXX revisit
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000934 self.assertEqual(B(x), B(y), detail)
935 self.assertEqual(x.__dict__, y.__dict__, detail)
936
Antoine Pitrou16c4ce12011-03-11 21:30:43 +0100937 def test_newobj_proxies(self):
938 # NEWOBJ should use the __class__ rather than the raw type
939 classes = myclasses[:]
940 # Cannot create weakproxies to these classes
941 for c in (MyInt, MyTuple):
942 classes.remove(c)
943 for proto in protocols:
944 for C in classes:
945 B = C.__base__
946 x = C(C.sample)
947 x.foo = 42
948 p = weakref.proxy(x)
949 s = self.dumps(p, proto)
950 y = self.loads(s)
951 self.assertEqual(type(y), type(x)) # rather than type(p)
952 detail = (proto, C, B, x, y, type(y))
953 self.assertEqual(B(x), B(y), detail)
954 self.assertEqual(x.__dict__, y.__dict__, detail)
955
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000956 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +0000957 # an object of that type. Check that the resulting pickle uses opcode
958 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +0000959
Tim Peters22e71712003-02-03 22:27:38 +0000960 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +0000961 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000962 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000963 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000964 x = MyList([1, 2, 3])
965 x.foo = 42
966 x.bar = "hello"
967
Tim Peters22e71712003-02-03 22:27:38 +0000968 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000969 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000970 self.assertIn(__name__.encode("utf-8"), s1)
971 self.assertIn(b"MyList", s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100972 self.assertFalse(opcode_in_pickle(opcode, s1))
Tim Peters3e667d52003-02-04 21:47:44 +0000973
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000974 y = self.loads(s1)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100975 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000976
Tim Peters22e71712003-02-03 22:27:38 +0000977 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000978 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000979 self.assertNotIn(__name__.encode("utf-8"), s2)
980 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000981 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +0000982
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000983 y = self.loads(s2)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +0100984 self.assert_is_copy(x, y)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000985 finally:
Tim Peters3e667d52003-02-04 21:47:44 +0000986 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +0000987
988 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000989 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
990 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000991
992 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000993 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
994 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
995 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000996
997 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000998 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
999 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
1000 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
1001
Tim Peters8d2613a2003-02-11 16:40:16 +00001002 def test_list_chunking(self):
1003 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +00001004 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001005 for proto in protocols:
1006 s = self.dumps(x, proto)
1007 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001008 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001009 num_appends = count_opcode(pickle.APPENDS, s)
1010 self.assertEqual(num_appends, proto > 0)
1011
1012 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001013 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +00001014 for proto in protocols:
1015 s = self.dumps(x, proto)
1016 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001017 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001018 num_appends = count_opcode(pickle.APPENDS, s)
1019 if proto == 0:
1020 self.assertEqual(num_appends, 0)
1021 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001022 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +00001023
1024 def test_dict_chunking(self):
1025 n = 10 # too small to chunk
1026 x = dict.fromkeys(range(n))
1027 for proto in protocols:
1028 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +00001029 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00001030 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001031 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001032 num_setitems = count_opcode(pickle.SETITEMS, s)
1033 self.assertEqual(num_setitems, proto > 0)
1034
1035 n = 2500 # expect at least two chunks when proto > 0
1036 x = dict.fromkeys(range(n))
1037 for proto in protocols:
1038 s = self.dumps(x, proto)
1039 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001040 self.assert_is_copy(x, y)
Tim Peters8d2613a2003-02-11 16:40:16 +00001041 num_setitems = count_opcode(pickle.SETITEMS, s)
1042 if proto == 0:
1043 self.assertEqual(num_setitems, 0)
1044 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001045 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001046
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001047 def test_set_chunking(self):
1048 n = 10 # too small to chunk
1049 x = set(range(n))
1050 for proto in protocols:
1051 s = self.dumps(x, proto)
1052 y = self.loads(s)
1053 self.assert_is_copy(x, y)
1054 num_additems = count_opcode(pickle.ADDITEMS, s)
1055 if proto < 4:
1056 self.assertEqual(num_additems, 0)
1057 else:
1058 self.assertEqual(num_additems, 1)
1059
1060 n = 2500 # expect at least two chunks when proto >= 4
1061 x = set(range(n))
1062 for proto in protocols:
1063 s = self.dumps(x, proto)
1064 y = self.loads(s)
1065 self.assert_is_copy(x, y)
1066 num_additems = count_opcode(pickle.ADDITEMS, s)
1067 if proto < 4:
1068 self.assertEqual(num_additems, 0)
1069 else:
1070 self.assertGreaterEqual(num_additems, 2)
1071
Tim Peterse9ef2032003-02-13 18:42:00 +00001072 def test_simple_newobj(self):
1073 x = object.__new__(SimpleNewObj) # avoid __init__
1074 x.abc = 666
1075 for proto in protocols:
1076 s = self.dumps(x, proto)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001077 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
1078 2 <= proto < 4)
1079 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
1080 proto >= 4)
Tim Peterse9ef2032003-02-13 18:42:00 +00001081 y = self.loads(s) # will raise TypeError if __init__ called
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001082 self.assert_is_copy(x, y)
Tim Peterse9ef2032003-02-13 18:42:00 +00001083
Tim Peters42f08ac2003-02-11 22:43:24 +00001084 def test_newobj_list_slots(self):
1085 x = SlotList([1, 2, 3])
1086 x.foo = 42
1087 x.bar = "hello"
1088 s = self.dumps(x, 2)
1089 y = self.loads(s)
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001090 self.assert_is_copy(x, y)
Tim Peters42f08ac2003-02-11 22:43:24 +00001091
Guido van Rossum2a30b212003-02-18 22:41:24 +00001092 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001093 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001094 x = REX_one()
1095 self.assertEqual(x._reduce_called, 0)
1096 s = self.dumps(x, proto)
1097 self.assertEqual(x._reduce_called, 1)
1098 y = self.loads(s)
1099 self.assertEqual(y._reduce_called, 0)
1100
1101 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001102 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001103 x = REX_two()
1104 self.assertEqual(x._proto, None)
1105 s = self.dumps(x, proto)
1106 self.assertEqual(x._proto, proto)
1107 y = self.loads(s)
1108 self.assertEqual(y._proto, None)
1109
1110 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001111 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001112 x = REX_three()
1113 self.assertEqual(x._proto, None)
1114 s = self.dumps(x, proto)
1115 self.assertEqual(x._proto, proto)
1116 y = self.loads(s)
1117 self.assertEqual(y._proto, None)
1118
Guido van Rossumd8faa362007-04-27 19:54:29 +00001119 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001120 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001121 x = REX_four()
1122 self.assertEqual(x._proto, None)
1123 s = self.dumps(x, proto)
1124 self.assertEqual(x._proto, proto)
1125 y = self.loads(s)
1126 self.assertEqual(y._proto, proto)
1127
1128 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001129 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001130 x = REX_five()
1131 self.assertEqual(x._reduce_called, 0)
1132 s = self.dumps(x, proto)
1133 self.assertEqual(x._reduce_called, 1)
1134 y = self.loads(s)
1135 self.assertEqual(y._reduce_called, 1)
1136
Brett Cannon31f59292011-02-21 19:29:56 +00001137 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001138 def test_bad_getattr(self):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001139 # Issue #3514: crash when there is an infinite loop in __getattr__
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001140 x = BadGetattr()
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001141 for proto in protocols:
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001142 self.assertRaises(RuntimeError, self.dumps, x, proto)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001143
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001144 def test_reduce_bad_iterator(self):
1145 # Issue4176: crash when 4th and 5th items of __reduce__()
1146 # are not iterators
1147 class C(object):
1148 def __reduce__(self):
1149 # 4th item is not an iterator
1150 return list, (), None, [], None
1151 class D(object):
1152 def __reduce__(self):
1153 # 5th item is not an iterator
1154 return dict, (), None, None, []
1155
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001156 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001157 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001158 try:
1159 self.dumps(C(), proto)
1160 except (pickle.PickleError):
1161 pass
1162 try:
1163 self.dumps(D(), proto)
1164 except (pickle.PickleError):
1165 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001166
Collin Winter771d8342009-04-16 03:18:06 +00001167 def test_many_puts_and_gets(self):
1168 # Test that internal data structures correctly deal with lots of
1169 # puts/gets.
1170 keys = ("aaa" + str(i) for i in range(100))
1171 large_dict = dict((k, [4, 5, 6]) for k in keys)
1172 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1173
1174 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001175 with self.subTest(proto=proto):
1176 dumped = self.dumps(obj, proto)
1177 loaded = self.loads(dumped)
1178 self.assert_is_copy(obj, loaded)
Collin Winter771d8342009-04-16 03:18:06 +00001179
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001180 def test_attribute_name_interning(self):
1181 # Test that attribute names of pickled objects are interned when
1182 # unpickling.
1183 for proto in protocols:
1184 x = C()
1185 x.foo = 42
1186 x.bar = "hello"
1187 s = self.dumps(x, proto)
1188 y = self.loads(s)
1189 x_keys = sorted(x.__dict__)
1190 y_keys = sorted(y.__dict__)
1191 for x_key, y_key in zip(x_keys, y_keys):
1192 self.assertIs(x_key, y_key)
1193
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001194 def test_unpickle_from_2x(self):
1195 # Unpickle non-trivial data from Python 2.x.
1196 loaded = self.loads(DATA3)
1197 self.assertEqual(loaded, set([1, 2]))
1198 loaded = self.loads(DATA4)
1199 self.assertEqual(type(loaded), type(range(0)))
1200 self.assertEqual(list(loaded), list(range(5)))
1201 loaded = self.loads(DATA5)
1202 self.assertEqual(type(loaded), SimpleCookie)
1203 self.assertEqual(list(loaded.keys()), ["key"])
1204 self.assertEqual(loaded["key"].value, "Set-Cookie: key=value")
1205
1206 def test_pickle_to_2x(self):
1207 # Pickle non-trivial data with protocol 2, expecting that it yields
1208 # the same result as Python 2.x did.
1209 # NOTE: this test is a bit too strong since we can produce different
1210 # bytecode that 2.x will still understand.
1211 dumped = self.dumps(range(5), 2)
1212 self.assertEqual(dumped, DATA4)
1213 dumped = self.dumps(set([3]), 2)
1214 self.assertEqual(dumped, DATA6)
1215
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001216 def test_large_pickles(self):
1217 # Test the correctness of internal buffering routines when handling
1218 # large data.
1219 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001220 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001221 dumped = self.dumps(data, proto)
1222 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001223 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001224 self.assertEqual(loaded, data)
1225
Alexander Belopolsky1ce92dc2011-02-24 19:40:09 +00001226 def test_empty_bytestring(self):
1227 # issue 11286
1228 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1229 self.assertEqual(empty, '')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001230
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001231 def test_int_pickling_efficiency(self):
1232 # Test compacity of int representation (see issue #12744)
1233 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001234 with self.subTest(proto=proto):
1235 pickles = [self.dumps(2**n, proto) for n in range(70)]
1236 sizes = list(map(len, pickles))
1237 # the size function is monotonic
1238 self.assertEqual(sorted(sizes), sizes)
1239 if proto >= 2:
1240 for p in pickles:
1241 self.assertFalse(opcode_in_pickle(pickle.LONG, p))
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001242
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001243 def check_negative_32b_binXXX(self, dumped):
1244 if sys.maxsize > 2**32:
1245 self.skipTest("test is only meaningful on 32-bit builds")
1246 # XXX Pure Python pickle reads lengths as signed and passes
1247 # them directly to read() (hence the EOFError)
1248 with self.assertRaises((pickle.UnpicklingError, EOFError,
1249 ValueError, OverflowError)):
1250 self.loads(dumped)
1251
1252 def test_negative_32b_binbytes(self):
1253 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1254 self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.')
1255
1256 def test_negative_32b_binunicode(self):
1257 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1258 self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.')
1259
Antoine Pitrou55549ec2011-08-30 00:27:10 +02001260 def test_negative_put(self):
1261 # Issue #12847
1262 dumped = b'Va\np-1\n.'
1263 self.assertRaises(ValueError, self.loads, dumped)
1264
1265 def test_negative_32b_binput(self):
1266 # Issue #12847
1267 if sys.maxsize > 2**32:
1268 self.skipTest("test is only meaningful on 32-bit builds")
1269 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
1270 self.assertRaises(ValueError, self.loads, dumped)
1271
Alexandre Vassalotti7c5e0942013-04-15 23:14:55 -07001272 def test_badly_escaped_string(self):
1273 self.assertRaises(ValueError, self.loads, b"S'\\'\n.")
1274
1275 def test_badly_quoted_string(self):
1276 # Issue #17710
1277 badpickles = [b"S'\n.",
1278 b'S"\n.',
1279 b'S\' \n.',
1280 b'S" \n.',
1281 b'S\'"\n.',
1282 b'S"\'\n.',
1283 b"S' ' \n.",
1284 b'S" " \n.',
1285 b"S ''\n.",
1286 b'S ""\n.',
1287 b'S \n.',
1288 b'S\n.',
1289 b'S.']
1290 for p in badpickles:
1291 self.assertRaises(pickle.UnpicklingError, self.loads, p)
1292
1293 def test_correctly_quoted_string(self):
1294 goodpickles = [(b"S''\n.", ''),
1295 (b'S""\n.', ''),
1296 (b'S"\\n"\n.', '\n'),
1297 (b"S'\\n'\n.", '\n')]
1298 for p, expected in goodpickles:
1299 self.assertEqual(self.loads(p), expected)
1300
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001301 def _check_pickling_with_opcode(self, obj, opcode, proto):
1302 pickled = self.dumps(obj, proto)
1303 self.assertTrue(opcode_in_pickle(opcode, pickled))
1304 unpickled = self.loads(pickled)
1305 self.assertEqual(obj, unpickled)
1306
1307 def test_appends_on_non_lists(self):
1308 # Issue #17720
1309 obj = REX_six([1, 2, 3])
1310 for proto in protocols:
1311 if proto == 0:
1312 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1313 else:
1314 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1315
1316 def test_setitems_on_non_dicts(self):
1317 obj = REX_seven({1: -1, 2: -2, 3: -3})
1318 for proto in protocols:
1319 if proto == 0:
1320 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1321 else:
1322 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1323
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001324 # Exercise framing (proto >= 4) for significant workloads
1325
1326 FRAME_SIZE_TARGET = 64 * 1024
1327
1328 def test_framing_many_objects(self):
1329 obj = list(range(10**5))
1330 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1331 with self.subTest(proto=proto):
1332 pickled = self.dumps(obj, proto)
1333 unpickled = self.loads(pickled)
1334 self.assertEqual(obj, unpickled)
1335 # Test the framing heuristic is sane,
1336 # assuming a given frame size target.
1337 bytes_per_frame = (len(pickled) /
1338 pickled.count(b'\x00\x00\x00\x00\x00'))
1339 self.assertGreater(bytes_per_frame,
1340 self.FRAME_SIZE_TARGET / 2)
1341 self.assertLessEqual(bytes_per_frame,
1342 self.FRAME_SIZE_TARGET * 1)
1343
1344 def test_framing_large_objects(self):
1345 N = 1024 * 1024
1346 obj = [b'x' * N, b'y' * N, b'z' * N]
1347 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1348 with self.subTest(proto=proto):
1349 pickled = self.dumps(obj, proto)
1350 unpickled = self.loads(pickled)
1351 self.assertEqual(obj, unpickled)
1352 # At least one frame was emitted per large bytes object.
1353 n_frames = pickled.count(b'\x00\x00\x00\x00\x00')
1354 self.assertGreaterEqual(n_frames, len(obj))
1355
1356 def test_nested_names(self):
1357 global Nested
1358 class Nested:
1359 class A:
1360 class B:
1361 class C:
1362 pass
1363
1364 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1365 for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
1366 with self.subTest(proto=proto, obj=obj):
1367 unpickled = self.loads(self.dumps(obj, proto))
1368 self.assertIs(obj, unpickled)
1369
1370 def test_py_methods(self):
1371 global PyMethodsTest
1372 class PyMethodsTest:
1373 @staticmethod
1374 def cheese():
1375 return "cheese"
1376 @classmethod
1377 def wine(cls):
1378 assert cls is PyMethodsTest
1379 return "wine"
1380 def biscuits(self):
1381 assert isinstance(self, PyMethodsTest)
1382 return "biscuits"
1383 class Nested:
1384 "Nested class"
1385 @staticmethod
1386 def ketchup():
1387 return "ketchup"
1388 @classmethod
1389 def maple(cls):
1390 assert cls is PyMethodsTest.Nested
1391 return "maple"
1392 def pie(self):
1393 assert isinstance(self, PyMethodsTest.Nested)
1394 return "pie"
1395
1396 py_methods = (
1397 PyMethodsTest.cheese,
1398 PyMethodsTest.wine,
1399 PyMethodsTest().biscuits,
1400 PyMethodsTest.Nested.ketchup,
1401 PyMethodsTest.Nested.maple,
1402 PyMethodsTest.Nested().pie
1403 )
1404 py_unbound_methods = (
1405 (PyMethodsTest.biscuits, PyMethodsTest),
1406 (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
1407 )
1408 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1409 for method in py_methods:
1410 with self.subTest(proto=proto, method=method):
1411 unpickled = self.loads(self.dumps(method, proto))
1412 self.assertEqual(method(), unpickled())
1413 for method, cls in py_unbound_methods:
1414 obj = cls()
1415 with self.subTest(proto=proto, method=method):
1416 unpickled = self.loads(self.dumps(method, proto))
1417 self.assertEqual(method(obj), unpickled(obj))
1418
1419
1420 def test_c_methods(self):
1421 global Subclass
1422 class Subclass(tuple):
1423 class Nested(str):
1424 pass
1425
1426 c_methods = (
1427 # bound built-in method
1428 ("abcd".index, ("c",)),
1429 # unbound built-in method
1430 (str.index, ("abcd", "c")),
1431 # bound "slot" method
1432 ([1, 2, 3].__len__, ()),
1433 # unbound "slot" method
1434 (list.__len__, ([1, 2, 3],)),
1435 # bound "coexist" method
1436 ({1, 2}.__contains__, (2,)),
1437 # unbound "coexist" method
1438 (set.__contains__, ({1, 2}, 2)),
1439 # built-in class method
1440 (dict.fromkeys, (("a", 1), ("b", 2))),
1441 # built-in static method
1442 (bytearray.maketrans, (b"abc", b"xyz")),
1443 # subclass methods
1444 (Subclass([1,2,2]).count, (2,)),
1445 (Subclass.count, (Subclass([1,2,2]), 2)),
1446 (Subclass.Nested("sweet").count, ("e",)),
1447 (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
1448 )
1449 for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
1450 for method, args in c_methods:
1451 with self.subTest(proto=proto, method=method):
1452 unpickled = self.loads(self.dumps(method, proto))
1453 self.assertEqual(method(*args), unpickled(*args))
1454
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001455
1456class BigmemPickleTests(unittest.TestCase):
1457
1458 # Binary protocols can serialize longs of up to 2GB-1
1459
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001460 @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001461 def test_huge_long_32b(self, size):
1462 data = 1 << (8 * size)
1463 try:
1464 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001465 with self.subTest(proto=proto):
1466 if proto < 2:
1467 continue
1468 with self.assertRaises((ValueError, OverflowError)):
1469 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001470 finally:
1471 data = None
1472
1473 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1474 # (older protocols don't have a dedicated opcode for bytes and are
1475 # too inefficient)
1476
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001477 @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001478 def test_huge_bytes_32b(self, size):
1479 data = b"abcd" * (size // 4)
1480 try:
1481 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001482 with self.subTest(proto=proto):
1483 if proto < 3:
1484 continue
1485 try:
1486 pickled = self.dumps(data, protocol=proto)
1487 self.assertTrue(b"abcd" in pickled[:19])
1488 self.assertTrue(b"abcd" in pickled[-18:])
1489 finally:
1490 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001491 finally:
1492 data = None
1493
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001494 @bigmemtest(size=_4G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001495 def test_huge_bytes_64b(self, size):
1496 data = b"a" * size
1497 try:
1498 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001499 with self.subTest(proto=proto):
1500 if proto < 3:
1501 continue
1502 with self.assertRaises((ValueError, OverflowError)):
1503 self.dumps(data, protocol=proto)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001504 finally:
1505 data = None
1506
1507 # All protocols use 1-byte per printable ASCII character; we add another
1508 # byte because the encoded form has to be copied into the internal buffer.
1509
Antoine Pitroub7591d42011-10-04 16:18:15 +02001510 @bigmemtest(size=_2G, memuse=2 + ascii_char_size, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001511 def test_huge_str_32b(self, size):
1512 data = "abcd" * (size // 4)
1513 try:
1514 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001515 with self.subTest(proto=proto):
1516 try:
1517 pickled = self.dumps(data, protocol=proto)
1518 self.assertTrue(b"abcd" in pickled[:19])
1519 self.assertTrue(b"abcd" in pickled[-18:])
1520 finally:
1521 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001522 finally:
1523 data = None
1524
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001525 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
1526 # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
1527 # unicode strings however.
Antoine Pitroue897e952011-08-30 23:39:34 +02001528
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001529 @bigmemtest(size=_4G, memuse=2 + ascii_char_size, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001530 def test_huge_str_64b(self, size):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001531 data = "abcd" * (size // 4)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001532 try:
1533 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001534 with self.subTest(proto=proto):
1535 if proto == 0:
1536 continue
1537 if proto < 4:
1538 with self.assertRaises((ValueError, OverflowError)):
1539 self.dumps(data, protocol=proto)
1540 else:
1541 try:
1542 pickled = self.dumps(data, protocol=proto)
1543 self.assertTrue(b"abcd" in pickled[:19])
1544 self.assertTrue(b"abcd" in pickled[-18:])
1545 finally:
1546 pickled = None
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001547 finally:
1548 data = None
1549
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001550
Guido van Rossum2a30b212003-02-18 22:41:24 +00001551# Test classes for reduce_ex
1552
1553class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001554 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001555 _reduce_called = 0
1556 def __reduce__(self):
1557 self._reduce_called = 1
1558 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001559
1560class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001561 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001562 _proto = None
1563 def __reduce_ex__(self, proto):
1564 self._proto = proto
1565 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001566
1567class REX_three(object):
1568 _proto = None
1569 def __reduce_ex__(self, proto):
1570 self._proto = proto
1571 return REX_two, ()
1572 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001573 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001574
Guido van Rossumd8faa362007-04-27 19:54:29 +00001575class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001576 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001577 _proto = None
1578 def __reduce_ex__(self, proto):
1579 self._proto = proto
1580 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001581
1582class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001583 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001584 _reduce_called = 0
1585 def __reduce__(self):
1586 self._reduce_called = 1
1587 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001588
1589class REX_six(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001590 """This class is used to check the 4th argument (list iterator) of
1591 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001592 """
1593 def __init__(self, items=None):
1594 self.items = items if items is not None else []
1595 def __eq__(self, other):
1596 return type(self) is type(other) and self.items == self.items
1597 def append(self, item):
1598 self.items.append(item)
1599 def __reduce__(self):
1600 return type(self), (), None, iter(self.items), None
1601
1602class REX_seven(object):
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001603 """This class is used to check the 5th argument (dict iterator) of
1604 the reduce protocol.
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001605 """
1606 def __init__(self, table=None):
1607 self.table = table if table is not None else {}
1608 def __eq__(self, other):
1609 return type(self) is type(other) and self.table == self.table
1610 def __setitem__(self, key, value):
1611 self.table[key] = value
1612 def __reduce__(self):
1613 return type(self), (), None, None, iter(self.table.items())
1614
Guido van Rossumd8faa362007-04-27 19:54:29 +00001615
Guido van Rossum2a30b212003-02-18 22:41:24 +00001616# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001617
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001618class MyInt(int):
1619 sample = 1
1620
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001621class MyFloat(float):
1622 sample = 1.0
1623
1624class MyComplex(complex):
1625 sample = 1.0 + 0.0j
1626
1627class MyStr(str):
1628 sample = "hello"
1629
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001630class MyUnicode(str):
1631 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001632
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001633class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001634 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001635
1636class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001637 sample = [1, 2, 3]
1638
1639class MyDict(dict):
1640 sample = {"a": 1, "b": 2}
1641
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001642class MySet(set):
1643 sample = {"a", "b"}
1644
1645class MyFrozenSet(frozenset):
1646 sample = frozenset({"a", "b"})
1647
Mark Dickinson5c2db372009-12-05 20:28:34 +00001648myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001649 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001650 MyStr, MyUnicode,
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001651 MyTuple, MyList, MyDict, MySet, MyFrozenSet]
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001652
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001653
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001654class SlotList(MyList):
1655 __slots__ = ["foo"]
1656
Tim Peterse9ef2032003-02-13 18:42:00 +00001657class SimpleNewObj(object):
1658 def __init__(self, a, b, c):
1659 # raise an error, to make sure this isn't called
1660 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001661 def __eq__(self, other):
1662 return self.__dict__ == other.__dict__
Tim Peterse9ef2032003-02-13 18:42:00 +00001663
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001664class BadGetattr:
1665 def __getattr__(self, key):
1666 self.foo
1667
Collin Winter771d8342009-04-16 03:18:06 +00001668
Jeremy Hylton66426532001-10-15 21:38:56 +00001669class AbstractPickleModuleTests(unittest.TestCase):
1670
1671 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001672 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001673 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001674 try:
1675 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001676 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001677 finally:
1678 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001679
1680 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001681 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001682 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001683 try:
1684 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001685 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001686 finally:
1687 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001688
Collin Winter771d8342009-04-16 03:18:06 +00001689 def test_load_from_and_dump_to_file(self):
1690 stream = io.BytesIO()
1691 data = [123, {}, 124]
1692 pickle.dump(data, stream)
1693 stream.seek(0)
1694 unpickled = pickle.load(stream)
1695 self.assertEqual(unpickled, data)
1696
Tim Petersc0c93702003-02-13 19:30:57 +00001697 def test_highest_protocol(self):
1698 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001699 self.assertEqual(pickle.HIGHEST_PROTOCOL, 4)
Tim Petersc0c93702003-02-13 19:30:57 +00001700
Martin v. Löwis544f1192004-07-27 05:22:33 +00001701 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001702 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001703 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001704 pickle.dump(123, f, -1)
1705 pickle.dump(123, file=f, protocol=-1)
1706 pickle.dumps(123, -1)
1707 pickle.dumps(123, protocol=-1)
1708 pickle.Pickler(f, -1)
1709 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001710
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001711 def test_bad_init(self):
1712 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001713 # Override initialization without calling __init__() of the superclass.
1714 class BadPickler(pickle.Pickler):
1715 def __init__(self): pass
1716
1717 class BadUnpickler(pickle.Unpickler):
1718 def __init__(self): pass
1719
1720 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1721 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1722
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001723 def test_bad_input(self):
1724 # Test issue4298
1725 s = bytes([0x58, 0, 0, 0, 0x54])
1726 self.assertRaises(EOFError, pickle.loads, s)
1727
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001728
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001729class AbstractPersistentPicklerTests(unittest.TestCase):
1730
1731 # This class defines persistent_id() and persistent_load()
1732 # functions that should be used by the pickler. All even integers
1733 # are pickled using persistent ids.
1734
1735 def persistent_id(self, object):
1736 if isinstance(object, int) and object % 2 == 0:
1737 self.id_count += 1
1738 return str(object)
1739 else:
1740 return None
1741
1742 def persistent_load(self, oid):
1743 self.load_count += 1
1744 object = int(oid)
1745 assert object % 2 == 0
1746 return object
1747
1748 def test_persistence(self):
1749 self.id_count = 0
1750 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001751 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001752 self.assertEqual(self.loads(self.dumps(L)), L)
1753 self.assertEqual(self.id_count, 5)
1754 self.assertEqual(self.load_count, 5)
1755
1756 def test_bin_persistence(self):
1757 self.id_count = 0
1758 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001759 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001760 self.assertEqual(self.loads(self.dumps(L, 1)), L)
1761 self.assertEqual(self.id_count, 5)
1762 self.assertEqual(self.load_count, 5)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001763
Collin Winter771d8342009-04-16 03:18:06 +00001764
1765class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1766
1767 pickler_class = None
1768 unpickler_class = None
1769
1770 def setUp(self):
1771 assert self.pickler_class
1772 assert self.unpickler_class
1773
1774 def test_clear_pickler_memo(self):
1775 # To test whether clear_memo() has any effect, we pickle an object,
1776 # then pickle it again without clearing the memo; the two serialized
1777 # forms should be different. If we clear_memo() and then pickle the
1778 # object again, the third serialized form should be identical to the
1779 # first one we obtained.
1780 data = ["abcdefg", "abcdefg", 44]
1781 f = io.BytesIO()
1782 pickler = self.pickler_class(f)
1783
1784 pickler.dump(data)
1785 first_pickled = f.getvalue()
1786
Serhiy Storchaka50254c52013-08-29 11:35:43 +03001787 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00001788 f.seek(0)
1789 f.truncate()
1790
1791 pickler.dump(data)
1792 second_pickled = f.getvalue()
1793
Serhiy Storchaka50254c52013-08-29 11:35:43 +03001794 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00001795 pickler.clear_memo()
1796 f.seek(0)
1797 f.truncate()
1798
1799 pickler.dump(data)
1800 third_pickled = f.getvalue()
1801
1802 self.assertNotEqual(first_pickled, second_pickled)
1803 self.assertEqual(first_pickled, third_pickled)
1804
1805 def test_priming_pickler_memo(self):
1806 # Verify that we can set the Pickler's memo attribute.
1807 data = ["abcdefg", "abcdefg", 44]
1808 f = io.BytesIO()
1809 pickler = self.pickler_class(f)
1810
1811 pickler.dump(data)
1812 first_pickled = f.getvalue()
1813
1814 f = io.BytesIO()
1815 primed = self.pickler_class(f)
1816 primed.memo = pickler.memo
1817
1818 primed.dump(data)
1819 primed_pickled = f.getvalue()
1820
1821 self.assertNotEqual(first_pickled, primed_pickled)
1822
1823 def test_priming_unpickler_memo(self):
1824 # Verify that we can set the Unpickler's memo attribute.
1825 data = ["abcdefg", "abcdefg", 44]
1826 f = io.BytesIO()
1827 pickler = self.pickler_class(f)
1828
1829 pickler.dump(data)
1830 first_pickled = f.getvalue()
1831
1832 f = io.BytesIO()
1833 primed = self.pickler_class(f)
1834 primed.memo = pickler.memo
1835
1836 primed.dump(data)
1837 primed_pickled = f.getvalue()
1838
1839 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
1840 unpickled_data1 = unpickler.load()
1841
1842 self.assertEqual(unpickled_data1, data)
1843
1844 primed = self.unpickler_class(io.BytesIO(primed_pickled))
1845 primed.memo = unpickler.memo
1846 unpickled_data2 = primed.load()
1847
1848 primed.memo.clear()
1849
1850 self.assertEqual(unpickled_data2, data)
1851 self.assertTrue(unpickled_data2 is unpickled_data1)
1852
1853 def test_reusing_unpickler_objects(self):
1854 data1 = ["abcdefg", "abcdefg", 44]
1855 f = io.BytesIO()
1856 pickler = self.pickler_class(f)
1857 pickler.dump(data1)
1858 pickled1 = f.getvalue()
1859
1860 data2 = ["abcdefg", 44, 44]
1861 f = io.BytesIO()
1862 pickler = self.pickler_class(f)
1863 pickler.dump(data2)
1864 pickled2 = f.getvalue()
1865
1866 f = io.BytesIO()
1867 f.write(pickled1)
1868 f.seek(0)
1869 unpickler = self.unpickler_class(f)
1870 self.assertEqual(unpickler.load(), data1)
1871
1872 f.seek(0)
1873 f.truncate()
1874 f.write(pickled2)
1875 f.seek(0)
1876 self.assertEqual(unpickler.load(), data2)
1877
Antoine Pitrou04248a82010-10-12 20:51:21 +00001878 def _check_multiple_unpicklings(self, ioclass):
1879 for proto in protocols:
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001880 with self.subTest(proto=proto):
1881 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
1882 f = ioclass()
1883 pickler = self.pickler_class(f, protocol=proto)
1884 pickler.dump(data1)
1885 pickled = f.getvalue()
Antoine Pitrou04248a82010-10-12 20:51:21 +00001886
Antoine Pitrouc9dc4a22013-11-23 18:59:12 +01001887 N = 5
1888 f = ioclass(pickled * N)
1889 unpickler = self.unpickler_class(f)
1890 for i in range(N):
1891 if f.seekable():
1892 pos = f.tell()
1893 self.assertEqual(unpickler.load(), data1)
1894 if f.seekable():
1895 self.assertEqual(f.tell(), pos + len(pickled))
1896 self.assertRaises(EOFError, unpickler.load)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001897
1898 def test_multiple_unpicklings_seekable(self):
1899 self._check_multiple_unpicklings(io.BytesIO)
1900
1901 def test_multiple_unpicklings_unseekable(self):
1902 self._check_multiple_unpicklings(UnseekableIO)
1903
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02001904 def test_unpickling_buffering_readline(self):
1905 # Issue #12687: the unpickler's buffering logic could fail with
1906 # text mode opcodes.
1907 data = list(range(10))
1908 for proto in protocols:
1909 for buf_size in range(1, 11):
1910 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
1911 pickler = self.pickler_class(f, protocol=proto)
1912 pickler.dump(data)
1913 f.seek(0)
1914 unpickler = self.unpickler_class(f)
1915 self.assertEqual(unpickler.load(), data)
1916
Collin Winter771d8342009-04-16 03:18:06 +00001917
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01001918# Tests for dispatch_table attribute
1919
1920REDUCE_A = 'reduce_A'
1921
1922class AAA(object):
1923 def __reduce__(self):
1924 return str, (REDUCE_A,)
1925
1926class BBB(object):
1927 pass
1928
1929class AbstractDispatchTableTests(unittest.TestCase):
1930
1931 def test_default_dispatch_table(self):
1932 # No dispatch_table attribute by default
1933 f = io.BytesIO()
1934 p = self.pickler_class(f, 0)
1935 with self.assertRaises(AttributeError):
1936 p.dispatch_table
1937 self.assertFalse(hasattr(p, 'dispatch_table'))
1938
1939 def test_class_dispatch_table(self):
1940 # A dispatch_table attribute can be specified class-wide
1941 dt = self.get_dispatch_table()
1942
1943 class MyPickler(self.pickler_class):
1944 dispatch_table = dt
1945
1946 def dumps(obj, protocol=None):
1947 f = io.BytesIO()
1948 p = MyPickler(f, protocol)
1949 self.assertEqual(p.dispatch_table, dt)
1950 p.dump(obj)
1951 return f.getvalue()
1952
1953 self._test_dispatch_table(dumps, dt)
1954
1955 def test_instance_dispatch_table(self):
1956 # A dispatch_table attribute can also be specified instance-wide
1957 dt = self.get_dispatch_table()
1958
1959 def dumps(obj, protocol=None):
1960 f = io.BytesIO()
1961 p = self.pickler_class(f, protocol)
1962 p.dispatch_table = dt
1963 self.assertEqual(p.dispatch_table, dt)
1964 p.dump(obj)
1965 return f.getvalue()
1966
1967 self._test_dispatch_table(dumps, dt)
1968
1969 def _test_dispatch_table(self, dumps, dispatch_table):
1970 def custom_load_dump(obj):
1971 return pickle.loads(dumps(obj, 0))
1972
1973 def default_load_dump(obj):
1974 return pickle.loads(pickle.dumps(obj, 0))
1975
1976 # pickling complex numbers using protocol 0 relies on copyreg
1977 # so check pickling a complex number still works
1978 z = 1 + 2j
1979 self.assertEqual(custom_load_dump(z), z)
1980 self.assertEqual(default_load_dump(z), z)
1981
1982 # modify pickling of complex
1983 REDUCE_1 = 'reduce_1'
1984 def reduce_1(obj):
1985 return str, (REDUCE_1,)
1986 dispatch_table[complex] = reduce_1
1987 self.assertEqual(custom_load_dump(z), REDUCE_1)
1988 self.assertEqual(default_load_dump(z), z)
1989
1990 # check picklability of AAA and BBB
1991 a = AAA()
1992 b = BBB()
1993 self.assertEqual(custom_load_dump(a), REDUCE_A)
1994 self.assertIsInstance(custom_load_dump(b), BBB)
1995 self.assertEqual(default_load_dump(a), REDUCE_A)
1996 self.assertIsInstance(default_load_dump(b), BBB)
1997
1998 # modify pickling of BBB
1999 dispatch_table[BBB] = reduce_1
2000 self.assertEqual(custom_load_dump(a), REDUCE_A)
2001 self.assertEqual(custom_load_dump(b), REDUCE_1)
2002 self.assertEqual(default_load_dump(a), REDUCE_A)
2003 self.assertIsInstance(default_load_dump(b), BBB)
2004
2005 # revert pickling of BBB and modify pickling of AAA
2006 REDUCE_2 = 'reduce_2'
2007 def reduce_2(obj):
2008 return str, (REDUCE_2,)
2009 dispatch_table[AAA] = reduce_2
2010 del dispatch_table[BBB]
2011 self.assertEqual(custom_load_dump(a), REDUCE_2)
2012 self.assertIsInstance(custom_load_dump(b), BBB)
2013 self.assertEqual(default_load_dump(a), REDUCE_A)
2014 self.assertIsInstance(default_load_dump(b), BBB)
2015
2016
Guido van Rossum98297ee2007-11-06 21:34:58 +00002017if __name__ == "__main__":
2018 # Print some stuff that can be used to rewrite DATA{0,1,2}
2019 from pickletools import dis
2020 x = create_data()
2021 for i in range(3):
2022 p = pickle.dumps(x, i)
2023 print("DATA{0} = (".format(i))
2024 for j in range(0, len(p), 20):
2025 b = bytes(p[j:j+20])
2026 print(" {0!r}".format(b))
2027 print(")")
2028 print()
2029 print("# Disassembly of DATA{0}".format(i))
2030 print("DATA{0}_DIS = \"\"\"\\".format(i))
2031 dis(p)
2032 print("\"\"\"")
2033 print()