[Python-3000] pep 3124 plans

Phillip J. Eby pje at telecommunity.com
Fri Jul 20 19:45:54 CEST 2007


At 07:49 AM 7/20/2007 -0700, Guido van Rossum wrote:
>On 7/19/07, Joe Smith <unknown_kev_cat at hotmail.com> wrote:
> > So the state of the PEP? From the rest of the posts so far,
> > it sounds like there is no real objection to the basic end user API as
> > described in the PEP,
>
>Actually I want to reserve judgment on that until the PEP is rewritten
>to explain and document the underlying mechanisms. It is currently
>impossible (for me, anyway) to understand how the machinery to support
>the described features could be built. Without that I cannot approve
>the PEP. Phillip knows this but is too busy to work on it.

Actually, I was under the impression you didn't want the API 
described in the PEP, and wanted the following changes in addition to 
dropping method combination, aspects, and interfaces:

* :next_method as a keyword-only argument

* @somegeneric.overload as the standard decorator (w/no @overload or @when)

* advance declaration of a function as overloadable (which is also 
required by the previous change and by your preference not to modify 
functions in-place)

Also, I didn't know you wanted an explanation of how the underlying 
mechanisms work in general.  I thought the only piece you were 
looking for more explanation of was the method combination machinery 
-- which would be moot if we're scaling back the API as described by the above.

Just to be sure I'm clear as to what you want, is that the only 
mechanism you're unclear on, or is the whole thing unclear?  The 
whole thing was inspired by your overloading prototype, I've just 
made all the concrete bits of it more... "generic".

That is, instead of using issubclass or other explicit relationship 
tests between overload signatures, I use a generic function 
implies().  Instead of simply storing a method added as an overload, 
I use a "combine_actions()" generic function to combine it with any 
method that's already there (possibly including a method type for "No 
Method Found").  Instead of simply finding the most-specific matching 
signature on cache misses, I use combine_actions() to combine *all 
applicable* actions (i.e., all those that the calling signature implies()).

The combine_actions() function uses another generic function, 
overrides(), to compare method priorities.  overrides() is defined so 
that Around beats Before beats After beats regular methods beats no 
method found.  The overrides() of two methods of the same type is 
determined by which signature implies() the other, without also being 
implied *by* the other.

If there is no overrides() order between two methods, you get an 
AmbiguousMethod combining the two -- which can be overridden by any 
method whose signature implies() everything in the AmbiguousMethod.

All this is pretty much the same as in your prototype, except that 
it's done by adding these rules to the generic functions, rather than 
by hardcoding them.  That's why it's bigger than your prototype, but 
also why it's extensible in terms of adding new method types or ways 
to specify signatures.

I then also added the ability to attach different dispatchers to a 
function, so that you could replace the simple "tuple of types" 
matching with more sophisticated engines like RuleDispatch's, while 
still retaining the ability to use the same method combinations and 
existing overloads registered for a function.

That is, it lets you keep the same API for defining overloads and 
method combinations as the basic implementation, while allowing the 
actual overload targets and dispatching mechanisms to vary.

That's pretty much it except for Aspects and Interfaces.  I've ended 
up making my Aspect implementation available separately in the 
ObjectRoles cheeseshop package, renaming them Roles instead of Aspects.

(And yes, I will add all the above explanation to the PEP.)


>AFAIK Phillip has declared that his implementation only uses (or could
>be made to only use) isinstance()/issubclass(), and the overriding of
>these two used by the ABCs is actually very convenient for the GF PEP.

Yep.  The overload of "implies(c1:type, c2:type)" is 
"issubclass".  "isinstance()" isn't used, since that would render 
your type-tuple caching strategy unusable.



More information about the Python-3000 mailing list