[Python-Dev] Unbinding of methods
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