[Python-Dev] CALL_ATTR patch (was: 2.3b1 release)

Thomas Wouters thomas@xs4all.net
Thu, 17 Apr 2003 22:59:56 +0200

On Thu, Apr 17, 2003 at 11:53:01AM -0400, Guido van Rossum wrote:
> > Anyway, if anyone has straightforward ideas about how CALL_ATTR should
> > deal with newstyle classes (if at all), please inform me (preferably via
> > SF) or just grab the patch and run with it. I'm still confused about
> > descrgets and where they come from.

> Yes, please.  Here's a quick explanation of descriptors:

[ the descriptor describes descriptors ]

> Hope this helps!

Well, yes, in that it reminded me to stop looking for how functions get
turned into methods. That part is the same for old-style classes, though,
and not quite what I'm confused about. What the call_attr patch does is
shortcut the instance_getattr functions in a new function, to do just that
what is necessary (and no more.) _Py_instance_getmethod() returns NULL for
anything that isn't a method, too, letting the slow case handle it. When it
does find a would-be method, it returns the unwrapped function. The
call_attr function basically does a PyInstance_Check() and a
_Py_instance_getmethod(), and calls the returned function.

The problem I have with newstyle classes is where to shortcut what. I
understand now how to detect a would-be method, but I'm not sure how to get
unwrapped attributes. As far as I understand, types can provide their own
getattr function with complete control over descriptors, so there isn't much
to shortcut. Unless I should make the shortcut depend on the actual value of
tp_getattro, as in shortcut only if it actually is PyObject_GenericGetAttr ?
In that case, I'm somewhat sceptical about the speed benefit's cost in
maintenance, as it would require a near copy of PyObject_GenericGetAttr
(which is already a near-copy of a few other functions :) It's also very hard
to control any nested getattrs (possible, I think, because the process goes
over all bases' dicts and the instance dict.) Or can we reduce
the number of steps PyObject_GenericGetAttr goes through if we know we are
just looking for a method ? I don't believe so, but I'm not sure.

(Looking at PyObject_GenericGetAttr with that in mind, I wonder if there
isn't a possible crash there. In the first MRO lookup, looking for descr's,
if a non-data-descr is found, it is kept around but not INCREF'd until
later, after the instance-dict is searched. Am I wrong in believing the
PyDict_GetItem of the instance dict can call Python code ? There isn't even
as much as an assert(PyDict_Check(dict)) there.)

Thomas Wouters <thomas@xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!