Bump version number to 2.4.2 to pick up the latest minor bug fixes.
[python/dscho.git] / Lib / test / pickletester.py
blob2294c3dd0f8897b48b193fd79088dd717c86238b
1 import unittest
2 from test.test_support import TestFailed, have_unicode, TESTFN
4 class C:
5 def __cmp__(self, other):
6 return cmp(self.__dict__, other.__dict__)
8 import __main__
9 __main__.C = C
10 C.__module__ = "__main__"
12 class myint(int):
13 def __init__(self, x):
14 self.str = str(x)
16 class initarg(C):
18 __safe_for_unpickling__ = 1
20 def __init__(self, a, b):
21 self.a = a
22 self.b = b
24 def __getinitargs__(self):
25 return self.a, self.b
27 class metaclass(type):
28 pass
30 class use_metaclass(object):
31 __metaclass__ = metaclass
33 # break into multiple strings to avoid confusing font-lock-mode
34 DATA = """(lp1
36 aL1L
37 aF2
38 ac__builtin__
39 complex
41 """ + \
42 """(F3
44 tRp3
45 aI1
46 aI-1
47 aI255
48 aI-255
49 aI-256
50 aI65535
51 aI-65535
52 aI-65536
53 aI2147483647
54 aI-2147483647
55 aI-2147483648
56 a""" + \
57 """(S'abc'
60 """ + \
61 """(i__main__
64 """ + \
65 """(dp6
66 S'foo'
69 sS'bar'
72 sbg5
73 tp9
74 ag9
75 aI5
77 """
79 BINDATA = ']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00' + \
80 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00' + \
81 '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff' + \
82 '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff' + \
83 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00' + \
84 '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n' + \
85 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh' + \
86 '\x06tq\nh\nK\x05e.'
88 def create_data():
89 c = C()
90 c.foo = 1
91 c.bar = 2
92 x = [0, 1L, 2.0, 3.0+0j]
93 # Append some integer test cases at cPickle.c's internal size
94 # cutoffs.
95 uint1max = 0xff
96 uint2max = 0xffff
97 int4max = 0x7fffffff
98 x.extend([1, -1,
99 uint1max, -uint1max, -uint1max-1,
100 uint2max, -uint2max, -uint2max-1,
101 int4max, -int4max, -int4max-1])
102 y = ('abc', 'abc', c, c)
103 x.append(y)
104 x.append(y)
105 x.append(5)
106 return x
108 class AbstractPickleTests(unittest.TestCase):
110 _testdata = create_data()
112 def setUp(self):
113 # subclass must define self.dumps, self.loads, self.error
114 pass
116 def test_misc(self):
117 # test various datatypes not tested by testdata
118 x = myint(4)
119 s = self.dumps(x)
120 y = self.loads(s)
121 self.assertEqual(x, y)
123 x = (1, ())
124 s = self.dumps(x)
125 y = self.loads(s)
126 self.assertEqual(x, y)
128 x = initarg(1, x)
129 s = self.dumps(x)
130 y = self.loads(s)
131 self.assertEqual(x, y)
133 # XXX test __reduce__ protocol?
135 def test_identity(self):
136 s = self.dumps(self._testdata)
137 x = self.loads(s)
138 self.assertEqual(x, self._testdata)
140 def test_constant(self):
141 x = self.loads(DATA)
142 self.assertEqual(x, self._testdata)
143 x = self.loads(BINDATA)
144 self.assertEqual(x, self._testdata)
146 def test_binary(self):
147 s = self.dumps(self._testdata, 1)
148 x = self.loads(s)
149 self.assertEqual(x, self._testdata)
151 def test_recursive_list(self):
152 l = []
153 l.append(l)
154 s = self.dumps(l)
155 x = self.loads(s)
156 self.assertEqual(x, l)
157 self.assertEqual(x, x[0])
158 self.assertEqual(id(x), id(x[0]))
160 def test_recursive_dict(self):
161 d = {}
162 d[1] = d
163 s = self.dumps(d)
164 x = self.loads(s)
165 self.assertEqual(x, d)
166 self.assertEqual(x[1], x)
167 self.assertEqual(id(x[1]), id(x))
169 def test_recursive_inst(self):
170 i = C()
171 i.attr = i
172 s = self.dumps(i)
173 x = self.loads(s)
174 self.assertEqual(x, i)
175 self.assertEqual(x.attr, x)
176 self.assertEqual(id(x.attr), id(x))
178 def test_recursive_multi(self):
179 l = []
180 d = {1:l}
181 i = C()
182 i.attr = d
183 l.append(i)
184 s = self.dumps(l)
185 x = self.loads(s)
186 self.assertEqual(x, l)
187 self.assertEqual(x[0], i)
188 self.assertEqual(x[0].attr, d)
189 self.assertEqual(x[0].attr[1], x)
190 self.assertEqual(x[0].attr[1][0], i)
191 self.assertEqual(x[0].attr[1][0].attr, d)
193 def test_garyp(self):
194 self.assertRaises(self.error, self.loads, 'garyp')
196 def test_insecure_strings(self):
197 insecure = ["abc", "2 + 2", # not quoted
198 #"'abc' + 'def'", # not a single quoted string
199 "'abc", # quote is not closed
200 "'abc\"", # open quote and close quote don't match
201 "'abc' ?", # junk after close quote
202 "'\\'", # trailing backslash
203 # some tests of the quoting rules
204 #"'abc\"\''",
205 #"'\\\\a\'\'\'\\\'\\\\\''",
207 for s in insecure:
208 buf = "S" + s + "\012p0\012."
209 self.assertRaises(ValueError, self.loads, buf)
211 if have_unicode:
212 def test_unicode(self):
213 endcases = [unicode(''), unicode('<\\u>'), unicode('<\\\u1234>'),
214 unicode('<\n>'), unicode('<\\>')]
215 for u in endcases:
216 p = self.dumps(u)
217 u2 = self.loads(p)
218 self.assertEqual(u2, u)
220 def test_ints(self):
221 import sys
222 n = sys.maxint
223 while n:
224 for expected in (-n, n):
225 s = self.dumps(expected)
226 n2 = self.loads(s)
227 self.assertEqual(expected, n2)
228 n = n >> 1
230 def test_maxint64(self):
231 maxint64 = (1L << 63) - 1
232 data = 'I' + str(maxint64) + '\n.'
233 got = self.loads(data)
234 self.assertEqual(got, maxint64)
236 # Try too with a bogus literal.
237 data = 'I' + str(maxint64) + 'JUNK\n.'
238 self.assertRaises(ValueError, self.loads, data)
240 def test_reduce(self):
241 pass
243 def test_getinitargs(self):
244 pass
246 def test_metaclass(self):
247 a = use_metaclass()
248 s = self.dumps(a)
249 b = self.loads(s)
250 self.assertEqual(a.__class__, b.__class__)
252 def test_structseq(self):
253 import time
254 t = time.localtime()
255 s = self.dumps(t)
256 u = self.loads(s)
257 self.assertEqual(t, u)
258 import os
259 if hasattr(os, "stat"):
260 t = os.stat(os.curdir)
261 s = self.dumps(t)
262 u = self.loads(s)
263 self.assertEqual(t, u)
264 if hasattr(os, "statvfs"):
265 t = os.statvfs(os.curdir)
266 s = self.dumps(t)
267 u = self.loads(s)
268 self.assertEqual(t, u)
270 class AbstractPickleModuleTests(unittest.TestCase):
272 def test_dump_closed_file(self):
273 import os
274 f = open(TESTFN, "w")
275 try:
276 f.close()
277 self.assertRaises(ValueError, self.module.dump, 123, f)
278 finally:
279 os.remove(TESTFN)
281 def test_load_closed_file(self):
282 import os
283 f = open(TESTFN, "w")
284 try:
285 f.close()
286 self.assertRaises(ValueError, self.module.dump, 123, f)
287 finally:
288 os.remove(TESTFN)