[PEAK] Missing pickling support for generic methods

PJ Eby pje at telecommunity.com
Fri Feb 1 22:00:49 EST 2013


On Fri, Feb 1, 2013 at 6:32 PM, Hervé Coatanhay
<herve.coatanhay at gmail.com> wrote:
> Hi,
>
> As a note, the `lock` issue occurs with stackless python, which allows
> instancemethod pickling. In standard cpython it is "TypeError: can't pickle
> instancemethod objects" obviously.

Try defining the method *outside* the class, then copying it inside, e.g.:

    @abstract
    def run(self, arg):
        pass

    class Test(object):
        run = run
        ...

This should cause the pickler to see the generic function as a global
function object rather than a standalone function.  Essentially, the
problem is that the function shouldn't be being pickled as a
standalone object with state, it should be pickled as a thing imported
from a particular module, so that when the pickle is loaded it just
imports the function rather than *recreating* the function.

If you're doing this a lot, you might be better off with a custom
reducer for methods, something like:

   class MethodWrapper(object):
       def __init__(self, inst, name):
            self.reduction = (getattr, (inst, name))
       def __reduce__(self):
            return self.reduction

Pickling a 'MethodWrapper(inst, methodname)' will create a pickle that
is loaded by fetching the named attribute from the (pickled) instance.

(Better still, write a version of this that you can register in the
copy_reg.dispatch_table as a custom handler for instance methods
within your program.)

In general, the workaround details are going to be highly specific to
the pickle implementation used; pickle and cPickle do things
differently, and if Stackless pickles methods, I imagine there are
even more differences.


More information about the PEAK mailing list