summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1998-07-08 14:58:16 (GMT)
committerGuido van Rossum <guido@python.org>1998-07-08 14:58:16 (GMT)
commit7859f87fdbcc0679aa6ed9c181ee3826002ac5ca (patch)
tree21deb8482707e62cf1b6a4d002c97d12a03eb3c3
parentbb71ab68f9c376a5cda676fa35713cea34783fc0 (diff)
downloadcpython-7859f87fdbcc0679aa6ed9c181ee3826002ac5ca.zip
cpython-7859f87fdbcc0679aa6ed9c181ee3826002ac5ca.tar.gz
cpython-7859f87fdbcc0679aa6ed9c181ee3826002ac5ca.tar.bz2
Marc-Andre Lemburg's patch to support instance methods with other
callable objects than regular Pythonm functions as their im_func.
-rw-r--r--Modules/newmodule.c18
-rw-r--r--Objects/classobject.c37
-rw-r--r--Python/ceval.c5
3 files changed, 41 insertions, 19 deletions
diff --git a/Modules/newmodule.c b/Modules/newmodule.c
index cfe7883..52328a9 100644
--- a/Modules/newmodule.c
+++ b/Modules/newmodule.c
@@ -71,11 +71,23 @@ new_instancemethod(unused, args)
PyObject* self;
PyObject* classObj;
- if (!PyArg_ParseTuple(args, "O!O!O!",
- &PyFunction_Type, &func,
- &PyInstance_Type, &self,
+ if (!PyArg_ParseTuple(args, "OOO!",
+ &func,
+ &self,
&PyClass_Type, &classObj))
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);
}
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 2154299..86fc1d3 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -1428,7 +1428,7 @@ PyMethod_New(func, self, class)
PyObject *class;
{
register PyMethodObject *im;
- if (!PyFunction_Check(func)) {
+ if (!PyCallable_Check(func)) {
PyErr_BadInternalCall();
return NULL;
}
@@ -1506,15 +1506,11 @@ instancemethod_getattr(im, name)
{
char *sname = PyString_AsString(name);
if (sname[0] == '_') {
- PyFunctionObject *func = (PyFunctionObject *)(im->im_func);
- if (strcmp(sname, "__name__") == 0) {
- Py_INCREF(func->func_name);
- return func->func_name;
- }
- if (strcmp(sname, "__doc__") == 0) {
- Py_INCREF(func->func_doc);
- return func->func_doc;
- }
+ /* Inherit __name__ and __doc__ from the callable object
+ implementing the method */
+ if (strcmp(sname, "__name__") == 0 ||
+ strcmp(sname, "__doc__") == 0)
+ return PyObject_GetAttr(im->im_func, name);
}
if (PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
@@ -1550,20 +1546,29 @@ instancemethod_repr(a)
{
char buf[240];
PyInstanceObject *self = (PyInstanceObject *)(a->im_self);
- PyFunctionObject *func = (PyFunctionObject *)(a->im_func);
+ PyObject *func = a->im_func;
PyClassObject *class = (PyClassObject *)(a->im_class);
PyObject *fclassname, *iclassname, *funcname;
char *fcname, *icname, *fname;
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))
fcname = PyString_AsString(fclassname);
else
fcname = "?";
- if (funcname != NULL && PyString_Check(funcname))
- fname = PyString_AsString(funcname);
- else
- fname = "?";
if (self == NULL)
sprintf(buf, "<unbound method %.100s.%.100s>", fcname, fname);
else {
diff --git a/Python/ceval.c b/Python/ceval.c
index 5aed5ff..d81f3fd 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2432,6 +2432,11 @@ call_function(func, arg, kw)
}
arg = newarg;
}
+ if (!PyFunction_Check(func)) {
+ result = PyEval_CallObjectWithKeywords(func, arg, kw);
+ Py_DECREF(arg);
+ return result;
+ }
}
else {
if (!PyFunction_Check(func)) {