[issue1497] Patch to remove API to create new unbound methods
Georg Brandl added the comment: As far as I can see, not really. -- status: pending - closed __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1497 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1497] Patch to remove API to create new unbound methods
Christian Heimes added the comment: Georg, do we need more docs? -- assignee: tiran - georg.brandl __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1497 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1497] Patch to remove API to create new unbound methods
Guido van Rossum added the comment: Reducing priority and changing assignee since this is now just waiting for a doc update. -- assignee: gvanrossum - tiran priority: high - low __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1497 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1497] Patch to remove API to create new unbound methods
Christian Heimes added the comment: Guido van Rossum wrote: - Please clean up the comment in classobject.c starting with Method objects are used for one purposes: -- to begin with, one purposes is ungrammatical. Best to remove the (a) bullet and rephrase the whole thing more like Method objects are used for bound instance methods (...) Done - The error unbound methods are not supported sounds a bit strange; better rephrase more positive as self must not be None Done. Didn't I say that I'm not good with short, precise error messages? :) - There is still a comment left No, it is an unbound method. Is this code still reachable? I though all ways to set im_self to NULL/None are blocked? It's not longer reachable but I left it there to catch problems. It's gone now. - Is bug 1202533 still worth testing for in test_descr.py? I don't know that using a lambda reproduces the error condition that once existed. Removed - Do we really need im_class for anything any more? ISTM that the one place where it is still used (in method_repr), we could as well use the class of im_self. (And before you think of super() as a counter-argument: super() passes the object's class in rather than the class where the method is found (though this may be considered a bug). You are right. im_class can be substituted with __self__.__class__. I've also removed the class argument from PyMethod_New(). It's not required anymore. - I think that, like func_code - __code__, the im_xxx attributes should be renamed __xxx__. Done im_func - __func__ im_self - __self__ im_class - removed I've left the names in the struct untouched. The 'new' module claims to exist solely for backwards compatibility. If that's true, why are we adding to it? In any case, the _BoundCFunction() class is redundant -- you can just use the method type, which is easily accessed as any bound method's __class__ attribute. And is there a use case for an *unbound* C function? If not, you could replace boundcfunction() with just a call to the method type. How could a bind a builtin method to a class so that instance().builtin() gets self as first argument? In one unit test the builtin function id() is bound to a class: class Example: id = somemagic(id) Example().id() results in id(Example()) I can't get the same effect with MethodType because it binds only to instances, not to classes. Christian __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1497 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1497] Patch to remove API to create new unbound methods
Christian Heimes added the comment: I've committed the changes in r59189. The documentation still needs updates. I had only time to fix some of the docs. -- resolution: - fixed status: open - pending __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1497 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1497] Patch to remove API to create new unbound methods
Christian Heimes added the comment: The new patch adds new.boundcfunction as a replacement for new.instancemethod(id, None, cls). I'm going to add docs if you like the approach. Added file: http://bugs.python.org/file8810/py3k_remove_newunbound2.patch __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1497 __Index: Objects/classobject.c === --- Objects/classobject.c (Revision 59184) +++ 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(unbound method %V.%V, - klassname, defname, - funcname, defname); + if (self == NULL) { + PyErr_BadInternalCall(); + return NULL; + } else { /* XXX Shouldn't use repr()/%R here! */ result = PyUnicode_FromFormat(bound method %V.%V of %R, @@ -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/new.py ===
[issue1497] Patch to remove API to create new unbound methods
Georg Brandl added the comment: Note though that the new module was deprecated once... __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1497 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1497] Patch to remove API to create new unbound methods
Guido van Rossum added the comment: OK. Some code review comments: - Please clean up the comment in classobject.c starting with Method objects are used for one purposes: -- to begin with, one purposes is ungrammatical. Best to remove the (a) bullet and rephrase the whole thing more like Method objects are used for bound instance methods (...) - The error unbound methods are not supported sounds a bit strange; better rephrase more positive as self must not be None - There is still a comment left No, it is an unbound method. Is this code still reachable? I though all ways to set im_self to NULL/None are blocked? - Is bug 1202533 still worth testing for in test_descr.py? I don't know that using a lambda reproduces the error condition that once existed. Functional suggestions: - Do we really need im_class for anything any more? ISTM that the one place where it is still used (in method_repr), we could as well use the class of im_self. (And before you think of super() as a counter-argument: super() passes the object's class in rather than the class where the method is found (though this may be considered a bug). - I think that, like func_code - __code__, the im_xxx attributes should be renamed __xxx__. The 'new' module claims to exist solely for backwards compatibility. If that's true, why are we adding to it? In any case, the _BoundCFunction() class is redundant -- you can just use the method type, which is easily accessed as any bound method's __class__ attribute. And is there a use case for an *unbound* C function? If not, you could replace boundcfunction() with just a call to the method type. __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1497 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1497] Patch to remove API to create new unbound methods
Changes by Christian Heimes: -- components: Interpreter Core files: py3k_remove_newunbound.patch keywords: patch, py3k nosy: georg.brandl, tiran priority: high severity: normal status: open title: Patch to remove API to create new unbound methods versions: Python 3.0 Added file: http://bugs.python.org/file8805/py3k_remove_newunbound.patch __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1497 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com