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)) _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com