Index: Objects/classobject.c =================================================================== --- Objects/classobject.c (Revision 59181) +++ Objects/classobject.c (Arbeitskopie) @@ -37,10 +37,9 @@ } -/* Method objects are used for two purposes: +/* Method objects are used for one purposes: (a) as bound instance methods (returned by instancename.methodname) - (b) as unbound methods (returned by ClassName.methodname) - In case (b), im_self is NULL + ClassName.methodname returns an ordinary function. */ static PyMethodObject *free_list; @@ -53,6 +52,10 @@ PyErr_BadInternalCall(); return NULL; } + if (self == NULL) { + PyErr_BadInternalCall(); + return NULL; + } im = free_list; if (im != NULL) { free_list = (PyMethodObject *)(im->im_self); @@ -86,7 +89,7 @@ {"im_func", T_OBJECT, OFF(im_func), READONLY|RESTRICTED, "the function (or other callable) implementing a method"}, {"im_self", T_OBJECT, OFF(im_self), READONLY|RESTRICTED, - "the instance to which a method is bound; None for unbound methods"}, + "the instance to which a method is bound"}, {NULL} /* Sentinel */ }; @@ -162,11 +165,9 @@ "first argument must be callable"); return NULL; } - if (self == Py_None) - self = NULL; - if (self == NULL && classObj == NULL) { + if (self == NULL || self == Py_None) { PyErr_SetString(PyExc_TypeError, - "unbound methods must have non-NULL im_class"); + "unbound methods are not supported"); return NULL; } @@ -253,10 +254,10 @@ klassname = NULL; } } - if (self == NULL) - result = PyUnicode_FromFormat("", - klassname, defname, - funcname, defname); + if (self == NULL) { + PyErr_BadInternalCall(); + return NULL; + } else { /* XXX Shouldn't use repr()/%R here! */ result = PyUnicode_FromFormat("", @@ -296,88 +297,16 @@ return 0; } -static void -getclassname(PyObject *klass, char *buf, int bufsize) -{ - PyObject *name; - - assert(bufsize > 1); - strcpy(buf, "?"); /* Default outcome */ - if (klass == NULL) - return; - name = PyObject_GetAttrString(klass, "__name__"); - if (name == NULL) { - /* This function cannot return an exception */ - PyErr_Clear(); - return; - } - if (PyUnicode_Check(name)) { - strncpy(buf, PyUnicode_AsString(name), bufsize); - buf[bufsize-1] = '\0'; - } - Py_DECREF(name); -} - -static void -getinstclassname(PyObject *inst, char *buf, int bufsize) -{ - PyObject *klass; - - if (inst == NULL) { - assert(bufsize > 0 && (size_t)bufsize > strlen("nothing")); - strcpy(buf, "nothing"); - return; - } - - klass = PyObject_GetAttrString(inst, "__class__"); - if (klass == NULL) { - /* This function cannot return an exception */ - PyErr_Clear(); - klass = (PyObject *)(inst->ob_type); - Py_INCREF(klass); - } - getclassname(klass, buf, bufsize); - Py_XDECREF(klass); -} - static PyObject * method_call(PyObject *func, PyObject *arg, PyObject *kw) { PyObject *self = PyMethod_GET_SELF(func); - PyObject *klass = PyMethod_GET_CLASS(func); PyObject *result; func = PyMethod_GET_FUNCTION(func); if (self == NULL) { - /* Unbound methods must be called with an instance of - the class (or a derived class) as first argument */ - int ok; - if (PyTuple_Size(arg) >= 1) - self = PyTuple_GET_ITEM(arg, 0); - if (self == NULL) - ok = 0; - else { - ok = PyObject_IsInstance(self, klass); - if (ok < 0) - return NULL; - } - if (!ok) { - char clsbuf[256]; - char instbuf[256]; - getclassname(klass, clsbuf, sizeof(clsbuf)); - getinstclassname(self, instbuf, sizeof(instbuf)); - PyErr_Format(PyExc_TypeError, - "unbound method %s%s must be called with " - "%s instance as first argument " - "(got %s%s instead)", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - clsbuf, - instbuf, - self == NULL ? "" : " instance"); - return NULL; - } - Py_INCREF(arg); + PyErr_BadInternalCall(); + return NULL; } else { Py_ssize_t argcount = PyTuple_Size(arg); @@ -412,14 +341,8 @@ } /* No, it is an unbound method */ if (PyMethod_GET_CLASS(meth) != NULL && cls != NULL) { - /* Do subclass test. If it fails, return meth unchanged. */ - int ok = PyObject_IsSubclass(cls, PyMethod_GET_CLASS(meth)); - if (ok < 0) - return NULL; - if (!ok) { - Py_INCREF(meth); - return meth; - } + PyErr_BadInternalCall(); + return NULL; } /* Bind it to obj */ return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj, cls); Index: Lib/test/test_descr.py =================================================================== --- Lib/test/test_descr.py (Revision 59183) +++ Lib/test/test_descr.py (Arbeitskopie) @@ -1867,7 +1867,7 @@ # Bug #1202533. class A(object): pass - A.__mul__ = new.instancemethod(lambda self, x: self * x, None, A) + A.__mul__ = lambda self, x: self * x try: A()*2 except RuntimeError: Index: Lib/test/test_funcattrs.py =================================================================== --- Lib/test/test_funcattrs.py (Revision 59183) +++ Lib/test/test_funcattrs.py (Arbeitskopie) @@ -106,9 +106,10 @@ # im_func may not be a Python method! import new -F.id = new.instancemethod(id, None, F) +F.id = id eff = F() +eff.id = new.instancemethod(id, eff, F) if eff.id() != id(eff): raise TestFailed