summaryrefslogtreecommitdiff
path: root/Modules/_functoolsmodule.c
diff options
context:
space:
mode:
authorJack Diederich <jackdied@gmail.com>2009-04-01 04:27:09 +0000
committerJack Diederich <jackdied@gmail.com>2009-04-01 04:27:09 +0000
commit538ae13cb6d975d438cee6daad05b7fb4e04c069 (patch)
tree6bf6de6f7f8f5db8c868a815b34c6e65348b8643 /Modules/_functoolsmodule.c
parentc1bf1b33c021918ab777caffd65401aa7632f8e3 (diff)
downloadcpython-538ae13cb6d975d438cee6daad05b7fb4e04c069.tar.gz
Merged revisions 70931 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r70931 | jack.diederich | 2009-03-31 19:46:48 -0400 (Tue, 31 Mar 2009) | 1 line #5228: add pickle support to functools.partial ........
Diffstat (limited to 'Modules/_functoolsmodule.c')
-rw-r--r--Modules/_functoolsmodule.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c
index 369eb5cc5a..5f389a9589 100644
--- a/Modules/_functoolsmodule.c
+++ b/Modules/_functoolsmodule.c
@@ -196,6 +196,53 @@ static PyGetSetDef partial_getsetlist[] = {
{NULL} /* Sentinel */
};
+/* Pickle strategy:
+ __reduce__ by itself doesn't support getting kwargs in the unpickle
+ operation so we define a __setstate__ that replaces all the information
+ about the partial. If we only replaced part of it someone would use
+ it as a hook to do stange things.
+ */
+
+PyObject *
+partial_reduce(partialobject *pto, PyObject *unused)
+{
+ return Py_BuildValue("O(O)(OOOO)", Py_TYPE(pto), pto->fn, pto->fn,
+ pto->args, pto->kw,
+ pto->dict ? pto->dict : Py_None);
+}
+
+PyObject *
+partial_setstate(partialobject *pto, PyObject *args)
+{
+ PyObject *fn, *fnargs, *kw, *dict;
+ if (!PyArg_ParseTuple(args, "(OOOO):__setstate__",
+ &fn, &fnargs, &kw, &dict))
+ return NULL;
+ Py_XDECREF(pto->fn);
+ Py_XDECREF(pto->args);
+ Py_XDECREF(pto->kw);
+ Py_XDECREF(pto->dict);
+ pto->fn = fn;
+ pto->args = fnargs;
+ pto->kw = kw;
+ if (dict != Py_None) {
+ pto->dict = dict;
+ Py_INCREF(dict);
+ } else {
+ pto->dict = NULL;
+ }
+ Py_INCREF(fn);
+ Py_INCREF(fnargs);
+ Py_INCREF(kw);
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef partial_methods[] = {
+ {"__reduce__", (PyCFunction)partial_reduce, METH_NOARGS},
+ {"__setstate__", (PyCFunction)partial_setstate, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
static PyTypeObject partial_type = {
PyVarObject_HEAD_INIT(NULL, 0)
"functools.partial", /* tp_name */
@@ -226,7 +273,7 @@ static PyTypeObject partial_type = {
offsetof(partialobject, weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
- 0, /* tp_methods */
+ partial_methods, /* tp_methods */
partial_memberlist, /* tp_members */
partial_getsetlist, /* tp_getset */
0, /* tp_base */