mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	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
					
				
					 3 changed files with 41 additions and 19 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Guido van Rossum
						Guido van Rossum