MI (was RE: Real Problems with Python)

Tim Peters tim_one at email.msn.com
Tue Feb 15 03:42:03 EST 2000

[Neel Krishnaswami]
>>> 3. Multiple inheritance is unsound
>>>    By 'unsound' I mean that a method call to a method inherited by a
>>>    subclass of two other classes can fail, even if that method call
>>>    would work on an instance of the base class.

>> Unsure what this is about; am pretty sure nobody has complained
>> about it before.  Certainly "depth first, left to right" is an
>> unprincipled approach, but in practice it's more than predictable
>> enough to use.

> Here's some code:
> class Foo:
>    x = 99
>    def frob(self):
>        print "%d bottles of beer" % self.x
> class Bar:
>    x = "bar"
>    def wibble(self):
>        print "Belly up to the " + self.x
> Note that all the operations on Foo and Bar work safely for direct
> instances of Foo and Bar.  But if you define a subclass like so:
> class Baz(Bar, Foo):
>    pass
> you can get type errors even though both of the superclasses have
> type-safe operations:
> >>> q = Baz()
> >>> q.frob()
> Traceback (innermost last):
>   [...]
> TypeError: illegal argument type for built-in operation

Ah!  That one.  Don't worry about it <wink>.

> This is only an annoyance in day-to-day work,

It's never been an annoyance for me -- simply hasn't come up.  I suppose it
may someday.  Then I'll rename the ambiguous attr <0.9 wink>.

> but it becomes a big problem if you are serious about building
> automatic code analysis tools for Python (eg for CP4E). This is
> because the soundness theorems needed to write things like soft
> typing tools no longer hold. :(

The Types-SIG is wrestling with such things in a preliminary way, and it
already appears all but decided that the full range of tricks you can pull
in Python today are simply uncheckable, or even inexpressible with
reasonable effort (e.g., the canonical example of that is "spelling" the
type of Python's "map" function -- Python isn't curried, so an unboundedly
many "base" signatures get involved).

The language won't be changed to forbid such things, but if you want to use
type checking you're going to have to accept restrictions on what you can
code.    I expect that, as in most other languages that take this all too
seriously <wink>, the checker will look at the code above and say "name
clash -- you're on your own; I can't help".  I personally would be delighted
to get such a warning & rewrite the offending code, since I personally would
never want to rely on "depth-first left-to-right" for resolving clashes.
But somebody else may want to, and that's fine too.

Then again, overall, I think MI where implementation (beyond mere interface)
is inherited from more than one class is usually far more trouble than it's
worth (simple mixin classes are an exception), so I don't tend to get
anywhere near this kind of trouble.  As you noted later, SI languages don't
have a problem here, and in practice it's (IMO) *usually* best to pretend an
MI language is an SI one.

I'll backtrack here & agree w/ your original post:  this is indeed unlikely
to "get fixed".  Although it's likely you *will* get an option to warn about
cases like this, at least in code where it *can* be detected at
compile-time, and provided you explicitly ask to get warned.

theoretically-absurd-yet-practically-sufficient-ly y'rs  - tim

More information about the Python-list mailing list