Marc-Andre Lemburg's patch to support instance methods with other
callable objects than regular Pythonm functions as their im_func.
This commit is contained in:
parent
bb71ab68f9
commit
7859f87fdb
@ -71,11 +71,23 @@ new_instancemethod(unused, args)
|
|||||||
PyObject* self;
|
PyObject* self;
|
||||||
PyObject* classObj;
|
PyObject* classObj;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O!O!O!",
|
if (!PyArg_ParseTuple(args, "OOO!",
|
||||||
&PyFunction_Type, &func,
|
&func,
|
||||||
&PyInstance_Type, &self,
|
&self,
|
||||||
&PyClass_Type, &classObj))
|
&PyClass_Type, &classObj))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (!PyCallable_Check(func)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"first argument must be callable");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (self == Py_None)
|
||||||
|
self = NULL;
|
||||||
|
else if (!PyInstance_Check(self)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"second argument must be instance or None");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return PyMethod_New(func, self, classObj);
|
return PyMethod_New(func, self, classObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1428,7 +1428,7 @@ PyMethod_New(func, self, class)
|
|||||||
PyObject *class;
|
PyObject *class;
|
||||||
{
|
{
|
||||||
register PyMethodObject *im;
|
register PyMethodObject *im;
|
||||||
if (!PyFunction_Check(func)) {
|
if (!PyCallable_Check(func)) {
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1506,15 +1506,11 @@ instancemethod_getattr(im, name)
|
|||||||
{
|
{
|
||||||
char *sname = PyString_AsString(name);
|
char *sname = PyString_AsString(name);
|
||||||
if (sname[0] == '_') {
|
if (sname[0] == '_') {
|
||||||
PyFunctionObject *func = (PyFunctionObject *)(im->im_func);
|
/* Inherit __name__ and __doc__ from the callable object
|
||||||
if (strcmp(sname, "__name__") == 0) {
|
implementing the method */
|
||||||
Py_INCREF(func->func_name);
|
if (strcmp(sname, "__name__") == 0 ||
|
||||||
return func->func_name;
|
strcmp(sname, "__doc__") == 0)
|
||||||
}
|
return PyObject_GetAttr(im->im_func, name);
|
||||||
if (strcmp(sname, "__doc__") == 0) {
|
|
||||||
Py_INCREF(func->func_doc);
|
|
||||||
return func->func_doc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (PyEval_GetRestricted()) {
|
if (PyEval_GetRestricted()) {
|
||||||
PyErr_SetString(PyExc_RuntimeError,
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
@ -1550,20 +1546,29 @@ instancemethod_repr(a)
|
|||||||
{
|
{
|
||||||
char buf[240];
|
char buf[240];
|
||||||
PyInstanceObject *self = (PyInstanceObject *)(a->im_self);
|
PyInstanceObject *self = (PyInstanceObject *)(a->im_self);
|
||||||
PyFunctionObject *func = (PyFunctionObject *)(a->im_func);
|
PyObject *func = a->im_func;
|
||||||
PyClassObject *class = (PyClassObject *)(a->im_class);
|
PyClassObject *class = (PyClassObject *)(a->im_class);
|
||||||
PyObject *fclassname, *iclassname, *funcname;
|
PyObject *fclassname, *iclassname, *funcname;
|
||||||
char *fcname, *icname, *fname;
|
char *fcname, *icname, *fname;
|
||||||
fclassname = class->cl_name;
|
fclassname = class->cl_name;
|
||||||
funcname = func->func_name;
|
if (PyFunction_Check(func)) {
|
||||||
|
funcname = ((PyFunctionObject *)func)->func_name;
|
||||||
|
Py_INCREF(funcname);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
funcname = PyObject_GetAttrString(func,"__name__");
|
||||||
|
if (funcname == NULL)
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
if (funcname != NULL && PyString_Check(funcname))
|
||||||
|
fname = PyString_AS_STRING(funcname);
|
||||||
|
else
|
||||||
|
fname = "?";
|
||||||
|
Py_XDECREF(funcname);
|
||||||
if (fclassname != NULL && PyString_Check(fclassname))
|
if (fclassname != NULL && PyString_Check(fclassname))
|
||||||
fcname = PyString_AsString(fclassname);
|
fcname = PyString_AsString(fclassname);
|
||||||
else
|
else
|
||||||
fcname = "?";
|
fcname = "?";
|
||||||
if (funcname != NULL && PyString_Check(funcname))
|
|
||||||
fname = PyString_AsString(funcname);
|
|
||||||
else
|
|
||||||
fname = "?";
|
|
||||||
if (self == NULL)
|
if (self == NULL)
|
||||||
sprintf(buf, "<unbound method %.100s.%.100s>", fcname, fname);
|
sprintf(buf, "<unbound method %.100s.%.100s>", fcname, fname);
|
||||||
else {
|
else {
|
||||||
|
@ -2432,6 +2432,11 @@ call_function(func, arg, kw)
|
|||||||
}
|
}
|
||||||
arg = newarg;
|
arg = newarg;
|
||||||
}
|
}
|
||||||
|
if (!PyFunction_Check(func)) {
|
||||||
|
result = PyEval_CallObjectWithKeywords(func, arg, kw);
|
||||||
|
Py_DECREF(arg);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!PyFunction_Check(func)) {
|
if (!PyFunction_Check(func)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user