Graham Dumpleton added the comment:

The classmethod __get__() method does:

static PyObject *
cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
{
    classmethod *cm = (classmethod *)self;

    if (cm->cm_callable == NULL) {
        PyErr_SetString(PyExc_RuntimeError,
                        "uninitialized classmethod object");
        return NULL;
    }
    if (type == NULL)
        type = (PyObject *)(Py_TYPE(obj));
    return PyMethod_New(cm->cm_callable,
                        type, (PyObject *)(Py_TYPE(type)));
}

So it isn't intentionally calling __call__(). If it still doing binding, but 
doing it by calling PyMethod_New() rather than using __get__() on the wrapped 
function. Where it wraps a regular function the result is same as if __get__() 
was called as __get__() for a regular function internally calls PyMethod_New() 
in the same way.

static PyObject *
func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
{
    if (obj == Py_None)
        obj = NULL;
    return PyMethod_New(func, obj, type);
}

By not using __get__(), you deny the ability to have chained decorators that 
want/need the knowledge of the fact that binding was being done. The result for 
stacking multiple decorators which use regular functions (closures) is exactly 
the same, but you open up other possibilities of smarter decorators.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue19072>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to