"""This started out as a test of toplevel-pickling of builtins, but has
turned into more of a test of pickling self-referencing objects (toplevels are
still tested, however). --fpm"""
import gnosis.xml.pickle as xml_pickle
import random, re, sys
from gnosis.xml.pickle.ext import XMLP_Mutator, XMLP_Mutated
import gnosis.xml.pickle.ext as mutate
from UserList import UserList
import funcs
funcs.set_parser()
class foo: pass
# so we can unpickle foo
xml_pickle.setParanoia(0)
# test the obvious self-refs
l = [1,2]
l.append(l)
print l
x = xml_pickle.dumps(l)
#print x
g = xml_pickle.loads(x)
print g
d = {'a':1}
d['b'] = d
print d
x = xml_pickle.dumps(d)
#print x
g = xml_pickle.loads(x)
print g
# pickle builtins as toplevel objects (the self-ref is actually
# inside the wrapper for these cases)
s = "abc"
x = xml_pickle.dumps(s)
print s
#print x
g = xml_pickle.loads(x)
print g
s = 123
x = xml_pickle.dumps(s)
print s
#print x
g = xml_pickle.loads(x)
print g
s = 123.45
x = xml_pickle.dumps(s)
print s
#print x
g = xml_pickle.loads(x)
print g
s = 12+34j
x = xml_pickle.dumps(s)
print s
#print x
g = xml_pickle.loads(x)
print g
s = {'A':1, 'B': 2, 'C': 3}
x = xml_pickle.dumps(s)
print s
#print x
g = xml_pickle.loads(x)
print g
s = [1,2,'a','b']
x = xml_pickle.dumps(s)
print s
#print x
g = xml_pickle.loads(x)
print g
s = ('a','b',1,2)
x = xml_pickle.dumps(s)
print s
#print x
g = xml_pickle.loads(x)
print g
# this is neat -- r first gets mutated into a wrapper
# object, then mutated again from SRE -> atom
# (in general, nested mutation doesn't work, but it does
# work at the toplevel this way)
r = re.compile('this\s*is (not)?a\npattern$')
x = xml_pickle.dumps(r)
print r.pattern
print x
g = xml_pickle.loads(x)
print g.pattern
# now, pickle the same objects as first-level attributes,
# just to sanity-check that we didn't break anything
f = foo()
f.s = "abc"
x = xml_pickle.dumps(f)
g = xml_pickle.loads(x)
print g.s
f.s = 123
x = xml_pickle.dumps(f)
g = xml_pickle.loads(x)
print g.s
f.s = 123.45
x = xml_pickle.dumps(f)
g = xml_pickle.loads(x)
print g.s
f.s = 12+34j
x = xml_pickle.dumps(f)
g = xml_pickle.loads(x)
print g.s
f.s = {'A':1, 'B': 2, 'C': 3}
x = xml_pickle.dumps(f)
g = xml_pickle.loads(x)
print g.s
f.s = [1,2,'a','b']
x = xml_pickle.dumps(f)
g = xml_pickle.loads(x)
print g.s
f.s = ('a','b',1,2)
x = xml_pickle.dumps(f)
g = xml_pickle.loads(x)
print g.s
f.s = re.compile('this\s*is (not)?a\npattern$')
x = xml_pickle.dumps(f)
g = xml_pickle.loads(x)
print g.s.pattern
# show that toplevel classes get mutated too
# a null-mutator, just for demonstration
class foomu(XMLP_Mutator):
def __init__(self):
XMLP_Mutator.__init__(self,type(foo()),'foomu')
# careful -- type(foo) == InstanceType == "everything" :-)
def wants_obj(self,obj):
return obj.__class__ == foo
def mutate(self,obj):
# a tricky self-ref
obj.breakage = obj
return XMLP_Mutated(obj)
def unmutate(self,mobj):
return mobj.obj
my = foomu()
mutate.add_mutator(my)
f = foo()
f.a = UserList([4,5,6])
f.b = "abc"
print f.a,f.b
x = xml_pickle.dumps(f)
#print x
g = xml_pickle.loads(x)
print g.a,g.b
mutate.remove_mutator(my)
# handcoded selfrefs from dqm that caused problems (even
# with xml_pickle-0.51)
s="""
"""
print s
o2 = xml_pickle.loads(s)
print xml_pickle.dumps(o2)
s="""
"""
print s
o2 = xml_pickle.loads(s)
print xml_pickle.dumps(o2)
#
# from a bug report sent by Wolfgang Feix
#
class A:
def __init__(self, x=0):
self.__parent__ = None
self.x = x
def setParent(self, p):
self.__parent__ = p
x = A(1)
x.y = A(2)
x.y.z = A(3)
x.y.z.setParent(x.y)
print "Expect: 1 2 3 2"
print x.x,x.y.x,x.y.z.x,x.y.z.__parent__.x
s = xml_pickle.dumps(x)
p = xml_pickle.loads(s)
print p.x,p.y.x,p.y.z.x,p.y.z.__parent__.x