Reputation: 1461
I need to have a static instance of a class of the same class and one solution I thought was using metaclasses.
I have the following word.py
:
from .token import Token
from .tag import Tag
class Token:
def __init__(self, tag_id):
self.tag = tag_id
def __str__(self):
return str(self.tag)
class MetaWord(type):
def __init__(cls, clsname, superclasses, attributedict):
cls.and_ = cls('&&', Tag.AND)
cls.or_ = cls("||", Tag.OR)
cls.eq = cls("==", Tag.EQ)
cls.ne = cls("!=", Tag.NE)
class Word(Token, metaclass=MetaWord):
def __init__(self, lexeme, tag):
super(self.__class__, self).__init__(tag)
self.lexeme = lexeme
and another file type.py
file, with a Type
class that inherits from Word
:
from lexer.word import Word
from lexer.tag import Tag
class MetaType(type):
def __init__(cls, clsname, superclasses, attributedict):
cls.int_ = cls('int', Tag.BASIC, 4)
cls.float_ = cls('float', Tag.BASIC, 8)
cls.char_ = cls('char', Tag.BASIC, 1)
cls.bool_ = cls('bool', Tag.BASIC, 1)
class Type(Word, metaclass=MetaType):
def __init__(self, word, tag_id, w):
super(self.__class__, self).__init__(word, tag_id)
self.width = w
The problem I am having is that everytime I import Type
it gives me the error:
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
I have read some topics on this issue, but haven't figured out how to fix the conflict between the metaclasses
Upvotes: 0
Views: 51
Reputation: 66
If you want the code to work in the way you have it organized, you will have to make MetaType a subclass of MetaWord. When Python tries to instantiate your Type class it looks at the MRO and sees that Type has metaclass MetaType and base class Word, but class Word has metaclass MetaWord. This raises a conflict because there is no way for Python to resolve the fact that Type seems to have two metaclasses, MetaWord and MetaType, which are unrelated to each other.
The following code is a minimal reproduction of what I think your problem is:
class Meta1(type):
pass
class Class1(metaclass=Meta1):
pass
class Meta2(type):
pass
class Class2(Class1, metaclass=Meta2):
pass
This code will give the same sort of error as yours. Changing the definition of Meta2 to:
class Meta2(Meta1):
pass
resolves the issue.
Upvotes: 2