[Python-checkins] r54989 - peps/trunk/pep-3119.txt peps/trunk/pep-3141.txt

guido.van.rossum python-checkins at python.org
Fri Apr 27 00:33:28 CEST 2007


Author: guido.van.rossum
Date: Fri Apr 27 00:33:22 2007
New Revision: 54989

Modified:
   peps/trunk/pep-3119.txt
   peps/trunk/pep-3141.txt
Log:
PEP 3141: Fix spelling of Transcendental.
PEP 3119: Add overloading isinstance() and issubclass();
	  tighten invariant for Mapping.keys/values/items to use list().


Modified: peps/trunk/pep-3119.txt
==============================================================================
--- peps/trunk/pep-3119.txt	(original)
+++ peps/trunk/pep-3119.txt	Fri Apr 27 00:33:22 2007
@@ -20,6 +20,8 @@
   can be used to define abstract methods.  A class containing an
   abstract method that isn't overridden cannot be instantiated.
 
+* A way to overload ``isinstance()`` and ``issubclass()``.
+
 * Specific ABCs for containers and iterators, to be added to the
   collections module.
 
@@ -124,6 +126,8 @@
 * An "ABC support framework" which defines a built-in decorator that
   make it easy to define ABCs, and mechanisms to support it.
 
+* A way to overload ``isinstance()`` and ``issubclass()``.
+
 * Specific ABCs for containers and iterators, to be added to the
   collections module.
 
@@ -180,6 +184,76 @@
 cooperative multiple-inheritance [7]_, [8]_.
 
 
+Overloading ``isinstance()`` and ``issubclass()``
+-------------------------------------------------
+
+During the development of this PEP and of its companion, PEP 3141, we
+repeatedly faced the choice between standardizing more, fine-grained
+ABCs or fewer, course-grained ones.  For example, at one stage, PEP
+3141 introduced the following stack of base classes used for complex
+numbers: MonoidUnderPlus, AdditiveGroup, Ring, Field, Complex (each
+derived from the previous).  And the discussion mentioned several
+other algebraic categorizations that were left out: Algebraic,
+Transcendental, and IntegralDomain, and PrincipalIdealDomain.  In this
+PEP, we are wondering about the use cases for separate classes like
+Set, ComposableSet, MutableSet, HashableSet, MutableComposableSet,
+HashableComposableSet.
+
+The dilemma here is that we'd rather have fewer ABCs, but then what
+should a user do who needs a less refined ABC?  Consider e.g. the
+plight of a mathematician who wants to define his own kind of
+Transcendental numbers, but also wants float and int to be considered
+Transcendental.  PEP 3141 originally proposed to patch float.__bases__
+for that purpose, but there are some good reasons to keep the built-in
+types immutable (for one, they are shared between all Python
+interpreters running in the same address space, as is used by
+mod_python).
+
+The solution proposed here is to allow overloading the built-in
+functions ``isinstance()`` and ``issubclass()``.  The overloading
+works as follows: The call ``isinstance(x, C)`` first checks whether
+``C.__instancecheck__`` exists, and if so, calls
+``C.__subclasscheck__(x)`` instead of its normal implementation.
+Similarly, the call ``issubclass(D, C)`` first checks whether
+``C.__subclasscheck__`` exists, and if so, calls
+``C.__subclasscheck__(D)`` instead of its normal implementation.
+
+Note that the magic names are not ``__isinstance__`` and
+``__issubclass__``; this is because the reversal of the arguments
+could cause confusion, especially for the ``issubclass()`` overloader.
+
+(We could also provide a default implementation of these that
+implements the old algorithms; this would be more regular but would
+have additional backwards compatibility issues, since the old
+algorithms special-case objects not deriving from ``type`` in order to
+support a different kind of overloading of these operations.)
+
+A prototype implementation of this is given in [12]_.
+
+Here is an example with (very simple) implementations of
+``__instancecheck__`` and ``__subclasscheck__``::
+
+    assert issubclass(set, HashableSet)  # Assume this is given
+
+    class ABC:
+
+        def __instancecheck__(cls, inst):
+            """Implement isinstance(inst, cls)."""
+            return any(cls.__subclasscheck__(c)
+                       for c in {type(inst), inst.__class__})
+
+        def __subclasscheck__(cls, sub):
+            """Implement issubclass(sub, cls)."""
+            candidates = cls.__dict__.get("__subclass__", set()) | {cls}
+            return any(c in candidates for c in sub.mro())
+
+    class NoncomposableHashableSet(Set, Hashable, metaclass=ABC):
+        __subclass__ = {HashableSet}
+
+    assert issubclass(set, NoncomposableHashableSet)
+    assert isinstance({1, 2, 3}, NoncomposableHashableSet)
+
+
 ABCs for Containers and Iterators
 ---------------------------------
 
@@ -514,12 +588,10 @@
 
     The following invariant should hold for any mapping ``m``::
 
-        set(m.items()) == set(zip(m.keys(), m.values()))
+        list(m.items()) == list(zip(m.keys(), m.values()))
 
-    i.e. iterating over the keys and the values in parallel should
-    return *corresponding* keys and values.  **Open issues:** Should
-    this always be required?  How about the stronger invariant using
-    ``list()`` instead of ``set()``?
+    i.e. iterating over the items, keys and values should return
+    results in the same order.
 
 ``HashableMapping``
     A subclass of ``Mapping`` and ``Hashable``.  The values should be
@@ -743,6 +815,9 @@
 .. [11] Finite set, in Wikipedia
    (http://en.wikipedia.org/wiki/Finite_set)
 
+.. [12] Make isinstance/issubclass overloadable
+   (http://python.org/sf/1708353)
+
 
 Copyright
 =========

Modified: peps/trunk/pep-3141.txt
==============================================================================
--- peps/trunk/pep-3141.txt	(original)
+++ peps/trunk/pep-3141.txt	Fri Apr 27 00:33:22 2007
@@ -237,7 +237,7 @@
     algebraic, but Python does define these operations on floats,
     which makes defining this class somewhat difficult.
 
-``Trancendental``
+``Transcendental``
     The elementary functions
     (http://en.wikipedia.org/wiki/Elementary_function) are
     defined. These are basically arbitrary powers, trig functions, and


More information about the Python-checkins mailing list