blob: c2ed0d284991aeb529ea2c647d544d9ff8d50e0e [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
Antoine Pitrou82be19f2011-08-29 23:09:33 +02005import sys
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00006import copyreg
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00007from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +00008
Antoine Pitrou82be19f2011-08-29 23:09:33 +02009from test.support import (
10 TestFailed, TESTFN, run_with_locale,
11 _2G, _4G, precisionbigmemtest,
12 )
Tim Peterse089c682001-04-10 03:41:41 +000013
Guido van Rossum98297ee2007-11-06 21:34:58 +000014from pickle import bytes_types
15
Tim Petersee1a53c2003-02-02 02:57:53 +000016# Tests that try a number of pickle protocols should have a
17# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000018# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000019protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000020
Antoine Pitrou82be19f2011-08-29 23:09:33 +020021character_size = 4 if sys.maxunicode > 0xFFFF else 2
22
Tim Peters22e71712003-02-03 22:27:38 +000023
24# Return True if opcode code appears in the pickle, else False.
25def opcode_in_pickle(code, pickle):
26 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000027 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000028 return True
29 return False
30
Tim Peters8d2613a2003-02-11 16:40:16 +000031# Return the number of times opcode code appears in pickle.
32def count_opcode(code, pickle):
33 n = 0
34 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000035 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000036 n += 1
37 return n
38
Antoine Pitrou04248a82010-10-12 20:51:21 +000039
40class UnseekableIO(io.BytesIO):
41 def peek(self, *args):
42 raise NotImplementedError
43
44 def seekable(self):
45 return False
46
47 def seek(self, *args):
48 raise io.UnsupportedOperation
49
50 def tell(self):
51 raise io.UnsupportedOperation
52
53
Tim Peters3e667d52003-02-04 21:47:44 +000054# We can't very well test the extension registry without putting known stuff
55# in it, but we have to be careful to restore its original state. Code
56# should do this:
57#
58# e = ExtensionSaver(extension_code)
59# try:
60# fiddle w/ the extension registry's stuff for extension_code
61# finally:
62# e.restore()
63
64class ExtensionSaver:
65 # Remember current registration for code (if any), and remove it (if
66 # there is one).
67 def __init__(self, code):
68 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000069 if code in copyreg._inverted_registry:
70 self.pair = copyreg._inverted_registry[code]
71 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000072 else:
73 self.pair = None
74
75 # Restore previous registration for code.
76 def restore(self):
77 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000078 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000079 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000080 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000081 pair = self.pair
82 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000083 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000084
Jeremy Hylton66426532001-10-15 21:38:56 +000085class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000086 def __eq__(self, other):
87 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000088
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000089class D(C):
90 def __init__(self, arg):
91 pass
92
93class E(C):
94 def __getinitargs__(self):
95 return ()
96
Jeremy Hylton66426532001-10-15 21:38:56 +000097import __main__
98__main__.C = C
99C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000100__main__.D = D
101D.__module__ = "__main__"
102__main__.E = E
103E.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000104
105class myint(int):
106 def __init__(self, x):
107 self.str = str(x)
108
109class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000110
Jeremy Hylton66426532001-10-15 21:38:56 +0000111 def __init__(self, a, b):
112 self.a = a
113 self.b = b
114
115 def __getinitargs__(self):
116 return self.a, self.b
117
Guido van Rossum04a86612001-12-19 16:58:54 +0000118class metaclass(type):
119 pass
120
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000121class use_metaclass(object, metaclass=metaclass):
122 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000123
Tim Peters70b02d72003-02-02 17:26:40 +0000124# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
125# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000126
Guido van Rossum98297ee2007-11-06 21:34:58 +0000127DATA0 = (
Mark Dickinson8dd05142009-01-20 20:43:58 +0000128 b'(lp0\nL0L\naL1L\naF2.0\nac'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000129 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000130 b'p1\n(F3.0\nF0.0\ntp2\nRp'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000131 b'3\naL1L\naL-1L\naL255L\naL-'
132 b'255L\naL-256L\naL65535L\na'
133 b'L-65535L\naL-65536L\naL2'
134 b'147483647L\naL-2147483'
135 b'647L\naL-2147483648L\na('
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000136 b'Vabc\np4\ng4\nccopyreg'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000137 b'\n_reconstructor\np5\n('
Georg Brandl1a3284e2007-12-02 09:40:06 +0000138 b'c__main__\nC\np6\ncbu'
139 b'iltins\nobject\np7\nNt'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000140 b'p8\nRp9\n(dp10\nVfoo\np1'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000141 b'1\nL1L\nsVbar\np12\nL2L\nsb'
142 b'g9\ntp13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000143)
Tim Peterse9358162001-01-22 22:05:20 +0000144
Guido van Rossum98297ee2007-11-06 21:34:58 +0000145# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000146DATA0_DIS = """\
147 0: ( MARK
148 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000149 2: p PUT 0
150 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000151 9: a APPEND
152 10: L LONG 1
153 14: a APPEND
154 15: F FLOAT 2.0
155 20: a APPEND
156 21: c GLOBAL 'builtins complex'
157 39: p PUT 1
158 42: ( MARK
159 43: F FLOAT 3.0
160 48: F FLOAT 0.0
161 53: t TUPLE (MARK at 42)
162 54: p PUT 2
163 57: R REDUCE
164 58: p PUT 3
165 61: a APPEND
166 62: L LONG 1
167 66: a APPEND
168 67: L LONG -1
169 72: a APPEND
170 73: L LONG 255
171 79: a APPEND
172 80: L LONG -255
173 87: a APPEND
174 88: L LONG -256
175 95: a APPEND
176 96: L LONG 65535
177 104: a APPEND
178 105: L LONG -65535
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000179 114: a APPEND
Mark Dickinson8dd05142009-01-20 20:43:58 +0000180 115: L LONG -65536
181 124: a APPEND
182 125: L LONG 2147483647
183 138: a APPEND
184 139: L LONG -2147483647
185 153: a APPEND
186 154: L LONG -2147483648
187 168: a APPEND
188 169: ( MARK
189 170: V UNICODE 'abc'
190 175: p PUT 4
191 178: g GET 4
192 181: c GLOBAL 'copyreg _reconstructor'
193 205: p PUT 5
194 208: ( MARK
195 209: c GLOBAL '__main__ C'
196 221: p PUT 6
197 224: c GLOBAL 'builtins object'
198 241: p PUT 7
199 244: N NONE
200 245: t TUPLE (MARK at 208)
201 246: p PUT 8
202 249: R REDUCE
203 250: p PUT 9
204 253: ( MARK
205 254: d DICT (MARK at 253)
206 255: p PUT 10
207 259: V UNICODE 'foo'
208 264: p PUT 11
209 268: L LONG 1
210 272: s SETITEM
211 273: V UNICODE 'bar'
212 278: p PUT 12
213 282: L LONG 2
214 286: s SETITEM
215 287: b BUILD
216 288: g GET 9
217 291: t TUPLE (MARK at 169)
218 292: p PUT 13
219 296: a APPEND
220 297: g GET 13
221 301: a APPEND
222 302: L LONG 5
223 306: a APPEND
224 307: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000225highest protocol among opcodes = 0
226"""
227
Guido van Rossum98297ee2007-11-06 21:34:58 +0000228DATA1 = (
Georg Brandl1a3284e2007-12-02 09:40:06 +0000229 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
230 b'builtins\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000231 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
232 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
233 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
234 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000235 b'cq\x04h\x04ccopyreg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000236 b'nstructor\nq\x05(c__main'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000237 b'__\nC\nq\x06cbuiltins\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000238 b'object\nq\x07Ntq\x08Rq\t}q\n('
239 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
240 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
241)
Tim Peters70b02d72003-02-02 17:26:40 +0000242
Guido van Rossum98297ee2007-11-06 21:34:58 +0000243# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000244DATA1_DIS = """\
245 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000246 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000247 3: ( MARK
248 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000249 6: K BININT1 1
250 8: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000251 17: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000252 35: q BINPUT 1
253 37: ( MARK
254 38: G BINFLOAT 3.0
255 47: G BINFLOAT 0.0
256 56: t TUPLE (MARK at 37)
257 57: q BINPUT 2
258 59: R REDUCE
259 60: q BINPUT 3
260 62: K BININT1 1
261 64: J BININT -1
262 69: K BININT1 255
263 71: J BININT -255
264 76: J BININT -256
265 81: M BININT2 65535
266 84: J BININT -65535
267 89: J BININT -65536
268 94: J BININT 2147483647
269 99: J BININT -2147483647
270 104: J BININT -2147483648
271 109: ( MARK
272 110: X BINUNICODE 'abc'
273 118: q BINPUT 4
274 120: h BINGET 4
275 122: c GLOBAL 'copyreg _reconstructor'
276 146: q BINPUT 5
277 148: ( MARK
278 149: c GLOBAL '__main__ C'
279 161: q BINPUT 6
280 163: c GLOBAL 'builtins object'
281 180: q BINPUT 7
282 182: N NONE
283 183: t TUPLE (MARK at 148)
284 184: q BINPUT 8
285 186: R REDUCE
286 187: q BINPUT 9
287 189: } EMPTY_DICT
288 190: q BINPUT 10
289 192: ( MARK
290 193: X BINUNICODE 'foo'
291 201: q BINPUT 11
292 203: K BININT1 1
293 205: X BINUNICODE 'bar'
294 213: q BINPUT 12
295 215: K BININT1 2
296 217: u SETITEMS (MARK at 192)
297 218: b BUILD
298 219: h BINGET 9
299 221: t TUPLE (MARK at 109)
300 222: q BINPUT 13
301 224: h BINGET 13
302 226: K BININT1 5
303 228: e APPENDS (MARK at 3)
304 229: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000305highest protocol among opcodes = 1
306"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000307
Guido van Rossum98297ee2007-11-06 21:34:58 +0000308DATA2 = (
309 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000310 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000311 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
312 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
313 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
314 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
315 b'bcq\x04h\x04c__main__\nC\nq\x05'
316 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
317 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
318 b'\nK\x05e.'
319)
Tim Petersfc273752003-03-02 04:54:24 +0000320
Guido van Rossum98297ee2007-11-06 21:34:58 +0000321# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000322DATA2_DIS = """\
323 0: \x80 PROTO 2
324 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000325 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000326 5: ( MARK
327 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000328 8: K BININT1 1
329 10: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000330 19: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000331 37: q BINPUT 1
332 39: G BINFLOAT 3.0
333 48: G BINFLOAT 0.0
334 57: \x86 TUPLE2
335 58: q BINPUT 2
336 60: R REDUCE
337 61: q BINPUT 3
338 63: K BININT1 1
339 65: J BININT -1
340 70: K BININT1 255
341 72: J BININT -255
342 77: J BININT -256
343 82: M BININT2 65535
344 85: J BININT -65535
345 90: J BININT -65536
346 95: J BININT 2147483647
347 100: J BININT -2147483647
348 105: J BININT -2147483648
349 110: ( MARK
350 111: X BINUNICODE 'abc'
351 119: q BINPUT 4
352 121: h BINGET 4
353 123: c GLOBAL '__main__ C'
354 135: q BINPUT 5
355 137: ) EMPTY_TUPLE
356 138: \x81 NEWOBJ
357 139: q BINPUT 6
358 141: } EMPTY_DICT
359 142: q BINPUT 7
360 144: ( MARK
361 145: X BINUNICODE 'foo'
362 153: q BINPUT 8
363 155: K BININT1 1
364 157: X BINUNICODE 'bar'
365 165: q BINPUT 9
366 167: K BININT1 2
367 169: u SETITEMS (MARK at 144)
368 170: b BUILD
369 171: h BINGET 6
370 173: t TUPLE (MARK at 110)
371 174: q BINPUT 10
372 176: h BINGET 10
373 178: K BININT1 5
374 180: e APPENDS (MARK at 5)
375 181: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000376highest protocol among opcodes = 2
377"""
378
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000379# set([1,2]) pickled from 2.x with protocol 2
380DATA3 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
381
382# xrange(5) pickled from 2.x with protocol 2
383DATA4 = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
384
385# a SimpleCookie() object pickled from 2.x with protocol 2
386DATA5 = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
387 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
388 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
389 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
390 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
391 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
392
393# set([3]) pickled from 2.x with protocol 2
394DATA6 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
395
396
Jeremy Hylton66426532001-10-15 21:38:56 +0000397def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000398 c = C()
399 c.foo = 1
400 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000401 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000402 # Append some integer test cases at cPickle.c's internal size
403 # cutoffs.
404 uint1max = 0xff
405 uint2max = 0xffff
406 int4max = 0x7fffffff
407 x.extend([1, -1,
408 uint1max, -uint1max, -uint1max-1,
409 uint2max, -uint2max, -uint2max-1,
410 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000411 y = ('abc', 'abc', c, c)
412 x.append(y)
413 x.append(y)
414 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000415 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000416
Jeremy Hylton66426532001-10-15 21:38:56 +0000417class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000418 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000419
Jeremy Hylton66426532001-10-15 21:38:56 +0000420 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000421
Jeremy Hylton66426532001-10-15 21:38:56 +0000422 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000423 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000424
Jeremy Hylton66426532001-10-15 21:38:56 +0000425 def test_misc(self):
426 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000427 for proto in protocols:
428 x = myint(4)
429 s = self.dumps(x, proto)
430 y = self.loads(s)
431 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000432
Tim Peters70b02d72003-02-02 17:26:40 +0000433 x = (1, ())
434 s = self.dumps(x, proto)
435 y = self.loads(s)
436 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000437
Tim Peters70b02d72003-02-02 17:26:40 +0000438 x = initarg(1, x)
439 s = self.dumps(x, proto)
440 y = self.loads(s)
441 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000442
Jeremy Hylton66426532001-10-15 21:38:56 +0000443 # XXX test __reduce__ protocol?
444
Tim Peters70b02d72003-02-02 17:26:40 +0000445 def test_roundtrip_equality(self):
446 expected = self._testdata
447 for proto in protocols:
448 s = self.dumps(expected, proto)
449 got = self.loads(s)
450 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000451
Guido van Rossum98297ee2007-11-06 21:34:58 +0000452 def test_load_from_data0(self):
453 self.assertEqual(self._testdata, self.loads(DATA0))
454
455 def test_load_from_data1(self):
456 self.assertEqual(self._testdata, self.loads(DATA1))
457
458 def test_load_from_data2(self):
459 self.assertEqual(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000460
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000461 def test_load_classic_instance(self):
462 # See issue5180. Test loading 2.x pickles that
463 # contain an instance of old style class.
464 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
465 xname = X.__name__.encode('ascii')
466 # Protocol 0 (text mode pickle):
467 """
468 0: ( MARK
469 1: i INST '__main__ X' (MARK at 0)
470 15: p PUT 0
471 18: ( MARK
472 19: d DICT (MARK at 18)
473 20: p PUT 1
474 23: b BUILD
475 24: . STOP
476 """
477 pickle0 = (b"(i__main__\n"
478 b"X\n"
479 b"p0\n"
480 b"(dp1\nb.").replace(b'X', xname)
481 self.assertEqual(X(*args), self.loads(pickle0))
482
483 # Protocol 1 (binary mode pickle)
484 """
485 0: ( MARK
486 1: c GLOBAL '__main__ X'
487 15: q BINPUT 0
488 17: o OBJ (MARK at 0)
489 18: q BINPUT 1
490 20: } EMPTY_DICT
491 21: q BINPUT 2
492 23: b BUILD
493 24: . STOP
494 """
495 pickle1 = (b'(c__main__\n'
496 b'X\n'
497 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
498 self.assertEqual(X(*args), self.loads(pickle1))
499
500 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
501 """
502 0: \x80 PROTO 2
503 2: ( MARK
504 3: c GLOBAL '__main__ X'
505 17: q BINPUT 0
506 19: o OBJ (MARK at 2)
507 20: q BINPUT 1
508 22: } EMPTY_DICT
509 23: q BINPUT 2
510 25: b BUILD
511 26: . STOP
512 """
513 pickle2 = (b'\x80\x02(c__main__\n'
514 b'X\n'
515 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
516 self.assertEqual(X(*args), self.loads(pickle2))
517
Tim Peters70b02d72003-02-02 17:26:40 +0000518 # There are gratuitous differences between pickles produced by
519 # pickle and cPickle, largely because cPickle starts PUT indices at
520 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
521 # there's a comment with an exclamation point there whose meaning
522 # is a mystery. cPickle also suppresses PUT for objects with a refcount
523 # of 1.
524 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000525 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000526 from pickletools import dis
527
528 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
529 s = self.dumps(self._testdata, proto)
530 filelike = StringIO()
531 dis(s, out=filelike)
532 got = filelike.getvalue()
533 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000534
535 def test_recursive_list(self):
536 l = []
537 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000538 for proto in protocols:
539 s = self.dumps(l, proto)
540 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000541 self.assertEqual(len(x), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000542 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000543
Collin Winter8ca69de2009-05-26 16:53:41 +0000544 def test_recursive_tuple(self):
545 t = ([],)
546 t[0].append(t)
547 for proto in protocols:
548 s = self.dumps(t, proto)
549 x = self.loads(s)
550 self.assertEqual(len(x), 1)
551 self.assertEqual(len(x[0]), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000552 self.assertTrue(x is x[0][0])
Collin Winter8ca69de2009-05-26 16:53:41 +0000553
Jeremy Hylton66426532001-10-15 21:38:56 +0000554 def test_recursive_dict(self):
555 d = {}
556 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000557 for proto in protocols:
558 s = self.dumps(d, proto)
559 x = self.loads(s)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000560 self.assertEqual(list(x.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000561 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000562
563 def test_recursive_inst(self):
564 i = C()
565 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000566 for proto in protocols:
567 s = self.dumps(i, 2)
568 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000569 self.assertEqual(dir(x), dir(i))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000570 self.assertTrue(x.attr is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000571
572 def test_recursive_multi(self):
573 l = []
574 d = {1:l}
575 i = C()
576 i.attr = d
577 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000578 for proto in protocols:
579 s = self.dumps(l, proto)
580 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000581 self.assertEqual(len(x), 1)
582 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000583 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000584 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000585
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000586 def test_get(self):
587 self.assertRaises(KeyError, self.loads, b'g0\np0')
Ezio Melottib3aedd42010-11-20 19:04:17 +0000588 self.assertEqual(self.loads(b'((Kdtp0\nh\x00l.))'), [(100,), (100,)])
Jeremy Hylton66426532001-10-15 21:38:56 +0000589
590 def test_insecure_strings(self):
Guido van Rossum39478e82007-08-27 17:23:59 +0000591 # XXX Some of these tests are temporarily disabled
592 insecure = [b"abc", b"2 + 2", # not quoted
593 ## b"'abc' + 'def'", # not a single quoted string
594 b"'abc", # quote is not closed
595 b"'abc\"", # open quote and close quote don't match
596 b"'abc' ?", # junk after close quote
597 b"'\\'", # trailing backslash
Jeremy Hylton66426532001-10-15 21:38:56 +0000598 # some tests of the quoting rules
Guido van Rossum39478e82007-08-27 17:23:59 +0000599 ## b"'abc\"\''",
600 ## b"'\\\\a\'\'\'\\\'\\\\\''",
Jeremy Hylton66426532001-10-15 21:38:56 +0000601 ]
Guido van Rossum39478e82007-08-27 17:23:59 +0000602 for b in insecure:
603 buf = b"S" + b + b"\012p0\012."
Jeremy Hylton66426532001-10-15 21:38:56 +0000604 self.assertRaises(ValueError, self.loads, buf)
605
Walter Dörwald9b775532007-06-08 14:30:53 +0000606 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000607 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +0000608 '<\\>', '<\\\U00012345>',
609 # surrogates
610 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000611 for proto in protocols:
612 for u in endcases:
613 p = self.dumps(u, proto)
614 u2 = self.loads(p)
615 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000616
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000617 def test_unicode_high_plane(self):
618 t = '\U00012345'
619 for proto in protocols:
620 p = self.dumps(t, proto)
621 t2 = self.loads(p)
622 self.assertEqual(t2, t)
623
Guido van Rossumf4169812008-03-17 22:56:06 +0000624 def test_bytes(self):
625 for proto in protocols:
626 for u in b'', b'xyz', b'xyz'*100:
627 p = self.dumps(u)
628 self.assertEqual(self.loads(p), u)
629
Jeremy Hylton66426532001-10-15 21:38:56 +0000630 def test_ints(self):
631 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000632 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000633 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000634 while n:
635 for expected in (-n, n):
636 s = self.dumps(expected, proto)
637 n2 = self.loads(s)
638 self.assertEqual(expected, n2)
639 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000640
Jeremy Hylton66426532001-10-15 21:38:56 +0000641 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000642 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000643 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000644 got = self.loads(data)
645 self.assertEqual(got, maxint64)
646
647 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000648 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000649 self.assertRaises(ValueError, self.loads, data)
650
Tim Petersee1a53c2003-02-02 02:57:53 +0000651 def test_long(self):
652 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000653 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000654 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000655 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000656 for npos in nbase-1, nbase, nbase+1:
657 for n in npos, -npos:
658 pickle = self.dumps(n, proto)
659 got = self.loads(pickle)
660 self.assertEqual(n, got)
661 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
662 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000663 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000664 nbase += nbase << 1000000
665 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000666 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000667 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000668 self.assertEqual(n, got)
669
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000670 def test_float(self):
671 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
672 3.14, 263.44582062374053, 6.022e23, 1e30]
673 test_values = test_values + [-x for x in test_values]
674 for proto in protocols:
675 for value in test_values:
676 pickle = self.dumps(value, proto)
677 got = self.loads(pickle)
678 self.assertEqual(value, got)
679
Thomas Wouters477c8d52006-05-27 19:21:47 +0000680 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
681 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000682 # make sure that floats are formatted locale independent with proto 0
683 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000684
Jeremy Hylton66426532001-10-15 21:38:56 +0000685 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000686 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000687
688 def test_getinitargs(self):
689 pass
690
Guido van Rossum04a86612001-12-19 16:58:54 +0000691 def test_metaclass(self):
692 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000693 for proto in protocols:
694 s = self.dumps(a, proto)
695 b = self.loads(s)
696 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000697
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000698 def test_structseq(self):
699 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000700 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000701
702 t = time.localtime()
703 for proto in protocols:
704 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000705 u = self.loads(s)
706 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000707 if hasattr(os, "stat"):
708 t = os.stat(os.curdir)
709 s = self.dumps(t, proto)
710 u = self.loads(s)
711 self.assertEqual(t, u)
712 if hasattr(os, "statvfs"):
713 t = os.statvfs(os.curdir)
714 s = self.dumps(t, proto)
715 u = self.loads(s)
716 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000717
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000718 # Tests for protocol 2
719
Tim Peters4190fb82003-02-02 16:09:05 +0000720 def test_proto(self):
721 build_none = pickle.NONE + pickle.STOP
722 for proto in protocols:
723 expected = build_none
724 if proto >= 2:
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000725 expected = pickle.PROTO + bytes([proto]) + expected
Tim Peters4190fb82003-02-02 16:09:05 +0000726 p = self.dumps(None, proto)
727 self.assertEqual(p, expected)
728
729 oob = protocols[-1] + 1 # a future protocol
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000730 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000731 try:
732 self.loads(badpickle)
Guido van Rossumb940e112007-01-10 16:19:56 +0000733 except ValueError as detail:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000734 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +0000735 "unsupported pickle protocol"))
736 else:
737 self.fail("expected bad protocol number to raise ValueError")
738
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000739 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000740 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000741 for proto in protocols:
742 s = self.dumps(x, proto)
743 y = self.loads(s)
744 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000745 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000746
747 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000748 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000749 for proto in protocols:
750 s = self.dumps(x, proto)
751 y = self.loads(s)
752 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000753 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000754
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000755 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000756 # Map (proto, len(tuple)) to expected opcode.
757 expected_opcode = {(0, 0): pickle.TUPLE,
758 (0, 1): pickle.TUPLE,
759 (0, 2): pickle.TUPLE,
760 (0, 3): pickle.TUPLE,
761 (0, 4): pickle.TUPLE,
762
763 (1, 0): pickle.EMPTY_TUPLE,
764 (1, 1): pickle.TUPLE,
765 (1, 2): pickle.TUPLE,
766 (1, 3): pickle.TUPLE,
767 (1, 4): pickle.TUPLE,
768
769 (2, 0): pickle.EMPTY_TUPLE,
770 (2, 1): pickle.TUPLE1,
771 (2, 2): pickle.TUPLE2,
772 (2, 3): pickle.TUPLE3,
773 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000774
775 (3, 0): pickle.EMPTY_TUPLE,
776 (3, 1): pickle.TUPLE1,
777 (3, 2): pickle.TUPLE2,
778 (3, 3): pickle.TUPLE3,
779 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000780 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000781 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000782 b = (1,)
783 c = (1, 2)
784 d = (1, 2, 3)
785 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000786 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000787 for x in a, b, c, d, e:
788 s = self.dumps(x, proto)
789 y = self.loads(s)
790 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000791 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +0000792 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +0000793
Guido van Rossum7d97d312003-01-28 04:25:27 +0000794 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000795 # Map (proto, singleton) to expected opcode.
796 expected_opcode = {(0, None): pickle.NONE,
797 (1, None): pickle.NONE,
798 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000799 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000800
801 (0, True): pickle.INT,
802 (1, True): pickle.INT,
803 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000804 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000805
806 (0, False): pickle.INT,
807 (1, False): pickle.INT,
808 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000809 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000810 }
Tim Peters4190fb82003-02-02 16:09:05 +0000811 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000812 for x in None, False, True:
813 s = self.dumps(x, proto)
814 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000815 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +0000816 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +0000817 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +0000818
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000819 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000820 x = MyTuple([1, 2, 3])
821 x.foo = 42
822 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000823 for proto in protocols:
824 s = self.dumps(x, proto)
825 y = self.loads(s)
826 self.assertEqual(tuple(x), tuple(y))
827 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000828
829 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000830 x = MyList([1, 2, 3])
831 x.foo = 42
832 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000833 for proto in protocols:
834 s = self.dumps(x, proto)
835 y = self.loads(s)
836 self.assertEqual(list(x), list(y))
837 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000838
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000839 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +0000840 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000841 for C in myclasses:
842 B = C.__base__
843 x = C(C.sample)
844 x.foo = 42
845 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000846 y = self.loads(s)
847 detail = (proto, C, B, x, y, type(y))
848 self.assertEqual(B(x), B(y), detail)
849 self.assertEqual(x.__dict__, y.__dict__, detail)
850
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000851 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +0000852 # an object of that type. Check that the resulting pickle uses opcode
853 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +0000854
Tim Peters22e71712003-02-03 22:27:38 +0000855 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +0000856 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000857 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000858 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000859 x = MyList([1, 2, 3])
860 x.foo = 42
861 x.bar = "hello"
862
Tim Peters22e71712003-02-03 22:27:38 +0000863 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000864 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000865 self.assertIn(__name__.encode("utf-8"), s1)
866 self.assertIn(b"MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +0000867 self.assertEqual(opcode_in_pickle(opcode, s1), False)
868
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000869 y = self.loads(s1)
870 self.assertEqual(list(x), list(y))
871 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000872
Tim Peters22e71712003-02-03 22:27:38 +0000873 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000874 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000875 self.assertNotIn(__name__.encode("utf-8"), s2)
876 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000877 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +0000878
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000879 y = self.loads(s2)
880 self.assertEqual(list(x), list(y))
881 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000882
883 finally:
Tim Peters3e667d52003-02-04 21:47:44 +0000884 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +0000885
886 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000887 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
888 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000889
890 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000891 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
892 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
893 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000894
895 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000896 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
897 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
898 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
899
Tim Peters8d2613a2003-02-11 16:40:16 +0000900 def test_list_chunking(self):
901 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +0000902 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000903 for proto in protocols:
904 s = self.dumps(x, proto)
905 y = self.loads(s)
906 self.assertEqual(x, y)
907 num_appends = count_opcode(pickle.APPENDS, s)
908 self.assertEqual(num_appends, proto > 0)
909
910 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +0000911 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000912 for proto in protocols:
913 s = self.dumps(x, proto)
914 y = self.loads(s)
915 self.assertEqual(x, y)
916 num_appends = count_opcode(pickle.APPENDS, s)
917 if proto == 0:
918 self.assertEqual(num_appends, 0)
919 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000920 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +0000921
922 def test_dict_chunking(self):
923 n = 10 # too small to chunk
924 x = dict.fromkeys(range(n))
925 for proto in protocols:
926 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +0000927 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +0000928 y = self.loads(s)
929 self.assertEqual(x, y)
930 num_setitems = count_opcode(pickle.SETITEMS, s)
931 self.assertEqual(num_setitems, proto > 0)
932
933 n = 2500 # expect at least two chunks when proto > 0
934 x = dict.fromkeys(range(n))
935 for proto in protocols:
936 s = self.dumps(x, proto)
937 y = self.loads(s)
938 self.assertEqual(x, y)
939 num_setitems = count_opcode(pickle.SETITEMS, s)
940 if proto == 0:
941 self.assertEqual(num_setitems, 0)
942 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000943 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000944
Tim Peterse9ef2032003-02-13 18:42:00 +0000945 def test_simple_newobj(self):
946 x = object.__new__(SimpleNewObj) # avoid __init__
947 x.abc = 666
948 for proto in protocols:
949 s = self.dumps(x, proto)
950 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
951 y = self.loads(s) # will raise TypeError if __init__ called
952 self.assertEqual(y.abc, 666)
953 self.assertEqual(x.__dict__, y.__dict__)
954
Tim Peters42f08ac2003-02-11 22:43:24 +0000955 def test_newobj_list_slots(self):
956 x = SlotList([1, 2, 3])
957 x.foo = 42
958 x.bar = "hello"
959 s = self.dumps(x, 2)
960 y = self.loads(s)
961 self.assertEqual(list(x), list(y))
962 self.assertEqual(x.__dict__, y.__dict__)
963 self.assertEqual(x.foo, y.foo)
964 self.assertEqual(x.bar, y.bar)
965
Guido van Rossum2a30b212003-02-18 22:41:24 +0000966 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +0000967 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000968 x = REX_one()
969 self.assertEqual(x._reduce_called, 0)
970 s = self.dumps(x, proto)
971 self.assertEqual(x._reduce_called, 1)
972 y = self.loads(s)
973 self.assertEqual(y._reduce_called, 0)
974
975 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +0000976 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000977 x = REX_two()
978 self.assertEqual(x._proto, None)
979 s = self.dumps(x, proto)
980 self.assertEqual(x._proto, proto)
981 y = self.loads(s)
982 self.assertEqual(y._proto, None)
983
984 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +0000985 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000986 x = REX_three()
987 self.assertEqual(x._proto, None)
988 s = self.dumps(x, proto)
989 self.assertEqual(x._proto, proto)
990 y = self.loads(s)
991 self.assertEqual(y._proto, None)
992
Guido van Rossumd8faa362007-04-27 19:54:29 +0000993 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +0000994 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000995 x = REX_four()
996 self.assertEqual(x._proto, None)
997 s = self.dumps(x, proto)
998 self.assertEqual(x._proto, proto)
999 y = self.loads(s)
1000 self.assertEqual(y._proto, proto)
1001
1002 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001003 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001004 x = REX_five()
1005 self.assertEqual(x._reduce_called, 0)
1006 s = self.dumps(x, proto)
1007 self.assertEqual(x._reduce_called, 1)
1008 y = self.loads(s)
1009 self.assertEqual(y._reduce_called, 1)
1010
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001011 def test_bad_getattr(self):
1012 x = BadGetattr()
1013 for proto in 0, 1:
1014 self.assertRaises(RuntimeError, self.dumps, x, proto)
1015 # protocol 2 don't raise a RuntimeError.
1016 d = self.dumps(x, 2)
Antoine Pitrouff150f22010-10-22 21:41:05 +00001017 self.assertRaises(RuntimeError, self.loads, d)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001018
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001019 def test_reduce_bad_iterator(self):
1020 # Issue4176: crash when 4th and 5th items of __reduce__()
1021 # are not iterators
1022 class C(object):
1023 def __reduce__(self):
1024 # 4th item is not an iterator
1025 return list, (), None, [], None
1026 class D(object):
1027 def __reduce__(self):
1028 # 5th item is not an iterator
1029 return dict, (), None, None, []
1030
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001031 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001032 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001033 try:
1034 self.dumps(C(), proto)
1035 except (pickle.PickleError):
1036 pass
1037 try:
1038 self.dumps(D(), proto)
1039 except (pickle.PickleError):
1040 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001041
Collin Winter771d8342009-04-16 03:18:06 +00001042 def test_many_puts_and_gets(self):
1043 # Test that internal data structures correctly deal with lots of
1044 # puts/gets.
1045 keys = ("aaa" + str(i) for i in range(100))
1046 large_dict = dict((k, [4, 5, 6]) for k in keys)
1047 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1048
1049 for proto in protocols:
1050 dumped = self.dumps(obj, proto)
1051 loaded = self.loads(dumped)
1052 self.assertEqual(loaded, obj,
1053 "Failed protocol %d: %r != %r"
1054 % (proto, obj, loaded))
1055
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001056 def test_attribute_name_interning(self):
1057 # Test that attribute names of pickled objects are interned when
1058 # unpickling.
1059 for proto in protocols:
1060 x = C()
1061 x.foo = 42
1062 x.bar = "hello"
1063 s = self.dumps(x, proto)
1064 y = self.loads(s)
1065 x_keys = sorted(x.__dict__)
1066 y_keys = sorted(y.__dict__)
1067 for x_key, y_key in zip(x_keys, y_keys):
1068 self.assertIs(x_key, y_key)
1069
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001070 def test_unpickle_from_2x(self):
1071 # Unpickle non-trivial data from Python 2.x.
1072 loaded = self.loads(DATA3)
1073 self.assertEqual(loaded, set([1, 2]))
1074 loaded = self.loads(DATA4)
1075 self.assertEqual(type(loaded), type(range(0)))
1076 self.assertEqual(list(loaded), list(range(5)))
1077 loaded = self.loads(DATA5)
1078 self.assertEqual(type(loaded), SimpleCookie)
1079 self.assertEqual(list(loaded.keys()), ["key"])
1080 self.assertEqual(loaded["key"].value, "Set-Cookie: key=value")
1081
1082 def test_pickle_to_2x(self):
1083 # Pickle non-trivial data with protocol 2, expecting that it yields
1084 # the same result as Python 2.x did.
1085 # NOTE: this test is a bit too strong since we can produce different
1086 # bytecode that 2.x will still understand.
1087 dumped = self.dumps(range(5), 2)
1088 self.assertEqual(dumped, DATA4)
1089 dumped = self.dumps(set([3]), 2)
1090 self.assertEqual(dumped, DATA6)
1091
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001092 def test_large_pickles(self):
1093 # Test the correctness of internal buffering routines when handling
1094 # large data.
1095 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001096 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001097 dumped = self.dumps(data, proto)
1098 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001099 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001100 self.assertEqual(loaded, data)
1101
Alexander Belopolskyec8f0df2011-02-24 20:34:38 +00001102 def test_empty_bytestring(self):
1103 # issue 11286
1104 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1105 self.assertEqual(empty, '')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001106
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001107 def check_negative_32b_binXXX(self, dumped):
1108 if sys.maxsize > 2**32:
1109 self.skipTest("test is only meaningful on 32-bit builds")
1110 # XXX Pure Python pickle reads lengths as signed and passes
1111 # them directly to read() (hence the EOFError)
1112 with self.assertRaises((pickle.UnpicklingError, EOFError,
1113 ValueError, OverflowError)):
1114 self.loads(dumped)
1115
1116 def test_negative_32b_binbytes(self):
1117 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1118 self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.')
1119
1120 def test_negative_32b_binunicode(self):
1121 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1122 self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.')
1123
Antoine Pitrou55549ec2011-08-30 00:27:10 +02001124 def test_negative_put(self):
1125 # Issue #12847
1126 dumped = b'Va\np-1\n.'
1127 self.assertRaises(ValueError, self.loads, dumped)
1128
1129 def test_negative_32b_binput(self):
1130 # Issue #12847
1131 if sys.maxsize > 2**32:
1132 self.skipTest("test is only meaningful on 32-bit builds")
1133 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
1134 self.assertRaises(ValueError, self.loads, dumped)
1135
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001136
1137class BigmemPickleTests(unittest.TestCase):
1138
1139 # Binary protocols can serialize longs of up to 2GB-1
1140
1141 @precisionbigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
1142 def test_huge_long_32b(self, size):
1143 data = 1 << (8 * size)
1144 try:
1145 for proto in protocols:
1146 if proto < 2:
1147 continue
1148 with self.assertRaises((ValueError, OverflowError)):
1149 self.dumps(data, protocol=proto)
1150 finally:
1151 data = None
1152
1153 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1154 # (older protocols don't have a dedicated opcode for bytes and are
1155 # too inefficient)
1156
1157 @precisionbigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
1158 def test_huge_bytes_32b(self, size):
1159 data = b"abcd" * (size // 4)
1160 try:
1161 for proto in protocols:
1162 if proto < 3:
1163 continue
1164 try:
1165 pickled = self.dumps(data, protocol=proto)
1166 self.assertTrue(b"abcd" in pickled[:15])
1167 self.assertTrue(b"abcd" in pickled[-15:])
1168 finally:
1169 pickled = None
1170 finally:
1171 data = None
1172
1173 @precisionbigmemtest(size=_4G, memuse=1 + 1, dry_run=False)
1174 def test_huge_bytes_64b(self, size):
1175 data = b"a" * size
1176 try:
1177 for proto in protocols:
1178 if proto < 3:
1179 continue
1180 with self.assertRaises((ValueError, OverflowError)):
1181 self.dumps(data, protocol=proto)
1182 finally:
1183 data = None
1184
1185 # All protocols use 1-byte per printable ASCII character; we add another
1186 # byte because the encoded form has to be copied into the internal buffer.
1187
1188 @precisionbigmemtest(size=_2G, memuse=2 + character_size, dry_run=False)
1189 def test_huge_str_32b(self, size):
1190 data = "abcd" * (size // 4)
1191 try:
1192 for proto in protocols:
1193 try:
1194 pickled = self.dumps(data, protocol=proto)
1195 self.assertTrue(b"abcd" in pickled[:15])
1196 self.assertTrue(b"abcd" in pickled[-15:])
1197 finally:
1198 pickled = None
1199 finally:
1200 data = None
1201
Antoine Pitroue897e952011-08-30 23:39:34 +02001202 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than
1203 # 2**32 - 1 bytes of utf-8 encoded unicode.
1204
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001205 @precisionbigmemtest(size=_4G, memuse=1 + character_size, dry_run=False)
1206 def test_huge_str_64b(self, size):
1207 data = "a" * size
1208 try:
1209 for proto in protocols:
Antoine Pitroue897e952011-08-30 23:39:34 +02001210 if proto == 0:
1211 continue
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001212 with self.assertRaises((ValueError, OverflowError)):
1213 self.dumps(data, protocol=proto)
1214 finally:
1215 data = None
1216
1217
Guido van Rossum2a30b212003-02-18 22:41:24 +00001218# Test classes for reduce_ex
1219
1220class REX_one(object):
1221 _reduce_called = 0
1222 def __reduce__(self):
1223 self._reduce_called = 1
1224 return REX_one, ()
1225 # No __reduce_ex__ here, but inheriting it from object
1226
1227class REX_two(object):
1228 _proto = None
1229 def __reduce_ex__(self, proto):
1230 self._proto = proto
1231 return REX_two, ()
1232 # No __reduce__ here, but inheriting it from object
1233
1234class REX_three(object):
1235 _proto = None
1236 def __reduce_ex__(self, proto):
1237 self._proto = proto
1238 return REX_two, ()
1239 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001240 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001241
Guido van Rossumd8faa362007-04-27 19:54:29 +00001242class REX_four(object):
1243 _proto = None
1244 def __reduce_ex__(self, proto):
1245 self._proto = proto
1246 return object.__reduce_ex__(self, proto)
1247 # Calling base class method should succeed
1248
1249class REX_five(object):
1250 _reduce_called = 0
1251 def __reduce__(self):
1252 self._reduce_called = 1
1253 return object.__reduce__(self)
1254 # This one used to fail with infinite recursion
1255
Guido van Rossum2a30b212003-02-18 22:41:24 +00001256# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001257
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001258class MyInt(int):
1259 sample = 1
1260
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001261class MyFloat(float):
1262 sample = 1.0
1263
1264class MyComplex(complex):
1265 sample = 1.0 + 0.0j
1266
1267class MyStr(str):
1268 sample = "hello"
1269
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001270class MyUnicode(str):
1271 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001272
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001273class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001274 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001275
1276class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001277 sample = [1, 2, 3]
1278
1279class MyDict(dict):
1280 sample = {"a": 1, "b": 2}
1281
Mark Dickinson5c2db372009-12-05 20:28:34 +00001282myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001283 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001284 MyStr, MyUnicode,
1285 MyTuple, MyList, MyDict]
1286
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001287
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001288class SlotList(MyList):
1289 __slots__ = ["foo"]
1290
Tim Peterse9ef2032003-02-13 18:42:00 +00001291class SimpleNewObj(object):
1292 def __init__(self, a, b, c):
1293 # raise an error, to make sure this isn't called
1294 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1295
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001296class BadGetattr:
1297 def __getattr__(self, key):
1298 self.foo
1299
Collin Winter771d8342009-04-16 03:18:06 +00001300
Jeremy Hylton66426532001-10-15 21:38:56 +00001301class AbstractPickleModuleTests(unittest.TestCase):
1302
1303 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001304 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001305 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001306 try:
1307 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001308 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001309 finally:
1310 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001311
1312 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001313 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001314 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001315 try:
1316 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001317 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001318 finally:
1319 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001320
Collin Winter771d8342009-04-16 03:18:06 +00001321 def test_load_from_and_dump_to_file(self):
1322 stream = io.BytesIO()
1323 data = [123, {}, 124]
1324 pickle.dump(data, stream)
1325 stream.seek(0)
1326 unpickled = pickle.load(stream)
1327 self.assertEqual(unpickled, data)
1328
Tim Petersc0c93702003-02-13 19:30:57 +00001329 def test_highest_protocol(self):
1330 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001331 self.assertEqual(pickle.HIGHEST_PROTOCOL, 3)
Tim Petersc0c93702003-02-13 19:30:57 +00001332
Martin v. Löwis544f1192004-07-27 05:22:33 +00001333 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001334 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001335 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001336 pickle.dump(123, f, -1)
1337 pickle.dump(123, file=f, protocol=-1)
1338 pickle.dumps(123, -1)
1339 pickle.dumps(123, protocol=-1)
1340 pickle.Pickler(f, -1)
1341 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001342
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001343 def test_bad_init(self):
1344 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001345 # Override initialization without calling __init__() of the superclass.
1346 class BadPickler(pickle.Pickler):
1347 def __init__(self): pass
1348
1349 class BadUnpickler(pickle.Unpickler):
1350 def __init__(self): pass
1351
1352 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1353 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1354
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001355 def test_bad_input(self):
1356 # Test issue4298
1357 s = bytes([0x58, 0, 0, 0, 0x54])
1358 self.assertRaises(EOFError, pickle.loads, s)
Antoine Pitrou01a15ea2010-01-07 17:57:31 +00001359 # Test issue7455
1360 s = b'0'
1361 self.assertRaises(pickle.UnpicklingError, pickle.loads, s)
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001362
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001363
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001364class AbstractPersistentPicklerTests(unittest.TestCase):
1365
1366 # This class defines persistent_id() and persistent_load()
1367 # functions that should be used by the pickler. All even integers
1368 # are pickled using persistent ids.
1369
1370 def persistent_id(self, object):
1371 if isinstance(object, int) and object % 2 == 0:
1372 self.id_count += 1
1373 return str(object)
1374 else:
1375 return None
1376
1377 def persistent_load(self, oid):
1378 self.load_count += 1
1379 object = int(oid)
1380 assert object % 2 == 0
1381 return object
1382
1383 def test_persistence(self):
1384 self.id_count = 0
1385 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001386 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001387 self.assertEqual(self.loads(self.dumps(L)), L)
1388 self.assertEqual(self.id_count, 5)
1389 self.assertEqual(self.load_count, 5)
1390
1391 def test_bin_persistence(self):
1392 self.id_count = 0
1393 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001394 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001395 self.assertEqual(self.loads(self.dumps(L, 1)), L)
1396 self.assertEqual(self.id_count, 5)
1397 self.assertEqual(self.load_count, 5)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001398
Collin Winter771d8342009-04-16 03:18:06 +00001399
1400class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1401
1402 pickler_class = None
1403 unpickler_class = None
1404
1405 def setUp(self):
1406 assert self.pickler_class
1407 assert self.unpickler_class
1408
1409 def test_clear_pickler_memo(self):
1410 # To test whether clear_memo() has any effect, we pickle an object,
1411 # then pickle it again without clearing the memo; the two serialized
1412 # forms should be different. If we clear_memo() and then pickle the
1413 # object again, the third serialized form should be identical to the
1414 # first one we obtained.
1415 data = ["abcdefg", "abcdefg", 44]
1416 f = io.BytesIO()
1417 pickler = self.pickler_class(f)
1418
1419 pickler.dump(data)
1420 first_pickled = f.getvalue()
1421
1422 # Reset StringIO object.
1423 f.seek(0)
1424 f.truncate()
1425
1426 pickler.dump(data)
1427 second_pickled = f.getvalue()
1428
1429 # Reset the Pickler and StringIO objects.
1430 pickler.clear_memo()
1431 f.seek(0)
1432 f.truncate()
1433
1434 pickler.dump(data)
1435 third_pickled = f.getvalue()
1436
1437 self.assertNotEqual(first_pickled, second_pickled)
1438 self.assertEqual(first_pickled, third_pickled)
1439
1440 def test_priming_pickler_memo(self):
1441 # Verify that we can set the Pickler's memo attribute.
1442 data = ["abcdefg", "abcdefg", 44]
1443 f = io.BytesIO()
1444 pickler = self.pickler_class(f)
1445
1446 pickler.dump(data)
1447 first_pickled = f.getvalue()
1448
1449 f = io.BytesIO()
1450 primed = self.pickler_class(f)
1451 primed.memo = pickler.memo
1452
1453 primed.dump(data)
1454 primed_pickled = f.getvalue()
1455
1456 self.assertNotEqual(first_pickled, primed_pickled)
1457
1458 def test_priming_unpickler_memo(self):
1459 # Verify that we can set the Unpickler's memo attribute.
1460 data = ["abcdefg", "abcdefg", 44]
1461 f = io.BytesIO()
1462 pickler = self.pickler_class(f)
1463
1464 pickler.dump(data)
1465 first_pickled = f.getvalue()
1466
1467 f = io.BytesIO()
1468 primed = self.pickler_class(f)
1469 primed.memo = pickler.memo
1470
1471 primed.dump(data)
1472 primed_pickled = f.getvalue()
1473
1474 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
1475 unpickled_data1 = unpickler.load()
1476
1477 self.assertEqual(unpickled_data1, data)
1478
1479 primed = self.unpickler_class(io.BytesIO(primed_pickled))
1480 primed.memo = unpickler.memo
1481 unpickled_data2 = primed.load()
1482
1483 primed.memo.clear()
1484
1485 self.assertEqual(unpickled_data2, data)
1486 self.assertTrue(unpickled_data2 is unpickled_data1)
1487
1488 def test_reusing_unpickler_objects(self):
1489 data1 = ["abcdefg", "abcdefg", 44]
1490 f = io.BytesIO()
1491 pickler = self.pickler_class(f)
1492 pickler.dump(data1)
1493 pickled1 = f.getvalue()
1494
1495 data2 = ["abcdefg", 44, 44]
1496 f = io.BytesIO()
1497 pickler = self.pickler_class(f)
1498 pickler.dump(data2)
1499 pickled2 = f.getvalue()
1500
1501 f = io.BytesIO()
1502 f.write(pickled1)
1503 f.seek(0)
1504 unpickler = self.unpickler_class(f)
1505 self.assertEqual(unpickler.load(), data1)
1506
1507 f.seek(0)
1508 f.truncate()
1509 f.write(pickled2)
1510 f.seek(0)
1511 self.assertEqual(unpickler.load(), data2)
1512
Antoine Pitrou04248a82010-10-12 20:51:21 +00001513 def _check_multiple_unpicklings(self, ioclass):
1514 for proto in protocols:
1515 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
1516 f = ioclass()
1517 pickler = self.pickler_class(f, protocol=proto)
1518 pickler.dump(data1)
1519 pickled = f.getvalue()
1520
1521 N = 5
1522 f = ioclass(pickled * N)
1523 unpickler = self.unpickler_class(f)
1524 for i in range(N):
1525 if f.seekable():
1526 pos = f.tell()
1527 self.assertEqual(unpickler.load(), data1)
1528 if f.seekable():
1529 self.assertEqual(f.tell(), pos + len(pickled))
1530 self.assertRaises(EOFError, unpickler.load)
1531
1532 def test_multiple_unpicklings_seekable(self):
1533 self._check_multiple_unpicklings(io.BytesIO)
1534
1535 def test_multiple_unpicklings_unseekable(self):
1536 self._check_multiple_unpicklings(UnseekableIO)
1537
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02001538 def test_unpickling_buffering_readline(self):
1539 # Issue #12687: the unpickler's buffering logic could fail with
1540 # text mode opcodes.
1541 data = list(range(10))
1542 for proto in protocols:
1543 for buf_size in range(1, 11):
1544 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
1545 pickler = self.pickler_class(f, protocol=proto)
1546 pickler.dump(data)
1547 f.seek(0)
1548 unpickler = self.unpickler_class(f)
1549 self.assertEqual(unpickler.load(), data)
1550
Collin Winter771d8342009-04-16 03:18:06 +00001551
Guido van Rossum98297ee2007-11-06 21:34:58 +00001552if __name__ == "__main__":
1553 # Print some stuff that can be used to rewrite DATA{0,1,2}
1554 from pickletools import dis
1555 x = create_data()
1556 for i in range(3):
1557 p = pickle.dumps(x, i)
1558 print("DATA{0} = (".format(i))
1559 for j in range(0, len(p), 20):
1560 b = bytes(p[j:j+20])
1561 print(" {0!r}".format(b))
1562 print(")")
1563 print()
1564 print("# Disassembly of DATA{0}".format(i))
1565 print("DATA{0}_DIS = \"\"\"\\".format(i))
1566 dis(p)
1567 print("\"\"\"")
1568 print()