Marc-Andre Lemburg's patch to support instance methods with other
callable objects than regular Pythonm functions as their im_func.
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 @@
 	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 @@
 	PyObject *class;
 {
 	register PyMethodObject *im;
-	if (!PyFunction_Check(func)) {
+	if (!PyCallable_Check(func)) {
 		PyErr_BadInternalCall();
 		return NULL;
 	}
@@ -1506,15 +1506,11 @@
 {
 	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 @@
 {
 	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 @@
 			}
 			arg = newarg;
 		}
+		if (!PyFunction_Check(func)) {
+			result = PyEval_CallObjectWithKeywords(func, arg, kw);
+			Py_DECREF(arg);
+			return result;
+		}
 	}
 	else {
 		if (!PyFunction_Check(func)) {