Strange Problem with a Product using SWIG Python Proxy Classes
Greetings, My question concerns the use of SWIG Python proxy classes in a Zope Product. In the ZDG and elsewhere, I have seen the statement that if an object is pickleable, it can be used as a persistent object in a Zope Product. In my experience, my SWIG Python proxy classes are pickleable, can be stored in a ZODB, the Product that uses them can be installed in Zope, instances of the Product classes can be added and work, but on a restart of Zope, the instances of my Product classes are broken and will cause Zope to segfault on any attempt to access the proxy class. I am using Python 2.1.3 with threads and the thread stack size patch built on OS X 10.2 and Zope 2.6.0. I've had no other problems with Python or Zope on this machine until I began developing this new Product. I am developing a Zope Product that will use a Python interface to a C language GIS library. The Python module is created with SWIG (1.3.17) and consists of proxy classes that dispatch methods and member variable access to the underlying C objects. For those who are unfamiliar with SWIG, here's a link to a doc that describes the proxy classes: http://www.swig.org/Doc1.3/Python.html#n28 Basically, I have a C structure with an attribute named 'name', a C library named '_mapscript' and have a proxy class like class mapObj(_object): __swig_setmethods__ = {} __setattr__ = lambda self, name, value: _swig_setattr(self, mapObj, name, value) __swig_getmethods__ = {} __getattr__ = lambda self, name: _swig_getattr(self, mapObj, name) __swig_setmethods__["name"] = _mapscript.mapObj_name_set __swig_getmethods__["name"] = _mapscript.mapObj_name_get if _newclass: name = property(_mapscript.mapObj_name_get, _mapscript.mapObj_name_set) def __init__(self,*args): self.this = apply(_mapscript.new_mapObj,args) self.thisown = 1 def __del__(self, destroy= _mapscript.delete_mapObj): try: if self.thisown: destroy(self) except: pass As I understand, the 'if _newclass ...' code should be passed by Python 2.1. I have verified that instances of this class can be pickled using dump/load from pickle and cPickle. I have also been able to successfully save and load instances of the mapObj proxy class using ZODB from the Python interpreter (outside of Zope). Instances loaded from a non-Zope ZODB FileStorage work as designed. In my Product, I use this SWIG Python proxy class as a member of a Python class (here's a fragment): def ZMap(...): def __init__(self): self._map = mapObj() def __del__(self): del self._map def getName(): return self._map.name I created methods to add the Product and they work. Once the Product is installed, I can add new instances and they work just as I've designed. For example, when an instance named 'map1' is added to a folder under the root named 'Maps' I can access the url /Maps/map1?getName and I get exactly what I expect. However, when I restart Zope, any attempt to access that url causes a segfault and a restart of Zope. I have had the same experience with testing my Zope FileStorage (Data.fs) from the Python interpreter. Newly created instances of my ZMap class work fine. Saved instances loaded from Data.fs are broken and cause a segfault when I try to access any member of _map. I'm very puzzled and would greatly appreciate answers, annecdotes or ideas from anyone who has experience in this area. thanks! Sean # Sean Gillies # sgillies@frii.com
Sean Gillies wrote at 2003-1-2 12:52 -0700:
My question concerns the use of SWIG Python proxy classes in a Zope Product. In the ZDG and elsewhere, I have seen the statement that if an object is pickleable, it can be used as a persistent object in a Zope Product. In my experience, my SWIG Python proxy classes are pickleable, can be stored in a ZODB, the Product that uses them can be installed in Zope, instances of the Product classes can be added and work, but on a restart of Zope, the instances of my Product classes are broken and will cause Zope to segfault on any attempt to access the proxy class. I am using Python 2.1.3 with threads and the thread stack size patch built on OS X 10.2 and Zope 2.6.0. I've had no other problems with Python or Zope on this machine until I began developing this new Product. Sounds like an "unpickling" problem.
For security reasons, "unpickling" is quite restricted. Objects must have special declarations to be "unpicklable". Try to unpickle your objects and see whether this produces any errors. Dieter
On Friday, January 3, 2003, at 12:33 PM, Dieter Maurer wrote:
Sean Gillies wrote at 2003-1-2 12:52 -0700:
My question concerns the use of SWIG Python proxy classes in a Zope Product. In the ZDG and elsewhere, I have seen the statement that if an object is pickleable, it can be used as a persistent object in a Zope Product. In my experience, my SWIG Python proxy classes are pickleable, can be stored in a ZODB, the Product that uses them can be installed in Zope, instances of the Product classes can be added and work, but on a restart of Zope, the instances of my Product classes are broken and will cause Zope to segfault on any attempt to access the proxy class. I am using Python 2.1.3 with threads and the thread stack size patch built on OS X 10.2 and Zope 2.6.0. I've had no other problems with Python or Zope on this machine until I began developing this new Product. Sounds like an "unpickling" problem.
For security reasons, "unpickling" is quite restricted. Objects must have special declarations to be "unpicklable".
Try to unpickle your objects and see whether this produces any errors.
Dieter
Dieter, Thanks for taking time to reply. I am able to unpickle the object without any problems. I am also able to save the object to a FileStorage using ZODB and can load it again from the database without problems. There must be more to it in Zope? I found a Product that also uses SWIG (m2crypto) and am going to look through it to see if I'm missing anything. cheers, Sean
participants (2)
-
Dieter Maurer -
Sean Gillies