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