Message117149
On Wed, Sep 22, 2010 at 9:39 AM, Jason R. Coombs <report@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
> Exception.__init__(self)
>
> 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
somewhere.
> 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
> (http://docs.python.org/tutorial/errors.html#tut-userexceptions).
>
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
this forward.
> 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
series. |
|
Date |
User |
Action |
Args |
2010-09-22 18:39:42 | belopolsky | set | recipients:
+ belopolsky, gvanrossum, loewis, nnorwitz, brett.cannon, georg.brandl, facundobatista, jafo, ehuss, tseaver, jaraco, zseil, alexandre.vassalotti, jarpa, kylev |
2010-09-22 18:39:40 | belopolsky | link | issue1692335 messages |
2010-09-22 18:39:39 | belopolsky | create | |
|