Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6642653

Browse files
committed
Covert pickle tests to use unittest.
Extend tests to cover a few more cases. For cPickle, test several of the undocumented features.
1 parent 499ab6a commit 6642653

5 files changed

Lines changed: 294 additions & 193 deletions

File tree

Lib/test/output/test_cpickle

Lines changed: 0 additions & 13 deletions
This file was deleted.

Lib/test/output/test_pickle

Lines changed: 0 additions & 13 deletions
This file was deleted.

Lib/test/pickletester.py

Lines changed: 177 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
1-
# test_pickle and test_cpickle both use this.
2-
1+
import unittest
32
from test_support import TestFailed, have_unicode
4-
import sys
53

6-
# break into multiple strings to please font-lock-mode
4+
class C:
5+
def __cmp__(self, other):
6+
return cmp(self.__dict__, other.__dict__)
7+
8+
import __main__
9+
__main__.C = C
10+
C.__module__ = "__main__"
11+
12+
class myint(int):
13+
def __init__(self, x):
14+
self.str = str(x)
15+
16+
class initarg(C):
17+
def __init__(self, a, b):
18+
self.a = a
19+
self.b = b
20+
21+
def __getinitargs__(self):
22+
return self.a, self.b
23+
24+
# break into multiple strings to avoid confusing font-lock-mode
725
DATA = """(lp1
826
I0
927
aL1L
@@ -57,18 +75,8 @@
5775
'\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n' + \
5876
'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh' + \
5977
'\x06tq\nh\nK\x05e.'
60-
61-
class C:
62-
def __cmp__(self, other):
63-
return cmp(self.__dict__, other.__dict__)
64-
65-
import __main__
66-
__main__.C = C
67-
C.__module__ = "__main__"
68-
69-
# Call this with the module to be tested (pickle or cPickle).
70-
71-
def dotest(pickle):
78+
79+
def create_data():
7280
c = C()
7381
c.foo = 1
7482
c.bar = 2
@@ -86,153 +94,159 @@ def dotest(pickle):
8694
x.append(y)
8795
x.append(y)
8896
x.append(5)
89-
r = []
90-
r.append(r)
91-
92-
print "dumps()"
93-
s = pickle.dumps(x)
94-
95-
print "loads()"
96-
x2 = pickle.loads(s)
97-
if x2 == x:
98-
print "ok"
99-
else:
100-
print "bad"
101-
102-
print "loads() DATA"
103-
x2 = pickle.loads(DATA)
104-
if x2 == x:
105-
print "ok"
106-
else:
107-
print "bad"
108-
109-
print "dumps() binary"
110-
s = pickle.dumps(x, 1)
111-
112-
print "loads() binary"
113-
x2 = pickle.loads(s)
114-
if x2 == x:
115-
print "ok"
116-
else:
117-
print "bad"
118-
119-
print "loads() BINDATA"
120-
x2 = pickle.loads(BINDATA)
121-
if x2 == x:
122-
print "ok"
123-
else:
124-
print "bad"
125-
126-
print "dumps() RECURSIVE"
127-
s = pickle.dumps(r)
128-
x2 = pickle.loads(s)
129-
if x2 == r:
130-
print "ok"
131-
else:
132-
print "bad"
133-
134-
# don't create cyclic garbage
135-
del x2[0]
136-
del r[0]
137-
138-
# Test protection against closed files
139-
import tempfile, os
140-
fn = tempfile.mktemp()
141-
f = open(fn, "w")
142-
f.close()
143-
try:
144-
pickle.dump(123, f)
145-
except ValueError:
146-
pass
147-
else:
148-
print "dump to closed file should raise ValueError"
149-
150-
f = open(fn, "r")
151-
f.close()
152-
try:
153-
pickle.load(f)
154-
except ValueError:
97+
return x
98+
99+
class AbstractPickleTests(unittest.TestCase):
100+
101+
_testdata = create_data()
102+
103+
def setUp(self):
104+
# subclass must define self.dumps, self.loads, self.error
155105
pass
156-
else:
157-
print "load from closed file should raise ValueError"
158-
os.remove(fn)
159-
160-
# Test specific bad cases
161-
for i in range(10):
162-
try:
163-
x = pickle.loads('garyp')
164-
except KeyError, y:
165-
# pickle
166-
del y
167-
except pickle.BadPickleGet, y:
168-
# cPickle
169-
del y
170-
else:
171-
print "unexpected success!"
172-
break
173-
174-
# Test insecure strings
175-
insecure = ["abc", "2 + 2", # not quoted
176-
"'abc' + 'def'", # not a single quoted string
177-
"'abc", # quote is not closed
178-
"'abc\"", # open quote and close quote don't match
179-
"'abc' ?", # junk after close quote
180-
# some tests of the quoting rules
181-
"'abc\"\''",
182-
"'\\\\a\'\'\'\\\'\\\\\''",
183-
]
184-
for s in insecure:
185-
buf = "S" + s + "\012p0\012."
186-
try:
187-
x = pickle.loads(buf)
188-
except ValueError:
189-
pass
190-
else:
191-
print "accepted insecure string: %s" % repr(buf)
192-
193-
# Test some Unicode end cases
106+
107+
def test_misc(self):
108+
# test various datatypes not tested by testdata
109+
x = myint(4)
110+
s = self.dumps(x)
111+
y = self.loads(s)
112+
self.assertEqual(x, y)
113+
114+
x = (1, ())
115+
s = self.dumps(x)
116+
y = self.loads(s)
117+
self.assertEqual(x, y)
118+
119+
x = initarg(1, x)
120+
s = self.dumps(x)
121+
y = self.loads(s)
122+
self.assertEqual(x, y)
123+
124+
# XXX test __reduce__ protocol?
125+
126+
def test_identity(self):
127+
s = self.dumps(self._testdata)
128+
x = self.loads(s)
129+
self.assertEqual(x, self._testdata)
130+
131+
def test_constant(self):
132+
x = self.loads(DATA)
133+
self.assertEqual(x, self._testdata)
134+
x = self.loads(BINDATA)
135+
self.assertEqual(x, self._testdata)
136+
137+
def test_binary(self):
138+
s = self.dumps(self._testdata, 1)
139+
x = self.loads(s)
140+
self.assertEqual(x, self._testdata)
141+
142+
def test_recursive_list(self):
143+
l = []
144+
l.append(l)
145+
s = self.dumps(l)
146+
x = self.loads(s)
147+
self.assertEqual(x, l)
148+
self.assertEqual(x, x[0])
149+
self.assertEqual(id(x), id(x[0]))
150+
151+
def test_recursive_dict(self):
152+
d = {}
153+
d[1] = d
154+
s = self.dumps(d)
155+
x = self.loads(s)
156+
self.assertEqual(x, d)
157+
self.assertEqual(x[1], x)
158+
self.assertEqual(id(x[1]), id(x))
159+
160+
def test_recursive_inst(self):
161+
i = C()
162+
i.attr = i
163+
s = self.dumps(i)
164+
x = self.loads(s)
165+
self.assertEqual(x, i)
166+
self.assertEqual(x.attr, x)
167+
self.assertEqual(id(x.attr), id(x))
168+
169+
def test_recursive_multi(self):
170+
l = []
171+
d = {1:l}
172+
i = C()
173+
i.attr = d
174+
l.append(i)
175+
s = self.dumps(l)
176+
x = self.loads(s)
177+
self.assertEqual(x, l)
178+
self.assertEqual(x[0], i)
179+
self.assertEqual(x[0].attr, d)
180+
self.assertEqual(x[0].attr[1], x)
181+
self.assertEqual(x[0].attr[1][0], i)
182+
self.assertEqual(x[0].attr[1][0].attr, d)
183+
184+
def test_garyp(self):
185+
self.assertRaises(self.error, self.loads, 'garyp')
186+
187+
def test_insecure_strings(self):
188+
insecure = ["abc", "2 + 2", # not quoted
189+
"'abc' + 'def'", # not a single quoted string
190+
"'abc", # quote is not closed
191+
"'abc\"", # open quote and close quote don't match
192+
"'abc' ?", # junk after close quote
193+
# some tests of the quoting rules
194+
"'abc\"\''",
195+
"'\\\\a\'\'\'\\\'\\\\\''",
196+
]
197+
for s in insecure:
198+
buf = "S" + s + "\012p0\012."
199+
self.assertRaises(ValueError, self.loads, buf)
200+
194201
if have_unicode:
195-
endcases = [unicode(''), unicode('<\\u>'), unicode('<\\\u1234>'),
196-
unicode('<\n>'), unicode('<\\>')]
197-
else:
198-
endcases = []
199-
for u in endcases:
200-
try:
201-
u2 = pickle.loads(pickle.dumps(u))
202-
except Exception, msg:
203-
print "Endcase exception: %s => %s(%s)" % \
204-
(`u`, msg.__class__.__name__, str(msg))
205-
else:
206-
if u2 != u:
207-
print "Endcase failure: %s => %s" % (`u`, `u2`)
208-
209-
# Test the full range of Python ints.
210-
n = sys.maxint
211-
while n:
212-
for expected in (-n, n):
213-
for binary_mode in (0, 1):
214-
s = pickle.dumps(expected, binary_mode)
215-
got = pickle.loads(s)
216-
if expected != got:
217-
raise TestFailed("for %s-mode pickle of %d, pickle "
218-
"string is %s, loaded back as %s" % (
219-
binary_mode and "binary" or "text",
220-
expected,
221-
repr(s),
222-
got))
223-
n = n >> 1
224-
225-
# Fake a pickle from a sizeof(long)==8 box.
226-
maxint64 = (1L << 63) - 1
227-
data = 'I' + str(maxint64) + '\n.'
228-
got = pickle.loads(data)
229-
if maxint64 != got:
230-
raise TestFailed("maxint64 test failed %r %r" % (maxint64, got))
231-
# Try too with a bogus literal.
232-
data = 'I' + str(maxint64) + 'JUNK\n.'
233-
try:
234-
got = pickle.loads(data)
235-
except ValueError:
202+
def test_unicode(self):
203+
endcases = [unicode(''), unicode('<\\u>'), unicode('<\\\u1234>'),
204+
unicode('<\n>'), unicode('<\\>')]
205+
for u in endcases:
206+
p = self.dumps(u)
207+
u2 = self.loads(p)
208+
self.assertEqual(u2, u)
209+
210+
def test_ints(self):
211+
import sys
212+
n = sys.maxint
213+
while n:
214+
for expected in (-n, n):
215+
s = self.dumps(expected)
216+
n2 = self.loads(s)
217+
self.assertEqual(expected, n2)
218+
n = n >> 1
219+
220+
def test_maxint64(self):
221+
maxint64 = (1L << 63) - 1
222+
data = 'I' + str(maxint64) + '\n.'
223+
got = self.loads(data)
224+
self.assertEqual(got, maxint64)
225+
226+
# Try too with a bogus literal.
227+
data = 'I' + str(maxint64) + 'JUNK\n.'
228+
self.assertRaises(ValueError, self.loads, data)
229+
230+
def test_reduce(self):
236231
pass
237-
else:
238-
raise TestFailed("should have raised error on bogus INT literal")
232+
233+
def test_getinitargs(self):
234+
pass
235+
236+
class AbstractPickleModuleTests(unittest.TestCase):
237+
238+
def test_dump_closed_file(self):
239+
import tempfile, os
240+
fn = tempfile.mktemp()
241+
f = open(fn, "w")
242+
f.close()
243+
self.assertRaises(ValueError, self.module.dump, 123, f)
244+
os.remove(fn)
245+
246+
def test_load_closed_file(self):
247+
import tempfile, os
248+
fn = tempfile.mktemp()
249+
f = open(fn, "w")
250+
f.close()
251+
self.assertRaises(ValueError, self.module.dump, 123, f)
252+
os.remove(fn)

0 commit comments

Comments
 (0)