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