[Python-checkins] r54946 - peps/trunk/pep-3119.txt
guido.van.rossum
python-checkins at python.org
Wed Apr 25 02:17:29 CEST 2007
Author: guido.van.rossum
Date: Wed Apr 25 02:17:23 2007
New Revision: 54946
Modified:
peps/trunk/pep-3119.txt
Log:
Add pointer to implementation of @abstractmethod in C.
Change ABC framework description to only mention @abstractmethod
and unconditionally propose it as a built-in.
Some more editorializing; explain why we have BasicMapping.
Modified: peps/trunk/pep-3119.txt
==============================================================================
--- peps/trunk/pep-3119.txt (original)
+++ peps/trunk/pep-3119.txt Wed Apr 25 02:17:23 2007
@@ -16,9 +16,9 @@
This is a proposal to add Abstract Base Class (ABC) support to Python
3000. It proposes:
-* An "ABC support framework" which defines a metaclass, a base class,
- a decorator, and some helpers that make it easy to define ABCs.
- This will be added as a new library module named "abc".
+* An "ABC support framework" which defines a built-in decorator that
+ can be used to define abstract methods. A class containing an
+ abstract method that isn't overridden cannot be instantiated.
* Specific ABCs for containers and iterators, to be added to the
collections module.
@@ -119,10 +119,10 @@
Specification
=============
-The specification follows the four categories listed in the abstract:
+The specification follows the categories listed in the abstract:
-* An "ABC support framework" which defines a metaclass, a base class,
- a decorator, and some helpers that make it easy to define ABCs.
+* An "ABC support framework" which defines a built-in decorator that
+ make it easy to define ABCs, and mechanisms to support it.
* Specific ABCs for containers and iterators, to be added to the
collections module.
@@ -131,58 +131,48 @@
ABC Support Framework
---------------------
-We define the following four new built-in objects that help defining
-ABCs:
+We define a new built-in decorator, ``@abstractmethod``, to be used to
+declare abstract methods. A class containing at least one method
+declared with this decorator that hasn't been overridden yet cannot be
+instantiated. Such a methods may be called from the overriding method
+in the subclass (using ``super`` or direct invocation). For example::
-``@abstractmethod``
- A decorator used to declare abstract methods. This should only be
- used with classes whose class is derived from ``Abstract`` below.
- A class containing at least one method declared with this
- decorator that hasn't been overridden yet cannot be instantiated.
- Such a methods may be called from the overriding method in the
- subclass (using ``super`` or direct invocation).
-
-``AbstractClass``
- A metaclass to be used with classes containing abstract methods.
- Classes whose metaclass is (or derives from) ``AbstractClass``
- cannot be instantiated unless all methods declared abstract using
- the ``@abstractmethod`` decorator have been overridden by concrete
- methods.
-
-``Abstract``
- An empty helper class whose metaclass is ``AbstractClass``. This
- only exists as a minor convenience; deriving a class from
- ``Abstract`` is the same as setting its metaclass to
- ``AbstractClass``.
-
-
-``AbstractInstantiationError``
- The exception raised when attempting to instantiate an abstract
- class. It derives from ``TypeError``.
-
-**Open issues:**
-
-* Implementing the prohibition on instantiation may weigh down
- instance creation of popular built-in classes like ``tuple`` or
- ``str``. Perhaps concrete built-in classes can use a shortcut; or
- perhaps there's a more efficient implementation.
-
-* Do we even need ``Abstract`` and ``AbstractClass``? Their
- functionality can be subsumed into ``object`` and ``type``,
- respectively.
+ class A:
+ @abstractmethod
+ def foo(self): pass
-* Even if we keep them separate, ``Abstract`` is quite unnecessary
- since there is hardly any difference in complexity between this::
+ A() # raises TypeError
- class C(metaclass=AbstractClass):
- @abstractmethod
- def foo(self): ...
+ class B(A):
+ pass
- and this::
+ B() # raises TypeError
- class C(Abstract):
- @abstractmethod
- def foo(self): ...
+ class C(A):
+ def foo(self): print(42)
+
+ C() # works
+
+**Implementation:** The ``@abstractmethod`` decorator sets the
+function attribute ``__isabstractmethod__`` to the value ``True``.
+The ``type.__new__`` method computes the type attribute
+``__abstractmethods__`` as the set of all method names that have an
+``__isabstractmethod__`` attribute whose value is true. It does this
+by combining the ``__abstractmethods__` attributes of the base
+classes, adding the names of all methods in the new class dict that
+have a true ``__isabstractmethod__`` attribute, and removing the names
+of all methods in the new class dict that don't have a true
+``__isabstractmethod__`` attribute. If the resulting
+``__abstractmethods__`` set is non-empty, the class is considered
+abstract, and attempts to instantiate it will raise ``TypeError``.
+(CPython can uses an internal flag ``Py_TPFLAGS_ABSTRACT`` to speed up
+this check [6]_.)
+
+**Discussion:** Unlike C++ or Java, abstract methods as defined here
+may have an implementation. This implementation can be called via the
+``super`` mechanism from the class that overrides it. This could be
+useful as an end-point for a super-call in framework using a
+cooperative multiple-inheritance [7]_, [8]_.
ABCs for Containers and Iterators
@@ -279,7 +269,7 @@
The abstract ``__len__`` method returns 0. **Invariant:** If a
class ``C`` derives from ``Sized`` as well as from ``Iterable``,
the invariant ``sum(1 for x in o) == len(o)`` should hold for any
- instance ``o`` of ``C``. **Open issue:** Is ``Sized`` the best
+ instance ``o`` of ``C``. **Open issues:** Is ``Sized`` the best
name? Proposed alternatives already tentatively rejected:
``Finite`` (nobody understood it), ``Lengthy``, ``Sizeable`` (both
too cute), ``Countable`` (the set of natural numbers is a
@@ -438,7 +428,16 @@
Mappings
''''''''
-These abstract classes represent various stages of mapping-ness.
+These abstract classes represent various stages of mapping-ness. The
+``Mapping`` class represents the most common read-only mapping API.
+However, code *accepting* a mapping is encouraged to check for the
+``BasicMapping`` ABC when iteration is not used. This allows for
+certain "black-box" implementations that can look up values by key but
+don't provide a convenient iteration API. A hypothetical example
+would be an interface to a hierarchical filesystem, where keys are
+pathnames relative to some root directory. Iterating over all
+pathnames would presumably take forever, as would counting the number
+of valid pathnames.
The built-in type ``dict`` derives from ``MutableMapping``.
@@ -488,10 +487,6 @@
**Open issues:**
-* Do we need both ``BasicMapping`` and ``Mapping``? We could just
- start with ``Mapping``; but I believe there's some use for a
- non-iterable mapping that nevertheless behaves like a basic mapping.
-
* We should say more about mapping view types.
@@ -545,8 +540,8 @@
**Open issues:** define the base interfaces for these so alternative
implementations and subclasses know what they are in for. This may be
-the subject of a new PEP or PEPs (maybe PEP 358 can be co-opted for
-the ``bytes`` type).
+the subject of a new PEP or PEPs (PEP 358 should be co-opted for the
+``bytes`` type).
ABCs for Numbers
@@ -555,16 +550,15 @@
**Open issues:** Define: ``Number``, ``Complex``, ``Real``,
``Rational``, ``Integer``. Maybe also ``Cardinal`` (``Integer`` >=
0)? We probably also need ``Index``, which converts to ``Integer``
-using ``__index__``. This should probably be moved out to a separate
-PEP.
+using ``__index__``. This should be moved out to a separate PEP.
Guidelines for Writing ABCs
---------------------------
-Some suggestions:
+Some suggestions for writing ABCs:
-* Use ``@abstractmethod`` and the ``Abstract`` base class.
+* Use the ``@abstractmethod`` decorator.
* Define abstract methods that could be useful as an end point when
called via a super chain.
@@ -575,8 +569,6 @@
* Keep abstract classes small, one per use case instead of one per
concept.
-* What else?
-
ABCs vs. Alternatives
=====================
@@ -680,6 +672,15 @@
.. [5] Charming Python: Scaling a new PEAK, by David Mertz
(http://www-128.ibm.com/developerworks/library/l-cppeak2/)
+.. [6] Implementation of @abstractmethod
+ (http://python.org/sf/1706989)
+
+.. [7] Unifying types and classes in Python 2.2, by GvR
+ (http://www.python.org/download/releases/2.2.3/descrintro/)
+
+.. [8] "Putting Metaclasses to Work: A New Dimension in Object-Oriented
+ Programming", by Ira R. Forman and Scott H. Danforth
+ (http://www.amazon.com/gp/product/0201433052)
Copyright
More information about the Python-checkins
mailing list