1- # test_pickle and test_cpickle both use this.
2-
1+ import unittest
32from 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
725DATA = """(lp1
826I0
927aL1L
5775 '\x00 \x80 J\x00 \x00 \x00 \x80 (U\x03 abcq\x04 h\x04 (c__main__\n ' + \
5876 'C\n q\x05 oq\x06 }q\x07 (U\x03 fooq\x08 K\x01 U\x03 barq\t K\x02 ubh' + \
5977 '\x06 tq\n h\n K\x05 e.'
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 + "\012 p0\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 + "\012 p0\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