Hi all, I'm migrating code from python 2.4 to python 2.6 and I've got into troubles with pickling/unpickling python Exceptions. The following code works fine in 2.4 but not in 2.6. See Exception1 example
I have found on python mail list similar problem http://mail.python.org/pipermail/python-list/2009-December/1228773.html They recommend to use __reduce__. But this does not help as I'm getting different Exception class after pickle See Exception_with_reduce example I also have found possible solution to this problem here http://bugs.python.org/issue1692335 As a workaround they propose to pass Exception arguments into base class See Exception2 example But there is another problem. Constructor is called 2 times which is not acceptable to me. Could you please advice on the solution? ------------------------------------------ test program ------------------------------------------ import cPickle class Exception1(Exception): def __init__(self,arg1): print "constructor called" Exception.__init__(self) class Exception2(Exception): def __init__(self,arg1): print "constructor called" Exception.__init__(self,arg1) class Exception_with_reduce(Exception): def __reduce__(self): try: getnewargs = self.__getnewargs__ except AttributeError: newargs = (self.__class__,) else: newargs = (self.__class__,) + getnewargs() try: getstate = self.__getstate__ except AttributeError: state = self.__dict__ else: state = getstate() return (Exception, newargs, state) def __init__(self,arg1): print "constructor called" Exception.__init__(self,arg1) def test(E,args): try: print ">>",E.__name__ e = E(*args) print "- pickling" s = cPickle.dumps(e) print "- unpickling" e = cPickle.loads(s) if E != e.__class__: print "! failed: expected %s, got %s"%(E.__name__,e.__class__.__name__) except Exception, e: print "! failed:",e print "\ finished" print import os if os.path.isfile("/home/ast1/blabla"): try: s = open("/home/ast1/blabla","r").read() e = cPickle.loads(s) print e.__class__ except Exception, e: print "error:",e test(Exception1,[1]) test(Exception2,[1]) test(Exception_with_reduce,[1]) ------------------------------------------ ------------------------------------------ run results on python 2.6: ------------------------------------------ constructor called <class '__main__.Exception2'> >> Exception1 constructor called - pickling - unpickling ! failed: ('__init__() takes exactly 2 arguments (1 given)', <class '__main__.Exception1'>, ()) \ finished >> Exception2 constructor called - pickling - unpickling constructor called \ finished >> Exception_with_reduce constructor called - pickling - unpickling ! failed: expected Exception_with_reduce, got Exception \ finished ------------------------------------------ run results on python 2.4: ------------------------------------------ __main__.Exception2 >> Exception1 constructor called - pickling - unpickling \ finished >> Exception2 constructor called - pickling - unpickling \ finished >> Exception_with_reduce constructor called - pickling - unpickling \ finished
-- http://mail.python.org/mailman/listinfo/python-list