blob: f4b50aa3758955a416cf30d837fc8a7998ca55df [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 Pitrou16c4ce12011-03-11 21:30:43 +01007import weakref
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00008from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +00009
Antoine Pitrou82be19f2011-08-29 23:09:33 +020010from test.support import (
Antoine Pitrouee763e22011-08-29 23:14:53 +020011 TestFailed, TESTFN, run_with_locale, no_tracing,
Antoine Pitrou82be19f2011-08-29 23:09:33 +020012 _2G, _4G, precisionbigmemtest,
13 )
Tim Peterse089c682001-04-10 03:41:41 +000014
Guido van Rossum98297ee2007-11-06 21:34:58 +000015from pickle import bytes_types
16
Tim Petersee1a53c2003-02-02 02:57:53 +000017# Tests that try a number of pickle protocols should have a
18# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000019# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000020protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000021
Antoine Pitrou82be19f2011-08-29 23:09:33 +020022character_size = 4 if sys.maxunicode > 0xFFFF else 2
23
Tim Peters22e71712003-02-03 22:27:38 +000024
25# Return True if opcode code appears in the pickle, else False.
26def opcode_in_pickle(code, pickle):
27 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000028 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000029 return True
30 return False
31
Tim Peters8d2613a2003-02-11 16:40:16 +000032# Return the number of times opcode code appears in pickle.
33def count_opcode(code, pickle):
34 n = 0
35 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000036 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000037 n += 1
38 return n
39
Antoine Pitrou04248a82010-10-12 20:51:21 +000040
41class UnseekableIO(io.BytesIO):
42 def peek(self, *args):
43 raise NotImplementedError
44
45 def seekable(self):
46 return False
47
48 def seek(self, *args):
49 raise io.UnsupportedOperation
50
51 def tell(self):
52 raise io.UnsupportedOperation
53
54
Tim Peters3e667d52003-02-04 21:47:44 +000055# We can't very well test the extension registry without putting known stuff
56# in it, but we have to be careful to restore its original state. Code
57# should do this:
58#
59# e = ExtensionSaver(extension_code)
60# try:
61# fiddle w/ the extension registry's stuff for extension_code
62# finally:
63# e.restore()
64
65class ExtensionSaver:
66 # Remember current registration for code (if any), and remove it (if
67 # there is one).
68 def __init__(self, code):
69 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000070 if code in copyreg._inverted_registry:
71 self.pair = copyreg._inverted_registry[code]
72 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000073 else:
74 self.pair = None
75
76 # Restore previous registration for code.
77 def restore(self):
78 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000079 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000080 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000081 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000082 pair = self.pair
83 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000084 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000085
Jeremy Hylton66426532001-10-15 21:38:56 +000086class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000087 def __eq__(self, other):
88 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000089
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000090class D(C):
91 def __init__(self, arg):
92 pass
93
94class E(C):
95 def __getinitargs__(self):
96 return ()
97
Jeremy Hylton66426532001-10-15 21:38:56 +000098import __main__
99__main__.C = C
100C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000101__main__.D = D
102D.__module__ = "__main__"
103__main__.E = E
104E.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000105
106class myint(int):
107 def __init__(self, x):
108 self.str = str(x)
109
110class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000111
Jeremy Hylton66426532001-10-15 21:38:56 +0000112 def __init__(self, a, b):
113 self.a = a
114 self.b = b
115
116 def __getinitargs__(self):
117 return self.a, self.b
118
Guido van Rossum04a86612001-12-19 16:58:54 +0000119class metaclass(type):
120 pass
121
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000122class use_metaclass(object, metaclass=metaclass):
123 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000124
Tim Peters70b02d72003-02-02 17:26:40 +0000125# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
126# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000127
Guido van Rossum98297ee2007-11-06 21:34:58 +0000128DATA0 = (
Mark Dickinson8dd05142009-01-20 20:43:58 +0000129 b'(lp0\nL0L\naL1L\naF2.0\nac'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000130 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000131 b'p1\n(F3.0\nF0.0\ntp2\nRp'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000132 b'3\naL1L\naL-1L\naL255L\naL-'
133 b'255L\naL-256L\naL65535L\na'
134 b'L-65535L\naL-65536L\naL2'
135 b'147483647L\naL-2147483'
136 b'647L\naL-2147483648L\na('
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000137 b'Vabc\np4\ng4\nccopyreg'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000138 b'\n_reconstructor\np5\n('
Georg Brandl1a3284e2007-12-02 09:40:06 +0000139 b'c__main__\nC\np6\ncbu'
140 b'iltins\nobject\np7\nNt'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000141 b'p8\nRp9\n(dp10\nVfoo\np1'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000142 b'1\nL1L\nsVbar\np12\nL2L\nsb'
143 b'g9\ntp13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000144)
Tim Peterse9358162001-01-22 22:05:20 +0000145
Guido van Rossum98297ee2007-11-06 21:34:58 +0000146# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000147DATA0_DIS = """\
148 0: ( MARK
149 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000150 2: p PUT 0
151 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000152 9: a APPEND
153 10: L LONG 1
154 14: a APPEND
155 15: F FLOAT 2.0
156 20: a APPEND
157 21: c GLOBAL 'builtins complex'
158 39: p PUT 1
159 42: ( MARK
160 43: F FLOAT 3.0
161 48: F FLOAT 0.0
162 53: t TUPLE (MARK at 42)
163 54: p PUT 2
164 57: R REDUCE
165 58: p PUT 3
166 61: a APPEND
167 62: L LONG 1
168 66: a APPEND
169 67: L LONG -1
170 72: a APPEND
171 73: L LONG 255
172 79: a APPEND
173 80: L LONG -255
174 87: a APPEND
175 88: L LONG -256
176 95: a APPEND
177 96: L LONG 65535
178 104: a APPEND
179 105: L LONG -65535
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000180 114: a APPEND
Mark Dickinson8dd05142009-01-20 20:43:58 +0000181 115: L LONG -65536
182 124: a APPEND
183 125: L LONG 2147483647
184 138: a APPEND
185 139: L LONG -2147483647
186 153: a APPEND
187 154: L LONG -2147483648
188 168: a APPEND
189 169: ( MARK
190 170: V UNICODE 'abc'
191 175: p PUT 4
192 178: g GET 4
193 181: c GLOBAL 'copyreg _reconstructor'
194 205: p PUT 5
195 208: ( MARK
196 209: c GLOBAL '__main__ C'
197 221: p PUT 6
198 224: c GLOBAL 'builtins object'
199 241: p PUT 7
200 244: N NONE
201 245: t TUPLE (MARK at 208)
202 246: p PUT 8
203 249: R REDUCE
204 250: p PUT 9
205 253: ( MARK
206 254: d DICT (MARK at 253)
207 255: p PUT 10
208 259: V UNICODE 'foo'
209 264: p PUT 11
210 268: L LONG 1
211 272: s SETITEM
212 273: V UNICODE 'bar'
213 278: p PUT 12
214 282: L LONG 2
215 286: s SETITEM
216 287: b BUILD
217 288: g GET 9
218 291: t TUPLE (MARK at 169)
219 292: p PUT 13
220 296: a APPEND
221 297: g GET 13
222 301: a APPEND
223 302: L LONG 5
224 306: a APPEND
225 307: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000226highest protocol among opcodes = 0
227"""
228
Guido van Rossum98297ee2007-11-06 21:34:58 +0000229DATA1 = (
Georg Brandl1a3284e2007-12-02 09:40:06 +0000230 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
231 b'builtins\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000232 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
233 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
234 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
235 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000236 b'cq\x04h\x04ccopyreg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000237 b'nstructor\nq\x05(c__main'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000238 b'__\nC\nq\x06cbuiltins\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000239 b'object\nq\x07Ntq\x08Rq\t}q\n('
240 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
241 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
242)
Tim Peters70b02d72003-02-02 17:26:40 +0000243
Guido van Rossum98297ee2007-11-06 21:34:58 +0000244# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000245DATA1_DIS = """\
246 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000247 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000248 3: ( MARK
249 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000250 6: K BININT1 1
251 8: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000252 17: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000253 35: q BINPUT 1
254 37: ( MARK
255 38: G BINFLOAT 3.0
256 47: G BINFLOAT 0.0
257 56: t TUPLE (MARK at 37)
258 57: q BINPUT 2
259 59: R REDUCE
260 60: q BINPUT 3
261 62: K BININT1 1
262 64: J BININT -1
263 69: K BININT1 255
264 71: J BININT -255
265 76: J BININT -256
266 81: M BININT2 65535
267 84: J BININT -65535
268 89: J BININT -65536
269 94: J BININT 2147483647
270 99: J BININT -2147483647
271 104: J BININT -2147483648
272 109: ( MARK
273 110: X BINUNICODE 'abc'
274 118: q BINPUT 4
275 120: h BINGET 4
276 122: c GLOBAL 'copyreg _reconstructor'
277 146: q BINPUT 5
278 148: ( MARK
279 149: c GLOBAL '__main__ C'
280 161: q BINPUT 6
281 163: c GLOBAL 'builtins object'
282 180: q BINPUT 7
283 182: N NONE
284 183: t TUPLE (MARK at 148)
285 184: q BINPUT 8
286 186: R REDUCE
287 187: q BINPUT 9
288 189: } EMPTY_DICT
289 190: q BINPUT 10
290 192: ( MARK
291 193: X BINUNICODE 'foo'
292 201: q BINPUT 11
293 203: K BININT1 1
294 205: X BINUNICODE 'bar'
295 213: q BINPUT 12
296 215: K BININT1 2
297 217: u SETITEMS (MARK at 192)
298 218: b BUILD
299 219: h BINGET 9
300 221: t TUPLE (MARK at 109)
301 222: q BINPUT 13
302 224: h BINGET 13
303 226: K BININT1 5
304 228: e APPENDS (MARK at 3)
305 229: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000306highest protocol among opcodes = 1
307"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000308
Guido van Rossum98297ee2007-11-06 21:34:58 +0000309DATA2 = (
310 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000311 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000312 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
313 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
314 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
315 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
316 b'bcq\x04h\x04c__main__\nC\nq\x05'
317 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
318 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
319 b'\nK\x05e.'
320)
Tim Petersfc273752003-03-02 04:54:24 +0000321
Guido van Rossum98297ee2007-11-06 21:34:58 +0000322# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000323DATA2_DIS = """\
324 0: \x80 PROTO 2
325 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000326 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000327 5: ( MARK
328 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000329 8: K BININT1 1
330 10: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000331 19: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000332 37: q BINPUT 1
333 39: G BINFLOAT 3.0
334 48: G BINFLOAT 0.0
335 57: \x86 TUPLE2
336 58: q BINPUT 2
337 60: R REDUCE
338 61: q BINPUT 3
339 63: K BININT1 1
340 65: J BININT -1
341 70: K BININT1 255
342 72: J BININT -255
343 77: J BININT -256
344 82: M BININT2 65535
345 85: J BININT -65535
346 90: J BININT -65536
347 95: J BININT 2147483647
348 100: J BININT -2147483647
349 105: J BININT -2147483648
350 110: ( MARK
351 111: X BINUNICODE 'abc'
352 119: q BINPUT 4
353 121: h BINGET 4
354 123: c GLOBAL '__main__ C'
355 135: q BINPUT 5
356 137: ) EMPTY_TUPLE
357 138: \x81 NEWOBJ
358 139: q BINPUT 6
359 141: } EMPTY_DICT
360 142: q BINPUT 7
361 144: ( MARK
362 145: X BINUNICODE 'foo'
363 153: q BINPUT 8
364 155: K BININT1 1
365 157: X BINUNICODE 'bar'
366 165: q BINPUT 9
367 167: K BININT1 2
368 169: u SETITEMS (MARK at 144)
369 170: b BUILD
370 171: h BINGET 6
371 173: t TUPLE (MARK at 110)
372 174: q BINPUT 10
373 176: h BINGET 10
374 178: K BININT1 5
375 180: e APPENDS (MARK at 5)
376 181: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000377highest protocol among opcodes = 2
378"""
379
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000380# set([1,2]) pickled from 2.x with protocol 2
381DATA3 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
382
383# xrange(5) pickled from 2.x with protocol 2
384DATA4 = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
385
386# a SimpleCookie() object pickled from 2.x with protocol 2
387DATA5 = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
388 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
389 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
390 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
391 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
392 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
393
394# set([3]) pickled from 2.x with protocol 2
395DATA6 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
396
397
Jeremy Hylton66426532001-10-15 21:38:56 +0000398def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000399 c = C()
400 c.foo = 1
401 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000402 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000403 # Append some integer test cases at cPickle.c's internal size
404 # cutoffs.
405 uint1max = 0xff
406 uint2max = 0xffff
407 int4max = 0x7fffffff
408 x.extend([1, -1,
409 uint1max, -uint1max, -uint1max-1,
410 uint2max, -uint2max, -uint2max-1,
411 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000412 y = ('abc', 'abc', c, c)
413 x.append(y)
414 x.append(y)
415 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000416 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000417
Jeremy Hylton66426532001-10-15 21:38:56 +0000418class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000419 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000420
Jeremy Hylton66426532001-10-15 21:38:56 +0000421 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000422
Jeremy Hylton66426532001-10-15 21:38:56 +0000423 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000424 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000425
Jeremy Hylton66426532001-10-15 21:38:56 +0000426 def test_misc(self):
427 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000428 for proto in protocols:
429 x = myint(4)
430 s = self.dumps(x, proto)
431 y = self.loads(s)
432 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000433
Tim Peters70b02d72003-02-02 17:26:40 +0000434 x = (1, ())
435 s = self.dumps(x, proto)
436 y = self.loads(s)
437 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000438
Tim Peters70b02d72003-02-02 17:26:40 +0000439 x = initarg(1, x)
440 s = self.dumps(x, proto)
441 y = self.loads(s)
442 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000443
Jeremy Hylton66426532001-10-15 21:38:56 +0000444 # XXX test __reduce__ protocol?
445
Tim Peters70b02d72003-02-02 17:26:40 +0000446 def test_roundtrip_equality(self):
447 expected = self._testdata
448 for proto in protocols:
449 s = self.dumps(expected, proto)
450 got = self.loads(s)
451 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000452
Guido van Rossum98297ee2007-11-06 21:34:58 +0000453 def test_load_from_data0(self):
454 self.assertEqual(self._testdata, self.loads(DATA0))
455
456 def test_load_from_data1(self):
457 self.assertEqual(self._testdata, self.loads(DATA1))
458
459 def test_load_from_data2(self):
460 self.assertEqual(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000461
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000462 def test_load_classic_instance(self):
463 # See issue5180. Test loading 2.x pickles that
464 # contain an instance of old style class.
465 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
466 xname = X.__name__.encode('ascii')
467 # Protocol 0 (text mode pickle):
468 """
469 0: ( MARK
470 1: i INST '__main__ X' (MARK at 0)
471 15: p PUT 0
472 18: ( MARK
473 19: d DICT (MARK at 18)
474 20: p PUT 1
475 23: b BUILD
476 24: . STOP
477 """
478 pickle0 = (b"(i__main__\n"
479 b"X\n"
480 b"p0\n"
481 b"(dp1\nb.").replace(b'X', xname)
482 self.assertEqual(X(*args), self.loads(pickle0))
483
484 # Protocol 1 (binary mode pickle)
485 """
486 0: ( MARK
487 1: c GLOBAL '__main__ X'
488 15: q BINPUT 0
489 17: o OBJ (MARK at 0)
490 18: q BINPUT 1
491 20: } EMPTY_DICT
492 21: q BINPUT 2
493 23: b BUILD
494 24: . STOP
495 """
496 pickle1 = (b'(c__main__\n'
497 b'X\n'
498 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
499 self.assertEqual(X(*args), self.loads(pickle1))
500
501 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
502 """
503 0: \x80 PROTO 2
504 2: ( MARK
505 3: c GLOBAL '__main__ X'
506 17: q BINPUT 0
507 19: o OBJ (MARK at 2)
508 20: q BINPUT 1
509 22: } EMPTY_DICT
510 23: q BINPUT 2
511 25: b BUILD
512 26: . STOP
513 """
514 pickle2 = (b'\x80\x02(c__main__\n'
515 b'X\n'
516 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
517 self.assertEqual(X(*args), self.loads(pickle2))
518
Tim Peters70b02d72003-02-02 17:26:40 +0000519 # There are gratuitous differences between pickles produced by
520 # pickle and cPickle, largely because cPickle starts PUT indices at
521 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
522 # there's a comment with an exclamation point there whose meaning
523 # is a mystery. cPickle also suppresses PUT for objects with a refcount
524 # of 1.
525 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000526 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000527 from pickletools import dis
528
529 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
530 s = self.dumps(self._testdata, proto)
531 filelike = StringIO()
532 dis(s, out=filelike)
533 got = filelike.getvalue()
534 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000535
536 def test_recursive_list(self):
537 l = []
538 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000539 for proto in protocols:
540 s = self.dumps(l, proto)
541 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000542 self.assertEqual(len(x), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000543 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000544
Collin Winter8ca69de2009-05-26 16:53:41 +0000545 def test_recursive_tuple(self):
546 t = ([],)
547 t[0].append(t)
548 for proto in protocols:
549 s = self.dumps(t, proto)
550 x = self.loads(s)
551 self.assertEqual(len(x), 1)
552 self.assertEqual(len(x[0]), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000553 self.assertTrue(x is x[0][0])
Collin Winter8ca69de2009-05-26 16:53:41 +0000554
Jeremy Hylton66426532001-10-15 21:38:56 +0000555 def test_recursive_dict(self):
556 d = {}
557 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000558 for proto in protocols:
559 s = self.dumps(d, proto)
560 x = self.loads(s)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000561 self.assertEqual(list(x.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000562 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000563
564 def test_recursive_inst(self):
565 i = C()
566 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000567 for proto in protocols:
568 s = self.dumps(i, 2)
569 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000570 self.assertEqual(dir(x), dir(i))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000571 self.assertTrue(x.attr is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000572
573 def test_recursive_multi(self):
574 l = []
575 d = {1:l}
576 i = C()
577 i.attr = d
578 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000579 for proto in protocols:
580 s = self.dumps(l, proto)
581 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000582 self.assertEqual(len(x), 1)
583 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000584 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000585 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000586
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000587 def test_get(self):
588 self.assertRaises(KeyError, self.loads, b'g0\np0')
Ezio Melottib3aedd42010-11-20 19:04:17 +0000589 self.assertEqual(self.loads(b'((Kdtp0\nh\x00l.))'), [(100,), (100,)])
Jeremy Hylton66426532001-10-15 21:38:56 +0000590
591 def test_insecure_strings(self):
Guido van Rossum39478e82007-08-27 17:23:59 +0000592 # XXX Some of these tests are temporarily disabled
593 insecure = [b"abc", b"2 + 2", # not quoted
594 ## b"'abc' + 'def'", # not a single quoted string
595 b"'abc", # quote is not closed
596 b"'abc\"", # open quote and close quote don't match
597 b"'abc' ?", # junk after close quote
598 b"'\\'", # trailing backslash
Jeremy Hylton66426532001-10-15 21:38:56 +0000599 # some tests of the quoting rules
Guido van Rossum39478e82007-08-27 17:23:59 +0000600 ## b"'abc\"\''",
601 ## b"'\\\\a\'\'\'\\\'\\\\\''",
Jeremy Hylton66426532001-10-15 21:38:56 +0000602 ]
Guido van Rossum39478e82007-08-27 17:23:59 +0000603 for b in insecure:
604 buf = b"S" + b + b"\012p0\012."
Jeremy Hylton66426532001-10-15 21:38:56 +0000605 self.assertRaises(ValueError, self.loads, buf)
606
Walter Dörwald9b775532007-06-08 14:30:53 +0000607 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000608 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +0000609 '<\\>', '<\\\U00012345>',
610 # surrogates
611 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000612 for proto in protocols:
613 for u in endcases:
614 p = self.dumps(u, proto)
615 u2 = self.loads(p)
616 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000617
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000618 def test_unicode_high_plane(self):
619 t = '\U00012345'
620 for proto in protocols:
621 p = self.dumps(t, proto)
622 t2 = self.loads(p)
623 self.assertEqual(t2, t)
624
Guido van Rossumf4169812008-03-17 22:56:06 +0000625 def test_bytes(self):
626 for proto in protocols:
627 for u in b'', b'xyz', b'xyz'*100:
628 p = self.dumps(u)
629 self.assertEqual(self.loads(p), u)
630
Jeremy Hylton66426532001-10-15 21:38:56 +0000631 def test_ints(self):
632 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000633 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000634 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000635 while n:
636 for expected in (-n, n):
637 s = self.dumps(expected, proto)
638 n2 = self.loads(s)
639 self.assertEqual(expected, n2)
640 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000641
Jeremy Hylton66426532001-10-15 21:38:56 +0000642 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000643 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000644 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000645 got = self.loads(data)
646 self.assertEqual(got, maxint64)
647
648 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000649 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000650 self.assertRaises(ValueError, self.loads, data)
651
Tim Petersee1a53c2003-02-02 02:57:53 +0000652 def test_long(self):
653 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000654 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000655 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000656 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000657 for npos in nbase-1, nbase, nbase+1:
658 for n in npos, -npos:
659 pickle = self.dumps(n, proto)
660 got = self.loads(pickle)
661 self.assertEqual(n, got)
662 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
663 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000664 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000665 nbase += nbase << 1000000
666 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000667 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000668 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000669 self.assertEqual(n, got)
670
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000671 def test_float(self):
672 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
673 3.14, 263.44582062374053, 6.022e23, 1e30]
674 test_values = test_values + [-x for x in test_values]
675 for proto in protocols:
676 for value in test_values:
677 pickle = self.dumps(value, proto)
678 got = self.loads(pickle)
679 self.assertEqual(value, got)
680
Thomas Wouters477c8d52006-05-27 19:21:47 +0000681 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
682 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000683 # make sure that floats are formatted locale independent with proto 0
684 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000685
Jeremy Hylton66426532001-10-15 21:38:56 +0000686 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000687 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000688
689 def test_getinitargs(self):
690 pass
691
Guido van Rossum04a86612001-12-19 16:58:54 +0000692 def test_metaclass(self):
693 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000694 for proto in protocols:
695 s = self.dumps(a, proto)
696 b = self.loads(s)
697 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000698
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000699 def test_structseq(self):
700 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000701 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000702
703 t = time.localtime()
704 for proto in protocols:
705 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000706 u = self.loads(s)
707 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000708 if hasattr(os, "stat"):
709 t = os.stat(os.curdir)
710 s = self.dumps(t, proto)
711 u = self.loads(s)
712 self.assertEqual(t, u)
713 if hasattr(os, "statvfs"):
714 t = os.statvfs(os.curdir)
715 s = self.dumps(t, proto)
716 u = self.loads(s)
717 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000718
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000719 # Tests for protocol 2
720
Tim Peters4190fb82003-02-02 16:09:05 +0000721 def test_proto(self):
722 build_none = pickle.NONE + pickle.STOP
723 for proto in protocols:
724 expected = build_none
725 if proto >= 2:
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000726 expected = pickle.PROTO + bytes([proto]) + expected
Tim Peters4190fb82003-02-02 16:09:05 +0000727 p = self.dumps(None, proto)
728 self.assertEqual(p, expected)
729
730 oob = protocols[-1] + 1 # a future protocol
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000731 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000732 try:
733 self.loads(badpickle)
Guido van Rossumb940e112007-01-10 16:19:56 +0000734 except ValueError as detail:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000735 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +0000736 "unsupported pickle protocol"))
737 else:
738 self.fail("expected bad protocol number to raise ValueError")
739
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000740 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000741 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000742 for proto in protocols:
743 s = self.dumps(x, proto)
744 y = self.loads(s)
745 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000746 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000747
748 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000749 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000750 for proto in protocols:
751 s = self.dumps(x, proto)
752 y = self.loads(s)
753 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000754 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000755
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000756 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000757 # Map (proto, len(tuple)) to expected opcode.
758 expected_opcode = {(0, 0): pickle.TUPLE,
759 (0, 1): pickle.TUPLE,
760 (0, 2): pickle.TUPLE,
761 (0, 3): pickle.TUPLE,
762 (0, 4): pickle.TUPLE,
763
764 (1, 0): pickle.EMPTY_TUPLE,
765 (1, 1): pickle.TUPLE,
766 (1, 2): pickle.TUPLE,
767 (1, 3): pickle.TUPLE,
768 (1, 4): pickle.TUPLE,
769
770 (2, 0): pickle.EMPTY_TUPLE,
771 (2, 1): pickle.TUPLE1,
772 (2, 2): pickle.TUPLE2,
773 (2, 3): pickle.TUPLE3,
774 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000775
776 (3, 0): pickle.EMPTY_TUPLE,
777 (3, 1): pickle.TUPLE1,
778 (3, 2): pickle.TUPLE2,
779 (3, 3): pickle.TUPLE3,
780 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000781 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000782 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000783 b = (1,)
784 c = (1, 2)
785 d = (1, 2, 3)
786 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000787 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000788 for x in a, b, c, d, e:
789 s = self.dumps(x, proto)
790 y = self.loads(s)
791 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000792 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +0000793 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +0000794
Guido van Rossum7d97d312003-01-28 04:25:27 +0000795 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000796 # Map (proto, singleton) to expected opcode.
797 expected_opcode = {(0, None): pickle.NONE,
798 (1, None): pickle.NONE,
799 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000800 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000801
802 (0, True): pickle.INT,
803 (1, True): pickle.INT,
804 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000805 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000806
807 (0, False): pickle.INT,
808 (1, False): pickle.INT,
809 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000810 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000811 }
Tim Peters4190fb82003-02-02 16:09:05 +0000812 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000813 for x in None, False, True:
814 s = self.dumps(x, proto)
815 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000816 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +0000817 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +0000818 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +0000819
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000820 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000821 x = MyTuple([1, 2, 3])
822 x.foo = 42
823 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000824 for proto in protocols:
825 s = self.dumps(x, proto)
826 y = self.loads(s)
827 self.assertEqual(tuple(x), tuple(y))
828 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000829
830 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000831 x = MyList([1, 2, 3])
832 x.foo = 42
833 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000834 for proto in protocols:
835 s = self.dumps(x, proto)
836 y = self.loads(s)
837 self.assertEqual(list(x), list(y))
838 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000839
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000840 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +0000841 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000842 for C in myclasses:
843 B = C.__base__
844 x = C(C.sample)
845 x.foo = 42
846 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000847 y = self.loads(s)
848 detail = (proto, C, B, x, y, type(y))
849 self.assertEqual(B(x), B(y), detail)
850 self.assertEqual(x.__dict__, y.__dict__, detail)
851
Antoine Pitrou16c4ce12011-03-11 21:30:43 +0100852 def test_newobj_proxies(self):
853 # NEWOBJ should use the __class__ rather than the raw type
854 classes = myclasses[:]
855 # Cannot create weakproxies to these classes
856 for c in (MyInt, MyTuple):
857 classes.remove(c)
858 for proto in protocols:
859 for C in classes:
860 B = C.__base__
861 x = C(C.sample)
862 x.foo = 42
863 p = weakref.proxy(x)
864 s = self.dumps(p, proto)
865 y = self.loads(s)
866 self.assertEqual(type(y), type(x)) # rather than type(p)
867 detail = (proto, C, B, x, y, type(y))
868 self.assertEqual(B(x), B(y), detail)
869 self.assertEqual(x.__dict__, y.__dict__, detail)
870
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000871 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +0000872 # an object of that type. Check that the resulting pickle uses opcode
873 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +0000874
Tim Peters22e71712003-02-03 22:27:38 +0000875 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +0000876 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000877 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000878 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000879 x = MyList([1, 2, 3])
880 x.foo = 42
881 x.bar = "hello"
882
Tim Peters22e71712003-02-03 22:27:38 +0000883 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000884 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000885 self.assertIn(__name__.encode("utf-8"), s1)
886 self.assertIn(b"MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +0000887 self.assertEqual(opcode_in_pickle(opcode, s1), False)
888
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000889 y = self.loads(s1)
890 self.assertEqual(list(x), list(y))
891 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000892
Tim Peters22e71712003-02-03 22:27:38 +0000893 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000894 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000895 self.assertNotIn(__name__.encode("utf-8"), s2)
896 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000897 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +0000898
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000899 y = self.loads(s2)
900 self.assertEqual(list(x), list(y))
901 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000902
903 finally:
Tim Peters3e667d52003-02-04 21:47:44 +0000904 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +0000905
906 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000907 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
908 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000909
910 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000911 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
912 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
913 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000914
915 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000916 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
917 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
918 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
919
Tim Peters8d2613a2003-02-11 16:40:16 +0000920 def test_list_chunking(self):
921 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +0000922 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000923 for proto in protocols:
924 s = self.dumps(x, proto)
925 y = self.loads(s)
926 self.assertEqual(x, y)
927 num_appends = count_opcode(pickle.APPENDS, s)
928 self.assertEqual(num_appends, proto > 0)
929
930 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +0000931 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000932 for proto in protocols:
933 s = self.dumps(x, proto)
934 y = self.loads(s)
935 self.assertEqual(x, y)
936 num_appends = count_opcode(pickle.APPENDS, s)
937 if proto == 0:
938 self.assertEqual(num_appends, 0)
939 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000940 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +0000941
942 def test_dict_chunking(self):
943 n = 10 # too small to chunk
944 x = dict.fromkeys(range(n))
945 for proto in protocols:
946 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +0000947 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +0000948 y = self.loads(s)
949 self.assertEqual(x, y)
950 num_setitems = count_opcode(pickle.SETITEMS, s)
951 self.assertEqual(num_setitems, proto > 0)
952
953 n = 2500 # expect at least two chunks when proto > 0
954 x = dict.fromkeys(range(n))
955 for proto in protocols:
956 s = self.dumps(x, proto)
957 y = self.loads(s)
958 self.assertEqual(x, y)
959 num_setitems = count_opcode(pickle.SETITEMS, s)
960 if proto == 0:
961 self.assertEqual(num_setitems, 0)
962 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000963 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000964
Tim Peterse9ef2032003-02-13 18:42:00 +0000965 def test_simple_newobj(self):
966 x = object.__new__(SimpleNewObj) # avoid __init__
967 x.abc = 666
968 for proto in protocols:
969 s = self.dumps(x, proto)
970 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
971 y = self.loads(s) # will raise TypeError if __init__ called
972 self.assertEqual(y.abc, 666)
973 self.assertEqual(x.__dict__, y.__dict__)
974
Tim Peters42f08ac2003-02-11 22:43:24 +0000975 def test_newobj_list_slots(self):
976 x = SlotList([1, 2, 3])
977 x.foo = 42
978 x.bar = "hello"
979 s = self.dumps(x, 2)
980 y = self.loads(s)
981 self.assertEqual(list(x), list(y))
982 self.assertEqual(x.__dict__, y.__dict__)
983 self.assertEqual(x.foo, y.foo)
984 self.assertEqual(x.bar, y.bar)
985
Guido van Rossum2a30b212003-02-18 22:41:24 +0000986 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +0000987 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000988 x = REX_one()
989 self.assertEqual(x._reduce_called, 0)
990 s = self.dumps(x, proto)
991 self.assertEqual(x._reduce_called, 1)
992 y = self.loads(s)
993 self.assertEqual(y._reduce_called, 0)
994
995 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +0000996 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000997 x = REX_two()
998 self.assertEqual(x._proto, None)
999 s = self.dumps(x, proto)
1000 self.assertEqual(x._proto, proto)
1001 y = self.loads(s)
1002 self.assertEqual(y._proto, None)
1003
1004 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001005 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001006 x = REX_three()
1007 self.assertEqual(x._proto, None)
1008 s = self.dumps(x, proto)
1009 self.assertEqual(x._proto, proto)
1010 y = self.loads(s)
1011 self.assertEqual(y._proto, None)
1012
Guido van Rossumd8faa362007-04-27 19:54:29 +00001013 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001014 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001015 x = REX_four()
1016 self.assertEqual(x._proto, None)
1017 s = self.dumps(x, proto)
1018 self.assertEqual(x._proto, proto)
1019 y = self.loads(s)
1020 self.assertEqual(y._proto, proto)
1021
1022 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001023 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001024 x = REX_five()
1025 self.assertEqual(x._reduce_called, 0)
1026 s = self.dumps(x, proto)
1027 self.assertEqual(x._reduce_called, 1)
1028 y = self.loads(s)
1029 self.assertEqual(y._reduce_called, 1)
1030
Brett Cannon31f59292011-02-21 19:29:56 +00001031 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001032 def test_bad_getattr(self):
1033 x = BadGetattr()
1034 for proto in 0, 1:
1035 self.assertRaises(RuntimeError, self.dumps, x, proto)
1036 # protocol 2 don't raise a RuntimeError.
1037 d = self.dumps(x, 2)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001038
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001039 def test_reduce_bad_iterator(self):
1040 # Issue4176: crash when 4th and 5th items of __reduce__()
1041 # are not iterators
1042 class C(object):
1043 def __reduce__(self):
1044 # 4th item is not an iterator
1045 return list, (), None, [], None
1046 class D(object):
1047 def __reduce__(self):
1048 # 5th item is not an iterator
1049 return dict, (), None, None, []
1050
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001051 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001052 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001053 try:
1054 self.dumps(C(), proto)
1055 except (pickle.PickleError):
1056 pass
1057 try:
1058 self.dumps(D(), proto)
1059 except (pickle.PickleError):
1060 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001061
Collin Winter771d8342009-04-16 03:18:06 +00001062 def test_many_puts_and_gets(self):
1063 # Test that internal data structures correctly deal with lots of
1064 # puts/gets.
1065 keys = ("aaa" + str(i) for i in range(100))
1066 large_dict = dict((k, [4, 5, 6]) for k in keys)
1067 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1068
1069 for proto in protocols:
1070 dumped = self.dumps(obj, proto)
1071 loaded = self.loads(dumped)
1072 self.assertEqual(loaded, obj,
1073 "Failed protocol %d: %r != %r"
1074 % (proto, obj, loaded))
1075
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001076 def test_attribute_name_interning(self):
1077 # Test that attribute names of pickled objects are interned when
1078 # unpickling.
1079 for proto in protocols:
1080 x = C()
1081 x.foo = 42
1082 x.bar = "hello"
1083 s = self.dumps(x, proto)
1084 y = self.loads(s)
1085 x_keys = sorted(x.__dict__)
1086 y_keys = sorted(y.__dict__)
1087 for x_key, y_key in zip(x_keys, y_keys):
1088 self.assertIs(x_key, y_key)
1089
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001090 def test_unpickle_from_2x(self):
1091 # Unpickle non-trivial data from Python 2.x.
1092 loaded = self.loads(DATA3)
1093 self.assertEqual(loaded, set([1, 2]))
1094 loaded = self.loads(DATA4)
1095 self.assertEqual(type(loaded), type(range(0)))
1096 self.assertEqual(list(loaded), list(range(5)))
1097 loaded = self.loads(DATA5)
1098 self.assertEqual(type(loaded), SimpleCookie)
1099 self.assertEqual(list(loaded.keys()), ["key"])
1100 self.assertEqual(loaded["key"].value, "Set-Cookie: key=value")
1101
1102 def test_pickle_to_2x(self):
1103 # Pickle non-trivial data with protocol 2, expecting that it yields
1104 # the same result as Python 2.x did.
1105 # NOTE: this test is a bit too strong since we can produce different
1106 # bytecode that 2.x will still understand.
1107 dumped = self.dumps(range(5), 2)
1108 self.assertEqual(dumped, DATA4)
1109 dumped = self.dumps(set([3]), 2)
1110 self.assertEqual(dumped, DATA6)
1111
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001112 def test_large_pickles(self):
1113 # Test the correctness of internal buffering routines when handling
1114 # large data.
1115 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001116 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001117 dumped = self.dumps(data, proto)
1118 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001119 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001120 self.assertEqual(loaded, data)
1121
Alexander Belopolsky1ce92dc2011-02-24 19:40:09 +00001122 def test_empty_bytestring(self):
1123 # issue 11286
1124 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1125 self.assertEqual(empty, '')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001126
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001127 def test_int_pickling_efficiency(self):
1128 # Test compacity of int representation (see issue #12744)
1129 for proto in protocols:
1130 sizes = [len(self.dumps(2**n, proto)) for n in range(70)]
Antoine Pitrou85674932011-08-14 01:51:52 +02001131 # the size function is monotonic
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001132 self.assertEqual(sorted(sizes), sizes)
1133 if proto >= 2:
1134 self.assertLessEqual(sizes[-1], 14)
1135
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001136 def check_negative_32b_binXXX(self, dumped):
1137 if sys.maxsize > 2**32:
1138 self.skipTest("test is only meaningful on 32-bit builds")
1139 # XXX Pure Python pickle reads lengths as signed and passes
1140 # them directly to read() (hence the EOFError)
1141 with self.assertRaises((pickle.UnpicklingError, EOFError,
1142 ValueError, OverflowError)):
1143 self.loads(dumped)
1144
1145 def test_negative_32b_binbytes(self):
1146 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1147 self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.')
1148
1149 def test_negative_32b_binunicode(self):
1150 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1151 self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.')
1152
Antoine Pitrou55549ec2011-08-30 00:27:10 +02001153 def test_negative_put(self):
1154 # Issue #12847
1155 dumped = b'Va\np-1\n.'
1156 self.assertRaises(ValueError, self.loads, dumped)
1157
1158 def test_negative_32b_binput(self):
1159 # Issue #12847
1160 if sys.maxsize > 2**32:
1161 self.skipTest("test is only meaningful on 32-bit builds")
1162 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
1163 self.assertRaises(ValueError, self.loads, dumped)
1164
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001165
1166class BigmemPickleTests(unittest.TestCase):
1167
1168 # Binary protocols can serialize longs of up to 2GB-1
1169
1170 @precisionbigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
1171 def test_huge_long_32b(self, size):
1172 data = 1 << (8 * size)
1173 try:
1174 for proto in protocols:
1175 if proto < 2:
1176 continue
1177 with self.assertRaises((ValueError, OverflowError)):
1178 self.dumps(data, protocol=proto)
1179 finally:
1180 data = None
1181
1182 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1183 # (older protocols don't have a dedicated opcode for bytes and are
1184 # too inefficient)
1185
1186 @precisionbigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
1187 def test_huge_bytes_32b(self, size):
1188 data = b"abcd" * (size // 4)
1189 try:
1190 for proto in protocols:
1191 if proto < 3:
1192 continue
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
1202 @precisionbigmemtest(size=_4G, memuse=1 + 1, dry_run=False)
1203 def test_huge_bytes_64b(self, size):
1204 data = b"a" * size
1205 try:
1206 for proto in protocols:
1207 if proto < 3:
1208 continue
1209 with self.assertRaises((ValueError, OverflowError)):
1210 self.dumps(data, protocol=proto)
1211 finally:
1212 data = None
1213
1214 # All protocols use 1-byte per printable ASCII character; we add another
1215 # byte because the encoded form has to be copied into the internal buffer.
1216
1217 @precisionbigmemtest(size=_2G, memuse=2 + character_size, dry_run=False)
1218 def test_huge_str_32b(self, size):
1219 data = "abcd" * (size // 4)
1220 try:
1221 for proto in protocols:
1222 try:
1223 pickled = self.dumps(data, protocol=proto)
1224 self.assertTrue(b"abcd" in pickled[:15])
1225 self.assertTrue(b"abcd" in pickled[-15:])
1226 finally:
1227 pickled = None
1228 finally:
1229 data = None
1230
1231 @precisionbigmemtest(size=_4G, memuse=1 + character_size, dry_run=False)
1232 def test_huge_str_64b(self, size):
1233 data = "a" * size
1234 try:
1235 for proto in protocols:
1236 with self.assertRaises((ValueError, OverflowError)):
1237 self.dumps(data, protocol=proto)
1238 finally:
1239 data = None
1240
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001241
Guido van Rossum2a30b212003-02-18 22:41:24 +00001242# Test classes for reduce_ex
1243
1244class REX_one(object):
1245 _reduce_called = 0
1246 def __reduce__(self):
1247 self._reduce_called = 1
1248 return REX_one, ()
1249 # No __reduce_ex__ here, but inheriting it from object
1250
1251class REX_two(object):
1252 _proto = None
1253 def __reduce_ex__(self, proto):
1254 self._proto = proto
1255 return REX_two, ()
1256 # No __reduce__ here, but inheriting it from object
1257
1258class REX_three(object):
1259 _proto = None
1260 def __reduce_ex__(self, proto):
1261 self._proto = proto
1262 return REX_two, ()
1263 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001264 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001265
Guido van Rossumd8faa362007-04-27 19:54:29 +00001266class REX_four(object):
1267 _proto = None
1268 def __reduce_ex__(self, proto):
1269 self._proto = proto
1270 return object.__reduce_ex__(self, proto)
1271 # Calling base class method should succeed
1272
1273class REX_five(object):
1274 _reduce_called = 0
1275 def __reduce__(self):
1276 self._reduce_called = 1
1277 return object.__reduce__(self)
1278 # This one used to fail with infinite recursion
1279
Guido van Rossum2a30b212003-02-18 22:41:24 +00001280# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001281
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001282class MyInt(int):
1283 sample = 1
1284
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001285class MyFloat(float):
1286 sample = 1.0
1287
1288class MyComplex(complex):
1289 sample = 1.0 + 0.0j
1290
1291class MyStr(str):
1292 sample = "hello"
1293
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001294class MyUnicode(str):
1295 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001296
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001297class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001298 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001299
1300class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001301 sample = [1, 2, 3]
1302
1303class MyDict(dict):
1304 sample = {"a": 1, "b": 2}
1305
Mark Dickinson5c2db372009-12-05 20:28:34 +00001306myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001307 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001308 MyStr, MyUnicode,
1309 MyTuple, MyList, MyDict]
1310
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001311
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001312class SlotList(MyList):
1313 __slots__ = ["foo"]
1314
Tim Peterse9ef2032003-02-13 18:42:00 +00001315class SimpleNewObj(object):
1316 def __init__(self, a, b, c):
1317 # raise an error, to make sure this isn't called
1318 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1319
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001320class BadGetattr:
1321 def __getattr__(self, key):
1322 self.foo
1323
Collin Winter771d8342009-04-16 03:18:06 +00001324
Jeremy Hylton66426532001-10-15 21:38:56 +00001325class AbstractPickleModuleTests(unittest.TestCase):
1326
1327 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001328 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001329 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001330 try:
1331 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001332 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001333 finally:
1334 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001335
1336 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001337 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001338 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001339 try:
1340 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001341 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001342 finally:
1343 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001344
Collin Winter771d8342009-04-16 03:18:06 +00001345 def test_load_from_and_dump_to_file(self):
1346 stream = io.BytesIO()
1347 data = [123, {}, 124]
1348 pickle.dump(data, stream)
1349 stream.seek(0)
1350 unpickled = pickle.load(stream)
1351 self.assertEqual(unpickled, data)
1352
Tim Petersc0c93702003-02-13 19:30:57 +00001353 def test_highest_protocol(self):
1354 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001355 self.assertEqual(pickle.HIGHEST_PROTOCOL, 3)
Tim Petersc0c93702003-02-13 19:30:57 +00001356
Martin v. Löwis544f1192004-07-27 05:22:33 +00001357 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001358 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001359 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001360 pickle.dump(123, f, -1)
1361 pickle.dump(123, file=f, protocol=-1)
1362 pickle.dumps(123, -1)
1363 pickle.dumps(123, protocol=-1)
1364 pickle.Pickler(f, -1)
1365 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001366
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001367 def test_bad_init(self):
1368 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001369 # Override initialization without calling __init__() of the superclass.
1370 class BadPickler(pickle.Pickler):
1371 def __init__(self): pass
1372
1373 class BadUnpickler(pickle.Unpickler):
1374 def __init__(self): pass
1375
1376 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1377 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1378
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001379 def test_bad_input(self):
1380 # Test issue4298
1381 s = bytes([0x58, 0, 0, 0, 0x54])
1382 self.assertRaises(EOFError, pickle.loads, s)
Antoine Pitrou01a15ea2010-01-07 17:57:31 +00001383 # Test issue7455
1384 s = b'0'
1385 self.assertRaises(pickle.UnpicklingError, pickle.loads, s)
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001386
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001387
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001388class AbstractPersistentPicklerTests(unittest.TestCase):
1389
1390 # This class defines persistent_id() and persistent_load()
1391 # functions that should be used by the pickler. All even integers
1392 # are pickled using persistent ids.
1393
1394 def persistent_id(self, object):
1395 if isinstance(object, int) and object % 2 == 0:
1396 self.id_count += 1
1397 return str(object)
1398 else:
1399 return None
1400
1401 def persistent_load(self, oid):
1402 self.load_count += 1
1403 object = int(oid)
1404 assert object % 2 == 0
1405 return object
1406
1407 def test_persistence(self):
1408 self.id_count = 0
1409 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001410 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001411 self.assertEqual(self.loads(self.dumps(L)), L)
1412 self.assertEqual(self.id_count, 5)
1413 self.assertEqual(self.load_count, 5)
1414
1415 def test_bin_persistence(self):
1416 self.id_count = 0
1417 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001418 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001419 self.assertEqual(self.loads(self.dumps(L, 1)), L)
1420 self.assertEqual(self.id_count, 5)
1421 self.assertEqual(self.load_count, 5)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001422
Collin Winter771d8342009-04-16 03:18:06 +00001423
1424class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1425
1426 pickler_class = None
1427 unpickler_class = None
1428
1429 def setUp(self):
1430 assert self.pickler_class
1431 assert self.unpickler_class
1432
1433 def test_clear_pickler_memo(self):
1434 # To test whether clear_memo() has any effect, we pickle an object,
1435 # then pickle it again without clearing the memo; the two serialized
1436 # forms should be different. If we clear_memo() and then pickle the
1437 # object again, the third serialized form should be identical to the
1438 # first one we obtained.
1439 data = ["abcdefg", "abcdefg", 44]
1440 f = io.BytesIO()
1441 pickler = self.pickler_class(f)
1442
1443 pickler.dump(data)
1444 first_pickled = f.getvalue()
1445
1446 # Reset StringIO object.
1447 f.seek(0)
1448 f.truncate()
1449
1450 pickler.dump(data)
1451 second_pickled = f.getvalue()
1452
1453 # Reset the Pickler and StringIO objects.
1454 pickler.clear_memo()
1455 f.seek(0)
1456 f.truncate()
1457
1458 pickler.dump(data)
1459 third_pickled = f.getvalue()
1460
1461 self.assertNotEqual(first_pickled, second_pickled)
1462 self.assertEqual(first_pickled, third_pickled)
1463
1464 def test_priming_pickler_memo(self):
1465 # Verify that we can set the Pickler's memo attribute.
1466 data = ["abcdefg", "abcdefg", 44]
1467 f = io.BytesIO()
1468 pickler = self.pickler_class(f)
1469
1470 pickler.dump(data)
1471 first_pickled = f.getvalue()
1472
1473 f = io.BytesIO()
1474 primed = self.pickler_class(f)
1475 primed.memo = pickler.memo
1476
1477 primed.dump(data)
1478 primed_pickled = f.getvalue()
1479
1480 self.assertNotEqual(first_pickled, primed_pickled)
1481
1482 def test_priming_unpickler_memo(self):
1483 # Verify that we can set the Unpickler's memo attribute.
1484 data = ["abcdefg", "abcdefg", 44]
1485 f = io.BytesIO()
1486 pickler = self.pickler_class(f)
1487
1488 pickler.dump(data)
1489 first_pickled = f.getvalue()
1490
1491 f = io.BytesIO()
1492 primed = self.pickler_class(f)
1493 primed.memo = pickler.memo
1494
1495 primed.dump(data)
1496 primed_pickled = f.getvalue()
1497
1498 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
1499 unpickled_data1 = unpickler.load()
1500
1501 self.assertEqual(unpickled_data1, data)
1502
1503 primed = self.unpickler_class(io.BytesIO(primed_pickled))
1504 primed.memo = unpickler.memo
1505 unpickled_data2 = primed.load()
1506
1507 primed.memo.clear()
1508
1509 self.assertEqual(unpickled_data2, data)
1510 self.assertTrue(unpickled_data2 is unpickled_data1)
1511
1512 def test_reusing_unpickler_objects(self):
1513 data1 = ["abcdefg", "abcdefg", 44]
1514 f = io.BytesIO()
1515 pickler = self.pickler_class(f)
1516 pickler.dump(data1)
1517 pickled1 = f.getvalue()
1518
1519 data2 = ["abcdefg", 44, 44]
1520 f = io.BytesIO()
1521 pickler = self.pickler_class(f)
1522 pickler.dump(data2)
1523 pickled2 = f.getvalue()
1524
1525 f = io.BytesIO()
1526 f.write(pickled1)
1527 f.seek(0)
1528 unpickler = self.unpickler_class(f)
1529 self.assertEqual(unpickler.load(), data1)
1530
1531 f.seek(0)
1532 f.truncate()
1533 f.write(pickled2)
1534 f.seek(0)
1535 self.assertEqual(unpickler.load(), data2)
1536
Antoine Pitrou04248a82010-10-12 20:51:21 +00001537 def _check_multiple_unpicklings(self, ioclass):
1538 for proto in protocols:
1539 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
1540 f = ioclass()
1541 pickler = self.pickler_class(f, protocol=proto)
1542 pickler.dump(data1)
1543 pickled = f.getvalue()
1544
1545 N = 5
1546 f = ioclass(pickled * N)
1547 unpickler = self.unpickler_class(f)
1548 for i in range(N):
1549 if f.seekable():
1550 pos = f.tell()
1551 self.assertEqual(unpickler.load(), data1)
1552 if f.seekable():
1553 self.assertEqual(f.tell(), pos + len(pickled))
1554 self.assertRaises(EOFError, unpickler.load)
1555
1556 def test_multiple_unpicklings_seekable(self):
1557 self._check_multiple_unpicklings(io.BytesIO)
1558
1559 def test_multiple_unpicklings_unseekable(self):
1560 self._check_multiple_unpicklings(UnseekableIO)
1561
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02001562 def test_unpickling_buffering_readline(self):
1563 # Issue #12687: the unpickler's buffering logic could fail with
1564 # text mode opcodes.
1565 data = list(range(10))
1566 for proto in protocols:
1567 for buf_size in range(1, 11):
1568 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
1569 pickler = self.pickler_class(f, protocol=proto)
1570 pickler.dump(data)
1571 f.seek(0)
1572 unpickler = self.unpickler_class(f)
1573 self.assertEqual(unpickler.load(), data)
1574
Collin Winter771d8342009-04-16 03:18:06 +00001575
Guido van Rossum98297ee2007-11-06 21:34:58 +00001576if __name__ == "__main__":
1577 # Print some stuff that can be used to rewrite DATA{0,1,2}
1578 from pickletools import dis
1579 x = create_data()
1580 for i in range(3):
1581 p = pickle.dumps(x, i)
1582 print("DATA{0} = (".format(i))
1583 for j in range(0, len(p), 20):
1584 b = bytes(p[j:j+20])
1585 print(" {0!r}".format(b))
1586 print(")")
1587 print()
1588 print("# Disassembly of DATA{0}".format(i))
1589 print("DATA{0}_DIS = \"\"\"\\".format(i))
1590 dis(p)
1591 print("\"\"\"")
1592 print()