[Python-checkins] cpython: Make built-in methods picklable through the reduce protocol.

alexandre.vassalotti python-checkins at python.org
Sun Nov 24 11:41:30 CET 2013


http://hg.python.org/cpython/rev/24c84d00cf1f
changeset:   87493:24c84d00cf1f
user:        Alexandre Vassalotti <alexandre at peadrop.com>
date:        Sun Nov 24 02:41:05 2013 -0800
summary:
  Make built-in methods picklable through the reduce protocol.

files:
  Lib/pickle.py          |   9 +-------
  Modules/_pickle.c      |  32 ------------------------------
  Objects/methodobject.c |  22 +++++++++++++++++++-
  3 files changed, 22 insertions(+), 41 deletions(-)


diff --git a/Lib/pickle.py b/Lib/pickle.py
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -23,7 +23,7 @@
 
 """
 
-from types import FunctionType, BuiltinFunctionType, ModuleType
+from types import FunctionType, ModuleType
 from copyreg import dispatch_table
 from copyreg import _extension_registry, _inverted_registry, _extension_cache
 from itertools import islice
@@ -962,14 +962,7 @@
 
         self.memoize(obj)
 
-    def save_method(self, obj):
-        if obj.__self__ is None or type(obj.__self__) is ModuleType:
-            self.save_global(obj)
-        else:
-            self.save_reduce(getattr, (obj.__self__, obj.__name__), obj=obj)
-
     dispatch[FunctionType] = save_global
-    dispatch[BuiltinFunctionType] = save_method
     dispatch[type] = save_global
 
 
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -3514,34 +3514,6 @@
 }
 
 static int
-save_method(PicklerObject *self, PyObject *obj)
-{
-    PyObject *method_self = PyCFunction_GET_SELF(obj);
-
-    if (method_self == NULL || PyModule_Check(method_self)) {
-        return save_global(self, obj, NULL);
-    }
-    else {
-        PyObject *builtins;
-        PyObject *getattr;
-        PyObject *reduce_value;
-        int status = -1;
-        _Py_IDENTIFIER(getattr);
-
-        builtins = PyEval_GetBuiltins();
-        getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
-        reduce_value = \
-            Py_BuildValue("O(Os)", getattr, method_self,
-                          ((PyCFunctionObject *)obj)->m_ml->ml_name);
-        if (reduce_value != NULL) {
-            status = save_reduce(self, reduce_value, obj);
-            Py_DECREF(reduce_value);
-        }
-        return status;
-    }
-}
-
-static int
 save(PicklerObject *self, PyObject *obj, int pers_save)
 {
     PyTypeObject *type;
@@ -3652,10 +3624,6 @@
             goto done;
         }
     }
-    else if (type == &PyCFunction_Type) {
-        status = save_method(self, obj);
-        goto done;
-    }
 
     /* XXX: This part needs some unit tests. */
 
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -159,6 +159,26 @@
     }
 }
 
+static PyObject *
+meth_reduce(PyCFunctionObject *m)
+{
+    PyObject *builtins;
+    PyObject *getattr;
+    _Py_IDENTIFIER(getattr);
+
+    if (m->m_self == NULL || PyModule_Check(m->m_self))
+        return PyUnicode_FromString(m->m_ml->ml_name);
+
+    builtins = PyEval_GetBuiltins();
+    getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
+    return Py_BuildValue("O(Os)", getattr, m->m_self, m->m_ml->ml_name);
+}
+
+static PyMethodDef meth_methods[] = {
+    {"__reduce__", (PyCFunction)meth_reduce, METH_NOARGS, NULL},
+    {NULL, NULL}
+};
+
 /*
  * finds the docstring's introspection signature.
  * if present, returns a pointer pointing to the first '('.
@@ -394,7 +414,7 @@
     0,                                          /* tp_weaklistoffset */
     0,                                          /* tp_iter */
     0,                                          /* tp_iternext */
-    0,                                          /* tp_methods */
+    meth_methods,                               /* tp_methods */
     meth_members,                               /* tp_members */
     meth_getsets,                               /* tp_getset */
     0,                                          /* tp_base */

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list