blob: f1a138488c92c6882a68d56fe7834e59b9b4918b [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
Tim Peters3c67d792003-02-02 17:59:11 +0000505 # Test that proto >= 2 really uses the bool opcodes.
506 if proto >= 2 and x in (False, True):
507 expected = x and pickle.NEWTRUE or pickle.NEWFALSE
508 # Skip the PROTO opcode at the start.
509 self.assertEqual(s[2], expected)
510
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000511 def test_newobj_tuple(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000512 x = MyTuple([1, 2, 3])
513 x.foo = 42
514 x.bar = "hello"
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000515 s = self.dumps(x, 2)
516 y = self.loads(s)
517 self.assertEqual(tuple(x), tuple(y))
518 self.assertEqual(x.__dict__, y.__dict__)
519
520 def test_newobj_list(self):
Guido van Rossum3d8c01b2003-01-28 19:48:18 +0000521 x = MyList([1, 2, 3])
522 x.foo = 42
523 x.bar = "hello"
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000524 s = self.dumps(x, 2)
525 y = self.loads(s)
526 self.assertEqual(list(x), list(y))
527 self.assertEqual(x.__dict__, y.__dict__)
528
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000529 def test_newobj_generic(self):
530 for proto in [0, 1, 2]:
531 for C in myclasses:
532 B = C.__base__
533 x = C(C.sample)
534 x.foo = 42
535 s = self.dumps(x, proto)
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000536 y = self.loads(s)
537 detail = (proto, C, B, x, y, type(y))
538 self.assertEqual(B(x), B(y), detail)
539 self.assertEqual(x.__dict__, y.__dict__, detail)
540
Tim Peters47a6b132003-01-28 22:34:11 +0000541# XXX Temporary hack, so long as the C implementation of pickle protocol
542# XXX 2 isn't ready. When it is, move the methods in TempAbstractPickleTests
543# XXX into AbstractPickleTests above, and get rid of TempAbstractPickleTests
544# XXX along with the references to it in test_pickle.py.
545class TempAbstractPickleTests(unittest.TestCase):
546
Guido van Rossumc8d6ef52003-01-28 22:02:31 +0000547 def test_newobj_list_slots(self):
548 x = SlotList([1, 2, 3])
549 x.foo = 42
550 x.bar = "hello"
551 s = self.dumps(x, 2)
552 y = self.loads(s)
553 self.assertEqual(list(x), list(y))
554 self.assertEqual(x.__dict__, y.__dict__)
555 self.assertEqual(x.foo, y.foo)
556 self.assertEqual(x.bar, y.bar)
557## import pickletools
558## print
559## pickletools.dis(s)
560
Guido van Rossum0322d0f2003-01-29 06:12:46 +0000561 def test_global_ext1(self):
562 import copy_reg
563 copy_reg.add_extension(__name__, "MyList", 0xf0)
564 try:
565 x = MyList([1, 2, 3])
566 x.foo = 42
567 x.bar = "hello"
568
569 # Dump using protocol 1 for comparison
570 s1 = self.dumps(x, 1)
571 y = self.loads(s1)
572 self.assertEqual(list(x), list(y))
573 self.assertEqual(x.__dict__, y.__dict__)
574 self.assert_(s1.find(__name__) >= 0)
575 self.assert_(s1.find("MyList") >= 0)
576## import pickletools
577## print
578## pickletools.dis(s1)
579
580 # Dump using protocol 2 for test
581 s2 = self.dumps(x, 2)
582 self.assertEqual(s2.find(__name__), -1)
583 self.assertEqual(s2.find("MyList"), -1)
584 y = self.loads(s2)
585 self.assertEqual(list(x), list(y))
586 self.assertEqual(x.__dict__, y.__dict__)
587## import pickletools
588## print
589## pickletools.dis(s2)
590
591 finally:
592 copy_reg.remove_extension(__name__, "MyList", 0xf0)
593
594 def test_global_ext2(self):
595 import copy_reg
596 copy_reg.add_extension(__name__, "MyList", 0xfff0)
597 try:
598 x = MyList()
599 s2 = self.dumps(x, 2)
600 self.assertEqual(s2.find(__name__), -1)
601 self.assertEqual(s2.find("MyList"), -1)
602 y = self.loads(s2)
603 self.assertEqual(list(x), list(y))
604 self.assertEqual(x.__dict__, y.__dict__)
605 finally:
606 copy_reg.remove_extension(__name__, "MyList", 0xfff0)
607
608 def test_global_ext4(self):
609 import copy_reg
610 copy_reg.add_extension(__name__, "MyList", 0xfffff0)
611 try:
612 x = MyList()
613 s2 = self.dumps(x, 2)
614 self.assertEqual(s2.find(__name__), -1)
615 self.assertEqual(s2.find("MyList"), -1)
616 y = self.loads(s2)
617 self.assertEqual(list(x), list(y))
618 self.assertEqual(x.__dict__, y.__dict__)
619 finally:
620 copy_reg.remove_extension(__name__, "MyList", 0xfffff0)
621
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000622class MyInt(int):
623 sample = 1
624
625class MyLong(long):
626 sample = 1L
627
628class MyFloat(float):
629 sample = 1.0
630
631class MyComplex(complex):
632 sample = 1.0 + 0.0j
633
634class MyStr(str):
635 sample = "hello"
636
637class MyUnicode(unicode):
638 sample = u"hello \u1234"
639
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000640class MyTuple(tuple):
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000641 sample = (1, 2, 3)
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000642
643class MyList(list):
Guido van Rossum5d9113d2003-01-29 17:58:45 +0000644 sample = [1, 2, 3]
645
646class MyDict(dict):
647 sample = {"a": 1, "b": 2}
648
649myclasses = [MyInt, MyLong, MyFloat,
650 # MyComplex, # XXX complex somehow doesn't work here :-(
651 MyStr, MyUnicode,
652 MyTuple, MyList, MyDict]
653
Guido van Rossum533dbcf2003-01-28 17:55:05 +0000654
Guido van Rossumc8d6ef52003-01-28 22:02:31 +0000655class SlotList(MyList):
656 __slots__ = ["foo"]
657
Jeremy Hylton66426532001-10-15 21:38:56 +0000658class AbstractPickleModuleTests(unittest.TestCase):
659
660 def test_dump_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +0000661 import os
662 f = open(TESTFN, "w")
663 try:
664 f.close()
665 self.assertRaises(ValueError, self.module.dump, 123, f)
666 finally:
667 os.remove(TESTFN)
Jeremy Hylton66426532001-10-15 21:38:56 +0000668
669 def test_load_closed_file(self):
Guido van Rossum3b0a3292002-08-09 16:38:32 +0000670 import os
671 f = open(TESTFN, "w")
672 try:
673 f.close()
674 self.assertRaises(ValueError, self.module.dump, 123, f)
675 finally:
676 os.remove(TESTFN)
Jeremy Hylton4c8be852002-11-13 22:10:47 +0000677
678class AbstractPersistentPicklerTests(unittest.TestCase):
679
680 # This class defines persistent_id() and persistent_load()
681 # functions that should be used by the pickler. All even integers
682 # are pickled using persistent ids.
683
684 def persistent_id(self, object):
685 if isinstance(object, int) and object % 2 == 0:
686 self.id_count += 1
687 return str(object)
688 else:
689 return None
690
691 def persistent_load(self, oid):
692 self.load_count += 1
693 object = int(oid)
694 assert object % 2 == 0
695 return object
696
697 def test_persistence(self):
698 self.id_count = 0
699 self.load_count = 0
700 L = range(10)
701 self.assertEqual(self.loads(self.dumps(L)), L)
702 self.assertEqual(self.id_count, 5)
703 self.assertEqual(self.load_count, 5)
704
705 def test_bin_persistence(self):
706 self.id_count = 0
707 self.load_count = 0
708 L = range(10)
709 self.assertEqual(self.loads(self.dumps(L, 1)), L)
710 self.assertEqual(self.id_count, 5)
711 self.assertEqual(self.load_count, 5)