blob: e21d490e56a0e851afa92094f1ae726042d225ee [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 Pitrou7eecffd2010-10-22 19:43:59 +00006import weakref
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00007from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +00008
Benjamin Petersonee8712c2008-05-20 21:35:26 +00009from test.support import TestFailed, TESTFN, run_with_locale
Tim Peterse089c682001-04-10 03:41:41 +000010
Guido van Rossum98297ee2007-11-06 21:34:58 +000011from pickle import bytes_types
12
Tim Petersee1a53c2003-02-02 02:57:53 +000013# Tests that try a number of pickle protocols should have a
14# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000015# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000016protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000017
Tim Peters22e71712003-02-03 22:27:38 +000018
19# Return True if opcode code appears in the pickle, else False.
20def opcode_in_pickle(code, pickle):
21 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000022 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000023 return True
24 return False
25
Tim Peters8d2613a2003-02-11 16:40:16 +000026# Return the number of times opcode code appears in pickle.
27def count_opcode(code, pickle):
28 n = 0
29 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000030 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000031 n += 1
32 return n
33
Antoine Pitrou04248a82010-10-12 20:51:21 +000034
35class UnseekableIO(io.BytesIO):
36 def peek(self, *args):
37 raise NotImplementedError
38
39 def seekable(self):
40 return False
41
42 def seek(self, *args):
43 raise io.UnsupportedOperation
44
45 def tell(self):
46 raise io.UnsupportedOperation
47
48
Tim Peters3e667d52003-02-04 21:47:44 +000049# We can't very well test the extension registry without putting known stuff
50# in it, but we have to be careful to restore its original state. Code
51# should do this:
52#
53# e = ExtensionSaver(extension_code)
54# try:
55# fiddle w/ the extension registry's stuff for extension_code
56# finally:
57# e.restore()
58
59class ExtensionSaver:
60 # Remember current registration for code (if any), and remove it (if
61 # there is one).
62 def __init__(self, code):
63 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000064 if code in copyreg._inverted_registry:
65 self.pair = copyreg._inverted_registry[code]
66 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000067 else:
68 self.pair = None
69
70 # Restore previous registration for code.
71 def restore(self):
72 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000073 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000074 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000075 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000076 pair = self.pair
77 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000078 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000079
Jeremy Hylton66426532001-10-15 21:38:56 +000080class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000081 def __eq__(self, other):
82 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000083
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000084class D(C):
85 def __init__(self, arg):
86 pass
87
88class E(C):
89 def __getinitargs__(self):
90 return ()
91
Jeremy Hylton66426532001-10-15 21:38:56 +000092import __main__
93__main__.C = C
94C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000095__main__.D = D
96D.__module__ = "__main__"
97__main__.E = E
98E.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +000099
100class myint(int):
101 def __init__(self, x):
102 self.str = str(x)
103
104class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000105
Jeremy Hylton66426532001-10-15 21:38:56 +0000106 def __init__(self, a, b):
107 self.a = a
108 self.b = b
109
110 def __getinitargs__(self):
111 return self.a, self.b
112
Guido van Rossum04a86612001-12-19 16:58:54 +0000113class metaclass(type):
114 pass
115
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000116class use_metaclass(object, metaclass=metaclass):
117 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000118
Tim Peters70b02d72003-02-02 17:26:40 +0000119# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
120# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000121
Guido van Rossum98297ee2007-11-06 21:34:58 +0000122DATA0 = (
Mark Dickinson8dd05142009-01-20 20:43:58 +0000123 b'(lp0\nL0L\naL1L\naF2.0\nac'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000124 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000125 b'p1\n(F3.0\nF0.0\ntp2\nRp'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000126 b'3\naL1L\naL-1L\naL255L\naL-'
127 b'255L\naL-256L\naL65535L\na'
128 b'L-65535L\naL-65536L\naL2'
129 b'147483647L\naL-2147483'
130 b'647L\naL-2147483648L\na('
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000131 b'Vabc\np4\ng4\nccopyreg'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000132 b'\n_reconstructor\np5\n('
Georg Brandl1a3284e2007-12-02 09:40:06 +0000133 b'c__main__\nC\np6\ncbu'
134 b'iltins\nobject\np7\nNt'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000135 b'p8\nRp9\n(dp10\nVfoo\np1'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000136 b'1\nL1L\nsVbar\np12\nL2L\nsb'
137 b'g9\ntp13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000138)
Tim Peterse9358162001-01-22 22:05:20 +0000139
Guido van Rossum98297ee2007-11-06 21:34:58 +0000140# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000141DATA0_DIS = """\
142 0: ( MARK
143 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000144 2: p PUT 0
145 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000146 9: a APPEND
147 10: L LONG 1
148 14: a APPEND
149 15: F FLOAT 2.0
150 20: a APPEND
151 21: c GLOBAL 'builtins complex'
152 39: p PUT 1
153 42: ( MARK
154 43: F FLOAT 3.0
155 48: F FLOAT 0.0
156 53: t TUPLE (MARK at 42)
157 54: p PUT 2
158 57: R REDUCE
159 58: p PUT 3
160 61: a APPEND
161 62: L LONG 1
162 66: a APPEND
163 67: L LONG -1
164 72: a APPEND
165 73: L LONG 255
166 79: a APPEND
167 80: L LONG -255
168 87: a APPEND
169 88: L LONG -256
170 95: a APPEND
171 96: L LONG 65535
172 104: a APPEND
173 105: L LONG -65535
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000174 114: a APPEND
Mark Dickinson8dd05142009-01-20 20:43:58 +0000175 115: L LONG -65536
176 124: a APPEND
177 125: L LONG 2147483647
178 138: a APPEND
179 139: L LONG -2147483647
180 153: a APPEND
181 154: L LONG -2147483648
182 168: a APPEND
183 169: ( MARK
184 170: V UNICODE 'abc'
185 175: p PUT 4
186 178: g GET 4
187 181: c GLOBAL 'copyreg _reconstructor'
188 205: p PUT 5
189 208: ( MARK
190 209: c GLOBAL '__main__ C'
191 221: p PUT 6
192 224: c GLOBAL 'builtins object'
193 241: p PUT 7
194 244: N NONE
195 245: t TUPLE (MARK at 208)
196 246: p PUT 8
197 249: R REDUCE
198 250: p PUT 9
199 253: ( MARK
200 254: d DICT (MARK at 253)
201 255: p PUT 10
202 259: V UNICODE 'foo'
203 264: p PUT 11
204 268: L LONG 1
205 272: s SETITEM
206 273: V UNICODE 'bar'
207 278: p PUT 12
208 282: L LONG 2
209 286: s SETITEM
210 287: b BUILD
211 288: g GET 9
212 291: t TUPLE (MARK at 169)
213 292: p PUT 13
214 296: a APPEND
215 297: g GET 13
216 301: a APPEND
217 302: L LONG 5
218 306: a APPEND
219 307: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000220highest protocol among opcodes = 0
221"""
222
Guido van Rossum98297ee2007-11-06 21:34:58 +0000223DATA1 = (
Georg Brandl1a3284e2007-12-02 09:40:06 +0000224 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
225 b'builtins\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000226 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
227 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
228 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
229 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000230 b'cq\x04h\x04ccopyreg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000231 b'nstructor\nq\x05(c__main'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000232 b'__\nC\nq\x06cbuiltins\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000233 b'object\nq\x07Ntq\x08Rq\t}q\n('
234 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
235 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
236)
Tim Peters70b02d72003-02-02 17:26:40 +0000237
Guido van Rossum98297ee2007-11-06 21:34:58 +0000238# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000239DATA1_DIS = """\
240 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000241 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000242 3: ( MARK
243 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000244 6: K BININT1 1
245 8: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000246 17: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000247 35: q BINPUT 1
248 37: ( MARK
249 38: G BINFLOAT 3.0
250 47: G BINFLOAT 0.0
251 56: t TUPLE (MARK at 37)
252 57: q BINPUT 2
253 59: R REDUCE
254 60: q BINPUT 3
255 62: K BININT1 1
256 64: J BININT -1
257 69: K BININT1 255
258 71: J BININT -255
259 76: J BININT -256
260 81: M BININT2 65535
261 84: J BININT -65535
262 89: J BININT -65536
263 94: J BININT 2147483647
264 99: J BININT -2147483647
265 104: J BININT -2147483648
266 109: ( MARK
267 110: X BINUNICODE 'abc'
268 118: q BINPUT 4
269 120: h BINGET 4
270 122: c GLOBAL 'copyreg _reconstructor'
271 146: q BINPUT 5
272 148: ( MARK
273 149: c GLOBAL '__main__ C'
274 161: q BINPUT 6
275 163: c GLOBAL 'builtins object'
276 180: q BINPUT 7
277 182: N NONE
278 183: t TUPLE (MARK at 148)
279 184: q BINPUT 8
280 186: R REDUCE
281 187: q BINPUT 9
282 189: } EMPTY_DICT
283 190: q BINPUT 10
284 192: ( MARK
285 193: X BINUNICODE 'foo'
286 201: q BINPUT 11
287 203: K BININT1 1
288 205: X BINUNICODE 'bar'
289 213: q BINPUT 12
290 215: K BININT1 2
291 217: u SETITEMS (MARK at 192)
292 218: b BUILD
293 219: h BINGET 9
294 221: t TUPLE (MARK at 109)
295 222: q BINPUT 13
296 224: h BINGET 13
297 226: K BININT1 5
298 228: e APPENDS (MARK at 3)
299 229: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000300highest protocol among opcodes = 1
301"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000302
Guido van Rossum98297ee2007-11-06 21:34:58 +0000303DATA2 = (
304 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000305 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000306 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
307 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
308 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
309 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
310 b'bcq\x04h\x04c__main__\nC\nq\x05'
311 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
312 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
313 b'\nK\x05e.'
314)
Tim Petersfc273752003-03-02 04:54:24 +0000315
Guido van Rossum98297ee2007-11-06 21:34:58 +0000316# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000317DATA2_DIS = """\
318 0: \x80 PROTO 2
319 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000320 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000321 5: ( MARK
322 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000323 8: K BININT1 1
324 10: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000325 19: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000326 37: q BINPUT 1
327 39: G BINFLOAT 3.0
328 48: G BINFLOAT 0.0
329 57: \x86 TUPLE2
330 58: q BINPUT 2
331 60: R REDUCE
332 61: q BINPUT 3
333 63: K BININT1 1
334 65: J BININT -1
335 70: K BININT1 255
336 72: J BININT -255
337 77: J BININT -256
338 82: M BININT2 65535
339 85: J BININT -65535
340 90: J BININT -65536
341 95: J BININT 2147483647
342 100: J BININT -2147483647
343 105: J BININT -2147483648
344 110: ( MARK
345 111: X BINUNICODE 'abc'
346 119: q BINPUT 4
347 121: h BINGET 4
348 123: c GLOBAL '__main__ C'
349 135: q BINPUT 5
350 137: ) EMPTY_TUPLE
351 138: \x81 NEWOBJ
352 139: q BINPUT 6
353 141: } EMPTY_DICT
354 142: q BINPUT 7
355 144: ( MARK
356 145: X BINUNICODE 'foo'
357 153: q BINPUT 8
358 155: K BININT1 1
359 157: X BINUNICODE 'bar'
360 165: q BINPUT 9
361 167: K BININT1 2
362 169: u SETITEMS (MARK at 144)
363 170: b BUILD
364 171: h BINGET 6
365 173: t TUPLE (MARK at 110)
366 174: q BINPUT 10
367 176: h BINGET 10
368 178: K BININT1 5
369 180: e APPENDS (MARK at 5)
370 181: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000371highest protocol among opcodes = 2
372"""
373
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000374# set([1,2]) pickled from 2.x with protocol 2
375DATA3 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
376
377# xrange(5) pickled from 2.x with protocol 2
378DATA4 = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
379
380# a SimpleCookie() object pickled from 2.x with protocol 2
381DATA5 = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
382 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
383 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
384 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
385 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
386 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
387
388# set([3]) pickled from 2.x with protocol 2
389DATA6 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
390
391
Jeremy Hylton66426532001-10-15 21:38:56 +0000392def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000393 c = C()
394 c.foo = 1
395 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000396 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000397 # Append some integer test cases at cPickle.c's internal size
398 # cutoffs.
399 uint1max = 0xff
400 uint2max = 0xffff
401 int4max = 0x7fffffff
402 x.extend([1, -1,
403 uint1max, -uint1max, -uint1max-1,
404 uint2max, -uint2max, -uint2max-1,
405 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000406 y = ('abc', 'abc', c, c)
407 x.append(y)
408 x.append(y)
409 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000410 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000411
Jeremy Hylton66426532001-10-15 21:38:56 +0000412class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000413 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000414
Jeremy Hylton66426532001-10-15 21:38:56 +0000415 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000416
Jeremy Hylton66426532001-10-15 21:38:56 +0000417 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000418 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000419
Jeremy Hylton66426532001-10-15 21:38:56 +0000420 def test_misc(self):
421 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000422 for proto in protocols:
423 x = myint(4)
424 s = self.dumps(x, proto)
425 y = self.loads(s)
426 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000427
Tim Peters70b02d72003-02-02 17:26:40 +0000428 x = (1, ())
429 s = self.dumps(x, proto)
430 y = self.loads(s)
431 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000432
Tim Peters70b02d72003-02-02 17:26:40 +0000433 x = initarg(1, x)
434 s = self.dumps(x, proto)
435 y = self.loads(s)
436 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000437
Jeremy Hylton66426532001-10-15 21:38:56 +0000438 # XXX test __reduce__ protocol?
439
Tim Peters70b02d72003-02-02 17:26:40 +0000440 def test_roundtrip_equality(self):
441 expected = self._testdata
442 for proto in protocols:
443 s = self.dumps(expected, proto)
444 got = self.loads(s)
445 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000446
Guido van Rossum98297ee2007-11-06 21:34:58 +0000447 def test_load_from_data0(self):
448 self.assertEqual(self._testdata, self.loads(DATA0))
449
450 def test_load_from_data1(self):
451 self.assertEqual(self._testdata, self.loads(DATA1))
452
453 def test_load_from_data2(self):
454 self.assertEqual(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000455
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000456 def test_load_classic_instance(self):
457 # See issue5180. Test loading 2.x pickles that
458 # contain an instance of old style class.
459 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
460 xname = X.__name__.encode('ascii')
461 # Protocol 0 (text mode pickle):
462 """
463 0: ( MARK
464 1: i INST '__main__ X' (MARK at 0)
465 15: p PUT 0
466 18: ( MARK
467 19: d DICT (MARK at 18)
468 20: p PUT 1
469 23: b BUILD
470 24: . STOP
471 """
472 pickle0 = (b"(i__main__\n"
473 b"X\n"
474 b"p0\n"
475 b"(dp1\nb.").replace(b'X', xname)
476 self.assertEqual(X(*args), self.loads(pickle0))
477
478 # Protocol 1 (binary mode pickle)
479 """
480 0: ( MARK
481 1: c GLOBAL '__main__ X'
482 15: q BINPUT 0
483 17: o OBJ (MARK at 0)
484 18: q BINPUT 1
485 20: } EMPTY_DICT
486 21: q BINPUT 2
487 23: b BUILD
488 24: . STOP
489 """
490 pickle1 = (b'(c__main__\n'
491 b'X\n'
492 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
493 self.assertEqual(X(*args), self.loads(pickle1))
494
495 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
496 """
497 0: \x80 PROTO 2
498 2: ( MARK
499 3: c GLOBAL '__main__ X'
500 17: q BINPUT 0
501 19: o OBJ (MARK at 2)
502 20: q BINPUT 1
503 22: } EMPTY_DICT
504 23: q BINPUT 2
505 25: b BUILD
506 26: . STOP
507 """
508 pickle2 = (b'\x80\x02(c__main__\n'
509 b'X\n'
510 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
511 self.assertEqual(X(*args), self.loads(pickle2))
512
Tim Peters70b02d72003-02-02 17:26:40 +0000513 # There are gratuitous differences between pickles produced by
514 # pickle and cPickle, largely because cPickle starts PUT indices at
515 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
516 # there's a comment with an exclamation point there whose meaning
517 # is a mystery. cPickle also suppresses PUT for objects with a refcount
518 # of 1.
519 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000520 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000521 from pickletools import dis
522
523 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
524 s = self.dumps(self._testdata, proto)
525 filelike = StringIO()
526 dis(s, out=filelike)
527 got = filelike.getvalue()
528 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000529
530 def test_recursive_list(self):
531 l = []
532 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000533 for proto in protocols:
534 s = self.dumps(l, proto)
535 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000536 self.assertEqual(len(x), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000537 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000538
Collin Winter8ca69de2009-05-26 16:53:41 +0000539 def test_recursive_tuple(self):
540 t = ([],)
541 t[0].append(t)
542 for proto in protocols:
543 s = self.dumps(t, proto)
544 x = self.loads(s)
545 self.assertEqual(len(x), 1)
546 self.assertEqual(len(x[0]), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000547 self.assertTrue(x is x[0][0])
Collin Winter8ca69de2009-05-26 16:53:41 +0000548
Jeremy Hylton66426532001-10-15 21:38:56 +0000549 def test_recursive_dict(self):
550 d = {}
551 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000552 for proto in protocols:
553 s = self.dumps(d, proto)
554 x = self.loads(s)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000555 self.assertEqual(list(x.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000556 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000557
558 def test_recursive_inst(self):
559 i = C()
560 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000561 for proto in protocols:
562 s = self.dumps(i, 2)
563 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000564 self.assertEqual(dir(x), dir(i))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000565 self.assertTrue(x.attr is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000566
567 def test_recursive_multi(self):
568 l = []
569 d = {1:l}
570 i = C()
571 i.attr = d
572 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000573 for proto in protocols:
574 s = self.dumps(l, proto)
575 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000576 self.assertEqual(len(x), 1)
577 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000578 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000579 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000580
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000581 def test_get(self):
582 self.assertRaises(KeyError, self.loads, b'g0\np0')
583 self.assertEquals(self.loads(b'((Kdtp0\nh\x00l.))'), [(100,), (100,)])
Jeremy Hylton66426532001-10-15 21:38:56 +0000584
585 def test_insecure_strings(self):
Guido van Rossum39478e82007-08-27 17:23:59 +0000586 # XXX Some of these tests are temporarily disabled
587 insecure = [b"abc", b"2 + 2", # not quoted
588 ## b"'abc' + 'def'", # not a single quoted string
589 b"'abc", # quote is not closed
590 b"'abc\"", # open quote and close quote don't match
591 b"'abc' ?", # junk after close quote
592 b"'\\'", # trailing backslash
Jeremy Hylton66426532001-10-15 21:38:56 +0000593 # some tests of the quoting rules
Guido van Rossum39478e82007-08-27 17:23:59 +0000594 ## b"'abc\"\''",
595 ## b"'\\\\a\'\'\'\\\'\\\\\''",
Jeremy Hylton66426532001-10-15 21:38:56 +0000596 ]
Guido van Rossum39478e82007-08-27 17:23:59 +0000597 for b in insecure:
598 buf = b"S" + b + b"\012p0\012."
Jeremy Hylton66426532001-10-15 21:38:56 +0000599 self.assertRaises(ValueError, self.loads, buf)
600
Walter Dörwald9b775532007-06-08 14:30:53 +0000601 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000602 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +0000603 '<\\>', '<\\\U00012345>',
604 # surrogates
605 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000606 for proto in protocols:
607 for u in endcases:
608 p = self.dumps(u, proto)
609 u2 = self.loads(p)
610 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000611
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000612 def test_unicode_high_plane(self):
613 t = '\U00012345'
614 for proto in protocols:
615 p = self.dumps(t, proto)
616 t2 = self.loads(p)
617 self.assertEqual(t2, t)
618
Guido van Rossumf4169812008-03-17 22:56:06 +0000619 def test_bytes(self):
620 for proto in protocols:
621 for u in b'', b'xyz', b'xyz'*100:
622 p = self.dumps(u)
623 self.assertEqual(self.loads(p), u)
624
Jeremy Hylton66426532001-10-15 21:38:56 +0000625 def test_ints(self):
626 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000627 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000628 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000629 while n:
630 for expected in (-n, n):
631 s = self.dumps(expected, proto)
632 n2 = self.loads(s)
633 self.assertEqual(expected, n2)
634 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000635
Jeremy Hylton66426532001-10-15 21:38:56 +0000636 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000637 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000638 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000639 got = self.loads(data)
640 self.assertEqual(got, maxint64)
641
642 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000643 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000644 self.assertRaises(ValueError, self.loads, data)
645
Tim Petersee1a53c2003-02-02 02:57:53 +0000646 def test_long(self):
647 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000648 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000649 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000650 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000651 for npos in nbase-1, nbase, nbase+1:
652 for n in npos, -npos:
653 pickle = self.dumps(n, proto)
654 got = self.loads(pickle)
655 self.assertEqual(n, got)
656 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
657 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000658 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000659 nbase += nbase << 1000000
660 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000661 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000662 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000663 self.assertEqual(n, got)
664
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000665 def test_float(self):
666 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
667 3.14, 263.44582062374053, 6.022e23, 1e30]
668 test_values = test_values + [-x for x in test_values]
669 for proto in protocols:
670 for value in test_values:
671 pickle = self.dumps(value, proto)
672 got = self.loads(pickle)
673 self.assertEqual(value, got)
674
Thomas Wouters477c8d52006-05-27 19:21:47 +0000675 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
676 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000677 # make sure that floats are formatted locale independent with proto 0
678 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000679
Jeremy Hylton66426532001-10-15 21:38:56 +0000680 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000681 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000682
683 def test_getinitargs(self):
684 pass
685
Guido van Rossum04a86612001-12-19 16:58:54 +0000686 def test_metaclass(self):
687 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000688 for proto in protocols:
689 s = self.dumps(a, proto)
690 b = self.loads(s)
691 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000692
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000693 def test_structseq(self):
694 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000695 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000696
697 t = time.localtime()
698 for proto in protocols:
699 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000700 u = self.loads(s)
701 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000702 if hasattr(os, "stat"):
703 t = os.stat(os.curdir)
704 s = self.dumps(t, proto)
705 u = self.loads(s)
706 self.assertEqual(t, u)
707 if hasattr(os, "statvfs"):
708 t = os.statvfs(os.curdir)
709 s = self.dumps(t, proto)
710 u = self.loads(s)
711 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000712
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000713 # Tests for protocol 2
714
Tim Peters4190fb82003-02-02 16:09:05 +0000715 def test_proto(self):
716 build_none = pickle.NONE + pickle.STOP
717 for proto in protocols:
718 expected = build_none
719 if proto >= 2:
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000720 expected = pickle.PROTO + bytes([proto]) + expected
Tim Peters4190fb82003-02-02 16:09:05 +0000721 p = self.dumps(None, proto)
722 self.assertEqual(p, expected)
723
724 oob = protocols[-1] + 1 # a future protocol
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000725 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000726 try:
727 self.loads(badpickle)
Guido van Rossumb940e112007-01-10 16:19:56 +0000728 except ValueError as detail:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000729 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +0000730 "unsupported pickle protocol"))
731 else:
732 self.fail("expected bad protocol number to raise ValueError")
733
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000734 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000735 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000736 for proto in protocols:
737 s = self.dumps(x, proto)
738 y = self.loads(s)
739 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000740 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000741
742 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000743 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000744 for proto in protocols:
745 s = self.dumps(x, proto)
746 y = self.loads(s)
747 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000748 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000749
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000750 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000751 # Map (proto, len(tuple)) to expected opcode.
752 expected_opcode = {(0, 0): pickle.TUPLE,
753 (0, 1): pickle.TUPLE,
754 (0, 2): pickle.TUPLE,
755 (0, 3): pickle.TUPLE,
756 (0, 4): pickle.TUPLE,
757
758 (1, 0): pickle.EMPTY_TUPLE,
759 (1, 1): pickle.TUPLE,
760 (1, 2): pickle.TUPLE,
761 (1, 3): pickle.TUPLE,
762 (1, 4): pickle.TUPLE,
763
764 (2, 0): pickle.EMPTY_TUPLE,
765 (2, 1): pickle.TUPLE1,
766 (2, 2): pickle.TUPLE2,
767 (2, 3): pickle.TUPLE3,
768 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000769
770 (3, 0): pickle.EMPTY_TUPLE,
771 (3, 1): pickle.TUPLE1,
772 (3, 2): pickle.TUPLE2,
773 (3, 3): pickle.TUPLE3,
774 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000775 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000776 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000777 b = (1,)
778 c = (1, 2)
779 d = (1, 2, 3)
780 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000781 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000782 for x in a, b, c, d, e:
783 s = self.dumps(x, proto)
784 y = self.loads(s)
785 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000786 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +0000787 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +0000788
Guido van Rossum7d97d312003-01-28 04:25:27 +0000789 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000790 # Map (proto, singleton) to expected opcode.
791 expected_opcode = {(0, None): pickle.NONE,
792 (1, None): pickle.NONE,
793 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000794 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000795
796 (0, True): pickle.INT,
797 (1, True): pickle.INT,
798 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000799 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000800
801 (0, False): pickle.INT,
802 (1, False): pickle.INT,
803 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000804 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000805 }
Tim Peters4190fb82003-02-02 16:09:05 +0000806 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000807 for x in None, False, True:
808 s = self.dumps(x, proto)
809 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000810 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +0000811 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +0000812 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +0000813
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000814 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000815 x = MyTuple([1, 2, 3])
816 x.foo = 42
817 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000818 for proto in protocols:
819 s = self.dumps(x, proto)
820 y = self.loads(s)
821 self.assertEqual(tuple(x), tuple(y))
822 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000823
824 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000825 x = MyList([1, 2, 3])
826 x.foo = 42
827 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000828 for proto in protocols:
829 s = self.dumps(x, proto)
830 y = self.loads(s)
831 self.assertEqual(list(x), list(y))
832 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000833
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000834 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +0000835 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000836 for C in myclasses:
837 B = C.__base__
838 x = C(C.sample)
839 x.foo = 42
840 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000841 y = self.loads(s)
842 detail = (proto, C, B, x, y, type(y))
843 self.assertEqual(B(x), B(y), detail)
844 self.assertEqual(x.__dict__, y.__dict__, detail)
845
Antoine Pitrou7eecffd2010-10-22 19:43:59 +0000846 def test_newobj_proxies(self):
847 # NEWOBJ should use the __class__ rather than the raw type
848 classes = myclasses[:]
849 # Cannot create weakproxies to these classes
850 for c in (MyInt, MyTuple):
851 classes.remove(c)
852 for proto in protocols:
853 for C in classes:
854 B = C.__base__
855 x = C(C.sample)
856 x.foo = 42
857 p = weakref.proxy(x)
858 s = self.dumps(p, proto)
859 y = self.loads(s)
860 self.assertEqual(type(y), type(x)) # rather than type(p)
861 detail = (proto, C, B, x, y, type(y))
862 self.assertEqual(B(x), B(y), detail)
863 self.assertEqual(x.__dict__, y.__dict__, detail)
864
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000865 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +0000866 # an object of that type. Check that the resulting pickle uses opcode
867 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +0000868
Tim Peters22e71712003-02-03 22:27:38 +0000869 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +0000870 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000871 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000872 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000873 x = MyList([1, 2, 3])
874 x.foo = 42
875 x.bar = "hello"
876
Tim Peters22e71712003-02-03 22:27:38 +0000877 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000878 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000879 self.assertIn(__name__.encode("utf-8"), s1)
880 self.assertIn(b"MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +0000881 self.assertEqual(opcode_in_pickle(opcode, s1), False)
882
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000883 y = self.loads(s1)
884 self.assertEqual(list(x), list(y))
885 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000886
Tim Peters22e71712003-02-03 22:27:38 +0000887 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000888 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000889 self.assertNotIn(__name__.encode("utf-8"), s2)
890 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000891 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +0000892
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000893 y = self.loads(s2)
894 self.assertEqual(list(x), list(y))
895 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000896
897 finally:
Tim Peters3e667d52003-02-04 21:47:44 +0000898 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +0000899
900 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000901 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
902 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000903
904 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000905 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
906 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
907 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000908
909 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000910 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
911 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
912 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
913
Tim Peters8d2613a2003-02-11 16:40:16 +0000914 def test_list_chunking(self):
915 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +0000916 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000917 for proto in protocols:
918 s = self.dumps(x, proto)
919 y = self.loads(s)
920 self.assertEqual(x, y)
921 num_appends = count_opcode(pickle.APPENDS, s)
922 self.assertEqual(num_appends, proto > 0)
923
924 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +0000925 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000926 for proto in protocols:
927 s = self.dumps(x, proto)
928 y = self.loads(s)
929 self.assertEqual(x, y)
930 num_appends = count_opcode(pickle.APPENDS, s)
931 if proto == 0:
932 self.assertEqual(num_appends, 0)
933 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000934 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +0000935
936 def test_dict_chunking(self):
937 n = 10 # too small to chunk
938 x = dict.fromkeys(range(n))
939 for proto in protocols:
940 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +0000941 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +0000942 y = self.loads(s)
943 self.assertEqual(x, y)
944 num_setitems = count_opcode(pickle.SETITEMS, s)
945 self.assertEqual(num_setitems, proto > 0)
946
947 n = 2500 # expect at least two chunks when proto > 0
948 x = dict.fromkeys(range(n))
949 for proto in protocols:
950 s = self.dumps(x, proto)
951 y = self.loads(s)
952 self.assertEqual(x, y)
953 num_setitems = count_opcode(pickle.SETITEMS, s)
954 if proto == 0:
955 self.assertEqual(num_setitems, 0)
956 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000957 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000958
Tim Peterse9ef2032003-02-13 18:42:00 +0000959 def test_simple_newobj(self):
960 x = object.__new__(SimpleNewObj) # avoid __init__
961 x.abc = 666
962 for proto in protocols:
963 s = self.dumps(x, proto)
964 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
965 y = self.loads(s) # will raise TypeError if __init__ called
966 self.assertEqual(y.abc, 666)
967 self.assertEqual(x.__dict__, y.__dict__)
968
Tim Peters42f08ac2003-02-11 22:43:24 +0000969 def test_newobj_list_slots(self):
970 x = SlotList([1, 2, 3])
971 x.foo = 42
972 x.bar = "hello"
973 s = self.dumps(x, 2)
974 y = self.loads(s)
975 self.assertEqual(list(x), list(y))
976 self.assertEqual(x.__dict__, y.__dict__)
977 self.assertEqual(x.foo, y.foo)
978 self.assertEqual(x.bar, y.bar)
979
Guido van Rossum2a30b212003-02-18 22:41:24 +0000980 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +0000981 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000982 x = REX_one()
983 self.assertEqual(x._reduce_called, 0)
984 s = self.dumps(x, proto)
985 self.assertEqual(x._reduce_called, 1)
986 y = self.loads(s)
987 self.assertEqual(y._reduce_called, 0)
988
989 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +0000990 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +0000991 x = REX_two()
992 self.assertEqual(x._proto, None)
993 s = self.dumps(x, proto)
994 self.assertEqual(x._proto, proto)
995 y = self.loads(s)
996 self.assertEqual(y._proto, None)
997
998 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +0000999 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001000 x = REX_three()
1001 self.assertEqual(x._proto, None)
1002 s = self.dumps(x, proto)
1003 self.assertEqual(x._proto, proto)
1004 y = self.loads(s)
1005 self.assertEqual(y._proto, None)
1006
Guido van Rossumd8faa362007-04-27 19:54:29 +00001007 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001008 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001009 x = REX_four()
1010 self.assertEqual(x._proto, None)
1011 s = self.dumps(x, proto)
1012 self.assertEqual(x._proto, proto)
1013 y = self.loads(s)
1014 self.assertEqual(y._proto, proto)
1015
1016 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001017 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001018 x = REX_five()
1019 self.assertEqual(x._reduce_called, 0)
1020 s = self.dumps(x, proto)
1021 self.assertEqual(x._reduce_called, 1)
1022 y = self.loads(s)
1023 self.assertEqual(y._reduce_called, 1)
1024
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001025 def test_bad_getattr(self):
1026 x = BadGetattr()
1027 for proto in 0, 1:
1028 self.assertRaises(RuntimeError, self.dumps, x, proto)
1029 # protocol 2 don't raise a RuntimeError.
1030 d = self.dumps(x, 2)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001031
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001032 def test_reduce_bad_iterator(self):
1033 # Issue4176: crash when 4th and 5th items of __reduce__()
1034 # are not iterators
1035 class C(object):
1036 def __reduce__(self):
1037 # 4th item is not an iterator
1038 return list, (), None, [], None
1039 class D(object):
1040 def __reduce__(self):
1041 # 5th item is not an iterator
1042 return dict, (), None, None, []
1043
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001044 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001045 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001046 try:
1047 self.dumps(C(), proto)
1048 except (pickle.PickleError):
1049 pass
1050 try:
1051 self.dumps(D(), proto)
1052 except (pickle.PickleError):
1053 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001054
Collin Winter771d8342009-04-16 03:18:06 +00001055 def test_many_puts_and_gets(self):
1056 # Test that internal data structures correctly deal with lots of
1057 # puts/gets.
1058 keys = ("aaa" + str(i) for i in range(100))
1059 large_dict = dict((k, [4, 5, 6]) for k in keys)
1060 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1061
1062 for proto in protocols:
1063 dumped = self.dumps(obj, proto)
1064 loaded = self.loads(dumped)
1065 self.assertEqual(loaded, obj,
1066 "Failed protocol %d: %r != %r"
1067 % (proto, obj, loaded))
1068
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001069 def test_attribute_name_interning(self):
1070 # Test that attribute names of pickled objects are interned when
1071 # unpickling.
1072 for proto in protocols:
1073 x = C()
1074 x.foo = 42
1075 x.bar = "hello"
1076 s = self.dumps(x, proto)
1077 y = self.loads(s)
1078 x_keys = sorted(x.__dict__)
1079 y_keys = sorted(y.__dict__)
1080 for x_key, y_key in zip(x_keys, y_keys):
1081 self.assertIs(x_key, y_key)
1082
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001083 def test_unpickle_from_2x(self):
1084 # Unpickle non-trivial data from Python 2.x.
1085 loaded = self.loads(DATA3)
1086 self.assertEqual(loaded, set([1, 2]))
1087 loaded = self.loads(DATA4)
1088 self.assertEqual(type(loaded), type(range(0)))
1089 self.assertEqual(list(loaded), list(range(5)))
1090 loaded = self.loads(DATA5)
1091 self.assertEqual(type(loaded), SimpleCookie)
1092 self.assertEqual(list(loaded.keys()), ["key"])
1093 self.assertEqual(loaded["key"].value, "Set-Cookie: key=value")
1094
1095 def test_pickle_to_2x(self):
1096 # Pickle non-trivial data with protocol 2, expecting that it yields
1097 # the same result as Python 2.x did.
1098 # NOTE: this test is a bit too strong since we can produce different
1099 # bytecode that 2.x will still understand.
1100 dumped = self.dumps(range(5), 2)
1101 self.assertEqual(dumped, DATA4)
1102 dumped = self.dumps(set([3]), 2)
1103 self.assertEqual(dumped, DATA6)
1104
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001105 def test_large_pickles(self):
1106 # Test the correctness of internal buffering routines when handling
1107 # large data.
1108 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001109 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001110 dumped = self.dumps(data, proto)
1111 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001112 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001113 self.assertEqual(loaded, data)
1114
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001115
Guido van Rossum2a30b212003-02-18 22:41:24 +00001116# Test classes for reduce_ex
1117
1118class REX_one(object):
1119 _reduce_called = 0
1120 def __reduce__(self):
1121 self._reduce_called = 1
1122 return REX_one, ()
1123 # No __reduce_ex__ here, but inheriting it from object
1124
1125class REX_two(object):
1126 _proto = None
1127 def __reduce_ex__(self, proto):
1128 self._proto = proto
1129 return REX_two, ()
1130 # No __reduce__ here, but inheriting it from object
1131
1132class REX_three(object):
1133 _proto = None
1134 def __reduce_ex__(self, proto):
1135 self._proto = proto
1136 return REX_two, ()
1137 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001138 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001139
Guido van Rossumd8faa362007-04-27 19:54:29 +00001140class REX_four(object):
1141 _proto = None
1142 def __reduce_ex__(self, proto):
1143 self._proto = proto
1144 return object.__reduce_ex__(self, proto)
1145 # Calling base class method should succeed
1146
1147class REX_five(object):
1148 _reduce_called = 0
1149 def __reduce__(self):
1150 self._reduce_called = 1
1151 return object.__reduce__(self)
1152 # This one used to fail with infinite recursion
1153
Guido van Rossum2a30b212003-02-18 22:41:24 +00001154# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001155
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001156class MyInt(int):
1157 sample = 1
1158
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001159class MyFloat(float):
1160 sample = 1.0
1161
1162class MyComplex(complex):
1163 sample = 1.0 + 0.0j
1164
1165class MyStr(str):
1166 sample = "hello"
1167
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001168class MyUnicode(str):
1169 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001170
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001171class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001172 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001173
1174class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001175 sample = [1, 2, 3]
1176
1177class MyDict(dict):
1178 sample = {"a": 1, "b": 2}
1179
Mark Dickinson5c2db372009-12-05 20:28:34 +00001180myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001181 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001182 MyStr, MyUnicode,
1183 MyTuple, MyList, MyDict]
1184
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001185
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001186class SlotList(MyList):
1187 __slots__ = ["foo"]
1188
Tim Peterse9ef2032003-02-13 18:42:00 +00001189class SimpleNewObj(object):
1190 def __init__(self, a, b, c):
1191 # raise an error, to make sure this isn't called
1192 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1193
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001194class BadGetattr:
1195 def __getattr__(self, key):
1196 self.foo
1197
Collin Winter771d8342009-04-16 03:18:06 +00001198
Jeremy Hylton66426532001-10-15 21:38:56 +00001199class AbstractPickleModuleTests(unittest.TestCase):
1200
1201 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001202 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001203 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001204 try:
1205 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001206 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001207 finally:
1208 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001209
1210 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001211 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001212 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001213 try:
1214 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001215 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001216 finally:
1217 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001218
Collin Winter771d8342009-04-16 03:18:06 +00001219 def test_load_from_and_dump_to_file(self):
1220 stream = io.BytesIO()
1221 data = [123, {}, 124]
1222 pickle.dump(data, stream)
1223 stream.seek(0)
1224 unpickled = pickle.load(stream)
1225 self.assertEqual(unpickled, data)
1226
Tim Petersc0c93702003-02-13 19:30:57 +00001227 def test_highest_protocol(self):
1228 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001229 self.assertEqual(pickle.HIGHEST_PROTOCOL, 3)
Tim Petersc0c93702003-02-13 19:30:57 +00001230
Martin v. Löwis544f1192004-07-27 05:22:33 +00001231 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001232 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001233 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001234 pickle.dump(123, f, -1)
1235 pickle.dump(123, file=f, protocol=-1)
1236 pickle.dumps(123, -1)
1237 pickle.dumps(123, protocol=-1)
1238 pickle.Pickler(f, -1)
1239 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001240
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001241 def test_bad_init(self):
1242 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001243 # Override initialization without calling __init__() of the superclass.
1244 class BadPickler(pickle.Pickler):
1245 def __init__(self): pass
1246
1247 class BadUnpickler(pickle.Unpickler):
1248 def __init__(self): pass
1249
1250 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1251 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1252
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001253 def test_bad_input(self):
1254 # Test issue4298
1255 s = bytes([0x58, 0, 0, 0, 0x54])
1256 self.assertRaises(EOFError, pickle.loads, s)
Antoine Pitrou01a15ea2010-01-07 17:57:31 +00001257 # Test issue7455
1258 s = b'0'
1259 self.assertRaises(pickle.UnpicklingError, pickle.loads, s)
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001260
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001261
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001262class AbstractPersistentPicklerTests(unittest.TestCase):
1263
1264 # This class defines persistent_id() and persistent_load()
1265 # functions that should be used by the pickler. All even integers
1266 # are pickled using persistent ids.
1267
1268 def persistent_id(self, object):
1269 if isinstance(object, int) and object % 2 == 0:
1270 self.id_count += 1
1271 return str(object)
1272 else:
1273 return None
1274
1275 def persistent_load(self, oid):
1276 self.load_count += 1
1277 object = int(oid)
1278 assert object % 2 == 0
1279 return object
1280
1281 def test_persistence(self):
1282 self.id_count = 0
1283 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001284 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001285 self.assertEqual(self.loads(self.dumps(L)), L)
1286 self.assertEqual(self.id_count, 5)
1287 self.assertEqual(self.load_count, 5)
1288
1289 def test_bin_persistence(self):
1290 self.id_count = 0
1291 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001292 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001293 self.assertEqual(self.loads(self.dumps(L, 1)), L)
1294 self.assertEqual(self.id_count, 5)
1295 self.assertEqual(self.load_count, 5)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001296
Collin Winter771d8342009-04-16 03:18:06 +00001297
1298class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1299
1300 pickler_class = None
1301 unpickler_class = None
1302
1303 def setUp(self):
1304 assert self.pickler_class
1305 assert self.unpickler_class
1306
1307 def test_clear_pickler_memo(self):
1308 # To test whether clear_memo() has any effect, we pickle an object,
1309 # then pickle it again without clearing the memo; the two serialized
1310 # forms should be different. If we clear_memo() and then pickle the
1311 # object again, the third serialized form should be identical to the
1312 # first one we obtained.
1313 data = ["abcdefg", "abcdefg", 44]
1314 f = io.BytesIO()
1315 pickler = self.pickler_class(f)
1316
1317 pickler.dump(data)
1318 first_pickled = f.getvalue()
1319
1320 # Reset StringIO object.
1321 f.seek(0)
1322 f.truncate()
1323
1324 pickler.dump(data)
1325 second_pickled = f.getvalue()
1326
1327 # Reset the Pickler and StringIO objects.
1328 pickler.clear_memo()
1329 f.seek(0)
1330 f.truncate()
1331
1332 pickler.dump(data)
1333 third_pickled = f.getvalue()
1334
1335 self.assertNotEqual(first_pickled, second_pickled)
1336 self.assertEqual(first_pickled, third_pickled)
1337
1338 def test_priming_pickler_memo(self):
1339 # Verify that we can set the Pickler's memo attribute.
1340 data = ["abcdefg", "abcdefg", 44]
1341 f = io.BytesIO()
1342 pickler = self.pickler_class(f)
1343
1344 pickler.dump(data)
1345 first_pickled = f.getvalue()
1346
1347 f = io.BytesIO()
1348 primed = self.pickler_class(f)
1349 primed.memo = pickler.memo
1350
1351 primed.dump(data)
1352 primed_pickled = f.getvalue()
1353
1354 self.assertNotEqual(first_pickled, primed_pickled)
1355
1356 def test_priming_unpickler_memo(self):
1357 # Verify that we can set the Unpickler's memo attribute.
1358 data = ["abcdefg", "abcdefg", 44]
1359 f = io.BytesIO()
1360 pickler = self.pickler_class(f)
1361
1362 pickler.dump(data)
1363 first_pickled = f.getvalue()
1364
1365 f = io.BytesIO()
1366 primed = self.pickler_class(f)
1367 primed.memo = pickler.memo
1368
1369 primed.dump(data)
1370 primed_pickled = f.getvalue()
1371
1372 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
1373 unpickled_data1 = unpickler.load()
1374
1375 self.assertEqual(unpickled_data1, data)
1376
1377 primed = self.unpickler_class(io.BytesIO(primed_pickled))
1378 primed.memo = unpickler.memo
1379 unpickled_data2 = primed.load()
1380
1381 primed.memo.clear()
1382
1383 self.assertEqual(unpickled_data2, data)
1384 self.assertTrue(unpickled_data2 is unpickled_data1)
1385
1386 def test_reusing_unpickler_objects(self):
1387 data1 = ["abcdefg", "abcdefg", 44]
1388 f = io.BytesIO()
1389 pickler = self.pickler_class(f)
1390 pickler.dump(data1)
1391 pickled1 = f.getvalue()
1392
1393 data2 = ["abcdefg", 44, 44]
1394 f = io.BytesIO()
1395 pickler = self.pickler_class(f)
1396 pickler.dump(data2)
1397 pickled2 = f.getvalue()
1398
1399 f = io.BytesIO()
1400 f.write(pickled1)
1401 f.seek(0)
1402 unpickler = self.unpickler_class(f)
1403 self.assertEqual(unpickler.load(), data1)
1404
1405 f.seek(0)
1406 f.truncate()
1407 f.write(pickled2)
1408 f.seek(0)
1409 self.assertEqual(unpickler.load(), data2)
1410
Antoine Pitrou04248a82010-10-12 20:51:21 +00001411 def _check_multiple_unpicklings(self, ioclass):
1412 for proto in protocols:
1413 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
1414 f = ioclass()
1415 pickler = self.pickler_class(f, protocol=proto)
1416 pickler.dump(data1)
1417 pickled = f.getvalue()
1418
1419 N = 5
1420 f = ioclass(pickled * N)
1421 unpickler = self.unpickler_class(f)
1422 for i in range(N):
1423 if f.seekable():
1424 pos = f.tell()
1425 self.assertEqual(unpickler.load(), data1)
1426 if f.seekable():
1427 self.assertEqual(f.tell(), pos + len(pickled))
1428 self.assertRaises(EOFError, unpickler.load)
1429
1430 def test_multiple_unpicklings_seekable(self):
1431 self._check_multiple_unpicklings(io.BytesIO)
1432
1433 def test_multiple_unpicklings_unseekable(self):
1434 self._check_multiple_unpicklings(UnseekableIO)
1435
Collin Winter771d8342009-04-16 03:18:06 +00001436
Guido van Rossum98297ee2007-11-06 21:34:58 +00001437if __name__ == "__main__":
1438 # Print some stuff that can be used to rewrite DATA{0,1,2}
1439 from pickletools import dis
1440 x = create_data()
1441 for i in range(3):
1442 p = pickle.dumps(x, i)
1443 print("DATA{0} = (".format(i))
1444 for j in range(0, len(p), 20):
1445 b = bytes(p[j:j+20])
1446 print(" {0!r}".format(b))
1447 print(")")
1448 print()
1449 print("# Disassembly of DATA{0}".format(i))
1450 print("DATA{0}_DIS = \"\"\"\\".format(i))
1451 dis(p)
1452 print("\"\"\"")
1453 print()