blob: 721429816f075ed61207fb875c47f7dc3ff7dce0 [file] [log] [blame]
Jeremy Hylton66426532001-10-15 21:38:56 +00001import unittest
Tim Peters4190fb82003-02-02 16:09:05 +00002import pickle
3
Guido van Rossum3b0a3292002-08-09 16:38:32 +00004from test.test_support import TestFailed, have_unicode, TESTFN
Tim Peterse089c682001-04-10 03:41:41 +00005
Tim Petersee1a53c2003-02-02 02:57:53 +00006# Tests that try a number of pickle protocols should have a
7# for proto in protocols:
8# kind of outer loop. Bump the 3 to 4 if/when protocol 3 is invented.
9protocols = range(3)
10
Jeremy Hylton66426532001-10-15 21:38:56 +000011class C:
12 def __cmp__(self, other):
13 return cmp(self.__dict__, other.__dict__)
14
15import __main__
16__main__.C = C
17C.__module__ = "__main__"
18
19class myint(int):
20 def __init__(self, x):
21 self.str = str(x)
22
23class initarg(C):
Guido van Rossum1444f672001-12-19 16:38:29 +000024
Jeremy Hylton66426532001-10-15 21:38:56 +000025 def __init__(self, a, b):
26 self.a = a
27 self.b = b
28
29 def __getinitargs__(self):
30 return self.a, self.b
31
Guido van Rossum04a86612001-12-19 16:58:54 +000032class metaclass(type):
33 pass
34
35class use_metaclass(object):
36 __metaclass__ = metaclass
37
Tim Peters70b02d72003-02-02 17:26:40 +000038# DATA0 .. DATA2 are the pickles we expect under the various protocols, for
39# the object returned by create_data().
40# XXX DATA2 doesn't exist yet, as it's not fully implemented in cPickle.
Tim Petersee1a53c2003-02-02 02:57:53 +000041
Jeremy Hylton66426532001-10-15 21:38:56 +000042# break into multiple strings to avoid confusing font-lock-mode
Tim Peters70b02d72003-02-02 17:26:40 +000043DATA0 = """(lp1
Tim Peterse9358162001-01-22 22:05:20 +000044I0
45aL1L
Tim Peters461922a2001-04-09 20:07:05 +000046aF2
Tim Peterse9358162001-01-22 22:05:20 +000047ac__builtin__
48complex
Tim Peters461922a2001-04-09 20:07:05 +000049p2
50""" + \
51"""(F3
52F0
53tRp3
54aI1
55aI-1
56aI255
57aI-255
58aI-256
59aI65535
60aI-65535
61aI-65536
62aI2147483647
63aI-2147483647
64aI-2147483648
65a""" + \
66"""(S'abc'
Tim Peterse9358162001-01-22 22:05:20 +000067p4
68g4
Tim Peters461922a2001-04-09 20:07:05 +000069""" + \
Guido van Rossum42f92da2001-04-16 00:28:21 +000070"""(i__main__
Tim Peterse9358162001-01-22 22:05:20 +000071C
72p5
Tim Peters461922a2001-04-09 20:07:05 +000073""" + \
Tim Peterse9358162001-01-22 22:05:20 +000074"""(dp6
75S'foo'
76p7
77I1
78sS'bar'
79p8
80I2
81sbg5
82tp9
83ag9
84aI5
85a.
86"""
87
Tim Peters70b02d72003-02-02 17:26:40 +000088# Disassembly of DATA0.
89DATA0_DIS = """\
90 0: ( MARK
91 1: l LIST (MARK at 0)
92 2: p PUT 1
93 5: I INT 0
94 8: a APPEND
95 9: L LONG 1L
96 13: a APPEND
97 14: F FLOAT 2.0
98 17: a APPEND
99 18: c GLOBAL '__builtin__ complex'
100 39: p PUT 2
101 42: ( MARK
102 43: F FLOAT 3.0
103 46: F FLOAT 0.0
104 49: t TUPLE (MARK at 42)
105 50: R REDUCE
106 51: p PUT 3
107 54: a APPEND
108 55: I INT 1
109 58: a APPEND
110 59: I INT -1
111 63: a APPEND
112 64: I INT 255
113 69: a APPEND
114 70: I INT -255
115 76: a APPEND
116 77: I INT -256
117 83: a APPEND
118 84: I INT 65535
119 91: a APPEND
120 92: I INT -65535
121 100: a APPEND
122 101: I INT -65536
123 109: a APPEND
124 110: I INT 2147483647
125 122: a APPEND
126 123: I INT -2147483647
127 136: a APPEND
128 137: I INT -2147483648
129 150: a APPEND
130 151: ( MARK
131 152: S STRING 'abc'
132 159: p PUT 4
133 162: g GET 4
134 165: ( MARK
135 166: i INST '__main__ C' (MARK at 165)
136 178: p PUT 5
137 181: ( MARK
138 182: d DICT (MARK at 181)
139 183: p PUT 6
140 186: S STRING 'foo'
141 193: p PUT 7
142 196: I INT 1
143 199: s SETITEM
144 200: S STRING 'bar'
145 207: p PUT 8
146 210: I INT 2
147 213: s SETITEM
148 214: b BUILD
149 215: g GET 5
150 218: t TUPLE (MARK at 151)
151 219: p PUT 9
152 222: a APPEND
153 223: g GET 9
154 226: a APPEND
155 227: I INT 5
156 230: a APPEND
157 231: . STOP
158highest protocol among opcodes = 0
159"""
160
161DATA1 = (']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00'
162 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00'
163 '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff'
164 '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff'
165 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00'
166 '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n'
167 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh'
168 '\x06tq\nh\nK\x05e.'
169 )
170
171# Disassembly of DATA1.
172DATA1_DIS = """\
173 0: ] EMPTY_LIST
174 1: q BINPUT 1
175 3: ( MARK
176 4: K BININT1 0
177 6: L LONG 1L
178 10: G BINFLOAT 2.0
179 19: c GLOBAL '__builtin__ complex'
180 40: q BINPUT 2
181 42: ( MARK
182 43: G BINFLOAT 3.0
183 52: G BINFLOAT 0.0
184 61: t TUPLE (MARK at 42)
185 62: R REDUCE
186 63: q BINPUT 3
187 65: K BININT1 1
188 67: J BININT -1
189 72: K BININT1 255
190 74: J BININT -255
191 79: J BININT -256
192 84: M BININT2 65535
193 87: J BININT -65535
194 92: J BININT -65536
195 97: J BININT 2147483647
196 102: J BININT -2147483647
197 107: J BININT -2147483648
198 112: ( MARK
199 113: U SHORT_BINSTRING 'abc'
200 118: q BINPUT 4
201 120: h BINGET 4
202 122: ( MARK
203 123: c GLOBAL '__main__ C'
204 135: q BINPUT 5
205 137: o OBJ (MARK at 122)
206 138: q BINPUT 6
207 140: } EMPTY_DICT
208 141: q BINPUT 7
209 143: ( MARK
210 144: U SHORT_BINSTRING 'foo'
211 149: q BINPUT 8
212 151: K BININT1 1
213 153: U SHORT_BINSTRING 'bar'
214 158: q BINPUT 9
215 160: K BININT1 2
216 162: u SETITEMS (MARK at 143)
217 163: b BUILD
218 164: h BINGET 6
219 166: t TUPLE (MARK at 112)
220 167: q BINPUT 10
221 169: h BINGET 10
222 171: K BININT1 5
223 173: e APPENDS (MARK at 3)
224 174: . STOP
225highest protocol among opcodes = 1
226"""
Tim Peterse0c446b2001-10-18 21:57:37 +0000227
Jeremy Hylton66426532001-10-15 21:38:56 +0000228def create_data():
Tim Peterse9358162001-01-22 22:05:20 +0000229 c = C()
230 c.foo = 1
231 c.bar = 2
232 x = [0, 1L, 2.0, 3.0+0j]
Tim Peters461922a2001-04-09 20:07:05 +0000233 # Append some integer test cases at cPickle.c's internal size
234 # cutoffs.
235 uint1max = 0xff
236 uint2max = 0xffff
237 int4max = 0x7fffffff
238 x.extend([1, -1,
239 uint1max, -uint1max, -uint1max-1,
240 uint2max, -uint2max, -uint2max-1,
241 int4max, -int4max, -int4max-1])
Tim Peterse9358162001-01-22 22:05:20 +0000242 y = ('abc', 'abc', c, c)
243 x.append(y)
244 x.append(y)
245 x.append(5)
Jeremy Hylton66426532001-10-15 21:38:56 +0000246 return x
Tim Petersc58440f2001-04-09 17:16:31 +0000247
Jeremy Hylton66426532001-10-15 21:38:56 +0000248class AbstractPickleTests(unittest.TestCase):
Tim Peters70b02d72003-02-02 17:26:40 +0000249 # Subclass must define self.dumps, self.loads, self.error.
Tim Petersc58440f2001-04-09 17:16:31 +0000250
Jeremy Hylton66426532001-10-15 21:38:56 +0000251 _testdata = create_data()
Tim Petersc58440f2001-04-09 17:16:31 +0000252
Jeremy Hylton66426532001-10-15 21:38:56 +0000253 def setUp(self):
Tim Peterse9358162001-01-22 22:05:20 +0000254 pass
Tim Petersc58440f2001-04-09 17:16:31 +0000255
Jeremy Hylton66426532001-10-15 21:38:56 +0000256 def test_misc(self):
257 # test various datatypes not tested by testdata
Tim Peters70b02d72003-02-02 17:26:40 +0000258 for proto in protocols:
259 x = myint(4)
260 s = self.dumps(x, proto)
261 y = self.loads(s)
262 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000263
Tim Peters70b02d72003-02-02 17:26:40 +0000264 x = (1, ())
265 s = self.dumps(x, proto)
266 y = self.loads(s)
267 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000268
Tim Peters70b02d72003-02-02 17:26:40 +0000269 x = initarg(1, x)
270 s = self.dumps(x, proto)
271 y = self.loads(s)
272 self.assertEqual(x, y)
Tim Peterse9358162001-01-22 22:05:20 +0000273
Jeremy Hylton66426532001-10-15 21:38:56 +0000274 # XXX test __reduce__ protocol?
275
Tim Peters70b02d72003-02-02 17:26:40 +0000276 def test_roundtrip_equality(self):
277 expected = self._testdata
278 for proto in protocols:
279 s = self.dumps(expected, proto)
280 got = self.loads(s)
281 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000282
Tim Peters70b02d72003-02-02 17:26:40 +0000283 def test_load_from_canned_string(self):
284 expected = self._testdata
285 for canned in DATA0, DATA1:
286 got = self.loads(canned)
287 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000288
Tim Peters70b02d72003-02-02 17:26:40 +0000289 # There are gratuitous differences between pickles produced by
290 # pickle and cPickle, largely because cPickle starts PUT indices at
291 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
292 # there's a comment with an exclamation point there whose meaning
293 # is a mystery. cPickle also suppresses PUT for objects with a refcount
294 # of 1.
295 def dont_test_disassembly(self):
296 from cStringIO import StringIO
297 from pickletools import dis
298
299 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
300 s = self.dumps(self._testdata, proto)
301 filelike = StringIO()
302 dis(s, out=filelike)
303 got = filelike.getvalue()
304 self.assertEqual(expected, got)
Jeremy Hylton66426532001-10-15 21:38:56 +0000305
306 def test_recursive_list(self):
307 l = []
308 l.append(l)
Tim Peters70b02d72003-02-02 17:26:40 +0000309 for proto in protocols:
310 s = self.dumps(l, proto)
311 x = self.loads(s)
312 self.assertEqual(x, l)
313 self.assertEqual(x, x[0])
314 self.assertEqual(id(x), id(x[0]))
Jeremy Hylton66426532001-10-15 21:38:56 +0000315
316 def test_recursive_dict(self):
317 d = {}
318 d[1] = d
Tim Peters70b02d72003-02-02 17:26:40 +0000319 for proto in protocols:
320 s = self.dumps(d, proto)
321 x = self.loads(s)
322 self.assertEqual(x, d)
323 self.assertEqual(x[1], x)
324 self.assertEqual(id(x[1]), id(x))
Jeremy Hylton66426532001-10-15 21:38:56 +0000325
326 def test_recursive_inst(self):
327 i = C()
328 i.attr = i
Tim Peters70b02d72003-02-02 17:26:40 +0000329 for proto in protocols:
330 s = self.dumps(i, 2)
331 x = self.loads(s)
332 self.assertEqual(x, i)
333 self.assertEqual(x.attr, x)
334 self.assertEqual(id(x.attr), id(x))
Jeremy Hylton66426532001-10-15 21:38:56 +0000335
336 def test_recursive_multi(self):
337 l = []
338 d = {1:l}
339 i = C()
340 i.attr = d
341 l.append(i)
Tim Peters70b02d72003-02-02 17:26:40 +0000342 for proto in protocols:
343 s = self.dumps(l, proto)
344 x = self.loads(s)
345 self.assertEqual(x, l)
346 self.assertEqual(x[0], i)
347 self.assertEqual(x[0].attr, d)
348 self.assertEqual(x[0].attr[1], x)
349 self.assertEqual(x[0].attr[1][0], i)
350 self.assertEqual(x[0].attr[1][0].attr, d)
Jeremy Hylton66426532001-10-15 21:38:56 +0000351
352 def test_garyp(self):
353 self.assertRaises(self.error, self.loads, 'garyp')
354
355 def test_insecure_strings(self):
356 insecure = ["abc", "2 + 2", # not quoted
Martin v. Löwis8a8da792002-08-14 07:46:28 +0000357 #"'abc' + 'def'", # not a single quoted string
Jeremy Hylton66426532001-10-15 21:38:56 +0000358 "'abc", # quote is not closed
359 "'abc\"", # open quote and close quote don't match
360 "'abc' ?", # junk after close quote
Martin v. Löwiseb3f00a2002-08-14 08:22:50 +0000361 "'\\'", # trailing backslash
Jeremy Hylton66426532001-10-15 21:38:56 +0000362 # some tests of the quoting rules
Martin v. Löwis8a8da792002-08-14 07:46:28 +0000363 #"'abc\"\''",
364 #"'\\\\a\'\'\'\\\'\\\\\''",
Jeremy Hylton66426532001-10-15 21:38:56 +0000365 ]
366 for s in insecure:
367 buf = "S" + s + "\012p0\012."
368 self.assertRaises(ValueError, self.loads, buf)
369
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000370 if have_unicode:
Jeremy Hylton66426532001-10-15 21:38:56 +0000371 def test_unicode(self):
372 endcases = [unicode(''), unicode('<\\u>'), unicode('<\\\u1234>'),
373 unicode('<\n>'), unicode('<\\>')]
Tim Petersee1a53c2003-02-02 02:57:53 +0000374 for proto in protocols:
375 for u in endcases:
376 p = self.dumps(u, proto)
377 u2 = self.loads(p)
378 self.assertEqual(u2, u)
Tim Peterse089c682001-04-10 03:41:41 +0000379
Jeremy Hylton66426532001-10-15 21:38:56 +0000380 def test_ints(self):
381 import sys
Tim Petersee1a53c2003-02-02 02:57:53 +0000382 for proto in protocols:
383 n = sys.maxint
384 while n:
385 for expected in (-n, n):
386 s = self.dumps(expected, proto)
387 n2 = self.loads(s)
388 self.assertEqual(expected, n2)
389 n = n >> 1
Tim Peters19ef62d2001-08-28 22:21:18 +0000390
Jeremy Hylton66426532001-10-15 21:38:56 +0000391 def test_maxint64(self):
392 maxint64 = (1L << 63) - 1
393 data = 'I' + str(maxint64) + '\n.'
394 got = self.loads(data)
395 self.assertEqual(got, maxint64)
396
397 # Try too with a bogus literal.
398 data = 'I' + str(maxint64) + 'JUNK\n.'
399 self.assertRaises(ValueError, self.loads, data)
400
Tim Petersee1a53c2003-02-02 02:57:53 +0000401 def test_long(self):
402 for proto in protocols:
Tim Petersbf2674b2003-02-02 07:51:32 +0000403 # 256 bytes is where LONG4 begins.
Tim Petersee1a53c2003-02-02 02:57:53 +0000404 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
405 nbase = 1L << nbits
406 for npos in nbase-1, nbase, nbase+1:
407 for n in npos, -npos:
408 pickle = self.dumps(n, proto)
409 got = self.loads(pickle)
410 self.assertEqual(n, got)
411 # Try a monster. This is quadratic-time in protos 0 & 1, so don't
412 # bother with those.
Tim Petersee1a53c2003-02-02 02:57:53 +0000413 nbase = long("deadbeeffeedface", 16)
414 nbase += nbase << 1000000
415 for n in nbase, -nbase:
Tim Petersee1a53c2003-02-02 02:57:53 +0000416 p = self.dumps(n, 2)
Tim Petersee1a53c2003-02-02 02:57:53 +0000417 got = self.loads(p)
Tim Petersee1a53c2003-02-02 02:57:53 +0000418 self.assertEqual(n, got)
419
Jeremy Hylton66426532001-10-15 21:38:56 +0000420 def test_reduce(self):
Tim Peters19ef62d2001-08-28 22:21:18 +0000421 pass
Jeremy Hylton66426532001-10-15 21:38:56 +0000422
423 def test_getinitargs(self):
424 pass
425
Guido van Rossum04a86612001-12-19 16:58:54 +0000426 def test_metaclass(self):
427 a = use_metaclass()
Tim Peters70b02d72003-02-02 17:26:40 +0000428 for proto in protocols:
429 s = self.dumps(a, proto)
430 b = self.loads(s)
431 self.assertEqual(a.__class__, b.__class__)
Guido van Rossum04a86612001-12-19 16:58:54 +0000432
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000433 def test_structseq(self):
434 import time
Michael W. Hudson0e025302002-03-06 17:11:18 +0000435 import os
Tim Peters70b02d72003-02-02 17:26:40 +0000436
437 t = time.localtime()
438 for proto in protocols:
439 s = self.dumps(t, proto)
Michael W. Hudson0e025302002-03-06 17:11:18 +0000440 u = self.loads(s)
441 self.assertEqual(t, u)
Tim Peters70b02d72003-02-02 17:26:40 +0000442 if hasattr(os, "stat"):
443 t = os.stat(os.curdir)
444 s = self.dumps(t, proto)
445 u = self.loads(s)
446 self.assertEqual(t, u)
447 if hasattr(os, "statvfs"):
448 t = os.statvfs(os.curdir)
449 s = self.dumps(t, proto)
450 u = self.loads(s)
451 self.assertEqual(t, u)
Michael W. Hudson7bb466a2002-03-05 13:27:58 +0000452
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000453 # Tests for protocol 2
454
Tim Peters4190fb82003-02-02 16:09:05 +0000455 def test_proto(self):
456 build_none = pickle.NONE + pickle.STOP
457 for proto in protocols:
458 expected = build_none
459 if proto >= 2:
460 expected = pickle.PROTO + chr(proto) + expected
461 p = self.dumps(None, proto)
462 self.assertEqual(p, expected)
463
464 oob = protocols[-1] + 1 # a future protocol
465 badpickle = pickle.PROTO + chr(oob) + build_none
466 try:
467 self.loads(badpickle)
468 except ValueError, detail:
469 self.failUnless(str(detail).startswith(
470 "unsupported pickle protocol"))
471 else:
472 self.fail("expected bad protocol number to raise ValueError")
473
Guido van Rossumd6c9e632003-01-28 03:49:52 +0000474 def test_long1(self):
475 x = 12345678910111213141516178920L
476 s = self.dumps(x, 2)
477 y = self.loads(s)
478 self.assertEqual(x, y)
479
480 def test_long4(self):
481 x = 12345678910111213141516178920L << (256*8)
482 s = self.dumps(x, 2)
483 y = self.loads(s)
484 self.assertEqual(x, y)
485
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000486 def test_short_tuples(self):
487 a = ()
Guido van Rossum025bc2f2003-01-28 04:20:02 +0000488 b = (1,)
489 c = (1, 2)
490 d = (1, 2, 3)
491 e = (1, 2, 3, 4)
Tim Peters4190fb82003-02-02 16:09:05 +0000492 for proto in protocols:
Guido van Rossum44f0ea52003-01-28 04:14:51 +0000493 for x in a, b, c, d, e:
494 s = self.dumps(x, proto)
495 y = self.loads(s)
496 self.assertEqual(x, y, (proto, x, s, y))
497
Guido van Rossum7d97d312003-01-28 04:25:27 +0000498 def test_singletons(self):
Tim Peters4190fb82003-02-02 16:09:05 +0000499 for proto in protocols:
Guido van Rossum7d97d312003-01-28 04:25:27 +0000500 for x in None, False, True:
501 s = self.dumps(x, proto)
502 y = self.loads(s)
503 self.assert_(x is y, (proto, x, s, y))
504
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000505 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000506 x = MyTuple([1, 2, 3])
507 x.foo = 42
508 x.bar = "hello"
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000509 s = self.dumps(x, 2)
510 y = self.loads(s)
511 self.assertEqual(tuple(x), tuple(y))
512 self.assertEqual(x.__dict__, y.__dict__)
513
514 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000515 x = MyList([1, 2, 3])
516 x.foo = 42
517 x.bar = "hello"
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000518 s = self.dumps(x, 2)
519 y = self.loads(s)
520 self.assertEqual(list(x), list(y))
521 self.assertEqual(x.__dict__, y.__dict__)
522
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000523 def test_newobj_generic(self):
524 for proto in [0, 1, 2]:
525 for C in myclasses:
526 B = C.__base__
527 x = C(C.sample)
528 x.foo = 42
529 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000530 y = self.loads(s)
531 detail = (proto, C, B, x, y, type(y))
532 self.assertEqual(B(x), B(y), detail)
533 self.assertEqual(x.__dict__, y.__dict__, detail)
534
Tim Peters47a6b132003-01-28 22:34:11 +0000535# XXX Temporary hack, so long as the C implementation of pickle protocol
536# XXX 2 isn't ready. When it is, move the methods in TempAbstractPickleTests
537# XXX into AbstractPickleTests above, and get rid of TempAbstractPickleTests
538# XXX along with the references to it in test_pickle.py.
539class TempAbstractPickleTests(unittest.TestCase):
540
Guido van Rossumc8d6ef52003-01-28 22:02:31 +0000541 def test_newobj_list_slots(self):
542 x = SlotList([1, 2, 3])
543 x.foo = 42
544 x.bar = "hello"
545 s = self.dumps(x, 2)
546 y = self.loads(s)
547 self.assertEqual(list(x), list(y))
548 self.assertEqual(x.__dict__, y.__dict__)
549 self.assertEqual(x.foo, y.foo)
550 self.assertEqual(x.bar, y.bar)
551## import pickletools
552## print
553## pickletools.dis(s)
554
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000555 def test_global_ext1(self):
556 import copy_reg
557 copy_reg.add_extension(__name__, "MyList", 0xf0)
558 try:
559 x = MyList([1, 2, 3])
560 x.foo = 42
561 x.bar = "hello"
562
563 # Dump using protocol 1 for comparison
564 s1 = self.dumps(x, 1)
565 y = self.loads(s1)
566 self.assertEqual(list(x), list(y))
567 self.assertEqual(x.__dict__, y.__dict__)
568 self.assert_(s1.find(__name__) >= 0)
569 self.assert_(s1.find("MyList") >= 0)
570## import pickletools
571## print
572## pickletools.dis(s1)
573
574 # Dump using protocol 2 for test
575 s2 = self.dumps(x, 2)
576 self.assertEqual(s2.find(__name__), -1)
577 self.assertEqual(s2.find("MyList"), -1)
578 y = self.loads(s2)
579 self.assertEqual(list(x), list(y))
580 self.assertEqual(x.__dict__, y.__dict__)
581## import pickletools
582## print
583## pickletools.dis(s2)
584
585 finally:
586 copy_reg.remove_extension(__name__, "MyList", 0xf0)
587
588 def test_global_ext2(self):
589 import copy_reg
590 copy_reg.add_extension(__name__, "MyList", 0xfff0)
591 try:
592 x = MyList()
593 s2 = self.dumps(x, 2)
594 self.assertEqual(s2.find(__name__), -1)
595 self.assertEqual(s2.find("MyList"), -1)
596 y = self.loads(s2)
597 self.assertEqual(list(x), list(y))
598 self.assertEqual(x.__dict__, y.__dict__)
599 finally:
600 copy_reg.remove_extension(__name__, "MyList", 0xfff0)
601
602 def test_global_ext4(self):
603 import copy_reg
604 copy_reg.add_extension(__name__, "MyList", 0xfffff0)
605 try:
606 x = MyList()
607 s2 = self.dumps(x, 2)
608 self.assertEqual(s2.find(__name__), -1)
609 self.assertEqual(s2.find("MyList"), -1)
610 y = self.loads(s2)
611 self.assertEqual(list(x), list(y))
612 self.assertEqual(x.__dict__, y.__dict__)
613 finally:
614 copy_reg.remove_extension(__name__, "MyList", 0xfffff0)
615
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000616class MyInt(int):
617 sample = 1
618
619class MyLong(long):
620 sample = 1L
621
622class MyFloat(float):
623 sample = 1.0
624
625class MyComplex(complex):
626 sample = 1.0 + 0.0j
627
628class MyStr(str):
629 sample = "hello"
630
631class MyUnicode(unicode):
632 sample = u"hello \u1234"
633
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000634class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000635 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000636
637class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000638 sample = [1, 2, 3]
639
640class MyDict(dict):
641 sample = {"a": 1, "b": 2}
642
643myclasses = [MyInt, MyLong, MyFloat,
644 # MyComplex, # XXX complex somehow doesn't work here :-(
645 MyStr, MyUnicode,
646 MyTuple, MyList, MyDict]
647
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000648
Guido van Rossumc8d6ef52003-01-28 22:02:31 +0000649class SlotList(MyList):
650 __slots__ = ["foo"]
651
Jeremy Hylton66426532001-10-15 21:38:56 +0000652class AbstractPickleModuleTests(unittest.TestCase):
653
654 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +0000655 import os
656 f = open(TESTFN, "w")
657 try:
658 f.close()
659 self.assertRaises(ValueError, self.module.dump, 123, f)
660 finally:
661 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +0000662
663 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +0000664 import os
665 f = open(TESTFN, "w")
666 try:
667 f.close()
668 self.assertRaises(ValueError, self.module.dump, 123, f)
669 finally:
670 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +0000671
672class AbstractPersistentPicklerTests(unittest.TestCase):
673
674 # This class defines persistent_id() and persistent_load()
675 # functions that should be used by the pickler. All even integers
676 # are pickled using persistent ids.
677
678 def persistent_id(self, object):
679 if isinstance(object, int) and object % 2 == 0:
680 self.id_count += 1
681 return str(object)
682 else:
683 return None
684
685 def persistent_load(self, oid):
686 self.load_count += 1
687 object = int(oid)
688 assert object % 2 == 0
689 return object
690
691 def test_persistence(self):
692 self.id_count = 0
693 self.load_count = 0
694 L = range(10)
695 self.assertEqual(self.loads(self.dumps(L)), L)
696 self.assertEqual(self.id_count, 5)
697 self.assertEqual(self.load_count, 5)
698
699 def test_bin_persistence(self):
700 self.id_count = 0
701 self.load_count = 0
702 L = range(10)
703 self.assertEqual(self.loads(self.dumps(L, 1)), L)
704 self.assertEqual(self.id_count, 5)
705 self.assertEqual(self.load_count, 5)