[Python-Dev] instancemethod_getattro seems to be partially wrong
Guido van Rossum
guido at python.org
Tue Nov 18 01:04:20 EST 2003
> instancemethod_getattro
>
> does this:
>
> if (PyType_HasFeature(tp, Py_TPFLAGS_HAVE_CLASS)) {
> if (tp->tp_dict == NULL) {
> if (PyType_Ready(tp) < 0)
> return NULL;
> }
> descr = _PyType_Lookup(tp, name);
> }
>
> f = NULL;
> if (descr != NULL) {
> f = TP_DESCR_GET(descr->ob_type);
> if (f != NULL && PyDescr_IsData(descr))
> return f(descr, obj, (PyObject *)obj->ob_type);
> }
>
> [...] why does it ask for PyDescr_IsData ???
It's the general pattern: a data descriptor on the class can override
an attribute on the instance, but a method descriptor cannot. You'll
find this in PyObject_Generic{Get,Set}Attr() too, and in type_getattro().
This is so that if you define a method in a class, you can override it
by setting an instance variable of the same name; this was always
possible for classic classes and I don't see why it shouldn't work for
new-style classes. But it should also be possible to put a descriptor
on the class that takes complete control.
The case you quote is about delegating bound method attributes to
function attributes, but the same reasoning applies generally, I would
think: unless the descriptor is a data descriptor, the function
attribute should have precedence, IOW a function attribute should be
able to override a method on a bound instance.
Here's an example of the difference:
class C:
def f(s): pass
f.__repr__ = lambda: "42"
print C().f.__repr__()
This prints "42". If you comment out the PyDescr_IsData() call, it
will print "<bound method C.f of <__main__.C instance at 0x...>>".
I'm not entirely clear what goes wrong in your case.
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-Dev
mailing list