[issue1692335] Fix exception pickling: Move initial args assignment to BaseException.__new__
report at bugs.python.org
Wed Sep 22 20:39:42 CEST 2010
Alexander Belopolsky <belopolsky at users.sourceforge.net> added the comment:
On Wed, Sep 22, 2010 at 9:39 AM, Jason R. Coombs <report at bugs.python.org> wrote:
> .. It appears __getinitargs__ does not work on Python 2.5 or Python 2.7.
Yes, __getinitargs__ is only used for old style classes. I was
wrong on that point.
> Exceptions of the following class still raise a TypeError on unpickling:
> class D(Exception):
> """Extension with values, init called with no args."""
> def __init__(self, foo):
> self.foo = foo
> def __getinitargs__(self):
> return self.foo,
The problem with your D class is that it does not provide correct args
attribute which is expected from an exception class:
> Using __reduce__ does seem to work. I suspect this is because Exceptions are extension types.
There are two ways to fix this class. Both fix the args issue as well:
1. Pass foo to Exception.__init__ like this: Exception.__init__(self,
foo) in D.__init__.
2. Explicitly initialize self.args: self.args = foo,
> I think the fundamental problem is that pickling exceptions does not follow the principle of least surprise. In particular:
> - Other built-in objects (dicts, lists, etc) don't require special handling (replace Exception with dict in the above example and it works).
Other built-in objects don't provide an API for retrieving their init arguments.
> - It's not obvious how to write an Exception subclass that takes additional arguments and make it pickleable.
AFAICT, this is python subclassing 101: if base class __init__ uses
arguments, they should be passed to it by subclass' __init__.
> - Neither the pickle documentation nor the Exception documentation describe how pickling is implemented in Exceptions.
Exception documentation may be improved by adding a section on
subclassing. Note that the args argument was not even mentioned in
2.7 documentation, so some discussion of its role may be helpful
> Eric has provided some good use cases. Furthermore, it seems counter-intuitive to me to pass a subclass' custom
> arguments to the parent class. Indeed, even the official tutorial defines exception classes that are unpickleable
Well, the tutorial examples should probably be changed. In these
examples base class __init__ is not called at all which is probably
not a good style.
> If the use case is obvious enough that it shows up in the hello world tutorial, I don't think
> there should be any argument that it's not a common use case.
I am not arguing against simplifying Exception subclassing. I just
don't see an easy solution that would not promote subclasses with
unusable args attribute. I also disagree with this issue classified
as a bug. It may be a valid feature request, but not a bug.
In any case, no proponent of this feature has come up with a patch for
3.2 so far and in my view, this would be a prerequisite for moving
> At the very least, there should be a section in the pickle documentation or Exception
> documentation describing how one should make a pickleable subclass. ..
I agree, but again someone has to step in to write such section.
Improving documentation may also be the only solution for the 2.x
Python tracker <report at bugs.python.org>
More information about the Python-bugs-list