source: trunk/tests/test_pickle.py @ 49

Revision 49, 9.0 KB checked in by xi, 8 years ago (diff)

Fix segfault under Python2.3.

Support for complex numbers.

Add /usr/local to the search path.

Line 
1# coding: utf-8
2
3import unittest
4
5import syck
6
7SIMPLE = """
8- !python/none ~
9- !python/bool True
10- !python/bool False
11- !python/int 123
12- !python/long 12345678901234567890
13- !python/float 123.456
14- !python/float 123456e-3
15- !python/complex 1.0
16- !python/complex 0.0+1.0j
17- !python/str foo bar
18- !python/unicode FOO ЀУ bar ба
19- !python/list [1, 2, 3]
20- !python/tuple [foo, bar]
21- !python/dict {foo: bar}
22""", [
23    None,
24    True,
25    False,
26    123,
27    12345678901234567890L,
28    123.456,
29    123.456,
30    1+0j,
31    1j,
32    'foo bar',
33    unicode('FOO ЀУ bar ба', 'utf-8'),
34    [1, 2, 3],
35    ('foo', 'bar'),
36    {'foo': 'bar'},
37]
38
39class AClass:
40    pass
41
42class ASubclass(AClass):
43    pass
44
45class AType(object):
46    pass
47
48class ASubtype(AType):
49    pass
50
51def a_function(*args, **kwds):
52    pass
53
54NAMES = """
55- !python/name:unittest.TestCase
56- !python/name:test_pickle.AClass
57- !python/name:test_pickle.ASubclass
58- !python/name:test_pickle.AType
59- !python/name:test_pickle.ASubtype
60- !python/name:test_pickle.a_function
61- !python/name:list
62- !python/name:__builtin__.dict
63- !python/name:file
64- !python/name:map
65- !python/name:type
66- !python/name:object
67""", [
68    unittest.TestCase,
69    AClass,
70    ASubclass,
71    AType,
72    ASubtype,
73    a_function,
74    list,
75    dict,
76    file,
77    map,
78    type,
79    object,
80]
81
82import sys, unittest, encodings.cp1251, os.path
83
84MODULES = """
85- !python/module:sys
86- !python/module:unittest
87- !python/module:encodings.cp1251
88- !python/module:os.path
89""", [sys, unittest, encodings.cp1251, os.path]
90
91class AnObject(object):
92
93    def __new__(cls, foo=None, bar=None, baz=None):
94        self = object.__new__(cls)
95        self.foo = foo
96        self.bar = bar
97        self.baz = baz
98        return self
99
100    def __cmp__(self, other):
101        return cmp((type(self), self.foo, self.bar, self.baz),
102                (type(other), other.foo, other.bar, other.baz))
103
104    def __eq__(self, other):
105        return type(self) is type(other) and    \
106                (self.foo, self.bar, self.baz) == (other.foo, other.bar, other.baz)
107
108class AnInstance:
109
110    def __init__(self, foo=None, bar=None, baz=None):
111        self.foo = foo
112        self.bar = bar
113        self.baz = baz
114
115    def __cmp__(self, other):
116        return cmp((type(self), self.foo, self.bar, self.baz),
117                (type(other), other.foo, other.bar, other.baz))
118
119    def __eq__(self, other):
120        return type(self) is type(other) and    \
121                (self.foo, self.bar, self.baz) == (other.foo, other.bar, other.baz)
122
123class AState(AnInstance):
124
125    def __getstate__(self):
126        return {
127            '_foo': self.foo,
128            '_bar': self.bar,
129            '_baz': self.baz,
130        }
131
132    def __setstate__(self, state):
133        self.foo = state['_foo']
134        self.bar = state['_bar']
135        self.baz = state['_baz']
136
137OBJECTS = """
138- !python/object:test_pickle.AnObject
139    foo: 1
140    bar: two
141    baz: [3, 4, 5]
142- !python/object:test_pickle.AnInstance
143    foo: 1
144    bar: two
145    baz: [3, 4, 5]
146- !python/object:test_pickle.AState
147    _foo: 1
148    _bar: two
149    _baz: [3, 4, 5]
150""", [
151    AnObject(foo=1, bar='two', baz=[3,4,5]),
152    AnInstance(foo=1, bar='two', baz=[3,4,5]),
153    AState(foo=1, bar='two', baz=[3,4,5]),
154]
155
156class ACustomState(AnInstance):
157
158    def __getstate__(self):
159        return (self.foo, self.bar, self.baz)
160
161    def __setstate__(self, state):
162        self.foo, self.bar, self.baz = state
163
164class InitArgs(AnInstance):
165
166    def __getinitargs__(self):
167        return (self.foo, self.bar, self.baz)
168
169class InitArgsWithState(AnInstance):
170
171    def __getinitargs__(self):
172        return (self.foo, self.bar)
173
174    def __getstate__(self):
175        return self.baz[:]
176
177    def __setstate__(self, state):
178        self.baz = state[:]
179
180class NewArgs(AnObject):
181
182    def __getnewargs__(self):
183        return (self.foo, self.bar, self.baz)
184
185    def __getstate__(self):
186        return None
187
188class NewArgsWithState(AnObject):
189
190    def __getnewargs__(self):
191        return (self.foo, self.bar)
192
193    def __getstate__(self):
194        return self.baz[:]
195
196    def __setstate__(self, state):
197        self.baz = state[:]
198
199NEWS = """
200- !python/new:test_pickle.ACustomState
201    state: !python/tuple [1, two, [3, 4, 5]]
202- !python/new:test_pickle.InitArgs [1, two, [3, 4, 5]]
203- !python/new:test_pickle.InitArgs
204    args: [1]
205    kwds: {bar: two, baz: [3, 4, 5]}
206- !python/new:test_pickle.InitArgsWithState
207    args: [1, two, [3, 4, 5]]
208    state: [3, 4, 5]
209- !python/new:test_pickle.NewArgs [1, two, [3, 4, 5]]
210- !python/new:test_pickle.NewArgs
211    args: [1]
212    kwds: {bar: two, baz: [3, 4, 5]}
213- !python/new:test_pickle.NewArgsWithState
214    args: [1, two, [3, 4, 5]]
215    state: [3, 4, 5]
216""", [
217    ACustomState(foo=1, bar='two', baz=[3,4,5]),
218    InitArgs(foo=1, bar='two', baz=[3,4,5]),
219    InitArgs(foo=1, bar='two', baz=[3,4,5]),
220    InitArgsWithState(foo=1, bar='two', baz=[3,4,5]),
221    NewArgs(foo=1, bar='two', baz=[3,4,5]),
222    NewArgs(foo=1, bar='two', baz=[3,4,5]),
223    NewArgsWithState(foo=1, bar='two', baz=[3,4,5]),
224]
225
226class Reduce(AnObject):
227
228    def __reduce__(self):
229        return self.__class__, (self.foo, self.bar, self.baz)
230
231class ReduceWithState(AnObject):
232
233    def __reduce__(self):
234        return self.__class__, (self.foo, self.bar), self.baz[:]
235
236    def __setstate__(self, state):
237        self.baz = state[:]
238
239APPLIES = """
240- !python/apply:test_pickle.Reduce [1, two, [3, 4, 5]]
241- !python/apply:test_pickle.Reduce
242    args: [1]
243    kwds: {bar: two, baz: [3, 4, 5]}
244- !python/apply:test_pickle.ReduceWithState
245    args: [1, two]
246    state: [3, 4, 5]
247""", [
248    Reduce(foo=1, bar='two', baz=[3,4,5]),
249    Reduce(foo=1, bar='two', baz=[3,4,5]),
250    ReduceWithState(foo=1, bar='two', baz=[3,4,5]),
251]
252
253class TestPickle(unittest.TestCase):
254
255    def testSimple(self):
256        self._testPickle(SIMPLE)
257
258    def testNames(self):
259        self._testPickle(NAMES)
260
261    def testModules(self):
262        self._testPickle(MODULES)
263
264    def testObjects(self):
265        self._testPickle(OBJECTS)
266
267    def testNews(self):
268        self._testPickle(NEWS)
269
270    def testApplies(self):
271        self._testPickle(APPLIES)
272
273    def _testPickle(self, (source, object)):
274        for left, right in zip(syck.load(source), object):
275            self.assertEqual(left, right)
276        for left, right in zip(syck.load(syck.dump(object)), object):
277            self.assertEqual(left, right)
278
279class MyPrivateType(AnObject):
280    pass
281
282class MyPublicType(AnObject):
283    pass
284
285class MyMapping(AnObject):
286
287    def yaml_construct(cls, node):
288        return cls(**node.value)
289    yaml_construct = classmethod(yaml_construct)
290
291    def yaml_represent(self, node):
292        return syck.Map(self.__dict__.copy(), inline=True)
293
294EXTENSIONS = """
295- !!MyPrivateType [1, 2, 3]
296- !domain.tld,2005/MyPublicType [1, 2, 3]
297- !domain.tld,2005/AnotherPublicType [1, 2, 3]
298- {foo: 1, bar: 2, baz: 3}
299""", [
300    MyPrivateType(1,2,3),
301    MyPublicType(1,2,3),
302    MyPublicType(1,2,3),
303    MyMapping(1,2,3),
304]
305
306NODES = """
307- foo
308- [bar, baz]
309"""
310
311BUGGY_NODES = """
312- foo
313- { bar: baz }
314"""
315
316class ExLoader(syck.Loader):
317
318    def find_constructor(self, node):
319        if node.kind == 'map':
320            return MyMapping.yaml_construct
321        return super(ExLoader, self).find_constructor(node)
322
323    def make_mapping(self, node):
324        return MyMapping(**node.value)
325
326    def construct_private_MyPrivateType(self, node):
327        return MyPrivateType(*node.value)
328
329    def construct_domain_tld_2005(self, node):
330        return MyPublicType(*node.value)
331
332class ExDumper(syck.Dumper):
333
334    def find_representer(self, object):
335        if isinstance(object, MyMapping):
336            return object.yaml_represent
337        return super(ExDumper, self).find_representer(object)
338
339    def represent_test_pickle_MyPrivateType(self, object):
340        return syck.Seq([object.foo, object.bar, object.baz],
341                tag="x-private:MyPrivateType", inline=True)
342
343    def represent_test_pickle_MyPublicType(self, object):
344        return syck.Seq([object.foo, object.bar, object.baz],
345                tag="tag:domain.tld,2005:APublicType", inline=True)
346
347class TestExtensions(unittest.TestCase):
348
349    def testExtensions(self):
350        source = EXTENSIONS[0]
351        object = EXTENSIONS[1]
352        object2 = syck.load(source, Loader=ExLoader)
353        for left, right in zip(object, object2):
354            self.assertEqual(left, right)
355        source2 = syck.dump(object2, Dumper=ExDumper)
356        object3 = syck.load(source2, Loader=ExLoader)
357        for left, right in zip(object, object3):
358            self.assertEqual(left, right)
359
360class TestNodesReduce(unittest.TestCase):
361
362    def testNodesReduce(self):
363        object = syck.load(NODES)
364        nodes = syck.parse(NODES)
365        output = syck.dump(nodes)
366        #print output
367        nodes2 = syck.load(output)
368        output2 = syck.emit(nodes2)
369        object2 = syck.load(output2)
370        self.assertEqual(object, object2)
371
372    def testBuggyNodesReduce(self):
373        object = syck.load(BUGGY_NODES)
374        nodes = syck.parse(BUGGY_NODES)
375        output = syck.dump(nodes)
376        #print output
377        nodes2 = syck.load(output)
378        output2 = syck.emit(nodes2)
379        object2 = syck.load(output2)
380        self.assertEqual(object, object2)
381
Note: See TracBrowser for help on using the repository browser.