[Python-3000] Generic function PEP won't make it in time (original) (raw)

Phillip J. Eby pje at telecommunity.com
Mon Apr 23 23:25:04 CEST 2007


At 04:52 PM 4/23/2007 -0400, Jim Jewett wrote:

On 4/23/07, Phillip J. Eby <pje at telecommunity.com> wrote:

At 11:43 AM 4/23/2007 -0700, Guido van Rossum wrote: >On 4/23/07, Phillip J. Eby <pje at telecommunity.com> wrote:

> > @abstract > > def spam(fizz): > > """This function has no default implementation, and raises > > a "no applicable methods" error if called...""" >(a) What's the point of having a separate keyword for this, as >opposed to just raising an exception from the body? EIBTI, mainly. Specifically, it's clear from the beginning that you're looking at an empty function -- i.e., one that can't be called successfully except for explicitly registered patterns -- versus one that has a truly "generic" base implementation. erm... not to me. To me it looks like any short function until I look carefully.

Which is precisely why @abstract is useful. Are you saying you don't want @abstract explicitly indicating that the function has no behavior?

I believe there was also another, somewhat more esoteric reason that gets involved when you build more sophisticated rulesystems on top of the base machinery, but the exact reason is escaping me at this moment. ... sort of like doing math without being able to write "zero": I think it had to do with nextmethod, and was the same problem super has. If you aren't sure the job is done -- no matter what you got mixed with -- then you have to call the next method. 99% of the time, it won't do anything useful, but you have to call it just in case. My favorite example is del(), or at least close(). I can be sure that I've cleaned up my scarce resources, but I don't know what subclasses might have mixed me in with. So I call super del, and catch the Exception when it turns out I wasn't mixed in at all. A "pass" default implementation is much nicer to subclasses than an Exception that they have to try...except.

Right. If you're defining a generic function as a hook, you would just define the function as a no-op -- i.e. NOT an @abstract function. (e.g., the "foo()" function in my previous post.)

> My point is, I could rename mine to @abstract so that it >would serve your purpose as well -- but only if it would serve.

Assuming that: 1. If you call such a function, it will raise some error, like NotImplementedError Note that your default methods don't do this either, except as part of the wrapper.

I don't understand what the sentence above means. I don't even understand it enough to misunderstand it. :)

Guido's current implementation is that

(a) An error is raised as soon as you try to instantiate a class that could call the method directly, even if you don't plan to ever actually call it. (b) The method itself is annotated, so that the rules engine could raise an error if it so chose.

Ah. I'm suggesting that a function object marked as abstract should also raise an exception (perhaps NotImplementedError) when it's actually called. @abstract could either change the function object's type, or set its func_code, or whatever else makes sense.

2. It's a normal function object (i.e., can have its funccode repointed later) 3. The isabstractmethod can be set back to False once there is other code registered I'm not sure that actually doing this would play well with ABC assumptions, but, yes, it is possible.

Since @overload requires a function of the same name to alread exist in the current namespace, you'll normally be doing this:

class Concrete(Abstract):

    def my_implementation_of_something_abstract(self, ...):
        """Default implementation"""

    @overload
    def my_implementation_of_something_abstract(self, ...):
        """This overloads *this* class' definition, not the ABC's"""

In any case, I don't really see any reason to add overloads to an ABC's abstract methods. The GF usage of @abstract is really only useful for standalone functions, at least as far as I can see.



More information about the Python-3000 mailing list