I am trying to design apps with a lot of nested parameterized classes, but I ran into a confusing situation.
If one runs the following minimal app:
import param import panel as pn class A(param.Parameterized): input_widget = param.ClassSelector(class_=pn.widgets.TextInput, default=pn.widgets.TextInput()) @param.depends('input_widget.value', watch=True) def do_stuff(self): print("Hello Panel") def __panel__(self): return self.input_widget class B(param.Parameterized): a = param.ClassSelector(class_=A, default=A()) def __panel__(self): return self.a pn.Column(B()).servable()
it fails to load with
AttributeError: 'TextInput' object has no attribute 'do_stuff'
This is very confusing for the user since the app just showing A works, so you’d expect it to work too if you embed A in B.
The issue seems to be related to some param copy-logic, and one way to work around this is by changing it to
class B(param.Parameterized): a = param.ClassSelector(class_=A, default=A(), instantiate=False) def __panel__(self): return self.a
But i am not sure that is correct if one has multiple instances of B. Maybe one would need to pass in a value for A each time, but that seems cumbersome too.
Is this pattern of nesting widgets fundamentally wrong or is this unexpected behavior?