TL;DR: if you want to stay sane, don't inherit two classes that share same inheritance graph
I recently got puzzled by a bug from a legacy lib (ClientForm) which have this code: class ParseError(sgmllib.SGMLParseError, HTMLParser.HTMLParseError, ): pass And fails because takes __init__ from sgmllib and __str__ from HTMLParser where __str__ uses attributes set by HTMLParser's init. At first look, I thought was just matter to swap the inherit classes. But a deeper look take me to the python's mro reading: http://www.python.org/download/releases/2.3/mro/ And to reproduce the error I code this: class Foo(object): def __init__(self, msg): self.msg = msg def __str__(self): return 'Foo: ' + self.msg class Bar(Exception): def __init__(self, msg): self.msg = msg def __str__(self): return 'Bar: ' + self.msg class A(Exception): pass class B(RuntimeError): pass class AFoo(A, Foo): pass class ABar(A, Bar): pass class BFoo(B, Foo): pass class BBar(B, Bar): pass print AFoo('ok') # ok print ABar('ok') # Bar: ok print BFoo('ok') # ok print BBar('fail') # AttributeError: ... not attribute 'msg' # EOF After running the code I was still confused. So I read carefully again the mro stuff. And ended doing this inheritance tree: object (__init__, __str__) | \ | Foo (__init__, __str__) | BaseException (__init__, __str__) | | | Exception (__init__) / | \ A | Bar (__init__, __str__) | StandardError (__init__) | | | RuntimeError (__init__) / B Then I figure out the method resolution following the inheritance graph: * AFoo(A, Foo): __init__ from Exception __str__ from BaseException * ABar(A, Bar): __init__ from Bar __str__ from Bar * BFoo(B, Foo): __init__ from RuntimeError __str__ from BaseException * BBar(B, Bar): __init__ from RuntimeError __str__ from Bar Finally everything make sense. And make think about be careful when doing multiple inheritance. Any thoughts? ~Rolando -- http://mail.python.org/mailman/listinfo/python-list