I need to change bases of some of my widget class, depending on passed arguments.
The simplest example is:
class A:
def a(self):
print (1)
class B:
def __init__(self):
self.extend_instance(A)
self.a()
def extend_instance(obj, cls):
base_cls = obj.__class__
base_cls_name = obj.__class__.__name__
obj.__class__ = type(base_cls_name, (base_cls, cls),{})
B()
Maybe not an optimal way, because it changes bases every time when a new B
instance created (if I undestand it right). But it seems to work.
This is a very simplified example (without arguments, depending on which class B instances with different bases should be created.)
Now I'm trying to implement this with kivy widgets
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
class CoolLabel(Label):
def a(self):
print (1)
class MyLabel:
def __init__(self, **kwargs):
#self.__basses__ = CoolLabel
self.extend_instance(CoolLabel)
self.a()
def extend_instance(obj, cls):
base_cls = obj.__class__
base_cls_name = obj.__class__.__name__
obj.__class__ = type(base_cls_name, (base_cls, cls),{})
class MyApp(App):
def build(self):
self.root = MyLabel(text= '123456')
MyApp().run()
And I get this error:
File "main.py", line 24, in extend_instance
obj.__class__ = type(base_cls_name, (base_cls, cls),{})
TypeError: __class__ assignment: 'MyLabel' object layout differs from 'MyLabel'
what is the reason? can this be related to kivy Widget Metaclass? and are there any ways to workaround this?
Update:
Let me simplify my problem. The main question is - why this doesn't work?
from kivy.uix.widget import Widget
class MyWidget:
def __init__(self, **kwargs):
self.__class__ = type('MyWidget', (Widget,),{})
MyWidget()
Here's the error I have:
File "main.py", line 7, in <module>
MyWidget()
File "main.py", line 5, in __init__
self.__class__ = type('MyWidget', (Widget,),{})
TypeError: __class__ assignment: 'MyWidget' object layout differs from 'MyWidget'