# HG changeset patch # Parent 53a2488605e30e3cbb3299c5f3f67f42bc08660a diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -18,6 +18,7 @@ PyObject *kw; PyObject *dict; PyObject *weakreflist; /* List of weak references */ + int bound; } partialobject; static PyTypeObject partial_type; @@ -67,6 +68,7 @@ pto->weakreflist = NULL; pto->dict = NULL; + pto->bound = 0; return (PyObject *)pto; } @@ -105,6 +107,15 @@ if (argappl == NULL) return NULL; } + if (pto->bound) { + Py_ssize_t self_pos = PyTuple_GET_SIZE(pto->args); + PyObject *self = PyTuple_GET_ITEM(argappl, self_pos); + Py_ssize_t pos; + for (pos = self_pos; pos > 0; pos--) { + PyTuple_SET_ITEM(argappl, pos, PyTuple_GET_ITEM(argappl, pos-1)); + } + PyTuple_SET_ITEM(argappl, 0, self); + } if (pto->kw == Py_None) { kwappl = kw; @@ -161,6 +172,34 @@ }; static PyObject * +partial_descr_get(partialobject *pto, PyObject *obj, PyObject *type) +{ + partialobject *bound_pto; + + if (obj == Py_None || obj == NULL || pto->bound) { + Py_INCREF(pto); + return (PyObject *)pto; + } + + bound_pto = (partialobject *)Py_TYPE(pto)->tp_alloc(Py_TYPE(pto), 0); + if (!bound_pto) + return NULL; + + bound_pto->fn = pto->fn; + Py_INCREF(bound_pto->fn); + bound_pto->args = pto->args; + Py_INCREF(bound_pto->args); + if (pto->kw) { + bound_pto->kw = pto->kw; + Py_INCREF(bound_pto->kw); + } + + bound_pto->bound = 1; + + return PyMethod_New((PyObject *)bound_pto, obj); +} + +static PyObject * partial_repr(partialobject *pto) { PyObject *result; @@ -284,7 +323,7 @@ partial_getsetlist, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ - 0, /* tp_descr_get */ + (descrgetfunc)partial_descr_get, /* tp_descr_get */ 0, /* tp_descr_set */ offsetof(partialobject, dict), /* tp_dictoffset */ 0, /* tp_init */