Cryptic error message when forgetting to call super().__init__ on Parameterized
- Dominant language
- Python
- Stars
- 521
- Forks
- 86
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 35
Description
#### ALL software version info
Holoviews 1.13.5
Param 1.10.1
Panel 0.10.3
#### Description of expected behavior and the observed behavior
Extending a Parameterized class without calling __init__ results in a cryptic message. See below
It would be nice to have a better message to remind user to call super().__init__(**kwargs)
```
AttributeError: 'TestStreamParam' object has no attribute '_param_watchers'
```
[See discussion on discourse](https://discourse.holoviz.org/t/cryptic-error-message-on-using-parameterized-class-in-panel/1932)
#### Minimal working example
```
import param
import panel as pn
class TestParam(param.Parameterized):
onoff = param.Boolean()
def __init__(self, initial=False):
onoff = initial
def view(self):
print(self.onoff)
```
Using it like this gives the error
```
tp = TestParam()
pn.Row(tp.param)
```
See stack trace below
#### Fix
The fix is quite simple, Just add **kwargs to the init method and call the super
```
class TestParam(param.Parameterized):
onoff = param.Boolean()
def __init__(self, initial=False, **kwargs):
super().__init__(**kwargs)
onoff = initial
....
```
#### Stack traceback and/or browser JavaScript console output
```
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
in
1 tsp=TestStreamParam()
2
----> 3 pn.Row(tsp.param)
~\AppData\Local\Continuum\anaconda3\envs\dms\lib\site-packages\panel\layout\base.py in __init__(self, *objects, **params)
358 "as positional arguments or as a keyword, "
359 "not both." % type(self).__name__)
--> 360 params['objects'] = [panel(pane) for pane in objects]
361 elif 'objects' in params:
362 params['objects'] = [panel(pane) for pane in params['objects']]
~\AppData\Local\Continuum\anaconda3\envs\dms\lib\site-packages\panel\layout\base.py in (.0)
358 "as positional arguments or as a keyword, "
359 "not both." % type(self).__name__)
--> 360 params['objects'] = [panel(pane) for pane in objects]
361 elif 'objects' in params:
362 params['objects'] = [panel(pane) for pane in params['objects']]
~\AppData\Local\Continuum\anaconda3\envs\dms\lib\site-packages\panel\pane\base.py in panel(obj, **kwargs)
49 if kwargs.get('name', False) is None:
50 kwargs.pop('name')
---> 51 pane = PaneBase.get_pane_type(obj, **kwargs)(obj, **kwargs)
52 if len(pane.layout) == 1 and pane._unpack:
53 return pane.layout[0]
~\AppData\Local\Continuum\anaconda3\envs\dms\lib\site-packages\panel\param.py in __init__(self, object, **params)
189 'object', 'parameters', 'name', 'display_threshold', 'expand_button',
190 'expand', 'expand_layout', 'widgets', 'show_labels', 'show_name'])
--> 191 self._update_widgets()
192
193 def __repr__(self, depth=0):
~\AppData\Local\Continuum\anaconda3\envs\dms\lib\site-packages\panel\param.py in _update_widgets(self, *events)
258 self._widgets = {}
259 else:
--> 260 self._widgets = self._get_widgets()
261
262 alias = {'_title': 'name'}
~\AppData\Local\Continuum\anaconda3\envs\dms\lib\site-packages\panel\param.py in _get_widgets(self)
540 else:
541 widgets = []
--> 542 widgets += [(pname, self.widget(pname)) for pname in self._ordered_params]
543 return OrderedDict(widgets)
544
~\AppData\Local\Continuum\anaconda3\envs\dms\lib\site-packages\panel\param.py in (.0)
540 else:
541 widgets = []
--> 542 widgets += [(pname, self.widget(pname)) for pname in self._ordered_params]
543 return OrderedDict(widgets)
544
~\AppData\Local\Continuum\anaconda3\envs\dms\lib\site-packages\panel\param.py in widget(self, p_name)
494 if 'step' in kw:
495 watchers.append(self.object.param.watch(link, p_name, 'step'))
--> 496 watchers.append(self.object.param.watch(link, p_name))
497
498 options = kwargs.get('options', [])
~\AppData\Local\Continuum\anaconda3\envs\dms\lib\site-packages\param\parameterized.py in watch(self_, fn, parameter_names, what, onlychanged, queued)
1892 onlychanged=onlychanged, parameter_names=parameter_names,
1893 what=what, queued=queued)
-> 1894 self_._watch('append', watcher, what)
1895 return watcher
1896
~\AppData\Local\Continuum\anaconda3\envs\dms\lib\site-packages\param\parameterized.py in _watch(self_, action, watcher, what, operation)
1875
1876 if self_.self is not None and what == "value":
-> 1877 watchers = self_.self._param_watchers
1878 if parameter_name not in watchers:
1879 watchers[parameter_name] = {}
AttributeError: 'TestStreamParam' object has no attribute '_param_watchers'
```
Contributor guide
Assessment
This issue has not been assessed yet.