Say I want to implement a metaclass that should serve as a class factory. But unlike the type
constructor, which takes 3 arguments, my metaclass should be callable without any arguments:
Cls1 = MyMeta()
Cls2 = MyMeta()
...
For this purpose I defined a custom __new__
method with no parameters:
class MyMeta(type):def __new__(cls):return super().__new__(cls, 'MyCls', (), {})
But the problem is that python automatically calls the __init__
method with the same arguments as the __new__
method, so trying to call MyMeta()
ends up throwing an exception:
TypeError: type.__init__() takes 1 or 3 arguments
Which makes sense, since type
can be called with 1 or 3 arguments. But what's the correct way to fix this? I see 3 (4?) options:
- I could add an empty
__init__
method to my metaclass, but since I'm not sure iftype.__init__
does anything important, this might not be a good idea. - I could implement an
__init__
method that callssuper().__init__(cls.__name__, cls.__bases__, vars(cls))
. - I could use a meta-metaclass and override its
__call__
method, rather than messing with__new__
and__init__
. - Bonus option: Maybe I shouldn't try to change the signature?
So my question is: Are the 3 solutions I listed correct or are there any subtle bugs hidden in them? Which solution is best (i.e. the most correct)?