raising an exception when multiple inheritance involves same base

M

Michael Hines

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).
Just before the return hc, print hc.__mro__ yields for the second call:
(<class '__main__.hc'>, <type 'hoc.HocObject'>, <type 'object'>)
wheras in the __new__, print cls.__mro__ yields:
(<class '__main__.Foo'>, <class '__main__.hc'>, <class '__main__.hc'>,
<type 'hoc.HocObject'>, <type 'object'>)


Thanks,
Michael
 
A

Arnaud Delobelle

Michael Hines said:
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:
....
Traceback (most recent call last):
File "<stdin>", line 1, in <module>

HTH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top