Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #28404 > unrolled thread
| Started by | Mathieu Courtois <mathieu.courtois@gmail.com> |
|---|---|
| First post | 2012-09-04 08:57 -0700 |
| Last post | 2012-09-05 03:18 -0700 |
| Articles | 6 — 3 participants |
Back to article view | Back to comp.lang.python
Why derivated exception can not be pickled ? Mathieu Courtois <mathieu.courtois@gmail.com> - 2012-09-04 08:57 -0700
Re: Why derivated exception can not be pickled ? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-09-05 00:34 +0000
Re: Why derivated exception can not be pickled ? Dieter Maurer <dieter@handshake.de> - 2012-09-05 08:02 +0200
Re: Why derivated exception can not be pickled ? Mathieu Courtois <mathieu.courtois@gmail.com> - 2012-09-05 01:54 -0700
Re: Why derivated exception can not be pickled ? Mathieu Courtois <mathieu.courtois@gmail.com> - 2012-09-05 01:54 -0700
Re: Why derivated exception can not be pickled ? Mathieu Courtois <mathieu.courtois@gmail.com> - 2012-09-05 03:18 -0700
| From | Mathieu Courtois <mathieu.courtois@gmail.com> |
|---|---|
| Date | 2012-09-04 08:57 -0700 |
| Subject | Why derivated exception can not be pickled ? |
| Message-ID | <7bb72fb5-5ab5-4748-acbf-c8e7666ee834@googlegroups.com> |
Here is my example :
import cPickle
ParentClass = object # works
ParentClass = Exception # does not
class MyError(ParentClass):
def __init__(self, arg):
self.arg = arg
def __getstate__(self):
print '#DBG pass in getstate'
odict = self.__dict__.copy()
return odict
def __setstate__(self, state):
print '#DBG pass in setstate'
self.__dict__.update(state)
exc = MyError('IDMESS')
fo = open('pick.1', 'w')
cPickle.dump(exc, fo)
fo.close()
fo = open('pick.1', 'r')
obj = cPickle.load(fo)
fo.close()
1. With ParentClass=object, it works as expected.
2. With ParentClass=Exception, __getstate__/__setstate__ are not called.
Does anyone explain me why ?
Thanks.
[toc] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-09-05 00:34 +0000 |
| Message-ID | <50469e1f$0$29981$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #28404 |
On Tue, 04 Sep 2012 08:57:00 -0700, Mathieu Courtois wrote: > Here is my example : > > > import cPickle > > ParentClass = object # works > ParentClass = Exception # does not [...] > 1. With ParentClass=object, it works as expected. > > 2. With ParentClass=Exception, __getstate__/__setstate__ are not called. > > Does anyone explain me why ? I think it is a bug. According to the documentation, if your class is unpickleable, an exception should be raised. If it is pickleable, __getstate__ should be called. I can't see anything to explain that what you are seeing is expected behaviour. Exceptions should definitely be pickleable: http://bugs.python.org/issue1692335 so __getstate__ should be called. I think you should report this as a bug. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Dieter Maurer <dieter@handshake.de> |
|---|---|
| Date | 2012-09-05 08:02 +0200 |
| Message-ID | <mailman.211.1346824947.27098.python-list@python.org> |
| In reply to | #28404 |
Mathieu Courtois <mathieu.courtois@gmail.com> writes:
> Here is my example :
>
>
> import cPickle
>
> ParentClass = object # works
> ParentClass = Exception # does not
>
> class MyError(ParentClass):
> def __init__(self, arg):
> self.arg = arg
>
> def __getstate__(self):
> print '#DBG pass in getstate'
> odict = self.__dict__.copy()
> return odict
>
> def __setstate__(self, state):
> print '#DBG pass in setstate'
> self.__dict__.update(state)
>
> exc = MyError('IDMESS')
>
> fo = open('pick.1', 'w')
> cPickle.dump(exc, fo)
> fo.close()
>
> fo = open('pick.1', 'r')
> obj = cPickle.load(fo)
> fo.close()
>
>
> 1. With ParentClass=object, it works as expected.
>
> 2. With ParentClass=Exception, __getstate__/__setstate__ are not called.
The pickle interface is actually more complex and there are several
ways an object can ensure picklability. For example, there is
also a "__reduce__" method. I suppose, that "Exception" defines methods
which trigger the use of an alternative picklability approach (different
from "__getstate__/__setstate__").
I would approach your case the following way: Use "pickle" instead
of "cPickle" and debug picking/unpickling to find out what
happens in detail.
[toc] | [prev] | [next] | [standalone]
| From | Mathieu Courtois <mathieu.courtois@gmail.com> |
|---|---|
| Date | 2012-09-05 01:54 -0700 |
| Message-ID | <f8fdaa79-5a58-4738-b18a-1df3f47abcba@googlegroups.com> |
| In reply to | #28454 |
Thanks for your reply On Wednesday, September 5, 2012 8:02:55 AM UTC+2, Dieter Maurer wrote: > > The pickle interface is actually more complex and there are several > > ways an object can ensure picklability. For example, there is > > also a "__reduce__" method. I suppose, that "Exception" defines methods > > which trigger the use of an alternative picklability approach (different > > from "__getstate__/__setstate__"). You're right: Exception has __reduce__ & __reduce_ex__ methods. Always read carefully the manual ;-) I must override these methods. MC
[toc] | [prev] | [next] | [standalone]
| From | Mathieu Courtois <mathieu.courtois@gmail.com> |
|---|---|
| Date | 2012-09-05 01:54 -0700 |
| Message-ID | <mailman.224.1346835264.27098.python-list@python.org> |
| In reply to | #28454 |
Thanks for your reply On Wednesday, September 5, 2012 8:02:55 AM UTC+2, Dieter Maurer wrote: > > The pickle interface is actually more complex and there are several > > ways an object can ensure picklability. For example, there is > > also a "__reduce__" method. I suppose, that "Exception" defines methods > > which trigger the use of an alternative picklability approach (different > > from "__getstate__/__setstate__"). You're right: Exception has __reduce__ & __reduce_ex__ methods. Always read carefully the manual ;-) I must override these methods. MC
[toc] | [prev] | [next] | [standalone]
| From | Mathieu Courtois <mathieu.courtois@gmail.com> |
|---|---|
| Date | 2012-09-05 03:18 -0700 |
| Message-ID | <daed0eb8-6100-4d05-b5b1-4d8ea56ac731@googlegroups.com> |
| In reply to | #28404 |
Hello,
The simple example works fine using __reduce__:
class MyError(Exception):
def __init__(self, arg):
self.arg = arg
def __reduce__(self):
return (MyError, (self.arg, ))
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web