blob: 70e5ad0fcf7978f8119aa999d25dc73101aea166 [file] [log] [blame]
Collin Winter771d8342009-04-16 03:18:06 +00001import io
Jeremy Hylton66426532001-10-15 21:38:56 +00002import unittest
Tim Peters4190fb82003-02-02 16:09:05 +00003import pickle
Tim Peters31f119e2003-02-03 16:20:13 +00004import pickletools
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00005import copyreg
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00006from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +00007
Benjamin Petersonee8712c2008-05-20 21:35:26 +00008from test.support import TestFailed, TESTFN, run_with_locale
Tim Peterse089c682001-04-10 03:41:41 +00009
Guido van Rossum98297ee2007-11-06 21:34:58 +000010from pickle import bytes_types
11
Tim Petersee1a53c2003-02-02 02:57:53 +000012# Tests that try a number of pickle protocols should have a
13# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000014# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000015protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000016
Tim Peters22e71712003-02-03 22:27:38 +000017
18# Return True if opcode code appears in the pickle, else False.
19def opcode_in_pickle(code, pickle):
20 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000021 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000022 return True
23 return False
24
Tim Peters8d2613a2003-02-11 16:40:16 +000025# Return the number of times opcode code appears in pickle.
26def count_opcode(code, pickle):
27 n = 0
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 Peters8d2613a2003-02-11 16:40:16 +000030 n += 1
31 return n
32
Tim Peters3e667d52003-02-04 21:47:44 +000033# We can't very well test the extension registry without putting known stuff
34# in it, but we have to be careful to restore its original state. Code
35# should do this:
36#
37# e = ExtensionSaver(extension_code)
38# try:
39# fiddle w/ the extension registry's stuff for extension_code
40# finally:
41# e.restore()
42
43class ExtensionSaver:
44 # Remember current registration for code (if any), and remove it (if
45 # there is one).
46 def __init__(self, code):
47 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000048 if code in copyreg._inverted_registry:
49 self.pair = copyreg._inverted_registry[code]
50 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000051 else:
52 self.pair = None
53
54 # Restore previous registration for code.
55 def restore(self):
56 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000057 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000058 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000059 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000060 pair = self.pair
61 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000062 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000063
Jeremy Hylton66426532001-10-15 21:38:56 +000064class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000065 def __eq__(self, other):
66 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000067
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000068class D(C):
69 def __init__(self, arg):
70 pass
71
72class E(C):
73 def __getinitargs__(self):
74 return ()
75
Jeremy Hylton66426532001-10-15 21:38:56 +000076import __main__
77__main__.C = C
78C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000079__main__.D = D
80D.__module__ = "__main__"
81__main__.E = E
82E.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +000083
84class myint(int):
85 def __init__(self, x):
86 self.str = str(x)
87
88class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +000089
Jeremy Hylton66426532001-10-15 21:38:56 +000090 def __init__(self, a, b):
91 self.a = a
92 self.b = b
93
94 def __getinitargs__(self):
95 return self.a, self.b
96
Guido van Rossum04a86612001-12-19 16:58:54 +000097class metaclass(type):
98 pass
99
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000100class use_metaclass(object, metaclass=metaclass):
101 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000102
Tim Peters70b02d72003-02-02 17:26:40 +0000103# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
104# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000105
Guido van Rossum98297ee2007-11-06 21:34:58 +0000106DATA0 = (
Mark Dickinson8dd05142009-01-20 20:43:58 +0000107 b'(lp0\nL0L\naL1L\naF2.0\nac'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000108 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000109 b'p1\n(F3.0\nF0.0\ntp2\nRp'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000110 b'3\naL1L\naL-1L\naL255L\naL-'
111 b'255L\naL-256L\naL65535L\na'
112 b'L-65535L\naL-65536L\naL2'
113 b'147483647L\naL-2147483'
114 b'647L\naL-2147483648L\na('
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000115 b'Vabc\np4\ng4\nccopyreg'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000116 b'\n_reconstructor\np5\n('
Georg Brandl1a3284e2007-12-02 09:40:06 +0000117 b'c__main__\nC\np6\ncbu'
118 b'iltins\nobject\np7\nNt'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000119 b'p8\nRp9\n(dp10\nVfoo\np1'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000120 b'1\nL1L\nsVbar\np12\nL2L\nsb'
121 b'g9\ntp13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000122)
Tim Peterse9358162001-01-22 22:05:20 +0000123
Guido van Rossum98297ee2007-11-06 21:34:58 +0000124# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000125DATA0_DIS = """\
126 0: ( MARK
127 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000128 2: p PUT 0
129 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000130 9: a APPEND
131 10: L LONG 1
132 14: a APPEND
133 15: F FLOAT 2.0
134 20: a APPEND
135 21: c GLOBAL 'builtins complex'
136 39: p PUT 1
137 42: ( MARK
138 43: F FLOAT 3.0
139 48: F FLOAT 0.0
140 53: t TUPLE (MARK at 42)
141 54: p PUT 2
142 57: R REDUCE
143 58: p PUT 3
144 61: a APPEND
145 62: L LONG 1
146 66: a APPEND
147 67: L LONG -1
148 72: a APPEND
149 73: L LONG 255
150 79: a APPEND
151 80: L LONG -255
152 87: a APPEND
153 88: L LONG -256
154 95: a APPEND
155 96: L LONG 65535
156 104: a APPEND
157 105: L LONG -65535
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000158 114: a APPEND
Mark Dickinson8dd05142009-01-20 20:43:58 +0000159 115: L LONG -65536
160 124: a APPEND
161 125: L LONG 2147483647
162 138: a APPEND
163 139: L LONG -2147483647
164 153: a APPEND
165 154: L LONG -2147483648
166 168: a APPEND
167 169: ( MARK
168 170: V UNICODE 'abc'
169 175: p PUT 4
170 178: g GET 4
171 181: c GLOBAL 'copyreg _reconstructor'
172 205: p PUT 5
173 208: ( MARK
174 209: c GLOBAL '__main__ C'
175 221: p PUT 6
176 224: c GLOBAL 'builtins object'
177 241: p PUT 7
178 244: N NONE
179 245: t TUPLE (MARK at 208)
180 246: p PUT 8
181 249: R REDUCE
182 250: p PUT 9
183 253: ( MARK
184 254: d DICT (MARK at 253)
185 255: p PUT 10
186 259: V UNICODE 'foo'
187 264: p PUT 11
188 268: L LONG 1
189 272: s SETITEM
190 273: V UNICODE 'bar'
191 278: p PUT 12
192 282: L LONG 2
193 286: s SETITEM
194 287: b BUILD
195 288: g GET 9
196 291: t TUPLE (MARK at 169)
197 292: p PUT 13
198 296: a APPEND
199 297: g GET 13
200 301: a APPEND
201 302: L LONG 5
202 306: a APPEND
203 307: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000204highest protocol among opcodes = 0
205"""
206
Guido van Rossum98297ee2007-11-06 21:34:58 +0000207DATA1 = (
Georg Brandl1a3284e2007-12-02 09:40:06 +0000208 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
209 b'builtins\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000210 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
211 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
212 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
213 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000214 b'cq\x04h\x04ccopyreg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000215 b'nstructor\nq\x05(c__main'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000216 b'__\nC\nq\x06cbuiltins\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000217 b'object\nq\x07Ntq\x08Rq\t}q\n('
218 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
219 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
220)
Tim Peters70b02d72003-02-02 17:26:40 +0000221
Guido van Rossum98297ee2007-11-06 21:34:58 +0000222# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000223DATA1_DIS = """\
224 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000225 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000226 3: ( MARK
227 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000228 6: K BININT1 1
229 8: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000230 17: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000231 35: q BINPUT 1
232 37: ( MARK
233 38: G BINFLOAT 3.0
234 47: G BINFLOAT 0.0
235 56: t TUPLE (MARK at 37)
236 57: q BINPUT 2
237 59: R REDUCE
238 60: q BINPUT 3
239 62: K BININT1 1
240 64: J BININT -1
241 69: K BININT1 255
242 71: J BININT -255
243 76: J BININT -256
244 81: M BININT2 65535
245 84: J BININT -65535
246 89: J BININT -65536
247 94: J BININT 2147483647
248 99: J BININT -2147483647
249 104: J BININT -2147483648
250 109: ( MARK
251 110: X BINUNICODE 'abc'
252 118: q BINPUT 4
253 120: h BINGET 4
254 122: c GLOBAL 'copyreg _reconstructor'
255 146: q BINPUT 5
256 148: ( MARK
257 149: c GLOBAL '__main__ C'
258 161: q BINPUT 6
259 163: c GLOBAL 'builtins object'
260 180: q BINPUT 7
261 182: N NONE
262 183: t TUPLE (MARK at 148)
263 184: q BINPUT 8
264 186: R REDUCE
265 187: q BINPUT 9
266 189: } EMPTY_DICT
267 190: q BINPUT 10
268 192: ( MARK
269 193: X BINUNICODE 'foo'
270 201: q BINPUT 11
271 203: K BININT1 1
272 205: X BINUNICODE 'bar'
273 213: q BINPUT 12
274 215: K BININT1 2
275 217: u SETITEMS (MARK at 192)
276 218: b BUILD
277 219: h BINGET 9
278 221: t TUPLE (MARK at 109)
279 222: q BINPUT 13
280 224: h BINGET 13
281 226: K BININT1 5
282 228: e APPENDS (MARK at 3)
283 229: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000284highest protocol among opcodes = 1
285"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000286
Guido van Rossum98297ee2007-11-06 21:34:58 +0000287DATA2 = (
288 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000289 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000290 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
291 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
292 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
293 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
294 b'bcq\x04h\x04c__main__\nC\nq\x05'
295 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
296 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
297 b'\nK\x05e.'
298)
Tim Petersfc273752003-03-02 04:54:24 +0000299
Guido van Rossum98297ee2007-11-06 21:34:58 +0000300# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000301DATA2_DIS = """\
302 0: \x80 PROTO 2
303 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000304 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000305 5: ( MARK
306 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000307 8: K BININT1 1
308 10: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000309 19: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000310 37: q BINPUT 1
311 39: G BINFLOAT 3.0
312 48: G BINFLOAT 0.0
313 57: \x86 TUPLE2
314 58: q BINPUT 2
315 60: R REDUCE
316 61: q BINPUT 3
317 63: K BININT1 1
318 65: J BININT -1
319 70: K BININT1 255
320 72: J BININT -255
321 77: J BININT -256
322 82: M BININT2 65535
323 85: J BININT -65535
324 90: J BININT -65536
325 95: J BININT 2147483647
326 100: J BININT -2147483647
327 105: J BININT -2147483648
328 110: ( MARK
329 111: X BINUNICODE 'abc'
330 119: q BINPUT 4
331 121: h BINGET 4
332 123: c GLOBAL '__main__ C'
333 135: q BINPUT 5
334 137: ) EMPTY_TUPLE
335 138: \x81 NEWOBJ
336 139: q BINPUT 6
337 141: } EMPTY_DICT
338 142: q BINPUT 7
339 144: ( MARK
340 145: X BINUNICODE 'foo'
341 153: q BINPUT 8
342 155: K BININT1 1
343 157: X BINUNICODE 'bar'
344 165: q BINPUT 9
345 167: K BININT1 2
346 169: u SETITEMS (MARK at 144)
347 170: b BUILD
348 171: h BINGET 6
349 173: t TUPLE (MARK at 110)
350 174: q BINPUT 10
351 176: h BINGET 10
352 178: K BININT1 5
353 180: e APPENDS (MARK at 5)
354 181: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000355highest protocol among opcodes = 2
356"""
357
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000358# set([1,2]) pickled from 2.x with protocol 2
359DATA3 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
360
361# xrange(5) pickled from 2.x with protocol 2
362DATA4 = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
363
364# a SimpleCookie() object pickled from 2.x with protocol 2
365DATA5 = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
366 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
367 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
368 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
369 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
370 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
371
372# set([3]) pickled from 2.x with protocol 2
373DATA6 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
374
375
Jeremy Hylton66426532001-10-15 21:38:56 +0000376def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000377 c = C()
378 c.foo = 1
379 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000380 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000381 # Append some integer test cases at cPickle.c's internal size
382 # cutoffs.
383 uint1max = 0xff
384 uint2max = 0xffff
385 int4max = 0x7fffffff
386 x.extend([1, -1,
387 uint1max, -uint1max, -uint1max-1,
388 uint2max, -uint2max, -uint2max-1,
389 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000390 y = ('abc', 'abc', c, c)
391 x.append(y)
392 x.append(y)
393 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000394 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000395
Jeremy Hylton66426532001-10-15 21:38:56 +0000396class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000397 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000398
Jeremy Hylton66426532001-10-15 21:38:56 +0000399 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000400
Jeremy Hylton66426532001-10-15 21:38:56 +0000401 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000402 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000403
Jeremy Hylton66426532001-10-15 21:38:56 +0000404 def test_misc(self):
405 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000406 for proto in protocols:
407 x = myint(4)
408 s = self.dumps(x, proto)
409 y = self.loads(s)
410 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000411
Tim Peters70b02d72003-02-02 17:26:40 +0000412 x = (1, ())
413 s = self.dumps(x, proto)
414 y = self.loads(s)
415 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000416
Tim Peters70b02d72003-02-02 17:26:40 +0000417 x = initarg(1, x)
418 s = self.dumps(x, proto)
419 y = self.loads(s)
420 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000421
Jeremy Hylton66426532001-10-15 21:38:56 +0000422 # XXX test __reduce__ protocol?
423
Tim Peters70b02d72003-02-02 17:26:40 +0000424 def test_roundtrip_equality(self):
425 expected = self._testdata
426 for proto in protocols:
427 s = self.dumps(expected, proto)
428 got = self.loads(s)
429 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000430
Guido van Rossum98297ee2007-11-06 21:34:58 +0000431 def test_load_from_data0(self):
432 self.assertEqual(self._testdata, self.loads(DATA0))
433
434 def test_load_from_data1(self):
435 self.assertEqual(self._testdata, self.loads(DATA1))
436
437 def test_load_from_data2(self):
438 self.assertEqual(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000439
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000440 def test_load_classic_instance(self):
441 # See issue5180. Test loading 2.x pickles that
442 # contain an instance of old style class.
443 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
444 xname = X.__name__.encode('ascii')
445 # Protocol 0 (text mode pickle):
446 """
447 0: ( MARK
448 1: i INST '__main__ X' (MARK at 0)
449 15: p PUT 0
450 18: ( MARK
451 19: d DICT (MARK at 18)
452 20: p PUT 1
453 23: b BUILD
454 24: . STOP
455 """
456 pickle0 = (b"(i__main__\n"
457 b"X\n"
458 b"p0\n"
459 b"(dp1\nb.").replace(b'X', xname)
460 self.assertEqual(X(*args), self.loads(pickle0))
461
462 # Protocol 1 (binary mode pickle)
463 """
464 0: ( MARK
465 1: c GLOBAL '__main__ X'
466 15: q BINPUT 0
467 17: o OBJ (MARK at 0)
468 18: q BINPUT 1
469 20: } EMPTY_DICT
470 21: q BINPUT 2
471 23: b BUILD
472 24: . STOP
473 """
474 pickle1 = (b'(c__main__\n'
475 b'X\n'
476 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
477 self.assertEqual(X(*args), self.loads(pickle1))
478
479 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
480 """
481 0: \x80 PROTO 2
482 2: ( MARK
483 3: c GLOBAL '__main__ X'
484 17: q BINPUT 0
485 19: o OBJ (MARK at 2)
486 20: q BINPUT 1
487 22: } EMPTY_DICT
488 23: q BINPUT 2
489 25: b BUILD
490 26: . STOP
491 """
492 pickle2 = (b'\x80\x02(c__main__\n'
493 b'X\n'
494 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
495 self.assertEqual(X(*args), self.loads(pickle2))
496
Tim Peters70b02d72003-02-02 17:26:40 +0000497 # There are gratuitous differences between pickles produced by
498 # pickle and cPickle, largely because cPickle starts PUT indices at
499 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
500 # there's a comment with an exclamation point there whose meaning
501 # is a mystery. cPickle also suppresses PUT for objects with a refcount
502 # of 1.
503 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000504 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000505 from pickletools import dis
506
507 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
508 s = self.dumps(self._testdata, proto)
509 filelike = StringIO()
510 dis(s, out=filelike)
511 got = filelike.getvalue()
512 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000513
514 def test_recursive_list(self):
515 l = []
516 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000517 for proto in protocols:
518 s = self.dumps(l, proto)
519 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000520 self.assertEqual(len(x), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000521 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000522
Collin Winter8ca69de2009-05-26 16:53:41 +0000523 def test_recursive_tuple(self):
524 t = ([],)
525 t[0].append(t)
526 for proto in protocols:
527 s = self.dumps(t, proto)
528 x = self.loads(s)
529 self.assertEqual(len(x), 1)
530 self.assertEqual(len(x[0]), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000531 self.assertTrue(x is x[0][0])
Collin Winter8ca69de2009-05-26 16:53:41 +0000532
Jeremy Hylton66426532001-10-15 21:38:56 +0000533 def test_recursive_dict(self):
534 d = {}
535 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000536 for proto in protocols:
537 s = self.dumps(d, proto)
538 x = self.loads(s)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000539 self.assertEqual(list(x.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000540 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000541
542 def test_recursive_inst(self):
543 i = C()
544 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000545 for proto in protocols:
546 s = self.dumps(i, 2)
547 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000548 self.assertEqual(dir(x), dir(i))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000549 self.assertTrue(x.attr is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000550
551 def test_recursive_multi(self):
552 l = []
553 d = {1:l}
554 i = C()
555 i.attr = d
556 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000557 for proto in protocols:
558 s = self.dumps(l, proto)
559 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000560 self.assertEqual(len(x), 1)
561 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000562 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000563 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000564
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000565 def test_get(self):
566 self.assertRaises(KeyError, self.loads, b'g0\np0')
567 self.assertEquals(self.loads(b'((Kdtp0\nh\x00l.))'), [(100,), (100,)])
Jeremy Hylton66426532001-10-15 21:38:56 +0000568
569 def test_insecure_strings(self):
Guido van Rossum39478e82007-08-27 17:23:59 +0000570 # XXX Some of these tests are temporarily disabled
571 insecure = [b"abc", b"2 + 2", # not quoted
572 ## b"'abc' + 'def'", # not a single quoted string
573 b"'abc", # quote is not closed
574 b"'abc\"", # open quote and close quote don't match
575 b"'abc' ?", # junk after close quote
576 b"'\\'", # trailing backslash
Jeremy Hylton66426532001-10-15 21:38:56 +0000577 # some tests of the quoting rules
Guido van Rossum39478e82007-08-27 17:23:59 +0000578 ## b"'abc\"\''",
579 ## b"'\\\\a\'\'\'\\\'\\\\\''",
Jeremy Hylton66426532001-10-15 21:38:56 +0000580 ]
Guido van Rossum39478e82007-08-27 17:23:59 +0000581 for b in insecure:
582 buf = b"S" + b + b"\012p0\012."
Jeremy Hylton66426532001-10-15 21:38:56 +0000583 self.assertRaises(ValueError, self.loads, buf)
584
Walter Dörwald9b775532007-06-08 14:30:53 +0000585 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000586 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +0000587 '<\\>', '<\\\U00012345>',
588 # surrogates
589 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000590 for proto in protocols:
591 for u in endcases:
592 p = self.dumps(u, proto)
593 u2 = self.loads(p)
594 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000595
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000596 def test_unicode_high_plane(self):
597 t = '\U00012345'
598 for proto in protocols:
599 p = self.dumps(t, proto)
600 t2 = self.loads(p)
601 self.assertEqual(t2, t)
602
Guido van Rossumf4169812008-03-17 22:56:06 +0000603 def test_bytes(self):
604 for proto in protocols:
605 for u in b'', b'xyz', b'xyz'*100:
606 p = self.dumps(u)
607 self.assertEqual(self.loads(p), u)
608
Jeremy Hylton66426532001-10-15 21:38:56 +0000609 def test_ints(self):
610 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000611 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000612 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000613 while n:
614 for expected in (-n, n):
615 s = self.dumps(expected, proto)
616 n2 = self.loads(s)
617 self.assertEqual(expected, n2)
618 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000619
Jeremy Hylton66426532001-10-15 21:38:56 +0000620 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000621 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000622 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000623 got = self.loads(data)
624 self.assertEqual(got, maxint64)
625
626 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000627 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000628 self.assertRaises(ValueError, self.loads, data)
629
Tim Petersee1a53c2003-02-02 02:57:53 +0000630 def test_long(self):
631 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000632 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000633 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000634 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000635 for npos in nbase-1, nbase, nbase+1:
636 for n in npos, -npos:
637 pickle = self.dumps(n, proto)
638 got = self.loads(pickle)
639 self.assertEqual(n, got)
640 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
641 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000642 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000643 nbase += nbase << 1000000
644 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000645 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000646 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000647 self.assertEqual(n, got)
648
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000649 def test_float(self):
650 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
651 3.14, 263.44582062374053, 6.022e23, 1e30]
652 test_values = test_values + [-x for x in test_values]
653 for proto in protocols:
654 for value in test_values:
655 pickle = self.dumps(value, proto)
656 got = self.loads(pickle)
657 self.assertEqual(value, got)
658
Thomas Wouters477c8d52006-05-27 19:21:47 +0000659 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
660 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000661 # make sure that floats are formatted locale independent with proto 0
662 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000663
Jeremy Hylton66426532001-10-15 21:38:56 +0000664 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000665 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000666
667 def test_getinitargs(self):
668 pass
669
Guido van Rossum04a86612001-12-19 16:58:54 +0000670 def test_metaclass(self):
671 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000672 for proto in protocols:
673 s = self.dumps(a, proto)
674 b = self.loads(s)
675 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000676
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000677 def test_structseq(self):
678 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000679 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000680
681 t = time.localtime()
682 for proto in protocols:
683 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000684 u = self.loads(s)
685 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000686 if hasattr(os, "stat"):
687 t = os.stat(os.curdir)
688 s = self.dumps(t, proto)
689 u = self.loads(s)
690 self.assertEqual(t, u)
691 if hasattr(os, "statvfs"):
692 t = os.statvfs(os.curdir)
693 s = self.dumps(t, proto)
694 u = self.loads(s)
695 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000696
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000697 # Tests for protocol 2
698
Tim Peters4190fb82003-02-02 16:09:05 +0000699 def test_proto(self):
700 build_none = pickle.NONE + pickle.STOP
701 for proto in protocols:
702 expected = build_none
703 if proto >= 2:
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000704 expected = pickle.PROTO + bytes([proto]) + expected
Tim Peters4190fb82003-02-02 16:09:05 +0000705 p = self.dumps(None, proto)
706 self.assertEqual(p, expected)
707
708 oob = protocols[-1] + 1 # a future protocol
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000709 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000710 try:
711 self.loads(badpickle)
Guido van Rossumb940e112007-01-10 16:19:56 +0000712 except ValueError as detail:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000713 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +0000714 "unsupported pickle protocol"))
715 else:
716 self.fail("expected bad protocol number to raise ValueError")
717
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000718 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000719 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000720 for proto in protocols:
721 s = self.dumps(x, proto)
722 y = self.loads(s)
723 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000724 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000725
726 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000727 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000728 for proto in protocols:
729 s = self.dumps(x, proto)
730 y = self.loads(s)
731 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000732 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000733
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000734 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000735 # Map (proto, len(tuple)) to expected opcode.
736 expected_opcode = {(0, 0): pickle.TUPLE,
737 (0, 1): pickle.TUPLE,
738 (0, 2): pickle.TUPLE,
739 (0, 3): pickle.TUPLE,
740 (0, 4): pickle.TUPLE,
741
742 (1, 0): pickle.EMPTY_TUPLE,
743 (1, 1): pickle.TUPLE,
744 (1, 2): pickle.TUPLE,
745 (1, 3): pickle.TUPLE,
746 (1, 4): pickle.TUPLE,
747
748 (2, 0): pickle.EMPTY_TUPLE,
749 (2, 1): pickle.TUPLE1,
750 (2, 2): pickle.TUPLE2,
751 (2, 3): pickle.TUPLE3,
752 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000753
754 (3, 0): pickle.EMPTY_TUPLE,
755 (3, 1): pickle.TUPLE1,
756 (3, 2): pickle.TUPLE2,
757 (3, 3): pickle.TUPLE3,
758 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000759 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000760 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000761 b = (1,)
762 c = (1, 2)
763 d = (1, 2, 3)
764 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000765 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000766 for x in a, b, c, d, e:
767 s = self.dumps(x, proto)
768 y = self.loads(s)
769 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000770 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +0000771 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +0000772
Guido van Rossum7d97d312003-01-28 04:25:27 +0000773 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000774 # Map (proto, singleton) to expected opcode.
775 expected_opcode = {(0, None): pickle.NONE,
776 (1, None): pickle.NONE,
777 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000778 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000779
780 (0, True): pickle.INT,
781 (1, True): pickle.INT,
782 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000783 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000784
785 (0, False): pickle.INT,
786 (1, False): pickle.INT,
787 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000788 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000789 }
Tim Peters4190fb82003-02-02 16:09:05 +0000790 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000791 for x in None, False, True:
792 s = self.dumps(x, proto)
793 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000794 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +0000795 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +0000796 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +0000797
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000798 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000799 x = MyTuple([1, 2, 3])
800 x.foo = 42
801 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000802 for proto in protocols:
803 s = self.dumps(x, proto)
804 y = self.loads(s)
805 self.assertEqual(tuple(x), tuple(y))
806 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000807
808 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000809 x = MyList([1, 2, 3])
810 x.foo = 42
811 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000812 for proto in protocols:
813 s = self.dumps(x, proto)
814 y = self.loads(s)
815 self.assertEqual(list(x), list(y))
816 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000817
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000818 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +0000819 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000820 for C in myclasses:
821 B = C.__base__
822 x = C(C.sample)
823 x.foo = 42
824 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000825 y = self.loads(s)
826 detail = (proto, C, B, x, y, type(y))
827 self.assertEqual(B(x), B(y), detail)
828 self.assertEqual(x.__dict__, y.__dict__, detail)
829
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000830 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +0000831 # an object of that type. Check that the resulting pickle uses opcode
832 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +0000833
Tim Peters22e71712003-02-03 22:27:38 +0000834 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +0000835 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000836 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000837 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000838 x = MyList([1, 2, 3])
839 x.foo = 42
840 x.bar = "hello"
841
Tim Peters22e71712003-02-03 22:27:38 +0000842 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000843 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000844 self.assertIn(__name__.encode("utf-8"), s1)
845 self.assertIn(b"MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +0000846 self.assertEqual(opcode_in_pickle(opcode, s1), False)
847
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000848 y = self.loads(s1)
849 self.assertEqual(list(x), list(y))
850 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000851
Tim Peters22e71712003-02-03 22:27:38 +0000852 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000853 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000854 self.assertNotIn(__name__.encode("utf-8"), s2)
855 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000856 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +0000857
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000858 y = self.loads(s2)
859 self.assertEqual(list(x), list(y))
860 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000861
862 finally:
Tim Peters3e667d52003-02-04 21:47:44 +0000863 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +0000864
865 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000866 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
867 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000868
869 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000870 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
871 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
872 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000873
874 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000875 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
876 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
877 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
878
Tim Peters8d2613a2003-02-11 16:40:16 +0000879 def test_list_chunking(self):
880 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +0000881 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000882 for proto in protocols:
883 s = self.dumps(x, proto)
884 y = self.loads(s)
885 self.assertEqual(x, y)
886 num_appends = count_opcode(pickle.APPENDS, s)
887 self.assertEqual(num_appends, proto > 0)
888
889 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +0000890 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000891 for proto in protocols:
892 s = self.dumps(x, proto)
893 y = self.loads(s)
894 self.assertEqual(x, y)
895 num_appends = count_opcode(pickle.APPENDS, s)
896 if proto == 0:
897 self.assertEqual(num_appends, 0)
898 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000899 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +0000900
901 def test_dict_chunking(self):
902 n = 10 # too small to chunk
903 x = dict.fromkeys(range(n))
904 for proto in protocols:
905 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +0000906 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +0000907 y = self.loads(s)
908 self.assertEqual(x, y)
909 num_setitems = count_opcode(pickle.SETITEMS, s)
910 self.assertEqual(num_setitems, proto > 0)
911
912 n = 2500 # expect at least two chunks when proto > 0
913 x = dict.fromkeys(range(n))
914 for proto in protocols:
915 s = self.dumps(x, proto)
916 y = self.loads(s)
917 self.assertEqual(x, y)
918 num_setitems = count_opcode(pickle.SETITEMS, s)
919 if proto == 0:
920 self.assertEqual(num_setitems, 0)
921 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000922 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000923
Tim Peterse9ef2032003-02-13 18:42:00 +0000924 def test_simple_newobj(self):
925 x = object.__new__(SimpleNewObj) # avoid __init__
926 x.abc = 666
927 for proto in protocols:
928 s = self.dumps(x, proto)
929 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
930 y = self.loads(s) # will raise TypeError if __init__ called
931 self.assertEqual(y.abc, 666)
932 self.assertEqual(x.__dict__, y.__dict__)
933
Tim Peters42f08ac2003-02-11 22:43:24 +0000934 def test_newobj_list_slots(self):
935 x = SlotList([1, 2, 3])
936 x.foo = 42
937 x.bar = "hello"
938 s = self.dumps(x, 2)
939 y = self.loads(s)
940 self.assertEqual(list(x), list(y))
941 self.assertEqual(x.__dict__, y.__dict__)
942 self.assertEqual(x.foo, y.foo)
943 self.assertEqual(x.bar, y.bar)
944
Guido van Rossum2a30b212003-02-18 22:41:24 +0000945 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +0000946 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000947 x = REX_one()
948 self.assertEqual(x._reduce_called, 0)
949 s = self.dumps(x, proto)
950 self.assertEqual(x._reduce_called, 1)
951 y = self.loads(s)
952 self.assertEqual(y._reduce_called, 0)
953
954 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +0000955 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000956 x = REX_two()
957 self.assertEqual(x._proto, None)
958 s = self.dumps(x, proto)
959 self.assertEqual(x._proto, proto)
960 y = self.loads(s)
961 self.assertEqual(y._proto, None)
962
963 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +0000964 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000965 x = REX_three()
966 self.assertEqual(x._proto, None)
967 s = self.dumps(x, proto)
968 self.assertEqual(x._proto, proto)
969 y = self.loads(s)
970 self.assertEqual(y._proto, None)
971
Guido van Rossumd8faa362007-04-27 19:54:29 +0000972 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +0000973 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000974 x = REX_four()
975 self.assertEqual(x._proto, None)
976 s = self.dumps(x, proto)
977 self.assertEqual(x._proto, proto)
978 y = self.loads(s)
979 self.assertEqual(y._proto, proto)
980
981 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +0000982 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000983 x = REX_five()
984 self.assertEqual(x._reduce_called, 0)
985 s = self.dumps(x, proto)
986 self.assertEqual(x._reduce_called, 1)
987 y = self.loads(s)
988 self.assertEqual(y._reduce_called, 1)
989
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +0000990 def test_bad_getattr(self):
991 x = BadGetattr()
992 for proto in 0, 1:
993 self.assertRaises(RuntimeError, self.dumps, x, proto)
994 # protocol 2 don't raise a RuntimeError.
995 d = self.dumps(x, 2)
996 self.assertRaises(RuntimeError, self.loads, d)
997
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +0000998 def test_reduce_bad_iterator(self):
999 # Issue4176: crash when 4th and 5th items of __reduce__()
1000 # are not iterators
1001 class C(object):
1002 def __reduce__(self):
1003 # 4th item is not an iterator
1004 return list, (), None, [], None
1005 class D(object):
1006 def __reduce__(self):
1007 # 5th item is not an iterator
1008 return dict, (), None, None, []
1009
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001010 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001011 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001012 try:
1013 self.dumps(C(), proto)
1014 except (pickle.PickleError):
1015 pass
1016 try:
1017 self.dumps(D(), proto)
1018 except (pickle.PickleError):
1019 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001020
Collin Winter771d8342009-04-16 03:18:06 +00001021 def test_many_puts_and_gets(self):
1022 # Test that internal data structures correctly deal with lots of
1023 # puts/gets.
1024 keys = ("aaa" + str(i) for i in range(100))
1025 large_dict = dict((k, [4, 5, 6]) for k in keys)
1026 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1027
1028 for proto in protocols:
1029 dumped = self.dumps(obj, proto)
1030 loaded = self.loads(dumped)
1031 self.assertEqual(loaded, obj,
1032 "Failed protocol %d: %r != %r"
1033 % (proto, obj, loaded))
1034
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001035 def test_attribute_name_interning(self):
1036 # Test that attribute names of pickled objects are interned when
1037 # unpickling.
1038 for proto in protocols:
1039 x = C()
1040 x.foo = 42
1041 x.bar = "hello"
1042 s = self.dumps(x, proto)
1043 y = self.loads(s)
1044 x_keys = sorted(x.__dict__)
1045 y_keys = sorted(y.__dict__)
1046 for x_key, y_key in zip(x_keys, y_keys):
1047 self.assertIs(x_key, y_key)
1048
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001049 def test_unpickle_from_2x(self):
1050 # Unpickle non-trivial data from Python 2.x.
1051 loaded = self.loads(DATA3)
1052 self.assertEqual(loaded, set([1, 2]))
1053 loaded = self.loads(DATA4)
1054 self.assertEqual(type(loaded), type(range(0)))
1055 self.assertEqual(list(loaded), list(range(5)))
1056 loaded = self.loads(DATA5)
1057 self.assertEqual(type(loaded), SimpleCookie)
1058 self.assertEqual(list(loaded.keys()), ["key"])
1059 self.assertEqual(loaded["key"].value, "Set-Cookie: key=value")
1060
1061 def test_pickle_to_2x(self):
1062 # Pickle non-trivial data with protocol 2, expecting that it yields
1063 # the same result as Python 2.x did.
1064 # NOTE: this test is a bit too strong since we can produce different
1065 # bytecode that 2.x will still understand.
1066 dumped = self.dumps(range(5), 2)
1067 self.assertEqual(dumped, DATA4)
1068 dumped = self.dumps(set([3]), 2)
1069 self.assertEqual(dumped, DATA6)
1070
1071
Guido van Rossum2a30b212003-02-18 22:41:24 +00001072# Test classes for reduce_ex
1073
1074class REX_one(object):
1075 _reduce_called = 0
1076 def __reduce__(self):
1077 self._reduce_called = 1
1078 return REX_one, ()
1079 # No __reduce_ex__ here, but inheriting it from object
1080
1081class REX_two(object):
1082 _proto = None
1083 def __reduce_ex__(self, proto):
1084 self._proto = proto
1085 return REX_two, ()
1086 # No __reduce__ here, but inheriting it from object
1087
1088class REX_three(object):
1089 _proto = None
1090 def __reduce_ex__(self, proto):
1091 self._proto = proto
1092 return REX_two, ()
1093 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001094 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001095
Guido van Rossumd8faa362007-04-27 19:54:29 +00001096class REX_four(object):
1097 _proto = None
1098 def __reduce_ex__(self, proto):
1099 self._proto = proto
1100 return object.__reduce_ex__(self, proto)
1101 # Calling base class method should succeed
1102
1103class REX_five(object):
1104 _reduce_called = 0
1105 def __reduce__(self):
1106 self._reduce_called = 1
1107 return object.__reduce__(self)
1108 # This one used to fail with infinite recursion
1109
Guido van Rossum2a30b212003-02-18 22:41:24 +00001110# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001111
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001112class MyInt(int):
1113 sample = 1
1114
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001115class MyFloat(float):
1116 sample = 1.0
1117
1118class MyComplex(complex):
1119 sample = 1.0 + 0.0j
1120
1121class MyStr(str):
1122 sample = "hello"
1123
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001124class MyUnicode(str):
1125 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001126
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001127class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001128 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001129
1130class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001131 sample = [1, 2, 3]
1132
1133class MyDict(dict):
1134 sample = {"a": 1, "b": 2}
1135
Mark Dickinson5c2db372009-12-05 20:28:34 +00001136myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001137 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001138 MyStr, MyUnicode,
1139 MyTuple, MyList, MyDict]
1140
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001141
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001142class SlotList(MyList):
1143 __slots__ = ["foo"]
1144
Tim Peterse9ef2032003-02-13 18:42:00 +00001145class SimpleNewObj(object):
1146 def __init__(self, a, b, c):
1147 # raise an error, to make sure this isn't called
1148 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1149
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001150class BadGetattr:
1151 def __getattr__(self, key):
1152 self.foo
1153
Collin Winter771d8342009-04-16 03:18:06 +00001154
Jeremy Hylton66426532001-10-15 21:38:56 +00001155class AbstractPickleModuleTests(unittest.TestCase):
1156
1157 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001158 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001159 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001160 try:
1161 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001162 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001163 finally:
1164 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001165
1166 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001167 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001168 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001169 try:
1170 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001171 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001172 finally:
1173 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001174
Collin Winter771d8342009-04-16 03:18:06 +00001175 def test_load_from_and_dump_to_file(self):
1176 stream = io.BytesIO()
1177 data = [123, {}, 124]
1178 pickle.dump(data, stream)
1179 stream.seek(0)
1180 unpickled = pickle.load(stream)
1181 self.assertEqual(unpickled, data)
1182
Tim Petersc0c93702003-02-13 19:30:57 +00001183 def test_highest_protocol(self):
1184 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001185 self.assertEqual(pickle.HIGHEST_PROTOCOL, 3)
Tim Petersc0c93702003-02-13 19:30:57 +00001186
Martin v. Löwis544f1192004-07-27 05:22:33 +00001187 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001188 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001189 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001190 pickle.dump(123, f, -1)
1191 pickle.dump(123, file=f, protocol=-1)
1192 pickle.dumps(123, -1)
1193 pickle.dumps(123, protocol=-1)
1194 pickle.Pickler(f, -1)
1195 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001196
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001197 def test_bad_init(self):
1198 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001199 # Override initialization without calling __init__() of the superclass.
1200 class BadPickler(pickle.Pickler):
1201 def __init__(self): pass
1202
1203 class BadUnpickler(pickle.Unpickler):
1204 def __init__(self): pass
1205
1206 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1207 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1208
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001209 def test_bad_input(self):
1210 # Test issue4298
1211 s = bytes([0x58, 0, 0, 0, 0x54])
1212 self.assertRaises(EOFError, pickle.loads, s)
Antoine Pitrou01a15ea2010-01-07 17:57:31 +00001213 # Test issue7455
1214 s = b'0'
1215 self.assertRaises(pickle.UnpicklingError, pickle.loads, s)
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001216
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001217
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001218class AbstractPersistentPicklerTests(unittest.TestCase):
1219
1220 # This class defines persistent_id() and persistent_load()
1221 # functions that should be used by the pickler. All even integers
1222 # are pickled using persistent ids.
1223
1224 def persistent_id(self, object):
1225 if isinstance(object, int) and object % 2 == 0:
1226 self.id_count += 1
1227 return str(object)
1228 else:
1229 return None
1230
1231 def persistent_load(self, oid):
1232 self.load_count += 1
1233 object = int(oid)
1234 assert object % 2 == 0
1235 return object
1236
1237 def test_persistence(self):
1238 self.id_count = 0
1239 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001240 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001241 self.assertEqual(self.loads(self.dumps(L)), L)
1242 self.assertEqual(self.id_count, 5)
1243 self.assertEqual(self.load_count, 5)
1244
1245 def test_bin_persistence(self):
1246 self.id_count = 0
1247 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001248 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001249 self.assertEqual(self.loads(self.dumps(L, 1)), L)
1250 self.assertEqual(self.id_count, 5)
1251 self.assertEqual(self.load_count, 5)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001252
Collin Winter771d8342009-04-16 03:18:06 +00001253
1254class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1255
1256 pickler_class = None
1257 unpickler_class = None
1258
1259 def setUp(self):
1260 assert self.pickler_class
1261 assert self.unpickler_class
1262
1263 def test_clear_pickler_memo(self):
1264 # To test whether clear_memo() has any effect, we pickle an object,
1265 # then pickle it again without clearing the memo; the two serialized
1266 # forms should be different. If we clear_memo() and then pickle the
1267 # object again, the third serialized form should be identical to the
1268 # first one we obtained.
1269 data = ["abcdefg", "abcdefg", 44]
1270 f = io.BytesIO()
1271 pickler = self.pickler_class(f)
1272
1273 pickler.dump(data)
1274 first_pickled = f.getvalue()
1275
1276 # Reset StringIO object.
1277 f.seek(0)
1278 f.truncate()
1279
1280 pickler.dump(data)
1281 second_pickled = f.getvalue()
1282
1283 # Reset the Pickler and StringIO objects.
1284 pickler.clear_memo()
1285 f.seek(0)
1286 f.truncate()
1287
1288 pickler.dump(data)
1289 third_pickled = f.getvalue()
1290
1291 self.assertNotEqual(first_pickled, second_pickled)
1292 self.assertEqual(first_pickled, third_pickled)
1293
1294 def test_priming_pickler_memo(self):
1295 # Verify that we can set the Pickler's memo attribute.
1296 data = ["abcdefg", "abcdefg", 44]
1297 f = io.BytesIO()
1298 pickler = self.pickler_class(f)
1299
1300 pickler.dump(data)
1301 first_pickled = f.getvalue()
1302
1303 f = io.BytesIO()
1304 primed = self.pickler_class(f)
1305 primed.memo = pickler.memo
1306
1307 primed.dump(data)
1308 primed_pickled = f.getvalue()
1309
1310 self.assertNotEqual(first_pickled, primed_pickled)
1311
1312 def test_priming_unpickler_memo(self):
1313 # Verify that we can set the Unpickler's memo attribute.
1314 data = ["abcdefg", "abcdefg", 44]
1315 f = io.BytesIO()
1316 pickler = self.pickler_class(f)
1317
1318 pickler.dump(data)
1319 first_pickled = f.getvalue()
1320
1321 f = io.BytesIO()
1322 primed = self.pickler_class(f)
1323 primed.memo = pickler.memo
1324
1325 primed.dump(data)
1326 primed_pickled = f.getvalue()
1327
1328 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
1329 unpickled_data1 = unpickler.load()
1330
1331 self.assertEqual(unpickled_data1, data)
1332
1333 primed = self.unpickler_class(io.BytesIO(primed_pickled))
1334 primed.memo = unpickler.memo
1335 unpickled_data2 = primed.load()
1336
1337 primed.memo.clear()
1338
1339 self.assertEqual(unpickled_data2, data)
1340 self.assertTrue(unpickled_data2 is unpickled_data1)
1341
1342 def test_reusing_unpickler_objects(self):
1343 data1 = ["abcdefg", "abcdefg", 44]
1344 f = io.BytesIO()
1345 pickler = self.pickler_class(f)
1346 pickler.dump(data1)
1347 pickled1 = f.getvalue()
1348
1349 data2 = ["abcdefg", 44, 44]
1350 f = io.BytesIO()
1351 pickler = self.pickler_class(f)
1352 pickler.dump(data2)
1353 pickled2 = f.getvalue()
1354
1355 f = io.BytesIO()
1356 f.write(pickled1)
1357 f.seek(0)
1358 unpickler = self.unpickler_class(f)
1359 self.assertEqual(unpickler.load(), data1)
1360
1361 f.seek(0)
1362 f.truncate()
1363 f.write(pickled2)
1364 f.seek(0)
1365 self.assertEqual(unpickler.load(), data2)
1366
1367
Guido van Rossum98297ee2007-11-06 21:34:58 +00001368if __name__ == "__main__":
1369 # Print some stuff that can be used to rewrite DATA{0,1,2}
1370 from pickletools import dis
1371 x = create_data()
1372 for i in range(3):
1373 p = pickle.dumps(x, i)
1374 print("DATA{0} = (".format(i))
1375 for j in range(0, len(p), 20):
1376 b = bytes(p[j:j+20])
1377 print(" {0!r}".format(b))
1378 print(")")
1379 print()
1380 print("# Disassembly of DATA{0}".format(i))
1381 print("DATA{0}_DIS = \"\"\"\\".format(i))
1382 dis(p)
1383 print("\"\"\"")
1384 print()