Exception classes don't follow pickle protocol, problems unpickling

Peter Otten __peter__ at web.de
Mon Dec 7 04:12:38 EST 2009


Irmen de Jong wrote:

> I am puzzled why Python's exception classes don't seem to follow the
> pickle protocol. To be more specific: an instance of a user defined
> exception, subclassed from Exception, cannot be pickled/unpickled
> correctly in the expected way.
> 
> The pickle protocol says that:
> __getinitargs__ is used if you want __init__ to be called for old-style
> classes __getnewargs__ is used if you want to pass params to __new__ for
> new-style classes __getstate__ is used to determine what to pickle instead
> of the objects __dict__
> 
> None of these are used when pickling Exception objects!
> I've pasted some test code at the end of this message that creates a
> normal object and an object derived from Exception, and pickles them both.
> Then it unpickles them. The output is:


> So there are 2 problems: the pickle protocol isn't used when exception
> objects (or instances of classes derived from Exception) are pickled, and
> during unpickling, it then
> crashes because it calls __init__  with the wrong amount of parameters.
> (why is it bothering with __init__ anyway? Aren't exceptions new style
> classes?)

The __reduce__() method is called when you pickle an object. It returns an 
argument tuple and a factory. For exceptions that factory is the class which 
is why __init__() is called when the object is unpickled.

> This started happening in Python 2.5, Python 2.4 works without error.
> 
> What is causing this? 

I think Exceptions need special treatment because they have state that is 
not stored in the instance __dict__.

> How can I best solve this error?

You could override __reduce__() to call __getstate__(). I don't see the need 
for __getnewargs__() because exceptions aren't immutable.

Peter



More information about the Python-list mailing list