[Python-3000] Generic function PEP won't make it in time
Guido van Rossum
guido at python.org
Thu Apr 26 06:07:58 CEST 2007
On 4/25/07, Emin.shopper Martinian.shopper <emin.shopper at gmail.com> wrote:
> Sure. Below is a slightly modified example from the doctest:
> >>> class AbstractCar(AbstractBaseClass): # inherit from AbstractBaseClass
> to make something abstract
> ... @Abstract
> ... def Drive(self,x): pass
> To make a class abstract, you inherit from AbstractBaseClass in order to get
> the metaclass set properly and then use a function decorator to declare
> methods abstract. This is similar to the proposed implementation in your
> abc.py and equally pythonic or unpythonic. The following shows what happens
> when you define a class that doesn't override the abstract methods:
> >>> try: # illustrate what happens when you don't implement @Abstract
> ... class fails(AbstractCar): # an erroneous implementation of
> ... pass
> ... except AssertionError, e: # doctest: +ELLIPSIS
> ... print e
> Class <class '...fails'> must override Drive to implement:
> [<class '...AbstractCar'>].
> The exception gets raised at definition time because the __call__ method of
> the metaclass inherited from AbstractBaseClass checks whether abstract
> methods have been implemented. In your implementation, you use the __new__
> method of the metaclass to do the check at instantiation. If desired you
> could enable/disable checking at definition and instantiation separately.
Well I like the PEP's approach better (and AFAIK it matches what C++
does). In the PEP, it is not an error to inherit from an abstract
class -- the resulting class itself is abstract.
In your version one has to repeat "AbstractBaseClass" each time a
class contains (or inherits) abstract methods. I find that an
unpythonic requirement, bordering on the repetition of the same
information that is so common to statically typed languages.
(Note that the PEP now proposes @abstractmethod as a builtin and the
Abstract[Class] functionality merged into object and type; I already
have an implementation, referenced in the PEP's References section.)
> In summary, let me try to clarify what I see as the only incompatibility
> between the current PEP and an ABC implementation: with def time checks
> turned on you would need partial abstractions like Set to somehow indicate
> that they are abstract by either inheriting directly from AbstractBaseClass
> or defining at least one abstract method. If people don't like that, then I
> don't have any response. But if people are worried about B&D and other
> things, I think those are non-issues. B&D at runtime is no better than B&D
> at def time (I think B&D at runtime is worse).
You summarize the differences clearly. Let's agree to disagree. I
think that having to have an abstraction marker on the class *and* on
the abstract methods is asking the user to repeat (nearly) the same
information twice, and I really don't think that a (partially)
abstract class needs to be re-marked as abstract.
I find it hard to believe that the definition-time error saves you
much development time at all compared to a instantiation-time error.
Others have already responded to your attitude towards unit tests --
if your unit tests take 10 minutes to run, you're doing something else
wrong. May I suggest you read this:
PS. My implementation costs one flag bit check and jump on each object
allocation, which surely vanishes compared to the rest of the
allocation cost (and if not, it could be shrunk even further by
substituting a different function for tp_alloc).
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-3000