blob: 052290d764054b27733b9e0a34f09fbfa549d700 [file] [log] [blame]
Collin Winter771d8342009-04-16 03:18:06 +00001import io
Jeremy Hylton66426532001-10-15 21:38:56 +00002import unittest
Tim Peters4190fb82003-02-02 16:09:05 +00003import pickle
Tim Peters31f119e2003-02-03 16:20:13 +00004import pickletools
Antoine Pitrou82be19f2011-08-29 23:09:33 +02005import sys
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00006import copyreg
Antoine Pitrou16c4ce12011-03-11 21:30:43 +01007import weakref
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00008from http.cookies import SimpleCookie
Tim Peters4190fb82003-02-02 16:09:05 +00009
Antoine Pitrou82be19f2011-08-29 23:09:33 +020010from test.support import (
Antoine Pitrouee763e22011-08-29 23:14:53 +020011 TestFailed, TESTFN, run_with_locale, no_tracing,
Antoine Pitrou94190bb2011-10-04 10:22:36 +020012 _2G, _4G, bigmemtest,
Antoine Pitrou82be19f2011-08-29 23:09:33 +020013 )
Tim Peterse089c682001-04-10 03:41:41 +000014
Guido van Rossum98297ee2007-11-06 21:34:58 +000015from pickle import bytes_types
16
Tim Petersee1a53c2003-02-02 02:57:53 +000017# Tests that try a number of pickle protocols should have a
18# for proto in protocols:
Tim Peters8587b3c2003-02-13 15:44:41 +000019# kind of outer loop.
Tim Peters8587b3c2003-02-13 15:44:41 +000020protocols = range(pickle.HIGHEST_PROTOCOL + 1)
Tim Petersee1a53c2003-02-02 02:57:53 +000021
Antoine Pitroub7591d42011-10-04 16:18:15 +020022ascii_char_size = 1
Antoine Pitrou82be19f2011-08-29 23:09:33 +020023
Tim Peters22e71712003-02-03 22:27:38 +000024
25# Return True if opcode code appears in the pickle, else False.
26def opcode_in_pickle(code, pickle):
27 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000028 if op.code == code.decode("latin-1"):
Tim Peters22e71712003-02-03 22:27:38 +000029 return True
30 return False
31
Tim Peters8d2613a2003-02-11 16:40:16 +000032# Return the number of times opcode code appears in pickle.
33def count_opcode(code, pickle):
34 n = 0
35 for op, dummy, dummy in pickletools.genops(pickle):
Guido van Rossumcfe5f202007-05-08 21:26:54 +000036 if op.code == code.decode("latin-1"):
Tim Peters8d2613a2003-02-11 16:40:16 +000037 n += 1
38 return n
39
Antoine Pitrou04248a82010-10-12 20:51:21 +000040
41class UnseekableIO(io.BytesIO):
42 def peek(self, *args):
43 raise NotImplementedError
44
45 def seekable(self):
46 return False
47
48 def seek(self, *args):
49 raise io.UnsupportedOperation
50
51 def tell(self):
52 raise io.UnsupportedOperation
53
54
Tim Peters3e667d52003-02-04 21:47:44 +000055# We can't very well test the extension registry without putting known stuff
56# in it, but we have to be careful to restore its original state. Code
57# should do this:
58#
59# e = ExtensionSaver(extension_code)
60# try:
61# fiddle w/ the extension registry's stuff for extension_code
62# finally:
63# e.restore()
64
65class ExtensionSaver:
66 # Remember current registration for code (if any), and remove it (if
67 # there is one).
68 def __init__(self, code):
69 self.code = code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000070 if code in copyreg._inverted_registry:
71 self.pair = copyreg._inverted_registry[code]
72 copyreg.remove_extension(self.pair[0], self.pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000073 else:
74 self.pair = None
75
76 # Restore previous registration for code.
77 def restore(self):
78 code = self.code
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000079 curpair = copyreg._inverted_registry.get(code)
Tim Peters3e667d52003-02-04 21:47:44 +000080 if curpair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000081 copyreg.remove_extension(curpair[0], curpair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000082 pair = self.pair
83 if pair is not None:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000084 copyreg.add_extension(pair[0], pair[1], code)
Tim Peters3e667d52003-02-04 21:47:44 +000085
Jeremy Hylton66426532001-10-15 21:38:56 +000086class C:
Guido van Rossum47b9ff62006-08-24 00:41:19 +000087 def __eq__(self, other):
88 return self.__dict__ == other.__dict__
Jeremy Hylton66426532001-10-15 21:38:56 +000089
Alexander Belopolskyd92f0402010-07-17 22:50:45 +000090class D(C):
91 def __init__(self, arg):
92 pass
93
94class E(C):
95 def __getinitargs__(self):
96 return ()
97
Jeremy Hylton66426532001-10-15 21:38:56 +000098import __main__
99__main__.C = C
100C.__module__ = "__main__"
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000101__main__.D = D
102D.__module__ = "__main__"
103__main__.E = E
104E.__module__ = "__main__"
Jeremy Hylton66426532001-10-15 21:38:56 +0000105
106class myint(int):
107 def __init__(self, x):
108 self.str = str(x)
109
110class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +0000111
Jeremy Hylton66426532001-10-15 21:38:56 +0000112 def __init__(self, a, b):
113 self.a = a
114 self.b = b
115
116 def __getinitargs__(self):
117 return self.a, self.b
118
Guido van Rossum04a86612001-12-19 16:58:54 +0000119class metaclass(type):
120 pass
121
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000122class use_metaclass(object, metaclass=metaclass):
123 pass
Guido van Rossum04a86612001-12-19 16:58:54 +0000124
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200125class pickling_metaclass(type):
126 def __eq__(self, other):
127 return (type(self) == type(other) and
128 self.reduce_args == other.reduce_args)
129
130 def __reduce__(self):
131 return (create_dynamic_class, self.reduce_args)
132
133def create_dynamic_class(name, bases):
134 result = pickling_metaclass(name, bases, dict())
135 result.reduce_args = (name, bases)
136 return result
137
Tim Peters70b02d72003-02-02 17:26:40 +0000138# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
139# the object returned by create_data().
Tim Petersee1a53c2003-02-02 02:57:53 +0000140
Guido van Rossum98297ee2007-11-06 21:34:58 +0000141DATA0 = (
Mark Dickinson8dd05142009-01-20 20:43:58 +0000142 b'(lp0\nL0L\naL1L\naF2.0\nac'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000143 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000144 b'p1\n(F3.0\nF0.0\ntp2\nRp'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000145 b'3\naL1L\naL-1L\naL255L\naL-'
146 b'255L\naL-256L\naL65535L\na'
147 b'L-65535L\naL-65536L\naL2'
148 b'147483647L\naL-2147483'
149 b'647L\naL-2147483648L\na('
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000150 b'Vabc\np4\ng4\nccopyreg'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000151 b'\n_reconstructor\np5\n('
Georg Brandl1a3284e2007-12-02 09:40:06 +0000152 b'c__main__\nC\np6\ncbu'
153 b'iltins\nobject\np7\nNt'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000154 b'p8\nRp9\n(dp10\nVfoo\np1'
Mark Dickinson8dd05142009-01-20 20:43:58 +0000155 b'1\nL1L\nsVbar\np12\nL2L\nsb'
156 b'g9\ntp13\nag13\naL5L\na.'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000157)
Tim Peterse9358162001-01-22 22:05:20 +0000158
Guido van Rossum98297ee2007-11-06 21:34:58 +0000159# Disassembly of DATA0
Tim Peters70b02d72003-02-02 17:26:40 +0000160DATA0_DIS = """\
161 0: ( MARK
162 1: l LIST (MARK at 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000163 2: p PUT 0
164 5: L LONG 0
Mark Dickinson8dd05142009-01-20 20:43:58 +0000165 9: a APPEND
166 10: L LONG 1
167 14: a APPEND
168 15: F FLOAT 2.0
169 20: a APPEND
170 21: c GLOBAL 'builtins complex'
171 39: p PUT 1
172 42: ( MARK
173 43: F FLOAT 3.0
174 48: F FLOAT 0.0
175 53: t TUPLE (MARK at 42)
176 54: p PUT 2
177 57: R REDUCE
178 58: p PUT 3
179 61: a APPEND
180 62: L LONG 1
181 66: a APPEND
182 67: L LONG -1
183 72: a APPEND
184 73: L LONG 255
185 79: a APPEND
186 80: L LONG -255
187 87: a APPEND
188 88: L LONG -256
189 95: a APPEND
190 96: L LONG 65535
191 104: a APPEND
192 105: L LONG -65535
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000193 114: a APPEND
Mark Dickinson8dd05142009-01-20 20:43:58 +0000194 115: L LONG -65536
195 124: a APPEND
196 125: L LONG 2147483647
197 138: a APPEND
198 139: L LONG -2147483647
199 153: a APPEND
200 154: L LONG -2147483648
201 168: a APPEND
202 169: ( MARK
203 170: V UNICODE 'abc'
204 175: p PUT 4
205 178: g GET 4
206 181: c GLOBAL 'copyreg _reconstructor'
207 205: p PUT 5
208 208: ( MARK
209 209: c GLOBAL '__main__ C'
210 221: p PUT 6
211 224: c GLOBAL 'builtins object'
212 241: p PUT 7
213 244: N NONE
214 245: t TUPLE (MARK at 208)
215 246: p PUT 8
216 249: R REDUCE
217 250: p PUT 9
218 253: ( MARK
219 254: d DICT (MARK at 253)
220 255: p PUT 10
221 259: V UNICODE 'foo'
222 264: p PUT 11
223 268: L LONG 1
224 272: s SETITEM
225 273: V UNICODE 'bar'
226 278: p PUT 12
227 282: L LONG 2
228 286: s SETITEM
229 287: b BUILD
230 288: g GET 9
231 291: t TUPLE (MARK at 169)
232 292: p PUT 13
233 296: a APPEND
234 297: g GET 13
235 301: a APPEND
236 302: L LONG 5
237 306: a APPEND
238 307: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000239highest protocol among opcodes = 0
240"""
241
Guido van Rossum98297ee2007-11-06 21:34:58 +0000242DATA1 = (
Georg Brandl1a3284e2007-12-02 09:40:06 +0000243 b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
244 b'builtins\ncomplex\nq\x01'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000245 b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
246 b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
247 b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
248 b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000249 b'cq\x04h\x04ccopyreg\n_reco'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000250 b'nstructor\nq\x05(c__main'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000251 b'__\nC\nq\x06cbuiltins\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000252 b'object\nq\x07Ntq\x08Rq\t}q\n('
253 b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
254 b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
255)
Tim Peters70b02d72003-02-02 17:26:40 +0000256
Guido van Rossum98297ee2007-11-06 21:34:58 +0000257# Disassembly of DATA1
Tim Peters70b02d72003-02-02 17:26:40 +0000258DATA1_DIS = """\
259 0: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000260 1: q BINPUT 0
Tim Peters70b02d72003-02-02 17:26:40 +0000261 3: ( MARK
262 4: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000263 6: K BININT1 1
264 8: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000265 17: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000266 35: q BINPUT 1
267 37: ( MARK
268 38: G BINFLOAT 3.0
269 47: G BINFLOAT 0.0
270 56: t TUPLE (MARK at 37)
271 57: q BINPUT 2
272 59: R REDUCE
273 60: q BINPUT 3
274 62: K BININT1 1
275 64: J BININT -1
276 69: K BININT1 255
277 71: J BININT -255
278 76: J BININT -256
279 81: M BININT2 65535
280 84: J BININT -65535
281 89: J BININT -65536
282 94: J BININT 2147483647
283 99: J BININT -2147483647
284 104: J BININT -2147483648
285 109: ( MARK
286 110: X BINUNICODE 'abc'
287 118: q BINPUT 4
288 120: h BINGET 4
289 122: c GLOBAL 'copyreg _reconstructor'
290 146: q BINPUT 5
291 148: ( MARK
292 149: c GLOBAL '__main__ C'
293 161: q BINPUT 6
294 163: c GLOBAL 'builtins object'
295 180: q BINPUT 7
296 182: N NONE
297 183: t TUPLE (MARK at 148)
298 184: q BINPUT 8
299 186: R REDUCE
300 187: q BINPUT 9
301 189: } EMPTY_DICT
302 190: q BINPUT 10
303 192: ( MARK
304 193: X BINUNICODE 'foo'
305 201: q BINPUT 11
306 203: K BININT1 1
307 205: X BINUNICODE 'bar'
308 213: q BINPUT 12
309 215: K BININT1 2
310 217: u SETITEMS (MARK at 192)
311 218: b BUILD
312 219: h BINGET 9
313 221: t TUPLE (MARK at 109)
314 222: q BINPUT 13
315 224: h BINGET 13
316 226: K BININT1 5
317 228: e APPENDS (MARK at 3)
318 229: . STOP
Tim Peters70b02d72003-02-02 17:26:40 +0000319highest protocol among opcodes = 1
320"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000321
Guido van Rossum98297ee2007-11-06 21:34:58 +0000322DATA2 = (
323 b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
Georg Brandl1a3284e2007-12-02 09:40:06 +0000324 b'builtins\ncomplex\n'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000325 b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
326 b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
327 b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
328 b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
329 b'bcq\x04h\x04c__main__\nC\nq\x05'
330 b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
331 b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
332 b'\nK\x05e.'
333)
Tim Petersfc273752003-03-02 04:54:24 +0000334
Guido van Rossum98297ee2007-11-06 21:34:58 +0000335# Disassembly of DATA2
Tim Petersfc273752003-03-02 04:54:24 +0000336DATA2_DIS = """\
337 0: \x80 PROTO 2
338 2: ] EMPTY_LIST
Guido van Rossum98297ee2007-11-06 21:34:58 +0000339 3: q BINPUT 0
Tim Petersfc273752003-03-02 04:54:24 +0000340 5: ( MARK
341 6: K BININT1 0
Guido van Rossum98297ee2007-11-06 21:34:58 +0000342 8: K BININT1 1
343 10: G BINFLOAT 2.0
Georg Brandl1a3284e2007-12-02 09:40:06 +0000344 19: c GLOBAL 'builtins complex'
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000345 37: q BINPUT 1
346 39: G BINFLOAT 3.0
347 48: G BINFLOAT 0.0
348 57: \x86 TUPLE2
349 58: q BINPUT 2
350 60: R REDUCE
351 61: q BINPUT 3
352 63: K BININT1 1
353 65: J BININT -1
354 70: K BININT1 255
355 72: J BININT -255
356 77: J BININT -256
357 82: M BININT2 65535
358 85: J BININT -65535
359 90: J BININT -65536
360 95: J BININT 2147483647
361 100: J BININT -2147483647
362 105: J BININT -2147483648
363 110: ( MARK
364 111: X BINUNICODE 'abc'
365 119: q BINPUT 4
366 121: h BINGET 4
367 123: c GLOBAL '__main__ C'
368 135: q BINPUT 5
369 137: ) EMPTY_TUPLE
370 138: \x81 NEWOBJ
371 139: q BINPUT 6
372 141: } EMPTY_DICT
373 142: q BINPUT 7
374 144: ( MARK
375 145: X BINUNICODE 'foo'
376 153: q BINPUT 8
377 155: K BININT1 1
378 157: X BINUNICODE 'bar'
379 165: q BINPUT 9
380 167: K BININT1 2
381 169: u SETITEMS (MARK at 144)
382 170: b BUILD
383 171: h BINGET 6
384 173: t TUPLE (MARK at 110)
385 174: q BINPUT 10
386 176: h BINGET 10
387 178: K BININT1 5
388 180: e APPENDS (MARK at 5)
389 181: . STOP
Tim Petersfc273752003-03-02 04:54:24 +0000390highest protocol among opcodes = 2
391"""
392
Antoine Pitroud9dfaa92009-06-04 20:32:06 +0000393# set([1,2]) pickled from 2.x with protocol 2
394DATA3 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'
395
396# xrange(5) pickled from 2.x with protocol 2
397DATA4 = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'
398
399# a SimpleCookie() object pickled from 2.x with protocol 2
400DATA5 = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
401 b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
402 b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
403 b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
404 b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
405 b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')
406
407# set([3]) pickled from 2.x with protocol 2
408DATA6 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'
409
410
Jeremy Hylton66426532001-10-15 21:38:56 +0000411def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000412 c = C()
413 c.foo = 1
414 c.bar = 2
Guido van Rossume2a383d2007-01-15 16:59:06 +0000415 x = [0, 1, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000416 # Append some integer test cases at cPickle.c's internal size
417 # cutoffs.
418 uint1max = 0xff
419 uint2max = 0xffff
420 int4max = 0x7fffffff
421 x.extend([1, -1,
422 uint1max, -uint1max, -uint1max-1,
423 uint2max, -uint2max, -uint2max-1,
424 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000425 y = ('abc', 'abc', c, c)
426 x.append(y)
427 x.append(y)
428 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000429 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000430
Jeremy Hylton66426532001-10-15 21:38:56 +0000431class AbstractPickleTests(unittest.TestCase):
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000432 # Subclass must define self.dumps, self.loads.
Tim Petersc58440f2001-04-09 17:16:31 +0000433
Jeremy Hylton66426532001-10-15 21:38:56 +0000434 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000435
Jeremy Hylton66426532001-10-15 21:38:56 +0000436 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000437 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000438
Jeremy Hylton66426532001-10-15 21:38:56 +0000439 def test_misc(self):
440 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000441 for proto in protocols:
442 x = myint(4)
443 s = self.dumps(x, proto)
444 y = self.loads(s)
445 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000446
Tim Peters70b02d72003-02-02 17:26:40 +0000447 x = (1, ())
448 s = self.dumps(x, proto)
449 y = self.loads(s)
450 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000451
Tim Peters70b02d72003-02-02 17:26:40 +0000452 x = initarg(1, x)
453 s = self.dumps(x, proto)
454 y = self.loads(s)
455 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000456
Jeremy Hylton66426532001-10-15 21:38:56 +0000457 # XXX test __reduce__ protocol?
458
Tim Peters70b02d72003-02-02 17:26:40 +0000459 def test_roundtrip_equality(self):
460 expected = self._testdata
461 for proto in protocols:
462 s = self.dumps(expected, proto)
463 got = self.loads(s)
464 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000465
Guido van Rossum98297ee2007-11-06 21:34:58 +0000466 def test_load_from_data0(self):
467 self.assertEqual(self._testdata, self.loads(DATA0))
468
469 def test_load_from_data1(self):
470 self.assertEqual(self._testdata, self.loads(DATA1))
471
472 def test_load_from_data2(self):
473 self.assertEqual(self._testdata, self.loads(DATA2))
Jeremy Hylton66426532001-10-15 21:38:56 +0000474
Alexander Belopolskyd92f0402010-07-17 22:50:45 +0000475 def test_load_classic_instance(self):
476 # See issue5180. Test loading 2.x pickles that
477 # contain an instance of old style class.
478 for X, args in [(C, ()), (D, ('x',)), (E, ())]:
479 xname = X.__name__.encode('ascii')
480 # Protocol 0 (text mode pickle):
481 """
482 0: ( MARK
483 1: i INST '__main__ X' (MARK at 0)
484 15: p PUT 0
485 18: ( MARK
486 19: d DICT (MARK at 18)
487 20: p PUT 1
488 23: b BUILD
489 24: . STOP
490 """
491 pickle0 = (b"(i__main__\n"
492 b"X\n"
493 b"p0\n"
494 b"(dp1\nb.").replace(b'X', xname)
495 self.assertEqual(X(*args), self.loads(pickle0))
496
497 # Protocol 1 (binary mode pickle)
498 """
499 0: ( MARK
500 1: c GLOBAL '__main__ X'
501 15: q BINPUT 0
502 17: o OBJ (MARK at 0)
503 18: q BINPUT 1
504 20: } EMPTY_DICT
505 21: q BINPUT 2
506 23: b BUILD
507 24: . STOP
508 """
509 pickle1 = (b'(c__main__\n'
510 b'X\n'
511 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
512 self.assertEqual(X(*args), self.loads(pickle1))
513
514 # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
515 """
516 0: \x80 PROTO 2
517 2: ( MARK
518 3: c GLOBAL '__main__ X'
519 17: q BINPUT 0
520 19: o OBJ (MARK at 2)
521 20: q BINPUT 1
522 22: } EMPTY_DICT
523 23: q BINPUT 2
524 25: b BUILD
525 26: . STOP
526 """
527 pickle2 = (b'\x80\x02(c__main__\n'
528 b'X\n'
529 b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
530 self.assertEqual(X(*args), self.loads(pickle2))
531
Tim Peters70b02d72003-02-02 17:26:40 +0000532 # There are gratuitous differences between pickles produced by
533 # pickle and cPickle, largely because cPickle starts PUT indices at
534 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
535 # there's a comment with an exclamation point there whose meaning
536 # is a mystery. cPickle also suppresses PUT for objects with a refcount
537 # of 1.
538 def dont_test_disassembly(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000539 from io import StringIO
Tim Peters70b02d72003-02-02 17:26:40 +0000540 from pickletools import dis
541
542 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
543 s = self.dumps(self._testdata, proto)
544 filelike = StringIO()
545 dis(s, out=filelike)
546 got = filelike.getvalue()
547 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000548
549 def test_recursive_list(self):
550 l = []
551 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000552 for proto in protocols:
553 s = self.dumps(l, proto)
554 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000555 self.assertEqual(len(x), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000556 self.assertTrue(x is x[0])
Jeremy Hylton66426532001-10-15 21:38:56 +0000557
Collin Winter8ca69de2009-05-26 16:53:41 +0000558 def test_recursive_tuple(self):
559 t = ([],)
560 t[0].append(t)
561 for proto in protocols:
562 s = self.dumps(t, proto)
563 x = self.loads(s)
564 self.assertEqual(len(x), 1)
565 self.assertEqual(len(x[0]), 1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000566 self.assertTrue(x is x[0][0])
Collin Winter8ca69de2009-05-26 16:53:41 +0000567
Jeremy Hylton66426532001-10-15 21:38:56 +0000568 def test_recursive_dict(self):
569 d = {}
570 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000571 for proto in protocols:
572 s = self.dumps(d, proto)
573 x = self.loads(s)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000574 self.assertEqual(list(x.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000575 self.assertTrue(x[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000576
577 def test_recursive_inst(self):
578 i = C()
579 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000580 for proto in protocols:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200581 s = self.dumps(i, proto)
Tim Peters70b02d72003-02-02 17:26:40 +0000582 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000583 self.assertEqual(dir(x), dir(i))
Ezio Melottiaaef3442013-03-04 15:17:56 +0200584 self.assertIs(x.attr, x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000585
586 def test_recursive_multi(self):
587 l = []
588 d = {1:l}
589 i = C()
590 i.attr = d
591 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000592 for proto in protocols:
593 s = self.dumps(l, proto)
594 x = self.loads(s)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000595 self.assertEqual(len(x), 1)
596 self.assertEqual(dir(x[0]), dir(i))
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000597 self.assertEqual(list(x[0].attr.keys()), [1])
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000598 self.assertTrue(x[0].attr[1] is x)
Jeremy Hylton66426532001-10-15 21:38:56 +0000599
Alexandre Vassalottica2d6102008-06-12 18:26:05 +0000600 def test_get(self):
601 self.assertRaises(KeyError, self.loads, b'g0\np0')
Ezio Melottib3aedd42010-11-20 19:04:17 +0000602 self.assertEqual(self.loads(b'((Kdtp0\nh\x00l.))'), [(100,), (100,)])
Jeremy Hylton66426532001-10-15 21:38:56 +0000603
604 def test_insecure_strings(self):
Guido van Rossum39478e82007-08-27 17:23:59 +0000605 # XXX Some of these tests are temporarily disabled
606 insecure = [b"abc", b"2 + 2", # not quoted
607 ## b"'abc' + 'def'", # not a single quoted string
608 b"'abc", # quote is not closed
609 b"'abc\"", # open quote and close quote don't match
610 b"'abc' ?", # junk after close quote
611 b"'\\'", # trailing backslash
Antoine Pitrou3034efd2013-04-15 21:51:09 +0200612 # Variations on issue #17710
613 b"'",
614 b'"',
615 b"' ",
616 b"' ",
617 b"' ",
618 b"' ",
619 b'" ',
Jeremy Hylton66426532001-10-15 21:38:56 +0000620 # some tests of the quoting rules
Guido van Rossum39478e82007-08-27 17:23:59 +0000621 ## b"'abc\"\''",
622 ## b"'\\\\a\'\'\'\\\'\\\\\''",
Jeremy Hylton66426532001-10-15 21:38:56 +0000623 ]
Guido van Rossum39478e82007-08-27 17:23:59 +0000624 for b in insecure:
625 buf = b"S" + b + b"\012p0\012."
Jeremy Hylton66426532001-10-15 21:38:56 +0000626 self.assertRaises(ValueError, self.loads, buf)
627
Walter Dörwald9b775532007-06-08 14:30:53 +0000628 def test_unicode(self):
Benjamin Petersond1486302008-12-27 16:58:50 +0000629 endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
Victor Stinner485fb562010-04-13 11:07:24 +0000630 '<\\>', '<\\\U00012345>',
631 # surrogates
632 '<\udc80>']
Walter Dörwald9b775532007-06-08 14:30:53 +0000633 for proto in protocols:
634 for u in endcases:
635 p = self.dumps(u, proto)
636 u2 = self.loads(p)
637 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000638
Alexandre Vassalotti554d8782008-12-27 07:32:41 +0000639 def test_unicode_high_plane(self):
640 t = '\U00012345'
641 for proto in protocols:
642 p = self.dumps(t, proto)
643 t2 = self.loads(p)
644 self.assertEqual(t2, t)
645
Guido van Rossumf4169812008-03-17 22:56:06 +0000646 def test_bytes(self):
647 for proto in protocols:
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500648 for s in b'', b'xyz', b'xyz'*100:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200649 p = self.dumps(s, proto)
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500650 self.assertEqual(self.loads(p), s)
651 for s in [bytes([i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200652 p = self.dumps(s, proto)
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500653 self.assertEqual(self.loads(p), s)
654 for s in [bytes([i, i]) for i in range(256)]:
Ezio Melottiaaef3442013-03-04 15:17:56 +0200655 p = self.dumps(s, proto)
Alexandre Vassalotti3bfc65a2011-12-13 13:08:09 -0500656 self.assertEqual(self.loads(p), s)
Guido van Rossumf4169812008-03-17 22:56:06 +0000657
Jeremy Hylton66426532001-10-15 21:38:56 +0000658 def test_ints(self):
659 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000660 for proto in protocols:
Christian Heimesa37d4c62007-12-04 23:02:19 +0000661 n = sys.maxsize
Tim Petersee1a53c2003-02-02 02:57:53 +0000662 while n:
663 for expected in (-n, n):
664 s = self.dumps(expected, proto)
665 n2 = self.loads(s)
666 self.assertEqual(expected, n2)
667 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000668
Jeremy Hylton66426532001-10-15 21:38:56 +0000669 def test_maxint64(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000670 maxint64 = (1 << 63) - 1
Guido van Rossum39478e82007-08-27 17:23:59 +0000671 data = b'I' + str(maxint64).encode("ascii") + b'\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000672 got = self.loads(data)
673 self.assertEqual(got, maxint64)
674
675 # Try too with a bogus literal.
Guido van Rossum39478e82007-08-27 17:23:59 +0000676 data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
Jeremy Hylton66426532001-10-15 21:38:56 +0000677 self.assertRaises(ValueError, self.loads, data)
678
Tim Petersee1a53c2003-02-02 02:57:53 +0000679 def test_long(self):
680 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000681 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000682 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000683 nbase = 1 << nbits
Tim Petersee1a53c2003-02-02 02:57:53 +0000684 for npos in nbase-1, nbase, nbase+1:
685 for n in npos, -npos:
686 pickle = self.dumps(n, proto)
687 got = self.loads(pickle)
688 self.assertEqual(n, got)
689 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
690 # bother with those.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000691 nbase = int("deadbeeffeedface", 16)
Tim Petersee1a53c2003-02-02 02:57:53 +0000692 nbase += nbase << 1000000
693 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000694 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000695 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000696 self.assertEqual(n, got)
697
Mark Dickinsoncddcf442009-01-24 21:46:33 +0000698 def test_float(self):
699 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
700 3.14, 263.44582062374053, 6.022e23, 1e30]
701 test_values = test_values + [-x for x in test_values]
702 for proto in protocols:
703 for value in test_values:
704 pickle = self.dumps(value, proto)
705 got = self.loads(pickle)
706 self.assertEqual(value, got)
707
Thomas Wouters477c8d52006-05-27 19:21:47 +0000708 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
709 def test_float_format(self):
Guido van Rossumf4169812008-03-17 22:56:06 +0000710 # make sure that floats are formatted locale independent with proto 0
711 self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000712
Jeremy Hylton66426532001-10-15 21:38:56 +0000713 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000714 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000715
716 def test_getinitargs(self):
717 pass
718
Antoine Pitrou79035bd2012-06-26 23:04:48 +0200719 def test_pop_empty_stack(self):
720 # Test issue7455
721 s = b'0'
722 self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s)
723
Guido van Rossum04a86612001-12-19 16:58:54 +0000724 def test_metaclass(self):
725 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000726 for proto in protocols:
727 s = self.dumps(a, proto)
728 b = self.loads(s)
729 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000730
Antoine Pitrouffd41d92011-10-04 09:23:04 +0200731 def test_dynamic_class(self):
732 a = create_dynamic_class("my_dynamic_class", (object,))
733 copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
734 for proto in protocols:
735 s = self.dumps(a, proto)
736 b = self.loads(s)
737 self.assertEqual(a, b)
738
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000739 def test_structseq(self):
740 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000741 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000742
743 t = time.localtime()
744 for proto in protocols:
745 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000746 u = self.loads(s)
747 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000748 if hasattr(os, "stat"):
749 t = os.stat(os.curdir)
750 s = self.dumps(t, proto)
751 u = self.loads(s)
752 self.assertEqual(t, u)
753 if hasattr(os, "statvfs"):
754 t = os.statvfs(os.curdir)
755 s = self.dumps(t, proto)
756 u = self.loads(s)
757 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000758
Łukasz Langaf3078fb2012-03-12 19:46:12 +0100759 def test_ellipsis(self):
760 for proto in protocols:
761 s = self.dumps(..., proto)
762 u = self.loads(s)
763 self.assertEqual(..., u)
764
765 def test_notimplemented(self):
766 for proto in protocols:
767 s = self.dumps(NotImplemented, proto)
768 u = self.loads(s)
769 self.assertEqual(NotImplemented, u)
770
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000771 # Tests for protocol 2
772
Tim Peters4190fb82003-02-02 16:09:05 +0000773 def test_proto(self):
774 build_none = pickle.NONE + pickle.STOP
775 for proto in protocols:
776 expected = build_none
777 if proto >= 2:
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000778 expected = pickle.PROTO + bytes([proto]) + expected
Tim Peters4190fb82003-02-02 16:09:05 +0000779 p = self.dumps(None, proto)
780 self.assertEqual(p, expected)
781
782 oob = protocols[-1] + 1 # a future protocol
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000783 badpickle = pickle.PROTO + bytes([oob]) + build_none
Tim Peters4190fb82003-02-02 16:09:05 +0000784 try:
785 self.loads(badpickle)
Guido van Rossumb940e112007-01-10 16:19:56 +0000786 except ValueError as detail:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000787 self.assertTrue(str(detail).startswith(
Tim Peters4190fb82003-02-02 16:09:05 +0000788 "unsupported pickle protocol"))
789 else:
790 self.fail("expected bad protocol number to raise ValueError")
791
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000792 def test_long1(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000793 x = 12345678910111213141516178920
Tim Peters61bf2572003-02-03 21:31:22 +0000794 for proto in protocols:
795 s = self.dumps(x, proto)
796 y = self.loads(s)
797 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000798 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000799
800 def test_long4(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000801 x = 12345678910111213141516178920 << (256*8)
Tim Peters61bf2572003-02-03 21:31:22 +0000802 for proto in protocols:
803 s = self.dumps(x, proto)
804 y = self.loads(s)
805 self.assertEqual(x, y)
Tim Peters22e71712003-02-03 22:27:38 +0000806 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000807
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000808 def test_short_tuples(self):
Tim Peters1d63c9f2003-02-02 20:29:39 +0000809 # Map (proto, len(tuple)) to expected opcode.
810 expected_opcode = {(0, 0): pickle.TUPLE,
811 (0, 1): pickle.TUPLE,
812 (0, 2): pickle.TUPLE,
813 (0, 3): pickle.TUPLE,
814 (0, 4): pickle.TUPLE,
815
816 (1, 0): pickle.EMPTY_TUPLE,
817 (1, 1): pickle.TUPLE,
818 (1, 2): pickle.TUPLE,
819 (1, 3): pickle.TUPLE,
820 (1, 4): pickle.TUPLE,
821
822 (2, 0): pickle.EMPTY_TUPLE,
823 (2, 1): pickle.TUPLE1,
824 (2, 2): pickle.TUPLE2,
825 (2, 3): pickle.TUPLE3,
826 (2, 4): pickle.TUPLE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000827
828 (3, 0): pickle.EMPTY_TUPLE,
829 (3, 1): pickle.TUPLE1,
830 (3, 2): pickle.TUPLE2,
831 (3, 3): pickle.TUPLE3,
832 (3, 4): pickle.TUPLE,
Tim Peters1d63c9f2003-02-02 20:29:39 +0000833 }
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000834 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000835 b = (1,)
836 c = (1, 2)
837 d = (1, 2, 3)
838 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000839 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000840 for x in a, b, c, d, e:
841 s = self.dumps(x, proto)
842 y = self.loads(s)
843 self.assertEqual(x, y, (proto, x, s, y))
Tim Peters1d63c9f2003-02-02 20:29:39 +0000844 expected = expected_opcode[proto, len(x)]
Tim Peters22e71712003-02-03 22:27:38 +0000845 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters1d63c9f2003-02-02 20:29:39 +0000846
Guido van Rossum7d97d312003-01-28 04:25:27 +0000847 def test_singletons(self):
Tim Peters61bf2572003-02-03 21:31:22 +0000848 # Map (proto, singleton) to expected opcode.
849 expected_opcode = {(0, None): pickle.NONE,
850 (1, None): pickle.NONE,
851 (2, None): pickle.NONE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000852 (3, None): pickle.NONE,
Tim Peters61bf2572003-02-03 21:31:22 +0000853
854 (0, True): pickle.INT,
855 (1, True): pickle.INT,
856 (2, True): pickle.NEWTRUE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000857 (3, True): pickle.NEWTRUE,
Tim Peters61bf2572003-02-03 21:31:22 +0000858
859 (0, False): pickle.INT,
860 (1, False): pickle.INT,
861 (2, False): pickle.NEWFALSE,
Guido van Rossumf4169812008-03-17 22:56:06 +0000862 (3, False): pickle.NEWFALSE,
Tim Peters61bf2572003-02-03 21:31:22 +0000863 }
Tim Peters4190fb82003-02-02 16:09:05 +0000864 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000865 for x in None, False, True:
866 s = self.dumps(x, proto)
867 y = self.loads(s)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000868 self.assertTrue(x is y, (proto, x, s, y))
Tim Peters61bf2572003-02-03 21:31:22 +0000869 expected = expected_opcode[proto, x]
Tim Peters22e71712003-02-03 22:27:38 +0000870 self.assertEqual(opcode_in_pickle(expected, s), True)
Tim Peters3c67d792003-02-02 17:59:11 +0000871
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000872 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000873 x = MyTuple([1, 2, 3])
874 x.foo = 42
875 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000876 for proto in protocols:
877 s = self.dumps(x, proto)
878 y = self.loads(s)
879 self.assertEqual(tuple(x), tuple(y))
880 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000881
882 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000883 x = MyList([1, 2, 3])
884 x.foo = 42
885 x.bar = "hello"
Tim Peters894453a2003-02-03 22:32:18 +0000886 for proto in protocols:
887 s = self.dumps(x, proto)
888 y = self.loads(s)
889 self.assertEqual(list(x), list(y))
890 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000891
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000892 def test_newobj_generic(self):
Tim Peters5013bd92003-02-03 22:28:41 +0000893 for proto in protocols:
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000894 for C in myclasses:
895 B = C.__base__
896 x = C(C.sample)
897 x.foo = 42
898 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000899 y = self.loads(s)
900 detail = (proto, C, B, x, y, type(y))
901 self.assertEqual(B(x), B(y), detail)
902 self.assertEqual(x.__dict__, y.__dict__, detail)
903
Antoine Pitrou16c4ce12011-03-11 21:30:43 +0100904 def test_newobj_proxies(self):
905 # NEWOBJ should use the __class__ rather than the raw type
906 classes = myclasses[:]
907 # Cannot create weakproxies to these classes
908 for c in (MyInt, MyTuple):
909 classes.remove(c)
910 for proto in protocols:
911 for C in classes:
912 B = C.__base__
913 x = C(C.sample)
914 x.foo = 42
915 p = weakref.proxy(x)
916 s = self.dumps(p, proto)
917 y = self.loads(s)
918 self.assertEqual(type(y), type(x)) # rather than type(p)
919 detail = (proto, C, B, x, y, type(y))
920 self.assertEqual(B(x), B(y), detail)
921 self.assertEqual(x.__dict__, y.__dict__, detail)
922
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000923 # Register a type with copyreg, with extension code extcode. Pickle
Tim Peters22e71712003-02-03 22:27:38 +0000924 # an object of that type. Check that the resulting pickle uses opcode
925 # (EXT[124]) under proto 2, and not in proto 1.
Tim Peters3e667d52003-02-04 21:47:44 +0000926
Tim Peters22e71712003-02-03 22:27:38 +0000927 def produce_global_ext(self, extcode, opcode):
Tim Peters3e667d52003-02-04 21:47:44 +0000928 e = ExtensionSaver(extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000929 try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000930 copyreg.add_extension(__name__, "MyList", extcode)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000931 x = MyList([1, 2, 3])
932 x.foo = 42
933 x.bar = "hello"
934
Tim Peters22e71712003-02-03 22:27:38 +0000935 # Dump using protocol 1 for comparison.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000936 s1 = self.dumps(x, 1)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000937 self.assertIn(__name__.encode("utf-8"), s1)
938 self.assertIn(b"MyList", s1)
Tim Peters3e667d52003-02-04 21:47:44 +0000939 self.assertEqual(opcode_in_pickle(opcode, s1), False)
940
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000941 y = self.loads(s1)
942 self.assertEqual(list(x), list(y))
943 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000944
Tim Peters22e71712003-02-03 22:27:38 +0000945 # Dump using protocol 2 for test.
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000946 s2 = self.dumps(x, 2)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000947 self.assertNotIn(__name__.encode("utf-8"), s2)
948 self.assertNotIn(b"MyList", s2)
Guido van Rossumcfe5f202007-05-08 21:26:54 +0000949 self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))
Tim Peters3e667d52003-02-04 21:47:44 +0000950
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000951 y = self.loads(s2)
952 self.assertEqual(list(x), list(y))
953 self.assertEqual(x.__dict__, y.__dict__)
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000954
955 finally:
Tim Peters3e667d52003-02-04 21:47:44 +0000956 e.restore()
Tim Peters22e71712003-02-03 22:27:38 +0000957
958 def test_global_ext1(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000959 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code
960 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000961
962 def test_global_ext2(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000963 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code
964 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code
965 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000966
967 def test_global_ext4(self):
Tim Peters3e667d52003-02-04 21:47:44 +0000968 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code
969 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code
970 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness
971
Tim Peters8d2613a2003-02-11 16:40:16 +0000972 def test_list_chunking(self):
973 n = 10 # too small to chunk
Guido van Rossum805365e2007-05-07 22:24:25 +0000974 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000975 for proto in protocols:
976 s = self.dumps(x, proto)
977 y = self.loads(s)
978 self.assertEqual(x, y)
979 num_appends = count_opcode(pickle.APPENDS, s)
980 self.assertEqual(num_appends, proto > 0)
981
982 n = 2500 # expect at least two chunks when proto > 0
Guido van Rossum805365e2007-05-07 22:24:25 +0000983 x = list(range(n))
Tim Peters8d2613a2003-02-11 16:40:16 +0000984 for proto in protocols:
985 s = self.dumps(x, proto)
986 y = self.loads(s)
987 self.assertEqual(x, y)
988 num_appends = count_opcode(pickle.APPENDS, s)
989 if proto == 0:
990 self.assertEqual(num_appends, 0)
991 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000992 self.assertTrue(num_appends >= 2)
Tim Peters8d2613a2003-02-11 16:40:16 +0000993
994 def test_dict_chunking(self):
995 n = 10 # too small to chunk
996 x = dict.fromkeys(range(n))
997 for proto in protocols:
998 s = self.dumps(x, proto)
Ezio Melottie9615932010-01-24 19:26:24 +0000999 self.assertIsInstance(s, bytes_types)
Tim Peters8d2613a2003-02-11 16:40:16 +00001000 y = self.loads(s)
1001 self.assertEqual(x, y)
1002 num_setitems = count_opcode(pickle.SETITEMS, s)
1003 self.assertEqual(num_setitems, proto > 0)
1004
1005 n = 2500 # expect at least two chunks when proto > 0
1006 x = dict.fromkeys(range(n))
1007 for proto in protocols:
1008 s = self.dumps(x, proto)
1009 y = self.loads(s)
1010 self.assertEqual(x, y)
1011 num_setitems = count_opcode(pickle.SETITEMS, s)
1012 if proto == 0:
1013 self.assertEqual(num_setitems, 0)
1014 else:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001015 self.assertTrue(num_setitems >= 2)
Guido van Rossum0322d0f2003-01-29 06:12:46 +00001016
Tim Peterse9ef2032003-02-13 18:42:00 +00001017 def test_simple_newobj(self):
1018 x = object.__new__(SimpleNewObj) # avoid __init__
1019 x.abc = 666
1020 for proto in protocols:
1021 s = self.dumps(x, proto)
1022 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)
1023 y = self.loads(s) # will raise TypeError if __init__ called
1024 self.assertEqual(y.abc, 666)
1025 self.assertEqual(x.__dict__, y.__dict__)
1026
Tim Peters42f08ac2003-02-11 22:43:24 +00001027 def test_newobj_list_slots(self):
1028 x = SlotList([1, 2, 3])
1029 x.foo = 42
1030 x.bar = "hello"
1031 s = self.dumps(x, 2)
1032 y = self.loads(s)
1033 self.assertEqual(list(x), list(y))
1034 self.assertEqual(x.__dict__, y.__dict__)
1035 self.assertEqual(x.foo, y.foo)
1036 self.assertEqual(x.bar, y.bar)
1037
Guido van Rossum2a30b212003-02-18 22:41:24 +00001038 def test_reduce_overrides_default_reduce_ex(self):
Collin Winter771d8342009-04-16 03:18:06 +00001039 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001040 x = REX_one()
1041 self.assertEqual(x._reduce_called, 0)
1042 s = self.dumps(x, proto)
1043 self.assertEqual(x._reduce_called, 1)
1044 y = self.loads(s)
1045 self.assertEqual(y._reduce_called, 0)
1046
1047 def test_reduce_ex_called(self):
Collin Winter771d8342009-04-16 03:18:06 +00001048 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001049 x = REX_two()
1050 self.assertEqual(x._proto, None)
1051 s = self.dumps(x, proto)
1052 self.assertEqual(x._proto, proto)
1053 y = self.loads(s)
1054 self.assertEqual(y._proto, None)
1055
1056 def test_reduce_ex_overrides_reduce(self):
Collin Winter771d8342009-04-16 03:18:06 +00001057 for proto in protocols:
Guido van Rossum2a30b212003-02-18 22:41:24 +00001058 x = REX_three()
1059 self.assertEqual(x._proto, None)
1060 s = self.dumps(x, proto)
1061 self.assertEqual(x._proto, proto)
1062 y = self.loads(s)
1063 self.assertEqual(y._proto, None)
1064
Guido van Rossumd8faa362007-04-27 19:54:29 +00001065 def test_reduce_ex_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001066 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001067 x = REX_four()
1068 self.assertEqual(x._proto, None)
1069 s = self.dumps(x, proto)
1070 self.assertEqual(x._proto, proto)
1071 y = self.loads(s)
1072 self.assertEqual(y._proto, proto)
1073
1074 def test_reduce_calls_base(self):
Collin Winter771d8342009-04-16 03:18:06 +00001075 for proto in protocols:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001076 x = REX_five()
1077 self.assertEqual(x._reduce_called, 0)
1078 s = self.dumps(x, proto)
1079 self.assertEqual(x._reduce_called, 1)
1080 y = self.loads(s)
1081 self.assertEqual(y._reduce_called, 1)
1082
Brett Cannon31f59292011-02-21 19:29:56 +00001083 @no_tracing
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001084 def test_bad_getattr(self):
1085 x = BadGetattr()
1086 for proto in 0, 1:
1087 self.assertRaises(RuntimeError, self.dumps, x, proto)
1088 # protocol 2 don't raise a RuntimeError.
1089 d = self.dumps(x, 2)
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001090
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001091 def test_reduce_bad_iterator(self):
1092 # Issue4176: crash when 4th and 5th items of __reduce__()
1093 # are not iterators
1094 class C(object):
1095 def __reduce__(self):
1096 # 4th item is not an iterator
1097 return list, (), None, [], None
1098 class D(object):
1099 def __reduce__(self):
1100 # 5th item is not an iterator
1101 return dict, (), None, None, []
1102
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001103 # Protocol 0 is less strict and also accept iterables.
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001104 for proto in protocols:
Amaury Forgeot d'Arc6285ffd2008-10-31 17:52:47 +00001105 try:
1106 self.dumps(C(), proto)
1107 except (pickle.PickleError):
1108 pass
1109 try:
1110 self.dumps(D(), proto)
1111 except (pickle.PickleError):
1112 pass
Amaury Forgeot d'Arc424b4812008-10-30 22:25:31 +00001113
Collin Winter771d8342009-04-16 03:18:06 +00001114 def test_many_puts_and_gets(self):
1115 # Test that internal data structures correctly deal with lots of
1116 # puts/gets.
1117 keys = ("aaa" + str(i) for i in range(100))
1118 large_dict = dict((k, [4, 5, 6]) for k in keys)
1119 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]
1120
1121 for proto in protocols:
1122 dumped = self.dumps(obj, proto)
1123 loaded = self.loads(dumped)
1124 self.assertEqual(loaded, obj,
1125 "Failed protocol %d: %r != %r"
1126 % (proto, obj, loaded))
1127
Antoine Pitroua9f48a02009-05-02 21:41:14 +00001128 def test_attribute_name_interning(self):
1129 # Test that attribute names of pickled objects are interned when
1130 # unpickling.
1131 for proto in protocols:
1132 x = C()
1133 x.foo = 42
1134 x.bar = "hello"
1135 s = self.dumps(x, proto)
1136 y = self.loads(s)
1137 x_keys = sorted(x.__dict__)
1138 y_keys = sorted(y.__dict__)
1139 for x_key, y_key in zip(x_keys, y_keys):
1140 self.assertIs(x_key, y_key)
1141
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001142 def test_unpickle_from_2x(self):
1143 # Unpickle non-trivial data from Python 2.x.
1144 loaded = self.loads(DATA3)
1145 self.assertEqual(loaded, set([1, 2]))
1146 loaded = self.loads(DATA4)
1147 self.assertEqual(type(loaded), type(range(0)))
1148 self.assertEqual(list(loaded), list(range(5)))
1149 loaded = self.loads(DATA5)
1150 self.assertEqual(type(loaded), SimpleCookie)
1151 self.assertEqual(list(loaded.keys()), ["key"])
1152 self.assertEqual(loaded["key"].value, "Set-Cookie: key=value")
1153
1154 def test_pickle_to_2x(self):
1155 # Pickle non-trivial data with protocol 2, expecting that it yields
1156 # the same result as Python 2.x did.
1157 # NOTE: this test is a bit too strong since we can produce different
1158 # bytecode that 2.x will still understand.
1159 dumped = self.dumps(range(5), 2)
1160 self.assertEqual(dumped, DATA4)
1161 dumped = self.dumps(set([3]), 2)
1162 self.assertEqual(dumped, DATA6)
1163
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001164 def test_large_pickles(self):
1165 # Test the correctness of internal buffering routines when handling
1166 # large data.
1167 for proto in protocols:
Antoine Pitrou04248a82010-10-12 20:51:21 +00001168 data = (1, min, b'xy' * (30 * 1024), len)
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001169 dumped = self.dumps(data, proto)
1170 loaded = self.loads(dumped)
Antoine Pitrou04248a82010-10-12 20:51:21 +00001171 self.assertEqual(len(loaded), len(data))
Antoine Pitrouea99c5c2010-09-09 18:33:21 +00001172 self.assertEqual(loaded, data)
1173
Alexander Belopolsky1ce92dc2011-02-24 19:40:09 +00001174 def test_empty_bytestring(self):
1175 # issue 11286
1176 empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
1177 self.assertEqual(empty, '')
Antoine Pitroud9dfaa92009-06-04 20:32:06 +00001178
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001179 def test_int_pickling_efficiency(self):
1180 # Test compacity of int representation (see issue #12744)
1181 for proto in protocols:
1182 sizes = [len(self.dumps(2**n, proto)) for n in range(70)]
Antoine Pitrou85674932011-08-14 01:51:52 +02001183 # the size function is monotonic
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001184 self.assertEqual(sorted(sizes), sizes)
1185 if proto >= 2:
1186 self.assertLessEqual(sizes[-1], 14)
1187
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001188 def check_negative_32b_binXXX(self, dumped):
1189 if sys.maxsize > 2**32:
1190 self.skipTest("test is only meaningful on 32-bit builds")
1191 # XXX Pure Python pickle reads lengths as signed and passes
1192 # them directly to read() (hence the EOFError)
1193 with self.assertRaises((pickle.UnpicklingError, EOFError,
1194 ValueError, OverflowError)):
1195 self.loads(dumped)
1196
1197 def test_negative_32b_binbytes(self):
1198 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
1199 self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.')
1200
1201 def test_negative_32b_binunicode(self):
1202 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
1203 self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.')
1204
Antoine Pitrou55549ec2011-08-30 00:27:10 +02001205 def test_negative_put(self):
1206 # Issue #12847
1207 dumped = b'Va\np-1\n.'
1208 self.assertRaises(ValueError, self.loads, dumped)
1209
1210 def test_negative_32b_binput(self):
1211 # Issue #12847
1212 if sys.maxsize > 2**32:
1213 self.skipTest("test is only meaningful on 32-bit builds")
1214 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
1215 self.assertRaises(ValueError, self.loads, dumped)
1216
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001217 def _check_pickling_with_opcode(self, obj, opcode, proto):
1218 pickled = self.dumps(obj, proto)
1219 self.assertTrue(opcode_in_pickle(opcode, pickled))
1220 unpickled = self.loads(pickled)
1221 self.assertEqual(obj, unpickled)
1222
1223 def test_appends_on_non_lists(self):
1224 # Issue #17720
1225 obj = REX_six([1, 2, 3])
1226 for proto in protocols:
1227 if proto == 0:
1228 self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
1229 else:
1230 self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)
1231
1232 def test_setitems_on_non_dicts(self):
1233 obj = REX_seven({1: -1, 2: -2, 3: -3})
1234 for proto in protocols:
1235 if proto == 0:
1236 self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
1237 else:
1238 self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)
1239
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001240
1241class BigmemPickleTests(unittest.TestCase):
1242
1243 # Binary protocols can serialize longs of up to 2GB-1
1244
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001245 @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001246 def test_huge_long_32b(self, size):
1247 data = 1 << (8 * size)
1248 try:
1249 for proto in protocols:
1250 if proto < 2:
1251 continue
1252 with self.assertRaises((ValueError, OverflowError)):
1253 self.dumps(data, protocol=proto)
1254 finally:
1255 data = None
1256
1257 # Protocol 3 can serialize up to 4GB-1 as a bytes object
1258 # (older protocols don't have a dedicated opcode for bytes and are
1259 # too inefficient)
1260
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001261 @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001262 def test_huge_bytes_32b(self, size):
1263 data = b"abcd" * (size // 4)
1264 try:
1265 for proto in protocols:
1266 if proto < 3:
1267 continue
1268 try:
1269 pickled = self.dumps(data, protocol=proto)
1270 self.assertTrue(b"abcd" in pickled[:15])
1271 self.assertTrue(b"abcd" in pickled[-15:])
1272 finally:
1273 pickled = None
1274 finally:
1275 data = None
1276
Antoine Pitrou94190bb2011-10-04 10:22:36 +02001277 @bigmemtest(size=_4G, memuse=1 + 1, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001278 def test_huge_bytes_64b(self, size):
1279 data = b"a" * size
1280 try:
1281 for proto in protocols:
1282 if proto < 3:
1283 continue
1284 with self.assertRaises((ValueError, OverflowError)):
1285 self.dumps(data, protocol=proto)
1286 finally:
1287 data = None
1288
1289 # All protocols use 1-byte per printable ASCII character; we add another
1290 # byte because the encoded form has to be copied into the internal buffer.
1291
Antoine Pitroub7591d42011-10-04 16:18:15 +02001292 @bigmemtest(size=_2G, memuse=2 + ascii_char_size, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001293 def test_huge_str_32b(self, size):
1294 data = "abcd" * (size // 4)
1295 try:
1296 for proto in protocols:
1297 try:
1298 pickled = self.dumps(data, protocol=proto)
1299 self.assertTrue(b"abcd" in pickled[:15])
1300 self.assertTrue(b"abcd" in pickled[-15:])
1301 finally:
1302 pickled = None
1303 finally:
1304 data = None
1305
Antoine Pitroue897e952011-08-30 23:39:34 +02001306 # BINUNICODE (protocols 1, 2 and 3) cannot carry more than
1307 # 2**32 - 1 bytes of utf-8 encoded unicode.
1308
Antoine Pitroub7591d42011-10-04 16:18:15 +02001309 @bigmemtest(size=_4G, memuse=1 + ascii_char_size, dry_run=False)
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001310 def test_huge_str_64b(self, size):
1311 data = "a" * size
1312 try:
1313 for proto in protocols:
Antoine Pitroue897e952011-08-30 23:39:34 +02001314 if proto == 0:
1315 continue
Antoine Pitrou82be19f2011-08-29 23:09:33 +02001316 with self.assertRaises((ValueError, OverflowError)):
1317 self.dumps(data, protocol=proto)
1318 finally:
1319 data = None
1320
Antoine Pitrou3c7e9282011-08-13 20:15:19 +02001321
Guido van Rossum2a30b212003-02-18 22:41:24 +00001322# Test classes for reduce_ex
1323
1324class REX_one(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001325 """No __reduce_ex__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001326 _reduce_called = 0
1327 def __reduce__(self):
1328 self._reduce_called = 1
1329 return REX_one, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001330
1331class REX_two(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001332 """No __reduce__ here, but inheriting it from object"""
Guido van Rossum2a30b212003-02-18 22:41:24 +00001333 _proto = None
1334 def __reduce_ex__(self, proto):
1335 self._proto = proto
1336 return REX_two, ()
Guido van Rossum2a30b212003-02-18 22:41:24 +00001337
1338class REX_three(object):
1339 _proto = None
1340 def __reduce_ex__(self, proto):
1341 self._proto = proto
1342 return REX_two, ()
1343 def __reduce__(self):
Collin Winter3add4d72007-08-29 23:37:32 +00001344 raise TestFailed("This __reduce__ shouldn't be called")
Guido van Rossum2a30b212003-02-18 22:41:24 +00001345
Guido van Rossumd8faa362007-04-27 19:54:29 +00001346class REX_four(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001347 """Calling base class method should succeed"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001348 _proto = None
1349 def __reduce_ex__(self, proto):
1350 self._proto = proto
1351 return object.__reduce_ex__(self, proto)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001352
1353class REX_five(object):
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001354 """This one used to fail with infinite recursion"""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001355 _reduce_called = 0
1356 def __reduce__(self):
1357 self._reduce_called = 1
1358 return object.__reduce__(self)
Alexandre Vassalotti1f7492c2013-04-20 13:19:46 -07001359
1360class REX_six(object):
1361 """This class is used to check the 4th argument (list iterator) of the reduce
1362 protocol.
1363 """
1364 def __init__(self, items=None):
1365 self.items = items if items is not None else []
1366 def __eq__(self, other):
1367 return type(self) is type(other) and self.items == self.items
1368 def append(self, item):
1369 self.items.append(item)
1370 def __reduce__(self):
1371 return type(self), (), None, iter(self.items), None
1372
1373class REX_seven(object):
1374 """This class is used to check the 5th argument (dict iterator) of the reduce
1375 protocol.
1376 """
1377 def __init__(self, table=None):
1378 self.table = table if table is not None else {}
1379 def __eq__(self, other):
1380 return type(self) is type(other) and self.table == self.table
1381 def __setitem__(self, key, value):
1382 self.table[key] = value
1383 def __reduce__(self):
1384 return type(self), (), None, None, iter(self.table.items())
1385
Guido van Rossumd8faa362007-04-27 19:54:29 +00001386
Guido van Rossum2a30b212003-02-18 22:41:24 +00001387# Test classes for newobj
Tim Peters080c88b2003-02-15 03:01:11 +00001388
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001389class MyInt(int):
1390 sample = 1
1391
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001392class MyFloat(float):
1393 sample = 1.0
1394
1395class MyComplex(complex):
1396 sample = 1.0 + 0.0j
1397
1398class MyStr(str):
1399 sample = "hello"
1400
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001401class MyUnicode(str):
1402 sample = "hello \u1234"
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001403
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001404class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001405 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001406
1407class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001408 sample = [1, 2, 3]
1409
1410class MyDict(dict):
1411 sample = {"a": 1, "b": 2}
1412
Mark Dickinson5c2db372009-12-05 20:28:34 +00001413myclasses = [MyInt, MyFloat,
Guido van Rossum206b9a72003-03-02 13:53:18 +00001414 MyComplex,
Guido van Rossum5d9113d2003-01-29 17:58:45 +00001415 MyStr, MyUnicode,
1416 MyTuple, MyList, MyDict]
1417
Guido van Rossum533dbcf2003-01-28 17:55:05 +00001418
Guido van Rossumc8d6ef52003-01-28 22:02:31 +00001419class SlotList(MyList):
1420 __slots__ = ["foo"]
1421
Tim Peterse9ef2032003-02-13 18:42:00 +00001422class SimpleNewObj(object):
1423 def __init__(self, a, b, c):
1424 # raise an error, to make sure this isn't called
1425 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
1426
Alexandre Vassalotti1f9d9072008-08-15 03:07:47 +00001427class BadGetattr:
1428 def __getattr__(self, key):
1429 self.foo
1430
Collin Winter771d8342009-04-16 03:18:06 +00001431
Jeremy Hylton66426532001-10-15 21:38:56 +00001432class AbstractPickleModuleTests(unittest.TestCase):
1433
1434 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001435 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001436 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001437 try:
1438 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001439 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001440 finally:
1441 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +00001442
1443 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001444 import os
Walter Dörwald11b41f62007-06-20 12:46:31 +00001445 f = open(TESTFN, "wb")
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001446 try:
1447 f.close()
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001448 self.assertRaises(ValueError, pickle.dump, 123, f)
Guido van Rossum3b0a3292002-08-09 16:38:32 +00001449 finally:
1450 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001451
Collin Winter771d8342009-04-16 03:18:06 +00001452 def test_load_from_and_dump_to_file(self):
1453 stream = io.BytesIO()
1454 data = [123, {}, 124]
1455 pickle.dump(data, stream)
1456 stream.seek(0)
1457 unpickled = pickle.load(stream)
1458 self.assertEqual(unpickled, data)
1459
Tim Petersc0c93702003-02-13 19:30:57 +00001460 def test_highest_protocol(self):
1461 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001462 self.assertEqual(pickle.HIGHEST_PROTOCOL, 3)
Tim Petersc0c93702003-02-13 19:30:57 +00001463
Martin v. Löwis544f1192004-07-27 05:22:33 +00001464 def test_callapi(self):
Collin Winter771d8342009-04-16 03:18:06 +00001465 f = io.BytesIO()
Martin v. Löwis544f1192004-07-27 05:22:33 +00001466 # With and without keyword arguments
Alexandre Vassalottica2d6102008-06-12 18:26:05 +00001467 pickle.dump(123, f, -1)
1468 pickle.dump(123, file=f, protocol=-1)
1469 pickle.dumps(123, -1)
1470 pickle.dumps(123, protocol=-1)
1471 pickle.Pickler(f, -1)
1472 pickle.Pickler(f, protocol=-1)
Tim Petersc0c93702003-02-13 19:30:57 +00001473
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001474 def test_bad_init(self):
1475 # Test issue3664 (pickle can segfault from a badly initialized Pickler).
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001476 # Override initialization without calling __init__() of the superclass.
1477 class BadPickler(pickle.Pickler):
1478 def __init__(self): pass
1479
1480 class BadUnpickler(pickle.Unpickler):
1481 def __init__(self): pass
1482
1483 self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
1484 self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)
1485
Amaury Forgeot d'Arc3e4e72f2008-11-11 20:05:06 +00001486 def test_bad_input(self):
1487 # Test issue4298
1488 s = bytes([0x58, 0, 0, 0, 0x54])
1489 self.assertRaises(EOFError, pickle.loads, s)
1490
Amaury Forgeot d'Arc87eee632008-10-17 20:15:53 +00001491
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001492class AbstractPersistentPicklerTests(unittest.TestCase):
1493
1494 # This class defines persistent_id() and persistent_load()
1495 # functions that should be used by the pickler. All even integers
1496 # are pickled using persistent ids.
1497
1498 def persistent_id(self, object):
1499 if isinstance(object, int) and object % 2 == 0:
1500 self.id_count += 1
1501 return str(object)
1502 else:
1503 return None
1504
1505 def persistent_load(self, oid):
1506 self.load_count += 1
1507 object = int(oid)
1508 assert object % 2 == 0
1509 return object
1510
1511 def test_persistence(self):
1512 self.id_count = 0
1513 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001514 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001515 self.assertEqual(self.loads(self.dumps(L)), L)
1516 self.assertEqual(self.id_count, 5)
1517 self.assertEqual(self.load_count, 5)
1518
1519 def test_bin_persistence(self):
1520 self.id_count = 0
1521 self.load_count = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001522 L = list(range(10))
Jeremy Hylton4c8be852002-11-13 22:10:47 +00001523 self.assertEqual(self.loads(self.dumps(L, 1)), L)
1524 self.assertEqual(self.id_count, 5)
1525 self.assertEqual(self.load_count, 5)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001526
Collin Winter771d8342009-04-16 03:18:06 +00001527
1528class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
1529
1530 pickler_class = None
1531 unpickler_class = None
1532
1533 def setUp(self):
1534 assert self.pickler_class
1535 assert self.unpickler_class
1536
1537 def test_clear_pickler_memo(self):
1538 # To test whether clear_memo() has any effect, we pickle an object,
1539 # then pickle it again without clearing the memo; the two serialized
1540 # forms should be different. If we clear_memo() and then pickle the
1541 # object again, the third serialized form should be identical to the
1542 # first one we obtained.
1543 data = ["abcdefg", "abcdefg", 44]
1544 f = io.BytesIO()
1545 pickler = self.pickler_class(f)
1546
1547 pickler.dump(data)
1548 first_pickled = f.getvalue()
1549
Serhiy Storchaka50254c52013-08-29 11:35:43 +03001550 # Reset BytesIO object.
Collin Winter771d8342009-04-16 03:18:06 +00001551 f.seek(0)
1552 f.truncate()
1553
1554 pickler.dump(data)
1555 second_pickled = f.getvalue()
1556
Serhiy Storchaka50254c52013-08-29 11:35:43 +03001557 # Reset the Pickler and BytesIO objects.
Collin Winter771d8342009-04-16 03:18:06 +00001558 pickler.clear_memo()
1559 f.seek(0)
1560 f.truncate()
1561
1562 pickler.dump(data)
1563 third_pickled = f.getvalue()
1564
1565 self.assertNotEqual(first_pickled, second_pickled)
1566 self.assertEqual(first_pickled, third_pickled)
1567
1568 def test_priming_pickler_memo(self):
1569 # Verify that we can set the Pickler's memo attribute.
1570 data = ["abcdefg", "abcdefg", 44]
1571 f = io.BytesIO()
1572 pickler = self.pickler_class(f)
1573
1574 pickler.dump(data)
1575 first_pickled = f.getvalue()
1576
1577 f = io.BytesIO()
1578 primed = self.pickler_class(f)
1579 primed.memo = pickler.memo
1580
1581 primed.dump(data)
1582 primed_pickled = f.getvalue()
1583
1584 self.assertNotEqual(first_pickled, primed_pickled)
1585
1586 def test_priming_unpickler_memo(self):
1587 # Verify that we can set the Unpickler's memo attribute.
1588 data = ["abcdefg", "abcdefg", 44]
1589 f = io.BytesIO()
1590 pickler = self.pickler_class(f)
1591
1592 pickler.dump(data)
1593 first_pickled = f.getvalue()
1594
1595 f = io.BytesIO()
1596 primed = self.pickler_class(f)
1597 primed.memo = pickler.memo
1598
1599 primed.dump(data)
1600 primed_pickled = f.getvalue()
1601
1602 unpickler = self.unpickler_class(io.BytesIO(first_pickled))
1603 unpickled_data1 = unpickler.load()
1604
1605 self.assertEqual(unpickled_data1, data)
1606
1607 primed = self.unpickler_class(io.BytesIO(primed_pickled))
1608 primed.memo = unpickler.memo
1609 unpickled_data2 = primed.load()
1610
1611 primed.memo.clear()
1612
1613 self.assertEqual(unpickled_data2, data)
1614 self.assertTrue(unpickled_data2 is unpickled_data1)
1615
1616 def test_reusing_unpickler_objects(self):
1617 data1 = ["abcdefg", "abcdefg", 44]
1618 f = io.BytesIO()
1619 pickler = self.pickler_class(f)
1620 pickler.dump(data1)
1621 pickled1 = f.getvalue()
1622
1623 data2 = ["abcdefg", 44, 44]
1624 f = io.BytesIO()
1625 pickler = self.pickler_class(f)
1626 pickler.dump(data2)
1627 pickled2 = f.getvalue()
1628
1629 f = io.BytesIO()
1630 f.write(pickled1)
1631 f.seek(0)
1632 unpickler = self.unpickler_class(f)
1633 self.assertEqual(unpickler.load(), data1)
1634
1635 f.seek(0)
1636 f.truncate()
1637 f.write(pickled2)
1638 f.seek(0)
1639 self.assertEqual(unpickler.load(), data2)
1640
Antoine Pitrou04248a82010-10-12 20:51:21 +00001641 def _check_multiple_unpicklings(self, ioclass):
1642 for proto in protocols:
1643 data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
1644 f = ioclass()
1645 pickler = self.pickler_class(f, protocol=proto)
1646 pickler.dump(data1)
1647 pickled = f.getvalue()
1648
1649 N = 5
1650 f = ioclass(pickled * N)
1651 unpickler = self.unpickler_class(f)
1652 for i in range(N):
1653 if f.seekable():
1654 pos = f.tell()
1655 self.assertEqual(unpickler.load(), data1)
1656 if f.seekable():
1657 self.assertEqual(f.tell(), pos + len(pickled))
1658 self.assertRaises(EOFError, unpickler.load)
1659
1660 def test_multiple_unpicklings_seekable(self):
1661 self._check_multiple_unpicklings(io.BytesIO)
1662
1663 def test_multiple_unpicklings_unseekable(self):
1664 self._check_multiple_unpicklings(UnseekableIO)
1665
Antoine Pitrouf6c7a852011-08-11 21:04:02 +02001666 def test_unpickling_buffering_readline(self):
1667 # Issue #12687: the unpickler's buffering logic could fail with
1668 # text mode opcodes.
1669 data = list(range(10))
1670 for proto in protocols:
1671 for buf_size in range(1, 11):
1672 f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
1673 pickler = self.pickler_class(f, protocol=proto)
1674 pickler.dump(data)
1675 f.seek(0)
1676 unpickler = self.unpickler_class(f)
1677 self.assertEqual(unpickler.load(), data)
1678
Collin Winter771d8342009-04-16 03:18:06 +00001679
Antoine Pitrou8d3c2902012-03-04 18:31:48 +01001680# Tests for dispatch_table attribute
1681
1682REDUCE_A = 'reduce_A'
1683
1684class AAA(object):
1685 def __reduce__(self):
1686 return str, (REDUCE_A,)
1687
1688class BBB(object):
1689 pass
1690
1691class AbstractDispatchTableTests(unittest.TestCase):
1692
1693 def test_default_dispatch_table(self):
1694 # No dispatch_table attribute by default
1695 f = io.BytesIO()
1696 p = self.pickler_class(f, 0)
1697 with self.assertRaises(AttributeError):
1698 p.dispatch_table
1699 self.assertFalse(hasattr(p, 'dispatch_table'))
1700
1701 def test_class_dispatch_table(self):
1702 # A dispatch_table attribute can be specified class-wide
1703 dt = self.get_dispatch_table()
1704
1705 class MyPickler(self.pickler_class):
1706 dispatch_table = dt
1707
1708 def dumps(obj, protocol=None):
1709 f = io.BytesIO()
1710 p = MyPickler(f, protocol)
1711 self.assertEqual(p.dispatch_table, dt)
1712 p.dump(obj)
1713 return f.getvalue()
1714
1715 self._test_dispatch_table(dumps, dt)
1716
1717 def test_instance_dispatch_table(self):
1718 # A dispatch_table attribute can also be specified instance-wide
1719 dt = self.get_dispatch_table()
1720
1721 def dumps(obj, protocol=None):
1722 f = io.BytesIO()
1723 p = self.pickler_class(f, protocol)
1724 p.dispatch_table = dt
1725 self.assertEqual(p.dispatch_table, dt)
1726 p.dump(obj)
1727 return f.getvalue()
1728
1729 self._test_dispatch_table(dumps, dt)
1730
1731 def _test_dispatch_table(self, dumps, dispatch_table):
1732 def custom_load_dump(obj):
1733 return pickle.loads(dumps(obj, 0))
1734
1735 def default_load_dump(obj):
1736 return pickle.loads(pickle.dumps(obj, 0))
1737
1738 # pickling complex numbers using protocol 0 relies on copyreg
1739 # so check pickling a complex number still works
1740 z = 1 + 2j
1741 self.assertEqual(custom_load_dump(z), z)
1742 self.assertEqual(default_load_dump(z), z)
1743
1744 # modify pickling of complex
1745 REDUCE_1 = 'reduce_1'
1746 def reduce_1(obj):
1747 return str, (REDUCE_1,)
1748 dispatch_table[complex] = reduce_1
1749 self.assertEqual(custom_load_dump(z), REDUCE_1)
1750 self.assertEqual(default_load_dump(z), z)
1751
1752 # check picklability of AAA and BBB
1753 a = AAA()
1754 b = BBB()
1755 self.assertEqual(custom_load_dump(a), REDUCE_A)
1756 self.assertIsInstance(custom_load_dump(b), BBB)
1757 self.assertEqual(default_load_dump(a), REDUCE_A)
1758 self.assertIsInstance(default_load_dump(b), BBB)
1759
1760 # modify pickling of BBB
1761 dispatch_table[BBB] = reduce_1
1762 self.assertEqual(custom_load_dump(a), REDUCE_A)
1763 self.assertEqual(custom_load_dump(b), REDUCE_1)
1764 self.assertEqual(default_load_dump(a), REDUCE_A)
1765 self.assertIsInstance(default_load_dump(b), BBB)
1766
1767 # revert pickling of BBB and modify pickling of AAA
1768 REDUCE_2 = 'reduce_2'
1769 def reduce_2(obj):
1770 return str, (REDUCE_2,)
1771 dispatch_table[AAA] = reduce_2
1772 del dispatch_table[BBB]
1773 self.assertEqual(custom_load_dump(a), REDUCE_2)
1774 self.assertIsInstance(custom_load_dump(b), BBB)
1775 self.assertEqual(default_load_dump(a), REDUCE_A)
1776 self.assertIsInstance(default_load_dump(b), BBB)
1777
1778
Guido van Rossum98297ee2007-11-06 21:34:58 +00001779if __name__ == "__main__":
1780 # Print some stuff that can be used to rewrite DATA{0,1,2}
1781 from pickletools import dis
1782 x = create_data()
1783 for i in range(3):
1784 p = pickle.dumps(x, i)
1785 print("DATA{0} = (".format(i))
1786 for j in range(0, len(p), 20):
1787 b = bytes(p[j:j+20])
1788 print(" {0!r}".format(b))
1789 print(")")
1790 print()
1791 print("# Disassembly of DATA{0}".format(i))
1792 print("DATA{0}_DIS = \"\"\"\\".format(i))
1793 dis(p)
1794 print("\"\"\"")
1795 print()