XML Pickle with PyGraphLib - Problems
no.spam.for.me. at thanks.com
Mon Sep 5 08:55:15 CEST 2005
I'm working on a simulation (can be considered a game) in Python where I
want to be able to dump the simulation state to a file and be able to load
it up later. I have used the standard Python pickle module and it works fine
pickling/unpickling from files.
However, I want to be able to use a third party tool like an XML editor (or
other custom tool) to setup the initial state of the simulation, so I have
been playing around with the gnosis set of tools written by David Mertz. In
particular I have been using the gnosis.xml.pickle module. Anyway, this
seems to work fine for most data structures, however I have problems getting
it to work with pygraphlib version 0.6.0.1 (from sourceforge). My simulation
needs to store data in a set of graphs, and pygraphlib seems like a nice
simple python graph library, that I found easy to use.
Anyway, the problem is that I can successfully pickle to XML a data
structure containing a pygraphlib graph, but I have trouble
reloading/unpickling the very same data structure that was produced by the
XML pickle module. I get an XMLUnpicklingError. Anyone have any ideas?
Here's some output from the interactive prompt of a small example which
demonstrates the error:
ActivePython 2.4 Build 244 (ActiveState Corp.) based on
Python 2.4 (#60, Feb 9 2005, 19:03:27) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pygraphlib import pygraph
>>> graph = pygraph.DGraph()
>>> graph.add_edge('Melbourne', 'Sydney')
>>> graph.add_edge('Melbourne', 'Brisbane')
>>> graph.add_edge('Melbourne', 'Adelaide')
>>> graph.add_edge('Adelaide', 'Perth')
>>> print graph
DGraph: 5 nodes, 4 edges
DGraph: 5 nodes, 4 edges
Melbourne -> ['Sydney', 'Brisbane', 'Adelaide']
Brisbane -> 
Perth -> 
Sydney -> 
Adelaide -> ['Perth']
>>> import gnosis.xml.pickle
>>> file = open('graph.xml', 'w')
>>> gnosis.xml.pickle.dump(graph, file)
>>> f2 = open('graph.xml', 'r')
>>> g2 = gnosis.xml.pickle.load(f2)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "C:\Python24\Lib\site-packages\gnosis\xml\pickle\_pickle.py", line
152, in load
return parser(fh, paranoia=paranoia)
line 42, in thing_from_dom
line 175, in _thing_from_dom
container = unpickle_instance(node, paranoia)
line 59, in unpickle_instance
raw = _thing_from_dom(node, _EmptyClass(), paranoia)
line 234, in _thing_from_dom
node_val = unpickle_instance(node, paranoia)
line 95, in unpickle_instance
raise XMLUnpicklingError, \
gnosis.xml.pickle.XMLUnpicklingError: Non-DictType without setstate violates
pickle protocol.(PARANOIA setting may be too high)
I find it strange that:
a) the standard pickle/unpickle works
b) the xml pickle dumps the file but the xml unpickle can't load it.
I'm guessing the problem lies somewhere with implementing __setstate__ and
__getstate__ for pygraphlib (I don't know much about this - haven't used
them before). However, I am a bit reluctant to go in and start playing
around with the internals pygraphlib, as I was hoping to just use it, and
ignore the internal implementation (as you would with any library). Funny
how the standard pickle module doesn't need to do this.
Another thing I tried was the generic xml marshaller (xml.marshal.generic)
that comes with PyXML 0.8.4 (for Python 2.4 on windows).
This also fails but for different reasons. The marshaller doesn't support
the boolean and set types which are part of Python 2.4 and are used in
I get errors of the form:
AttributeError: Marshaller instance has no attribute 'tag_bool'
AttributeError: Marshaller instance has no attribute 'm_Set'
Again strange given that bool and sets should be supported in Python 2.4.
Anyway, back to my question - does anyone have any suggestions as to where I
could proceed next? I was hoping to be able to XML Pickle/Unpickle Python
data structures containing graphs from pygraphlib fairly easily without
having to stuff around in the internals of third party libraries.
It would be nice if I could just concentrate on my application logic :-)
More information about the Python-list