[Python-3000] Updated and simplified PEP 3141: A Type Hierarchy for Numbers

Talin talin at acm.org
Thu May 17 09:40:19 CEST 2007

Jeffrey Yasskin wrote:
> I've updated PEP3141 to remove the algebraic classes and bring the
> numeric hierarchy much closer to scheme's design. Let me know what you
> think. Feel free to send typographical and formatting problems just to
> me. My schedule's a little shaky the next couple weeks, but I'll make
> updates as quickly as I can.

General comments:

I need to give some background first, so be patient :)

The original version of this PEP was written at a time when ABCs were at 
an earlier stage in their conceptual development. The notion of 
overriding 'isinstance' had not yet been introduced, and so the only way 
to inherit from an ABC was by the traditional inheritance mechanism.

At that time, there were a number of proposals for adding ABC base 
classes to Python's built-in types. Those ABCs, being the foundation for 
the built-in types, would have had to be built-ins themselves, and would 
have been required to be initialized prior to the built-ins that 
depended on them. This in turn meant that those ABCs were "special", in 
the sense that they were officially sanctioned by the Python runtime 
itself. The ABCs in this PEP and in the other ABC PEPs would have been 
given a privileged status, elevated even above the classes in the 
standard library.

My feeling at the time was that I was uncomfortable with a brand new 
type hierarchy, still in a relatively immature stage of development, 
being deeply rooted into the core of Python. Being embedded into the 
interpreter means that it would be hard to experiment with different 
variations and to test out different options for the number hierarchy. 
Not only would the embedded classes be hard to change, but there would 
be no way that alternative proposals could compete.

My concern was that there would be little, if any, evolution of these 
concepts, and that we would be stuck with a set of decisions which had 
been made in haste. This is exactly contrary to the usual prescription 
for Python library modules, which are supposed to prove themselves in 
real-world apps before being enshrined in the standard library.

Now, the situation has changed somewhat. The ABC PEP has radically 
shifted its focus, de-emphasizing traditional inheritance towards a new 
mechanism which I call 'dynamic inheritance' - the ability to declare 
new inheritance relations after a class has been created.

Lets therefore assume that the numeric ABCs will use this new 
inheritance mechanism, avoiding the problem of taking an immature class 
hierarchy and setting it in stone. The PEPs in this class would then no 
longer need to have this privileged status; They could be replaced and 
changed at will.

Assuming that this is true, the question then becomes whether these 
classes should be treated like any other standard library submission. In 
other words, shouldn't this PEP be implemented as a separate module, and 
have to prove itself 'in the wild' before being adopted into the stdlib? 
Does this PEP even need to be a PEP at all, or can it just be a 
3rd-party library that is eventually adopted into Python?

Now, I *could* see adopting an untried library embodying untested ideas 
into the stdlib if there was a crying need for the features of such a 
library, and those needs were clearly being unfulfilled. However, I am 
not certain that this is the case here.

At the very least, I think it should be stated in the PEP whether or not 
the ABCs defined here are going to be using traditional or dynamic 

If it is the latter, and we decide that this PEP is going to be part of 
the stdlib, then I propose the following library organization:

    import abc              # Imports the basic ABC mechanics
    import abc.collections  # MutableSequence and such
    import abc.math         # The number hierarchy
    ... and so on

Now, there is another issue that needs to be dicussed.

The classes in the PEP appear to be written with lots of mixin methods, 
such as __rsub__ and __abs__ and such. Unfortunately, the current 
proposed method for dynamic inheritance does not allow for methods or 
properties to be inherited from the 'virtual' base class. Which means 
that all of the various methods defined in this PEP are utterly 
meaningless other than as documentation - except in the case of a new 
user-created class of numbers which inherit from these ABCs using 
traditional inheritance, which is not something that I expect to happen 
very often at all. For virtually all practical uses, the elaborate 
methods defined in this PEP will be unused and inaccessible.

This really highlights what I think is a problem with dynamic 
inheritance, and I think that this inconsistency between traditional and 
dynamic inheritance will eventually come back to haunt us. It has always 
been the case in the past that for every property of class B, if 
isinstance(A, B) == True, then A also has that property, either 
inherited from B, or overridden in A. The fact that this invariant will 
no longer hold true is a problem in my opinion.

I realize that there isn't currently a solution to efficiently allow 
inheritance of properties via dynamic inheritance. As a software 
engineer, however, I generally feel that if a feature is unreliable, 
then it shouldn't be used at all. So if I were designing a class 
hierarchy of ABCs, I would probably make a rule for myself not to define 
any properties or methods in the ABCs at all, and to *only* use ABCs for 
type testing via 'isinstance'.

In other words, if I were writing this PEP, all of those special methods 
would be omitted, simply because as a writer of a subclass I couldn't 
rely on being able to use them.

The only alternative that I can see is to not use dynamic inheritance at 
all, and instead have the number classes inherit from these ABCs using 
the traditional mechanism. But that brings up all the problems of 
immaturity and requiring them to be built-in that I brought up earlier.

-- Talin

More information about the Python-3000 mailing list