Pickling/Unpickling python Exceptions

Sergey Lukin lukin.s.v at gmail.com
Thu Jan 27 10:49:45 EST 2011


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20110127/a1318b05/attachment.html>


More information about the Python-list mailing list

AltStyle によって変換されたページ (->オリジナル) /