Bug or Feature?

Tim Peters tim.one at comcast.net
Mon Nov 24 19:23:26 CET 2003

[Stephan Diehl]
> I was playing around with defining new types and have seen the
> following behaviour:
> Python 2.3.1
> ============
> >>> class Int(int):pass
> ...
> >>> a = Int(7)
> >>> b = Int(8)
> >>> c = a + b
> >>> type(c)
> <type 'int'>
> Basicly: Int is not closed under it's defined operations. :-(
> ...

Yes, and that's intentional.  The difficulty is that the base class can't
know how to construct a subclass instance -- there's no guarantee, for
example, that a subclass constructor even accepts an argument list
consisting of one int.  There's also no guarantee that, e.g., an instance S
of a subclass of str *wants*

    S + ""

to return S identically (if type(S) is str, then S+"" is S).  So substantial
work was actually done to disable optimizations (like S+"" is S) for
base-class operations performed on instances of subclasses of builtin types.

So the implementation strives never to screw you, but it may not do what you
want, either.  If you want Ints to be closed under an operation, you need to
supply an appropriate implementation of that operation as a method of Int.
Then you control the optimizations you're willing to accept, and can
construct your Int instances so as to satisfy Int invariants (something the
base class can't know how to do, since it can't have any idea of what
user-defined invariants may be -- although it's hard to see the point to
this in the Int example as given, because the Int class is trivial).

> by contrast:
> >>> class myset(Set):pass
> ...
> >>> a = myset([1,2])
> >>> b = myset([2,3])
> >>> c = a & b
> >>> type(c)
> <class '__main__.myset'>
> subclasses of Set are closed under the set operations. :-)

If you let Guido see that, it won't in 2.4 <wink>.

More information about the Python-list mailing list