[Python-Dev] Unbinding of methods (original) (raw)

Richard Oudkerk shibturn at gmail.com
Thu Jul 19 21:51:39 CEST 2012


On 19/07/2012 7:54pm, Antoine Pitrou wrote:

Instead of a specific opcode, can't you use a suitable reduce magic (or getnewargs, perhaps)? We want to limit the number of opcodes except for performance-critical types (and I don't think bound methods are performance-critical for the purpose of serialization).

The one wrinkle is that BuiltinFunctionType is special cased to be pickled with save_global, and has no fallback to reduce/reduce_ex/copyreg. (The C implementation for FunctionType does have such a fallback, whereas the Python implementation doesn't -- see bug http://bugs.python.org/issue14336.)

If the fallback is added for BuiltinFunctionType then "reduce magic" should be enough.

The following code works as expected:

import pickle import copyreg

class A(object): def f(self): pass @classmethod def g(cls): pass

def f(self): pass

ClassMethodDescriptorType = type(A.g) BuiltinFunctionType = type(len) FunctionType = type(f) MethodType = type(A().f) MethodDescriptorType = type(list.append) WrapperDescriptorType = type(list.add) MethodWrapperType = type([].add)

obj_list = [A.g, len, f, A().f, list.append, list.add, [].add]

assert ClassMethodDescriptorType is MethodType

def reduce_self(self): return getattr, (self.self, self.name)

def reduce_objclass(self): return getattr, (self.objclass, self.name)

copyreg.pickle(MethodType, reduce_self) copyreg.pickle(BuiltinFunctionType, reduce_self) copyreg.pickle(MethodWrapperType, reduce_self) copyreg.pickle(MethodDescriptorType, reduce_objclass) copyreg.pickle(WrapperDescriptorType, reduce_objclass)

for obj in obj_list: data = pickle.dumps(obj) new_obj = pickle.loads(data) print('%s\n%s\n' % (obj, new_obj))



More information about the Python-Dev mailing list