blob: 7645b548a5b5026d929be0b6d1092a85766e5cd4 [file] [log] [blame]
Collin Winter771d8342009-04-16 03:18:06 +00001import io
Jeremy Hylton66426532001-10-15 21:38:56 +00002import unittest
Tim Peters4190fb82003-02-02 16:09:05 +00003import pickle
Tim Peters31f119e2003-02-03 16:20:13 +00004import pickletools
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00005import copyreg
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00006from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +00007
Benjamin Petersonee8712c2008-05-20 21:35:26 +00008from test.support import TestFailed, TESTFN, run_with_locale
Tim Peterse089c682001-04-10 03:41:41 +00009
Guido van Rossum98297ee2007-11-06 21:34:58 +000010from pickle import bytes_types
11
Tim Petersee1a53c2003-02-02 02:57:53 +000012# Tests that try a number of pickle protocols should have a
13# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000014# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000015protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000016
Tim Peters22e71712003-02-03 22:27:38 +000017
18# Return True if opcode code appears in the pickle, else False.
19def opcode_in_pickle(code, pickle):
20 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000021 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000022 return True
23 return False
24
Tim Peters8d2613a2003-02-11 16:40:16 +000025# Return the number of times opcode code appears in pickle.
26def count_opcode(code, pickle):
27 n = 0
28 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000029 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000030 n += 1
31 return n
32
Antoine Pitrou04248a82010-10-12 20:51:21 +000033
34class UnseekableIO(io.BytesIO):
35 def peek(self, *args):
36 raise NotImplementedError
37
38 def seekable(self):
39 return False
40
41 def seek(self, *args):
42 raise io.UnsupportedOperation
43
44 def tell(self):
45 raise io.UnsupportedOperation
46
47
Tim Peters3e667d52003-02-04 21:47:44 +000048# We can't very well test the extension registry without putting known stuff
49# in it, but we have to be careful to restore its original state. Code
50# should do this:
51#
52# e = ExtensionSaver(extension_code)
53# try:
54# fiddle w/ the extension registry's stuff for extension_code
55# finally:
56# e.restore()
57
58class ExtensionSaver:
59 # Remember current registration for code (if any), and remove it (if
60 # there is one).
61 def __init__(self, code):
62 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000063 if code in copyreg._inverted_registry:
64 self.pair = copyreg._inverted_registry[code]
65 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000066 else:
67 self.pair = None
68
69 # Restore previous registration for code.
70 def restore(self):
71 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000072 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000073 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000074 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000075 pair = self.pair
76 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000077 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000078
Jeremy Hylton66426532001-10-15 21:38:56 +000079class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000080 def __eq__(self, other):
81 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000082
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000083class D(C):
84 def __init__(self, arg):
85 pass
86
87class E(C):
88 def __getinitargs__(self):
89 return ()
90
Jeremy Hylton66426532001-10-15 21:38:56 +000091import __main__
92__main__.C = C
93C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000094__main__.D = D
95D.__module__ = "__main__"
96__main__.E = E
97E.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +000098
99class myint(int):
100 def __init__(self, x):
101 self.str = str(x)
102
103class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000104
Jeremy Hylton66426532001-10-15 21:38:56 +0000105 def __init__(self, a, b):
106 self.a = a
107 self.b = b
108
109 def __getinitargs__(self):
110 return self.a, self.b
111
Guido van Rossum04a86612001-12-19 16:58:54 +0000112class metaclass(type):
113 pass
114
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000115class use_metaclass(object, metaclass=metaclass):
116 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000117
Tim Peters70b02d72003-02-02 17:26:40 +0000118# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
119# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000120
Guido van Rossum98297ee2007-11-06 21:34:58 +0000121DATA0 = (
Mark Dickinson8dd05142009-01-20 20:43:58 +0000122 b'(lp0\nL0L\naL1L\naF2.0\nac'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000123 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000124 b'p1\n(F3.0\nF0.0\ntp2\nRp'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000125 b'3\naL1L\naL-1L\naL255L\naL-'
126 b'255L\naL-256L\naL65535L\na'
127 b'L-65535L\naL-65536L\naL2'
128 b'147483647L\naL-2147483'
129 b'647L\naL-2147483648L\na('
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000130 b'Vabc\np4\ng4\nccopyreg'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000131 b'\n_reconstructor\np5\n('
Georg Brandl1a3284e2007-12-02 09:40:06 +0000132 b'c__main__\nC\np6\ncbu'
133 b'iltins\nobject\np7\nNt'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000134 b'p8\nRp9\n(dp10\nVfoo\np1'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000135 b'1\nL1L\nsVbar\np12\nL2L\nsb'
136 b'g9\ntp13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000137)
Tim Peterse9358162001-01-22 22:05:20 +0000138
Guido van Rossum98297ee2007-11-06 21:34:58 +0000139# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000140DATA0_DIS = """\
141 0: ( MARK
142 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000143 2: p PUT 0
144 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000145 9: a APPEND
146 10: L LONG 1
147 14: a APPEND
148 15: F FLOAT 2.0
149 20: a APPEND
150 21: c GLOBAL 'builtins complex'
151 39: p PUT 1
152 42: ( MARK
153 43: F FLOAT 3.0
154 48: F FLOAT 0.0
155 53: t TUPLE (MARK at 42)
156 54: p PUT 2
157 57: R REDUCE
158 58: p PUT 3
159 61: a APPEND
160 62: L LONG 1
161 66: a APPEND
162 67: L LONG -1
163 72: a APPEND
164 73: L LONG 255
165 79: a APPEND
166 80: L LONG -255
167 87: a APPEND
168 88: L LONG -256
169 95: a APPEND
170 96: L LONG 65535
171 104: a APPEND
172 105: L LONG -65535
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000173 114: a APPEND
Mark Dickinson8dd05142009-01-20 20:43:58 +0000174 115: L LONG -65536
175 124: a APPEND
176 125: L LONG 2147483647
177 138: a APPEND
178 139: L LONG -2147483647
179 153: a APPEND
180 154: L LONG -2147483648
181 168: a APPEND
182 169: ( MARK
183 170: V UNICODE 'abc'
184 175: p PUT 4
185 178: g GET 4
186 181: c GLOBAL 'copyreg _reconstructor'
187 205: p PUT 5
188 208: ( MARK
189 209: c GLOBAL '__main__ C'
190 221: p PUT 6
191 224: c GLOBAL 'builtins object'
192 241: p PUT 7
193 244: N NONE
194 245: t TUPLE (MARK at 208)
195 246: p PUT 8
196 249: R REDUCE
197 250: p PUT 9
198 253: ( MARK
199 254: d DICT (MARK at 253)
200 255: p PUT 10
201 259: V UNICODE 'foo'
202 264: p PUT 11
203 268: L LONG 1
204 272: s SETITEM
205 273: V UNICODE 'bar'
206 278: p PUT 12
207 282: L LONG 2
208 286: s SETITEM
209 287: b BUILD
210 288: g GET 9
211 291: t TUPLE (MARK at 169)
212 292: p PUT 13
213 296: a APPEND
214 297: g GET 13
215 301: a APPEND
216 302: L LONG 5
217 306: a APPEND
218 307: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000219highest protocol among opcodes = 0
220"""
221
Guido van Rossum98297ee2007-11-06 21:34:58 +0000222DATA1 = (
Georg Brandl1a3284e2007-12-02 09:40:06 +0000223 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
224 b'builtins\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000225 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
226 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
227 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
228 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000229 b'cq\x04h\x04ccopyreg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000230 b'nstructor\nq\x05(c__main'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000231 b'__\nC\nq\x06cbuiltins\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000232 b'object\nq\x07Ntq\x08Rq\t}q\n('
233 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
234 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
235)
Tim Peters70b02d72003-02-02 17:26:40 +0000236
Guido van Rossum98297ee2007-11-06 21:34:58 +0000237# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000238DATA1_DIS = """\
239 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000240 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000241 3: ( MARK
242 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000243 6: K BININT1 1
244 8: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000245 17: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000246 35: q BINPUT 1
247 37: ( MARK
248 38: G BINFLOAT 3.0
249 47: G BINFLOAT 0.0
250 56: t TUPLE (MARK at 37)
251 57: q BINPUT 2
252 59: R REDUCE
253 60: q BINPUT 3
254 62: K BININT1 1
255 64: J BININT -1
256 69: K BININT1 255
257 71: J BININT -255
258 76: J BININT -256
259 81: M BININT2 65535
260 84: J BININT -65535
261 89: J BININT -65536
262 94: J BININT 2147483647
263 99: J BININT -2147483647
264 104: J BININT -2147483648
265 109: ( MARK
266 110: X BINUNICODE 'abc'
267 118: q BINPUT 4
268 120: h BINGET 4
269 122: c GLOBAL 'copyreg _reconstructor'
270 146: q BINPUT 5
271 148: ( MARK
272 149: c GLOBAL '__main__ C'
273 161: q BINPUT 6
274 163: c GLOBAL 'builtins object'
275 180: q BINPUT 7
276 182: N NONE
277 183: t TUPLE (MARK at 148)
278 184: q BINPUT 8
279 186: R REDUCE
280 187: q BINPUT 9
281 189: } EMPTY_DICT
282 190: q BINPUT 10
283 192: ( MARK
284 193: X BINUNICODE 'foo'
285 201: q BINPUT 11
286 203: K BININT1 1
287 205: X BINUNICODE 'bar'
288 213: q BINPUT 12
289 215: K BININT1 2
290 217: u SETITEMS (MARK at 192)
291 218: b BUILD
292 219: h BINGET 9
293 221: t TUPLE (MARK at 109)
294 222: q BINPUT 13
295 224: h BINGET 13
296 226: K BININT1 5
297 228: e APPENDS (MARK at 3)
298 229: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000299highest protocol among opcodes = 1
300"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000301
Guido van Rossum98297ee2007-11-06 21:34:58 +0000302DATA2 = (
303 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000304 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000305 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
306 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
307 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
308 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
309 b'bcq\x04h\x04c__main__\nC\nq\x05'
310 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
311 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
312 b'\nK\x05e.'
313)
Tim Petersfc273752003-03-02 04:54:24 +0000314
Guido van Rossum98297ee2007-11-06 21:34:58 +0000315# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000316DATA2_DIS = """\
317 0: \x80 PROTO 2
318 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000319 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000320 5: ( MARK
321 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000322 8: K BININT1 1
323 10: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000324 19: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000325 37: q BINPUT 1
326 39: G BINFLOAT 3.0
327 48: G BINFLOAT 0.0
328 57: \x86 TUPLE2
329 58: q BINPUT 2
330 60: R REDUCE
331 61: q BINPUT 3
332 63: K BININT1 1
333 65: J BININT -1
334 70: K BININT1 255
335 72: J BININT -255
336 77: J BININT -256
337 82: M BININT2 65535
338 85: J BININT -65535
339 90: J BININT -65536
340 95: J BININT 2147483647
341 100: J BININT -2147483647
342 105: J BININT -2147483648
343 110: ( MARK
344 111: X BINUNICODE 'abc'
345 119: q BINPUT 4
346 121: h BINGET 4
347 123: c GLOBAL '__main__ C'
348 135: q BINPUT 5
349 137: ) EMPTY_TUPLE
350 138: \x81 NEWOBJ
351 139: q BINPUT 6
352 141: } EMPTY_DICT
353 142: q BINPUT 7
354 144: ( MARK
355 145: X BINUNICODE 'foo'
356 153: q BINPUT 8
357 155: K BININT1 1
358 157: X BINUNICODE 'bar'
359 165: q BINPUT 9
360 167: K BININT1 2
361 169: u SETITEMS (MARK at 144)
362 170: b BUILD
363 171: h BINGET 6
364 173: t TUPLE (MARK at 110)
365 174: q BINPUT 10
366 176: h BINGET 10
367 178: K BININT1 5
368 180: e APPENDS (MARK at 5)
369 181: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000370highest protocol among opcodes = 2
371"""
372
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000373# set([1,2]) pickled from 2.x with protocol 2
374DATA3 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
375
376# xrange(5) pickled from 2.x with protocol 2
377DATA4 = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
378
379# a SimpleCookie() object pickled from 2.x with protocol 2
380DATA5 = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
381 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
382 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
383 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
384 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
385 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
386
387# set([3]) pickled from 2.x with protocol 2
388DATA6 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
389
390
Jeremy Hylton66426532001-10-15 21:38:56 +0000391def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000392 c = C()
393 c.foo = 1
394 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000395 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000396 # Append some integer test cases at cPickle.c's internal size
397 # cutoffs.
398 uint1max = 0xff
399 uint2max = 0xffff
400 int4max = 0x7fffffff
401 x.extend([1, -1,
402 uint1max, -uint1max, -uint1max-1,
403 uint2max, -uint2max, -uint2max-1,
404 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000405 y = ('abc', 'abc', c, c)
406 x.append(y)
407 x.append(y)
408 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000409 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000410
Jeremy Hylton66426532001-10-15 21:38:56 +0000411class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000412 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000413
Jeremy Hylton66426532001-10-15 21:38:56 +0000414 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000415
Jeremy Hylton66426532001-10-15 21:38:56 +0000416 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000417 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000418
Jeremy Hylton66426532001-10-15 21:38:56 +0000419 def test_misc(self):
420 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000421 for proto in protocols:
422 x = myint(4)
423 s = self.dumps(x, proto)
424 y = self.loads(s)
425 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000426
Tim Peters70b02d72003-02-02 17:26:40 +0000427 x = (1, ())
428 s = self.dumps(x, proto)
429 y = self.loads(s)
430 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000431
Tim Peters70b02d72003-02-02 17:26:40 +0000432 x = initarg(1, x)
433 s = self.dumps(x, proto)
434 y = self.loads(s)
435 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000436
Jeremy Hylton66426532001-10-15 21:38:56 +0000437 # XXX test __reduce__ protocol?
438
Tim Peters70b02d72003-02-02 17:26:40 +0000439 def test_roundtrip_equality(self):
440 expected = self._testdata
441 for proto in protocols:
442 s = self.dumps(expected, proto)
443 got = self.loads(s)
444 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000445
Guido van Rossum98297ee2007-11-06 21:34:58 +0000446 def test_load_from_data0(self):
447 self.assertEqual(self._testdata, self.loads(DATA0))
448
449 def test_load_from_data1(self):
450 self.assertEqual(self._testdata, self.loads(DATA1))
451
452 def test_load_from_data2(self):
453 self.assertEqual(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000454
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000455 def test_load_classic_instance(self):
456 # See issue5180. Test loading 2.x pickles that
457 # contain an instance of old style class.
458 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
459 xname = X.__name__.encode('ascii')
460 # Protocol 0 (text mode pickle):
461 """
462 0: ( MARK
463 1: i INST '__main__ X' (MARK at 0)
464 15: p PUT 0
465 18: ( MARK
466 19: d DICT (MARK at 18)
467 20: p PUT 1
468 23: b BUILD
469 24: . STOP
470 """
471 pickle0 = (b"(i__main__\n"
472 b"X\n"
473 b"p0\n"
474 b"(dp1\nb.").replace(b'X', xname)
475 self.assertEqual(X(*args), self.loads(pickle0))
476
477 # Protocol 1 (binary mode pickle)
478 """
479 0: ( MARK
480 1: c GLOBAL '__main__ X'
481 15: q BINPUT 0
482 17: o OBJ (MARK at 0)
483 18: q BINPUT 1
484 20: } EMPTY_DICT
485 21: q BINPUT 2
486 23: b BUILD
487 24: . STOP
488 """
489 pickle1 = (b'(c__main__\n'
490 b'X\n'
491 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
492 self.assertEqual(X(*args), self.loads(pickle1))
493
494 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
495 """
496 0: \x80 PROTO 2
497 2: ( MARK
498 3: c GLOBAL '__main__ X'
499 17: q BINPUT 0
500 19: o OBJ (MARK at 2)
501 20: q BINPUT 1
502 22: } EMPTY_DICT
503 23: q BINPUT 2
504 25: b BUILD
505 26: . STOP
506 """
507 pickle2 = (b'\x80\x02(c__main__\n'
508 b'X\n'
509 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
510 self.assertEqual(X(*args), self.loads(pickle2))
511
Tim Peters70b02d72003-02-02 17:26:40 +0000512 # There are gratuitous differences between pickles produced by
513 # pickle and cPickle, largely because cPickle starts PUT indices at
514 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
515 # there's a comment with an exclamation point there whose meaning
516 # is a mystery. cPickle also suppresses PUT for objects with a refcount
517 # of 1.
518 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000519 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000520 from pickletools import dis
521
522 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
523 s = self.dumps(self._testdata, proto)
524 filelike = StringIO()
525 dis(s, out=filelike)
526 got = filelike.getvalue()
527 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000528
529 def test_recursive_list(self):
530 l = []
531 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000532 for proto in protocols:
533 s = self.dumps(l, proto)
534 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000535 self.assertEqual(len(x), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000536 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000537
Collin Winter8ca69de2009-05-26 16:53:41 +0000538 def test_recursive_tuple(self):
539 t = ([],)
540 t[0].append(t)
541 for proto in protocols:
542 s = self.dumps(t, proto)
543 x = self.loads(s)
544 self.assertEqual(len(x), 1)
545 self.assertEqual(len(x[0]), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000546 self.assertTrue(x is x[0][0])
Collin Winter8ca69de2009-05-26 16:53:41 +0000547
Jeremy Hylton66426532001-10-15 21:38:56 +0000548 def test_recursive_dict(self):
549 d = {}
550 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000551 for proto in protocols:
552 s = self.dumps(d, proto)
553 x = self.loads(s)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000554 self.assertEqual(list(x.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000555 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000556
557 def test_recursive_inst(self):
558 i = C()
559 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000560 for proto in protocols:
561 s = self.dumps(i, 2)
562 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000563 self.assertEqual(dir(x), dir(i))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000564 self.assertTrue(x.attr is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000565
566 def test_recursive_multi(self):
567 l = []
568 d = {1:l}
569 i = C()
570 i.attr = d
571 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000572 for proto in protocols:
573 s = self.dumps(l, proto)
574 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000575 self.assertEqual(len(x), 1)
576 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000577 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000578 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000579
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000580 def test_get(self):
581 self.assertRaises(KeyError, self.loads, b'g0\np0')
582 self.assertEquals(self.loads(b'((Kdtp0\nh\x00l.))'), [(100,), (100,)])
Jeremy Hylton66426532001-10-15 21:38:56 +0000583
584 def test_insecure_strings(self):
Guido van Rossum39478e82007-08-27 17:23:59 +0000585 # XXX Some of these tests are temporarily disabled
586 insecure = [b"abc", b"2 + 2", # not quoted
587 ## b"'abc' + 'def'", # not a single quoted string
588 b"'abc", # quote is not closed
589 b"'abc\"", # open quote and close quote don't match
590 b"'abc' ?", # junk after close quote
591 b"'\\'", # trailing backslash
Jeremy Hylton66426532001-10-15 21:38:56 +0000592 # some tests of the quoting rules
Guido van Rossum39478e82007-08-27 17:23:59 +0000593 ## b"'abc\"\''",
594 ## b"'\\\\a\'\'\'\\\'\\\\\''",
Jeremy Hylton66426532001-10-15 21:38:56 +0000595 ]
Guido van Rossum39478e82007-08-27 17:23:59 +0000596 for b in insecure:
597 buf = b"S" + b + b"\012p0\012."
Jeremy Hylton66426532001-10-15 21:38:56 +0000598 self.assertRaises(ValueError, self.loads, buf)
599
Walter Dörwald9b775532007-06-08 14:30:53 +0000600 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000601 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +0000602 '<\\>', '<\\\U00012345>',
603 # surrogates
604 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000605 for proto in protocols:
606 for u in endcases:
607 p = self.dumps(u, proto)
608 u2 = self.loads(p)
609 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000610
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000611 def test_unicode_high_plane(self):
612 t = '\U00012345'
613 for proto in protocols:
614 p = self.dumps(t, proto)
615 t2 = self.loads(p)
616 self.assertEqual(t2, t)
617
Guido van Rossumf4169812008-03-17 22:56:06 +0000618 def test_bytes(self):
619 for proto in protocols:
620 for u in b'', b'xyz', b'xyz'*100:
621 p = self.dumps(u)
622 self.assertEqual(self.loads(p), u)
623
Jeremy Hylton66426532001-10-15 21:38:56 +0000624 def test_ints(self):
625 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000626 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000627 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000628 while n:
629 for expected in (-n, n):
630 s = self.dumps(expected, proto)
631 n2 = self.loads(s)
632 self.assertEqual(expected, n2)
633 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000634
Jeremy Hylton66426532001-10-15 21:38:56 +0000635 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000636 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000637 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000638 got = self.loads(data)
639 self.assertEqual(got, maxint64)
640
641 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000642 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000643 self.assertRaises(ValueError, self.loads, data)
644
Tim Petersee1a53c2003-02-02 02:57:53 +0000645 def test_long(self):
646 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000647 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000648 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000649 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000650 for npos in nbase-1, nbase, nbase+1:
651 for n in npos, -npos:
652 pickle = self.dumps(n, proto)
653 got = self.loads(pickle)
654 self.assertEqual(n, got)
655 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
656 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000657 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000658 nbase += nbase << 1000000
659 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000660 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000661 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000662 self.assertEqual(n, got)
663
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000664 def test_float(self):
665 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
666 3.14, 263.44582062374053, 6.022e23, 1e30]
667 test_values = test_values + [-x for x in test_values]
668 for proto in protocols:
669 for value in test_values:
670 pickle = self.dumps(value, proto)
671 got = self.loads(pickle)
672 self.assertEqual(value, got)
673
Thomas Wouters477c8d52006-05-27 19:21:47 +0000674 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
675 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000676 # make sure that floats are formatted locale independent with proto 0
677 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000678
Jeremy Hylton66426532001-10-15 21:38:56 +0000679 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000680 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000681
682 def test_getinitargs(self):
683 pass
684
Guido van Rossum04a86612001-12-19 16:58:54 +0000685 def test_metaclass(self):
686 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000687 for proto in protocols:
688 s = self.dumps(a, proto)
689 b = self.loads(s)
690 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000691
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000692 def test_structseq(self):
693 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000694 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000695
696 t = time.localtime()
697 for proto in protocols:
698 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000699 u = self.loads(s)
700 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000701 if hasattr(os, "stat"):
702 t = os.stat(os.curdir)
703 s = self.dumps(t, proto)
704 u = self.loads(s)
705 self.assertEqual(t, u)
706 if hasattr(os, "statvfs"):
707 t = os.statvfs(os.curdir)
708 s = self.dumps(t, proto)
709 u = self.loads(s)
710 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000711
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000712 # Tests for protocol 2
713
Tim Peters4190fb82003-02-02 16:09:05 +0000714 def test_proto(self):
715 build_none = pickle.NONE + pickle.STOP
716 for proto in protocols:
717 expected = build_none
718 if proto >= 2:
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000719 expected = pickle.PROTO + bytes([proto]) + expected
Tim Peters4190fb82003-02-02 16:09:05 +0000720 p = self.dumps(None, proto)
721 self.assertEqual(p, expected)
722
723 oob = protocols[-1] + 1 # a future protocol
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000724 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000725 try:
726 self.loads(badpickle)
Guido van Rossumb940e112007-01-10 16:19:56 +0000727 except ValueError as detail:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000728 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +0000729 "unsupported pickle protocol"))
730 else:
731 self.fail("expected bad protocol number to raise ValueError")
732
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000733 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000734 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000735 for proto in protocols:
736 s = self.dumps(x, proto)
737 y = self.loads(s)
738 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000739 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000740
741 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000742 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000743 for proto in protocols:
744 s = self.dumps(x, proto)
745 y = self.loads(s)
746 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000747 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000748
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000749 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000750 # Map (proto, len(tuple)) to expected opcode.
751 expected_opcode = {(0, 0): pickle.TUPLE,
752 (0, 1): pickle.TUPLE,
753 (0, 2): pickle.TUPLE,
754 (0, 3): pickle.TUPLE,
755 (0, 4): pickle.TUPLE,
756
757 (1, 0): pickle.EMPTY_TUPLE,
758 (1, 1): pickle.TUPLE,
759 (1, 2): pickle.TUPLE,
760 (1, 3): pickle.TUPLE,
761 (1, 4): pickle.TUPLE,
762
763 (2, 0): pickle.EMPTY_TUPLE,
764 (2, 1): pickle.TUPLE1,
765 (2, 2): pickle.TUPLE2,
766 (2, 3): pickle.TUPLE3,
767 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000768
769 (3, 0): pickle.EMPTY_TUPLE,
770 (3, 1): pickle.TUPLE1,
771 (3, 2): pickle.TUPLE2,
772 (3, 3): pickle.TUPLE3,
773 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000774 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000775 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000776 b = (1,)
777 c = (1, 2)
778 d = (1, 2, 3)
779 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000780 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000781 for x in a, b, c, d, e:
782 s = self.dumps(x, proto)
783 y = self.loads(s)
784 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000785 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +0000786 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +0000787
Guido van Rossum7d97d312003-01-28 04:25:27 +0000788 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000789 # Map (proto, singleton) to expected opcode.
790 expected_opcode = {(0, None): pickle.NONE,
791 (1, None): pickle.NONE,
792 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000793 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000794
795 (0, True): pickle.INT,
796 (1, True): pickle.INT,
797 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000798 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000799
800 (0, False): pickle.INT,
801 (1, False): pickle.INT,
802 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000803 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000804 }
Tim Peters4190fb82003-02-02 16:09:05 +0000805 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000806 for x in None, False, True:
807 s = self.dumps(x, proto)
808 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000809 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +0000810 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +0000811 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +0000812
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000813 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000814 x = MyTuple([1, 2, 3])
815 x.foo = 42
816 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000817 for proto in protocols:
818 s = self.dumps(x, proto)
819 y = self.loads(s)
820 self.assertEqual(tuple(x), tuple(y))
821 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000822
823 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000824 x = MyList([1, 2, 3])
825 x.foo = 42
826 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000827 for proto in protocols:
828 s = self.dumps(x, proto)
829 y = self.loads(s)
830 self.assertEqual(list(x), list(y))
831 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000832
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000833 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +0000834 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000835 for C in myclasses:
836 B = C.__base__
837 x = C(C.sample)
838 x.foo = 42
839 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000840 y = self.loads(s)
841 detail = (proto, C, B, x, y, type(y))
842 self.assertEqual(B(x), B(y), detail)
843 self.assertEqual(x.__dict__, y.__dict__, detail)
844
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000845 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +0000846 # an object of that type. Check that the resulting pickle uses opcode
847 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +0000848
Tim Peters22e71712003-02-03 22:27:38 +0000849 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +0000850 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000851 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000852 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000853 x = MyList([1, 2, 3])
854 x.foo = 42
855 x.bar = "hello"
856
Tim Peters22e71712003-02-03 22:27:38 +0000857 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000858 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000859 self.assertIn(__name__.encode("utf-8"), s1)
860 self.assertIn(b"MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +0000861 self.assertEqual(opcode_in_pickle(opcode, s1), False)
862
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000863 y = self.loads(s1)
864 self.assertEqual(list(x), list(y))
865 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000866
Tim Peters22e71712003-02-03 22:27:38 +0000867 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000868 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000869 self.assertNotIn(__name__.encode("utf-8"), s2)
870 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000871 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +0000872
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000873 y = self.loads(s2)
874 self.assertEqual(list(x), list(y))
875 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000876
877 finally:
Tim Peters3e667d52003-02-04 21:47:44 +0000878 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +0000879
880 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000881 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
882 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000883
884 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000885 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
886 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
887 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000888
889 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000890 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
891 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
892 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
893
Tim Peters8d2613a2003-02-11 16:40:16 +0000894 def test_list_chunking(self):
895 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +0000896 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000897 for proto in protocols:
898 s = self.dumps(x, proto)
899 y = self.loads(s)
900 self.assertEqual(x, y)
901 num_appends = count_opcode(pickle.APPENDS, s)
902 self.assertEqual(num_appends, proto > 0)
903
904 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +0000905 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000906 for proto in protocols:
907 s = self.dumps(x, proto)
908 y = self.loads(s)
909 self.assertEqual(x, y)
910 num_appends = count_opcode(pickle.APPENDS, s)
911 if proto == 0:
912 self.assertEqual(num_appends, 0)
913 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000914 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +0000915
916 def test_dict_chunking(self):
917 n = 10 # too small to chunk
918 x = dict.fromkeys(range(n))
919 for proto in protocols:
920 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +0000921 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +0000922 y = self.loads(s)
923 self.assertEqual(x, y)
924 num_setitems = count_opcode(pickle.SETITEMS, s)
925 self.assertEqual(num_setitems, proto > 0)
926
927 n = 2500 # expect at least two chunks when proto > 0
928 x = dict.fromkeys(range(n))
929 for proto in protocols:
930 s = self.dumps(x, proto)
931 y = self.loads(s)
932 self.assertEqual(x, y)
933 num_setitems = count_opcode(pickle.SETITEMS, s)
934 if proto == 0:
935 self.assertEqual(num_setitems, 0)
936 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000937 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000938
Tim Peterse9ef2032003-02-13 18:42:00 +0000939 def test_simple_newobj(self):
940 x = object.__new__(SimpleNewObj) # avoid __init__
941 x.abc = 666
942 for proto in protocols:
943 s = self.dumps(x, proto)
944 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
945 y = self.loads(s) # will raise TypeError if __init__ called
946 self.assertEqual(y.abc, 666)
947 self.assertEqual(x.__dict__, y.__dict__)
948
Tim Peters42f08ac2003-02-11 22:43:24 +0000949 def test_newobj_list_slots(self):
950 x = SlotList([1, 2, 3])
951 x.foo = 42
952 x.bar = "hello"
953 s = self.dumps(x, 2)
954 y = self.loads(s)
955 self.assertEqual(list(x), list(y))
956 self.assertEqual(x.__dict__, y.__dict__)
957 self.assertEqual(x.foo, y.foo)
958 self.assertEqual(x.bar, y.bar)
959
Guido van Rossum2a30b212003-02-18 22:41:24 +0000960 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +0000961 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000962 x = REX_one()
963 self.assertEqual(x._reduce_called, 0)
964 s = self.dumps(x, proto)
965 self.assertEqual(x._reduce_called, 1)
966 y = self.loads(s)
967 self.assertEqual(y._reduce_called, 0)
968
969 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +0000970 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000971 x = REX_two()
972 self.assertEqual(x._proto, None)
973 s = self.dumps(x, proto)
974 self.assertEqual(x._proto, proto)
975 y = self.loads(s)
976 self.assertEqual(y._proto, None)
977
978 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +0000979 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000980 x = REX_three()
981 self.assertEqual(x._proto, None)
982 s = self.dumps(x, proto)
983 self.assertEqual(x._proto, proto)
984 y = self.loads(s)
985 self.assertEqual(y._proto, None)
986
Guido van Rossumd8faa362007-04-27 19:54:29 +0000987 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +0000988 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000989 x = REX_four()
990 self.assertEqual(x._proto, None)
991 s = self.dumps(x, proto)
992 self.assertEqual(x._proto, proto)
993 y = self.loads(s)
994 self.assertEqual(y._proto, proto)
995
996 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +0000997 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000998 x = REX_five()
999 self.assertEqual(x._reduce_called, 0)
1000 s = self.dumps(x, proto)
1001 self.assertEqual(x._reduce_called, 1)
1002 y = self.loads(s)
1003 self.assertEqual(y._reduce_called, 1)
1004
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001005 def test_bad_getattr(self):
1006 x = BadGetattr()
1007 for proto in 0, 1:
1008 self.assertRaises(RuntimeError, self.dumps, x, proto)
1009 # protocol 2 don't raise a RuntimeError.
1010 d = self.dumps(x, 2)
Antoine Pitrouff150f22010-10-22 21:41:05 +00001011 self.assertRaises(RuntimeError, self.loads, d)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001012
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001013 def test_reduce_bad_iterator(self):
1014 # Issue4176: crash when 4th and 5th items of __reduce__()
1015 # are not iterators
1016 class C(object):
1017 def __reduce__(self):
1018 # 4th item is not an iterator
1019 return list, (), None, [], None
1020 class D(object):
1021 def __reduce__(self):
1022 # 5th item is not an iterator
1023 return dict, (), None, None, []
1024
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001025 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001026 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001027 try:
1028 self.dumps(C(), proto)
1029 except (pickle.PickleError):
1030 pass
1031 try:
1032 self.dumps(D(), proto)
1033 except (pickle.PickleError):
1034 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001035
Collin Winter771d8342009-04-16 03:18:06 +00001036 def test_many_puts_and_gets(self):
1037 # Test that internal data structures correctly deal with lots of
1038 # puts/gets.
1039 keys = ("aaa" + str(i) for i in range(100))
1040 large_dict = dict((k, [4, 5, 6]) for k in keys)
1041 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1042
1043 for proto in protocols:
1044 dumped = self.dumps(obj, proto)
1045 loaded = self.loads(dumped)
1046 self.assertEqual(loaded, obj,
1047 "Failed protocol %d: %r != %r"
1048 % (proto, obj, loaded))
1049
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001050 def test_attribute_name_interning(self):
1051 # Test that attribute names of pickled objects are interned when
1052 # unpickling.
1053 for proto in protocols:
1054 x = C()
1055 x.foo = 42
1056 x.bar = "hello"
1057 s = self.dumps(x, proto)
1058 y = self.loads(s)
1059 x_keys = sorted(x.__dict__)
1060 y_keys = sorted(y.__dict__)
1061 for x_key, y_key in zip(x_keys, y_keys):
1062 self.assertIs(x_key, y_key)
1063
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001064 def test_unpickle_from_2x(self):
1065 # Unpickle non-trivial data from Python 2.x.
1066 loaded = self.loads(DATA3)
1067 self.assertEqual(loaded, set([1, 2]))
1068 loaded = self.loads(DATA4)
1069 self.assertEqual(type(loaded), type(range(0)))
1070 self.assertEqual(list(loaded), list(range(5)))
1071 loaded = self.loads(DATA5)
1072 self.assertEqual(type(loaded), SimpleCookie)
1073 self.assertEqual(list(loaded.keys()), ["key"])
1074 self.assertEqual(loaded["key"].value, "Set-Cookie: key=value")
1075
1076 def test_pickle_to_2x(self):
1077 # Pickle non-trivial data with protocol 2, expecting that it yields
1078 # the same result as Python 2.x did.
1079 # NOTE: this test is a bit too strong since we can produce different
1080 # bytecode that 2.x will still understand.
1081 dumped = self.dumps(range(5), 2)
1082 self.assertEqual(dumped, DATA4)
1083 dumped = self.dumps(set([3]), 2)
1084 self.assertEqual(dumped, DATA6)
1085
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001086 def test_large_pickles(self):
1087 # Test the correctness of internal buffering routines when handling
1088 # large data.
1089 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001090 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001091 dumped = self.dumps(data, proto)
1092 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001093 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001094 self.assertEqual(loaded, data)
1095
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001096
Guido van Rossum2a30b212003-02-18 22:41:24 +00001097# Test classes for reduce_ex
1098
1099class REX_one(object):
1100 _reduce_called = 0
1101 def __reduce__(self):
1102 self._reduce_called = 1
1103 return REX_one, ()
1104 # No __reduce_ex__ here, but inheriting it from object
1105
1106class REX_two(object):
1107 _proto = None
1108 def __reduce_ex__(self, proto):
1109 self._proto = proto
1110 return REX_two, ()
1111 # No __reduce__ here, but inheriting it from object
1112
1113class REX_three(object):
1114 _proto = None
1115 def __reduce_ex__(self, proto):
1116 self._proto = proto
1117 return REX_two, ()
1118 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001119 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001120
Guido van Rossumd8faa362007-04-27 19:54:29 +00001121class REX_four(object):
1122 _proto = None
1123 def __reduce_ex__(self, proto):
1124 self._proto = proto
1125 return object.__reduce_ex__(self, proto)
1126 # Calling base class method should succeed
1127
1128class REX_five(object):
1129 _reduce_called = 0
1130 def __reduce__(self):
1131 self._reduce_called = 1
1132 return object.__reduce__(self)
1133 # This one used to fail with infinite recursion
1134
Guido van Rossum2a30b212003-02-18 22:41:24 +00001135# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001136
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001137class MyInt(int):
1138 sample = 1
1139
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001140class MyFloat(float):
1141 sample = 1.0
1142
1143class MyComplex(complex):
1144 sample = 1.0 + 0.0j
1145
1146class MyStr(str):
1147 sample = "hello"
1148
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001149class MyUnicode(str):
1150 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001151
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001152class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001153 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001154
1155class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001156 sample = [1, 2, 3]
1157
1158class MyDict(dict):
1159 sample = {"a": 1, "b": 2}
1160
Mark Dickinson5c2db372009-12-05 20:28:34 +00001161myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001162 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001163 MyStr, MyUnicode,
1164 MyTuple, MyList, MyDict]
1165
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001166
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001167class SlotList(MyList):
1168 __slots__ = ["foo"]
1169
Tim Peterse9ef2032003-02-13 18:42:00 +00001170class SimpleNewObj(object):
1171 def __init__(self, a, b, c):
1172 # raise an error, to make sure this isn't called
1173 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1174
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001175class BadGetattr:
1176 def __getattr__(self, key):
1177 self.foo
1178
Collin Winter771d8342009-04-16 03:18:06 +00001179
Jeremy Hylton66426532001-10-15 21:38:56 +00001180class AbstractPickleModuleTests(unittest.TestCase):
1181
1182 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001183 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001184 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001185 try:
1186 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001187 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001188 finally:
1189 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001190
1191 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001192 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001193 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001194 try:
1195 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001196 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001197 finally:
1198 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001199
Collin Winter771d8342009-04-16 03:18:06 +00001200 def test_load_from_and_dump_to_file(self):
1201 stream = io.BytesIO()
1202 data = [123, {}, 124]
1203 pickle.dump(data, stream)
1204 stream.seek(0)
1205 unpickled = pickle.load(stream)
1206 self.assertEqual(unpickled, data)
1207
Tim Petersc0c93702003-02-13 19:30:57 +00001208 def test_highest_protocol(self):
1209 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001210 self.assertEqual(pickle.HIGHEST_PROTOCOL, 3)
Tim Petersc0c93702003-02-13 19:30:57 +00001211
Martin v. Löwis544f1192004-07-27 05:22:33 +00001212 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001213 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001214 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001215 pickle.dump(123, f, -1)
1216 pickle.dump(123, file=f, protocol=-1)
1217 pickle.dumps(123, -1)
1218 pickle.dumps(123, protocol=-1)
1219 pickle.Pickler(f, -1)
1220 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001221
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001222 def test_bad_init(self):
1223 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001224 # Override initialization without calling __init__() of the superclass.
1225 class BadPickler(pickle.Pickler):
1226 def __init__(self): pass
1227
1228 class BadUnpickler(pickle.Unpickler):
1229 def __init__(self): pass
1230
1231 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1232 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1233
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001234 def test_bad_input(self):
1235 # Test issue4298
1236 s = bytes([0x58, 0, 0, 0, 0x54])
1237 self.assertRaises(EOFError, pickle.loads, s)
Antoine Pitrou01a15ea2010-01-07 17:57:31 +00001238 # Test issue7455
1239 s = b'0'
1240 self.assertRaises(pickle.UnpicklingError, pickle.loads, s)
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001241
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001242
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001243class AbstractPersistentPicklerTests(unittest.TestCase):
1244
1245 # This class defines persistent_id() and persistent_load()
1246 # functions that should be used by the pickler. All even integers
1247 # are pickled using persistent ids.
1248
1249 def persistent_id(self, object):
1250 if isinstance(object, int) and object % 2 == 0:
1251 self.id_count += 1
1252 return str(object)
1253 else:
1254 return None
1255
1256 def persistent_load(self, oid):
1257 self.load_count += 1
1258 object = int(oid)
1259 assert object % 2 == 0
1260 return object
1261
1262 def test_persistence(self):
1263 self.id_count = 0
1264 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001265 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001266 self.assertEqual(self.loads(self.dumps(L)), L)
1267 self.assertEqual(self.id_count, 5)
1268 self.assertEqual(self.load_count, 5)
1269
1270 def test_bin_persistence(self):
1271 self.id_count = 0
1272 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001273 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001274 self.assertEqual(self.loads(self.dumps(L, 1)), L)
1275 self.assertEqual(self.id_count, 5)
1276 self.assertEqual(self.load_count, 5)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001277
Collin Winter771d8342009-04-16 03:18:06 +00001278
1279class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1280
1281 pickler_class = None
1282 unpickler_class = None
1283
1284 def setUp(self):
1285 assert self.pickler_class
1286 assert self.unpickler_class
1287
1288 def test_clear_pickler_memo(self):
1289 # To test whether clear_memo() has any effect, we pickle an object,
1290 # then pickle it again without clearing the memo; the two serialized
1291 # forms should be different. If we clear_memo() and then pickle the
1292 # object again, the third serialized form should be identical to the
1293 # first one we obtained.
1294 data = ["abcdefg", "abcdefg", 44]
1295 f = io.BytesIO()
1296 pickler = self.pickler_class(f)
1297
1298 pickler.dump(data)
1299 first_pickled = f.getvalue()
1300
1301 # Reset StringIO object.
1302 f.seek(0)
1303 f.truncate()
1304
1305 pickler.dump(data)
1306 second_pickled = f.getvalue()
1307
1308 # Reset the Pickler and StringIO objects.
1309 pickler.clear_memo()
1310 f.seek(0)
1311 f.truncate()
1312
1313 pickler.dump(data)
1314 third_pickled = f.getvalue()
1315
1316 self.assertNotEqual(first_pickled, second_pickled)
1317 self.assertEqual(first_pickled, third_pickled)
1318
1319 def test_priming_pickler_memo(self):
1320 # Verify that we can set the Pickler's memo attribute.
1321 data = ["abcdefg", "abcdefg", 44]
1322 f = io.BytesIO()
1323 pickler = self.pickler_class(f)
1324
1325 pickler.dump(data)
1326 first_pickled = f.getvalue()
1327
1328 f = io.BytesIO()
1329 primed = self.pickler_class(f)
1330 primed.memo = pickler.memo
1331
1332 primed.dump(data)
1333 primed_pickled = f.getvalue()
1334
1335 self.assertNotEqual(first_pickled, primed_pickled)
1336
1337 def test_priming_unpickler_memo(self):
1338 # Verify that we can set the Unpickler's memo attribute.
1339 data = ["abcdefg", "abcdefg", 44]
1340 f = io.BytesIO()
1341 pickler = self.pickler_class(f)
1342
1343 pickler.dump(data)
1344 first_pickled = f.getvalue()
1345
1346 f = io.BytesIO()
1347 primed = self.pickler_class(f)
1348 primed.memo = pickler.memo
1349
1350 primed.dump(data)
1351 primed_pickled = f.getvalue()
1352
1353 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
1354 unpickled_data1 = unpickler.load()
1355
1356 self.assertEqual(unpickled_data1, data)
1357
1358 primed = self.unpickler_class(io.BytesIO(primed_pickled))
1359 primed.memo = unpickler.memo
1360 unpickled_data2 = primed.load()
1361
1362 primed.memo.clear()
1363
1364 self.assertEqual(unpickled_data2, data)
1365 self.assertTrue(unpickled_data2 is unpickled_data1)
1366
1367 def test_reusing_unpickler_objects(self):
1368 data1 = ["abcdefg", "abcdefg", 44]
1369 f = io.BytesIO()
1370 pickler = self.pickler_class(f)
1371 pickler.dump(data1)
1372 pickled1 = f.getvalue()
1373
1374 data2 = ["abcdefg", 44, 44]
1375 f = io.BytesIO()
1376 pickler = self.pickler_class(f)
1377 pickler.dump(data2)
1378 pickled2 = f.getvalue()
1379
1380 f = io.BytesIO()
1381 f.write(pickled1)
1382 f.seek(0)
1383 unpickler = self.unpickler_class(f)
1384 self.assertEqual(unpickler.load(), data1)
1385
1386 f.seek(0)
1387 f.truncate()
1388 f.write(pickled2)
1389 f.seek(0)
1390 self.assertEqual(unpickler.load(), data2)
1391
Antoine Pitrou04248a82010-10-12 20:51:21 +00001392 def _check_multiple_unpicklings(self, ioclass):
1393 for proto in protocols:
1394 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
1395 f = ioclass()
1396 pickler = self.pickler_class(f, protocol=proto)
1397 pickler.dump(data1)
1398 pickled = f.getvalue()
1399
1400 N = 5
1401 f = ioclass(pickled * N)
1402 unpickler = self.unpickler_class(f)
1403 for i in range(N):
1404 if f.seekable():
1405 pos = f.tell()
1406 self.assertEqual(unpickler.load(), data1)
1407 if f.seekable():
1408 self.assertEqual(f.tell(), pos + len(pickled))
1409 self.assertRaises(EOFError, unpickler.load)
1410
1411 def test_multiple_unpicklings_seekable(self):
1412 self._check_multiple_unpicklings(io.BytesIO)
1413
1414 def test_multiple_unpicklings_unseekable(self):
1415 self._check_multiple_unpicklings(UnseekableIO)
1416
Collin Winter771d8342009-04-16 03:18:06 +00001417
Guido van Rossum98297ee2007-11-06 21:34:58 +00001418if __name__ == "__main__":
1419 # Print some stuff that can be used to rewrite DATA{0,1,2}
1420 from pickletools import dis
1421 x = create_data()
1422 for i in range(3):
1423 p = pickle.dumps(x, i)
1424 print("DATA{0} = (".format(i))
1425 for j in range(0, len(p), 20):
1426 b = bytes(p[j:j+20])
1427 print(" {0!r}".format(b))
1428 print(")")
1429 print()
1430 print("# Disassembly of DATA{0}".format(i))
1431 print("DATA{0}_DIS = \"\"\"\\".format(i))
1432 dis(p)
1433 print("\"\"\"")
1434 print()