raising an exception when multiple inheritance involves same base

Arnaud Delobelle arnodel at googlemail.com
Sat May 24 11:26:55 EDT 2008


Michael Hines <michael.hines at yale.edu> writes:

> Hello,
> I have a class factory that supports single inheritance but it is
> an error if the base appears twice. e.g
> class Foo(hclass(h.Vector), hclass(h.List)):
> should raise an exception since h.Vector and h.List are really the same
> extension class, HocObject.
>
> So far I have only been able to do this by iterating over __mro__ during
> creation of an object as in:
>
> def hclass(c):
>     class hc(hoc.HocObject):
>         def __new__(cls, *args, **kwds):
>             m = False
>             for x in cls.__mro__:
>                 if (type(x) == type(hc)):
>                     if m == True:
>                         raise HocError, 'Multiple inheritance...'
>                     m = True
>             kwds.update({'hocbase':cls.htype})
>             return hoc.HocObject.__new__(cls, *args, **kwds)
>     setattr(hc, 'htype', c)
>     return hc
>
> Is there a way to do the test earlier (e.g during creation of the Foo
> class when hclass is called the second time
> instead of during creation of a Foo object).

Yes, by giving hoc.HocObject a custom metaclass:

class MetaHocObject(type):
    def __new__(cls, name, bases, attrs):
        if len(bases) > 1:
            raise Exception("Only single inheritance allowed")
        return type.__new__(cls, name, bases, attrs)

class HocObject(object):
    __metaclass__ = MetaHocObject


That'll forbid descendants of MetaHocObject having several bases:

>> class A(HocObject): pass
... 
>>> class B(HocObject): pass
... 
>>> class C(A, B): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __new__
Exception: Only single inheritance allowed
>>> 

HTH

-- 
Arnaud



More information about the Python-list mailing list