raising an exception when multiple inheritance involves same baseThank
Arnaud Delobelle
arnodel at googlemail.com
Sun May 25 13:21:47 EDT 2008
Sorry I lost the original post.
Paul McGuire <ptmcg at austin.rr.com> writes:
> On May 25, 8:37 am, Michael Hines <michael.hi... at yale.edu> wrote:
>> Thanks very much, Arnaud. That is exactly the hint I needed. Since it is
>> not multiple inheritance per se I prohibit but only multiple inheritance
>> involving more than one HocObject class, I replaced your len(bases) > 1
>> test with
>> <code>
>> m = False
>> for b in bases :
>> if hasattr(b, '__mro__'):
>> for bb in b.__mro__ :
>> if bb == MetaHocObject.ho :
>> if m == True:
>> raise Exception("Inheritance of multiple HocObject not
>> allowed")
>> m = True
>>
>> </code>
I think you don't need to look at the bases' mros, just use
issubclass(), e.g. (untested):
if sum(1 for b in bases if issubclass(b, HocObject)) > 1:
raise Exception("Multiple inheritance from HocObject")
>> to get
>>
>> class A(HocObject): pass
>>
>> class B(object): pass
>>
>> class C(): pass
>>
>> class D(C, B, HocObject): pass # ok
>>
>> class D(C, A, HocObject): pass # fail
>>
>> When I fold this idea into my code I may even try to eliminate the class
>> factory aspect of
>> class Foo(hclass(h.Vector))
>> in favor of
>> class Foo(h.Vector)
>>
>> Thanks again,
>> Michael
>
> Here's a more general version of your testing code, to detect *any*
> diamond multiple inheritance (using your sample classes).
>
> -- Paul
>
>
> for cls in (A,B,C,D):
> seen = set()
> try:
> bases = cls.__bases__
> for b in bases:
> if hasattr(b,"__mro__"):
> for m in b.__mro__:
> if m in seen:
> raise Exception("diamond multiple
> inheritance")
> seen.add(m)
> except Exception, e:
> print cls,"has diamond MI"
> else:
> print cls,"is ok"
All new-style classes descend from object, so any new-style class
with at least two bases makes a diamond! For example the first
version of class D above inherits twice from object, so it will be
caught.
OTOH, old-style classes don't have an __mro__, so this will not catch
diamond inheritance of old-style classes. E.g
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
--
Arnaud
More information about the Python-list
mailing list