'
@@ -68,12 +74,12 @@ class Bokeh(PaneBase):
theme = param.ClassSelector(default=None, class_=(Theme, str), doc="""
Bokeh theme to apply to the plot.""")
- priority = 0.8
+ priority: ClassVar[float | bool | None] = 0.8
_rename: ClassVar[Mapping[str, str | None]] = {'autodispatch': None, 'theme': None}
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: Any) -> float | bool | None:
return isinstance(obj, LayoutDOM)
@classmethod
@@ -106,7 +112,10 @@ def _wrap_bokeh_callbacks(cls, root, bokeh_model, doc, comm):
for cb in cbs
]
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
if root is None:
return self.get_root(doc, comm)
@@ -178,7 +187,7 @@ class Matplotlib(PNG, IPyWidget):
_rerender_params = PNG._rerender_params + ['object', 'dpi', 'tight']
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: Any) -> float | bool | None:
if 'matplotlib' not in sys.modules:
return False
from matplotlib.figure import Figure
@@ -221,7 +230,10 @@ def _update_dimensions(self):
self.width = self.width or int(dpi * w)
self.height = self.height or int(dpi * h)
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
self._update_dimensions()
if not self.interactive:
model = PNG._get_model(self, doc, root, parent, comm)
@@ -243,7 +255,7 @@ def _get_model(self, doc, root=None, parent=None, comm=None):
self._managers[root.ref['id']] = manager
return model
- def _update(self, ref=None, model=None):
+ def _update(self, ref: Optional[str] = None, model: Optional[Model] = None) -> None:
if not self.interactive:
self._update_dimensions()
model.update(**self._get_properties())
@@ -287,7 +299,7 @@ class RGGPlot(PNG):
_rerender_params = PNG._rerender_params + ['object', 'dpi', 'width', 'height']
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: Any) -> float | bool | None:
return type(obj).__name__ == 'GGPlot' and hasattr(obj, 'r_repr')
def _img(self):
@@ -308,10 +320,10 @@ class YT(HTML):
provide additional space.
"""
- priority = 0.5
+ priority: ClassVar[float | bool | None] = 0.5
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: bool) -> float | bool | None:
return (getattr(obj, '__module__', '').startswith('yt.') and
hasattr(obj, "plots") and
hasattr(obj, "_repr_html_"))
@@ -345,10 +357,10 @@ class Folium(HTML):
'fixed', 'stretch_width', 'stretch_height', 'stretch_both',
'scale_width', 'scale_height', 'scale_both', None])
- priority = 0.6
+ priority: ClassVar[float | bool | None] = 0.6
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: Any) -> float | bool | None:
return (getattr(obj, '__module__', '').startswith('folium.') and
hasattr(obj, "_repr_html_"))
diff --git a/panel/pane/plotly.py b/panel/pane/plotly.py
index c922b6f991b..41b82374d4f 100644
--- a/panel/pane/plotly.py
+++ b/panel/pane/plotly.py
@@ -2,6 +2,12 @@
Defines a PlotlyPane which renders a plotly plot using PlotlyPlot
bokeh model.
"""
+from __future__ import annotations
+
+from typing import (
+ TYPE_CHECKING, Any, ClassVar, Optional,
+)
+
import numpy as np
import param
@@ -12,6 +18,11 @@
from ..viewable import Layoutable
from .base import PaneBase
+if TYPE_CHECKING:
+ from bokeh.document import Document
+ from bokeh.model import Model
+ from pyviz_comms import Comm
+
class Plotly(PaneBase):
"""
@@ -66,12 +77,12 @@ class Plotly(PaneBase):
_render_count = param.Integer(default=0, doc="""
Number of renders, increment to trigger re-render""")
- priority = 0.8
+ priority: ClassVar[float | bool | None] = 0.8
- _updates = True
+ _updates: ClassVar[bool] = True
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: Any) -> float | bool | None:
return ((isinstance(obj, list) and obj and all(cls.applies(o) for o in obj)) or
hasattr(obj, 'to_plotly_json') or (isinstance(obj, dict)
and 'data' in obj and 'layout' in obj))
@@ -256,7 +267,10 @@ def _init_params(self):
params['sizing_mode'] = 'stretch_both'
return params
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
PlotlyPlot = lazy_load('panel.models.plotly', 'PlotlyPlot', isinstance(comm, JupyterComm), root)
model = PlotlyPlot(**self._init_params())
if root is None:
@@ -265,7 +279,7 @@ def _get_model(self, doc, root=None, parent=None, comm=None):
self._models[root.ref['id']] = (model, parent)
return model
- def _update(self, ref=None, model=None):
+ def _update(self, ref: Optional[str] = None, model: Optional[Model] = None) -> None:
if self.object is None:
model.update(data=[], layout={})
model._render_count += 1
diff --git a/panel/pane/streamz.py b/panel/pane/streamz.py
index 2a2dcec378b..c4cbc636416 100644
--- a/panel/pane/streamz.py
+++ b/panel/pane/streamz.py
@@ -5,12 +5,19 @@
import sys
-from typing import ClassVar, Mapping
+from typing import (
+ TYPE_CHECKING, Any, ClassVar, Mapping, Optional,
+)
import param
from .base import ReplacementPane
+if TYPE_CHECKING:
+ from bokeh.document import Document
+ from bokeh.model import Model
+ from pyviz_comms import Comm
+
class Streamz(ReplacementPane):
"""
@@ -50,12 +57,15 @@ def _setup_stream(self):
self._stream = self.object.latest().rate_limit(self.rate_limit).gather()
self._stream.sink(self._update_inner)
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
model = super()._get_model(doc, root, parent, comm)
self._setup_stream()
return model
- def _cleanup(self, root=None):
+ def _cleanup(self, root: Model | None = None):
super()._cleanup(root)
if not self._pane._models and self._stream:
self._stream.destroy()
@@ -66,7 +76,7 @@ def _cleanup(self, root=None):
#----------------------------------------------------------------
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: Any) -> float | bool | None:
if 'streamz' in sys.modules:
from streamz import Stream
return isinstance(obj, Stream)
diff --git a/panel/pane/vega.py b/panel/pane/vega.py
index 5f09c5961f9..35f44fe0b03 100644
--- a/panel/pane/vega.py
+++ b/panel/pane/vega.py
@@ -3,7 +3,9 @@
import sys
from functools import partial
-from typing import ClassVar, Mapping
+from typing import (
+ TYPE_CHECKING, Any, ClassVar, Mapping, Optional,
+)
import numpy as np
import param
@@ -15,6 +17,11 @@
from ..viewable import Layoutable
from .base import PaneBase
+if TYPE_CHECKING:
+ from bokeh.document import Document
+ from bokeh.model import Model
+ from pyviz_comms import Comm
+
def ds_as_cds(dataset):
"""
@@ -106,11 +113,11 @@ class Vega(PaneBase):
'excel', 'ggplot2', 'quartz', 'vox', 'fivethirtyeight', 'dark',
'latimes', 'urbaninstitute', 'googlecharts'])
- priority = 0.8
+ priority: ClassVar[float | bool | None] = 0.8
_rename: ClassVar[Mapping[str, str | None]] = {'selection': None, 'debounce': None}
- _updates = True
+ _updates: ClassVar[bool] = True
def __init__(self, object=None, **params):
super().__init__(object, **params)
@@ -148,7 +155,7 @@ def is_altair(cls, obj):
return False
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: Any) -> float | bool | None:
if isinstance(obj, dict) and 'vega' in obj.get('$schema', '').lower():
return True
return cls.is_altair(obj)
@@ -239,7 +246,10 @@ def _process_event(self, event):
value = list(value)
self.selection.param.update(**{name: value})
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
VegaPlot = lazy_load('panel.models.vega', 'VegaPlot', isinstance(comm, JupyterComm), root)
sources = {}
if self.object is None:
@@ -262,7 +272,7 @@ def _get_model(self, doc, root=None, parent=None, comm=None):
self._models[root.ref['id']] = (model, parent)
return model
- def _update(self, ref=None, model=None):
+ def _update(self, ref: Optional[str] = None, model: Optional[Model] = None) -> None:
if self.object is None:
json = None
else:
diff --git a/panel/pane/vtk/vtk.py b/panel/pane/vtk/vtk.py
index d486748f572..19ece2d6425 100644
--- a/panel/pane/vtk/vtk.py
+++ b/panel/pane/vtk/vtk.py
@@ -9,7 +9,9 @@
import zipfile
from abc import abstractmethod
-from typing import ClassVar, Mapping
+from typing import (
+ TYPE_CHECKING, Any, ClassVar, Dict, Mapping, Optional,
+)
from urllib.request import urlopen
import numpy as np
@@ -23,6 +25,11 @@
from ..base import Pane, PaneBase
from .enums import PRESET_CMAPS
+if TYPE_CHECKING:
+ from bokeh.document import Document
+ from bokeh.model import Model
+ from pyviz_comms import Comm
+
base64encode = lambda x: base64.b64encode(x).decode('utf-8')
@@ -72,7 +79,10 @@ def _process_param_change(self, msg):
msg['axes'] = VTKAxes(**axes)
return msg
- def _update_model(self, events, msg, root, model, doc, comm):
+ def _update_model(
+ self, events: Dict[str, param.parameterized.Event], msg: Dict[str, Any],
+ root: Model, model: Model, doc: Document, comm: Optional[Comm]
+ ) -> None:
if 'axes' in msg and msg['axes'] is not None:
VTKAxes = getattr(sys.modules['panel.models.vtk'], 'VTKAxes')
axes = msg['axes']
@@ -369,7 +379,10 @@ def __init__(self, object=None, **params):
self.color_mappers = self.get_color_mappers()
self._update()
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
VTKSynchronizedPlot = lazy_load(
'panel.models.vtk', 'VTKSynchronizedPlot', isinstance(comm, JupyterComm), root
)
@@ -386,7 +399,7 @@ def _get_model(self, doc, root=None, parent=None, comm=None):
self._models[root.ref['id']] = (model, parent)
return model
- def _update(self, ref=None, model=None):
+ def _update(self, ref: Optional[str] = None, model: Optional[Model] = None) -> None:
import panel.pane.vtk.synchronizable_serializer as rws
context = rws.SynchronizationContext(
id_root=make_globally_unique_id(),
@@ -429,7 +442,10 @@ def __init__(self, object=None, **params):
super().__init__(object, **params)
self._contexts = {}
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
VTKSynchronizedPlot = lazy_load(
'panel.models.vtk', 'VTKSynchronizedPlot', isinstance(comm, JupyterComm), root
)
@@ -455,12 +471,12 @@ def _get_model(self, doc, root=None, parent=None, comm=None):
self._models[root.ref['id']] = (model, parent)
return model
- def _cleanup(self, root):
+ def _cleanup(self, root: Model | None = None) -> None:
ref = root.ref['id']
self._contexts.pop(ref, None)
super()._cleanup(root)
- def _update(self, ref=None, model=None):
+ def _update(self, ref: Optional[str] = None, model: Optional[Model] = None) -> None:
context = self._contexts[model.id]
scene, arrays, annotations = self._serialize_ren_win(
self.object,
@@ -637,7 +653,7 @@ def __init__(self, object=None, **params):
self._update()
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: Any) -> float | bool | None:
if ((isinstance(obj, np.ndarray) and obj.ndim == 3) or
any([isinstance(obj, k) for k in cls._serializers.keys()])):
return True
@@ -647,7 +663,10 @@ def applies(cls, obj):
import vtk
return isinstance(obj, vtk.vtkImageData)
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
VTKVolumePlot = lazy_load(
'panel.models.vtk', 'VTKVolumePlot', isinstance(comm, JupyterComm), root
)
@@ -696,7 +715,7 @@ def _process_property_change(self, msg):
msg[k] = int(np.round(v * ori_dim[index] / sub_dim[index]))
return msg
- def _update(self, ref=None, model=None):
+ def _update(self, ref: Optional[str] = None, model: Optional[Model] = None) -> None:
self._volume_data = self._get_volume_data()
if self._volume_data is not None:
self._orginal_dimensions = self._get_object_dimensions()
@@ -809,11 +828,14 @@ def __init__(self, object=None, **params):
self._vtkjs = None
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: Any) -> float | bool | None:
if isinstance(obj, str) and obj.endswith('.vtkjs'):
return True
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
"""
Should return the bokeh model to be rendered.
"""
@@ -843,7 +865,7 @@ def _get_vtkjs(self):
self._vtkjs = vtkjs
return self._vtkjs
- def _update(self, ref=None, model=None):
+ def _update(self, ref: Optional[str] = None, model: Optional[Model] = None) -> None:
self._vtkjs = None
vtkjs = self._get_vtkjs()
model.data = base64encode(vtkjs) if vtkjs is not None else vtkjs
diff --git a/panel/param.py b/panel/param.py
index 3e3b4945427..f83556a5a3c 100644
--- a/panel/param.py
+++ b/panel/param.py
@@ -2,6 +2,8 @@
Defines the Param pane which converts Parameterized classes into a
set of widgets.
"""
+from __future__ import annotations
+
import inspect
import itertools
import json
@@ -12,6 +14,9 @@
from collections.abc import Callable
from contextlib import contextmanager
from functools import partial
+from typing import (
+ TYPE_CHECKING, Any, ClassVar, List, Mapping, Optional,
+)
import param
@@ -37,8 +42,13 @@
)
from .widgets.button import _ButtonBase
+if TYPE_CHECKING:
+ from bokeh.document import Document
+ from bokeh.model import Model
+ from pyviz_comms import Comm
+
-def SingleFileSelector(pobj):
+def SingleFileSelector(pobj: param.Parameter) -> Widget:
"""
Determines whether to use a TextInput or Select widget for FileSelector
"""
@@ -48,7 +58,7 @@ def SingleFileSelector(pobj):
return TextInput
-def LiteralInputTyped(pobj):
+def LiteralInputTyped(pobj: param.Parameter) -> Widget:
if isinstance(pobj, param.Tuple):
return type(str('TupleInput'), (LiteralInput,), {'type': tuple})
elif isinstance(pobj, param.Number):
@@ -151,7 +161,7 @@ class Param(PaneBase):
Dictionary of widget overrides, mapping from parameter name
to widget class.""")
- mapping = {
+ mapping: ClassVar[Mapping[param.Parameter, Widget | Callable[[param.Parameter], Widget]]] = {
param.Action: Button,
param.Array: ArrayInput,
param.Boolean: Checkbox,
@@ -183,11 +193,11 @@ class Param(PaneBase):
if bokeh_version >= Version('2.4.3'):
mapping[param.DateRange] = DatetimeRangeSlider
- priority = 0.1
+ priority: ClassVar[float | bool | None] = 0.1
- _unpack = True
+ _unpack: ClassVar[bool] = True
- _rerender_params = []
+ _rerender_params: ClassVar[List[str]] = []
def __init__(self, object=None, **params):
if isinstance(object, param.Parameter):
@@ -647,12 +657,15 @@ def _get_widgets(self):
widgets += [(pname, self.widget(pname)) for pname in self._ordered_params]
return OrderedDict(widgets)
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
model = self.layout._get_model(doc, root, parent, comm)
self._models[root.ref['id']] = (model, parent)
return model
- def _cleanup(self, root):
+ def _cleanup(self, root: Model | None = None) -> None:
self.layout._cleanup(root)
super()._cleanup(root)
@@ -661,7 +674,7 @@ def _cleanup(self, root):
#----------------------------------------------------------------
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: Any) -> float | bool | None:
return (is_parameterized(obj) or
isinstance(obj, param.parameterized.Parameters) or
(isinstance(obj, param.Parameter) and obj.owner is not None))
@@ -694,7 +707,10 @@ def select(self, selector=None):
"""
return super().select(selector) + self.layout.select(selector)
- def get_root(self, doc=None, comm=None, preprocess=True):
+ def get_root(
+ self, doc: Optional[Document] = None, comm: Optional[Comm] = None,
+ preprocess: bool = True
+ ) -> Model:
"""
Returns the root model and applies pre-processing hooks
@@ -853,7 +869,10 @@ def update_pane(*events):
watcher = pobj.param.watch(update_pane, ps, p.what)
self._callbacks.append(watcher)
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
if not self._evaled:
self._replace_pane(force=True)
return super()._get_model(doc, root, parent, comm)
@@ -863,7 +882,7 @@ def _get_model(self, doc, root=None, parent=None, comm=None):
#----------------------------------------------------------------
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: Any) -> float | bool | None:
return inspect.ismethod(obj) and isinstance(get_method_owner(obj), param.Parameterized)
@@ -877,7 +896,7 @@ class ParamFunction(ParamMethod):
a widget to some other output.
"""
- priority = 0.6
+ priority: ClassVar[float | bool | None] = 0.6
def _link_object_params(self):
deps = getattr(self.object, '_dinfo', {})
@@ -913,7 +932,7 @@ def _link_object_params(self):
#----------------------------------------------------------------
@classmethod
- def applies(cls, obj):
+ def applies(cls, obj: Any) -> float | bool | None:
if isinstance(obj, types.FunctionType):
if hasattr(obj, '_dinfo'):
return True
diff --git a/panel/viewable.py b/panel/viewable.py
index 2548a9b5125..4eb8931abb5 100644
--- a/panel/viewable.py
+++ b/panel/viewable.py
@@ -476,7 +476,7 @@ def _get_model(
"""
raise NotImplementedError
- def _cleanup(self, root: 'Model' | None) -> None:
+ def _cleanup(self, root: Model | None = None) -> None:
"""
Clean up method which is called when a Viewable is destroyed.
@@ -537,7 +537,7 @@ def _server_destroy(self, session_context: 'BokehSessionContext') -> None:
def get_root(
self, doc: Optional[Document] = None, comm: Optional[Comm] = None,
preprocess: bool = True
- ) -> 'Model':
+ ) -> Model:
"""
Returns the root model and applies pre-processing hooks
diff --git a/panel/widgets/ace.py b/panel/widgets/ace.py
index 968b94fda8a..cac813d7afd 100644
--- a/panel/widgets/ace.py
+++ b/panel/widgets/ace.py
@@ -3,7 +3,9 @@
"""
from __future__ import annotations
-from typing import ClassVar, Mapping
+from typing import (
+ TYPE_CHECKING, ClassVar, Mapping, Optional,
+)
import param
@@ -13,6 +15,11 @@
from ..util import lazy_load
from .base import Widget
+if TYPE_CHECKING:
+ from bokeh.document import Document
+ from bokeh.model import Model
+ from pyviz_comms import Comm
+
class Ace(Widget):
"""
@@ -55,14 +62,17 @@ def __init__(self, **params):
self.param.watch(self._update_disabled, ['disabled', 'readonly'])
self.jslink(self, readonly='disabled', bidirectional=True)
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
if self._widget_type is None:
self._widget_type = lazy_load(
'panel.models.ace', 'AcePlot', isinstance(comm, JupyterComm), root
)
return super()._get_model(doc, root, parent, comm)
- def _update_disabled(self, *events):
+ def _update_disabled(self, *events: param.parameterized.Event):
for event in events:
if event.name == 'disabled':
self.readonly = event.new
diff --git a/panel/widgets/base.py b/panel/widgets/base.py
index 3494182ccc9..eb5552219ff 100644
--- a/panel/widgets/base.py
+++ b/panel/widgets/base.py
@@ -48,10 +48,10 @@ class Widget(Reactive):
_rename: ClassVar[Mapping[str, str | None]] = {'name': 'title'}
# Whether the widget supports embedding
- _supports_embed: bool = False
+ _supports_embed: ClassVar[bool] = False
# Declares the Bokeh model type of the widget
- _widget_type: 'Model' = None
+ _widget_type: ClassVar[Model] = None
__abstract = True
@@ -91,9 +91,9 @@ def from_param(cls, parameter: param.Parameter, **params) -> Viewable:
return layout[0]
def _get_model(
- self, doc: 'Document', root: Optional['Model'] = None,
- parent: Optional['Model'] = None, comm: Optional['Comm'] = None
- ) -> 'Model':
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
model = self._widget_type(**self._process_param_change(self._init_params()))
if root is None:
root = model
@@ -147,7 +147,7 @@ class CompositeWidget(Widget):
widgets
"""
- _composite_type: 'Panel' = Row
+ _composite_type: ClassVar[Panel] = Row
__abstract = True
@@ -188,14 +188,14 @@ def select(
objects += obj.select(selector)
return objects
- def _cleanup(self, root: 'Model') -> None:
+ def _cleanup(self, root: Model | None = None) -> None:
self._composite._cleanup(root)
super()._cleanup(root)
def _get_model(
- self, doc: 'Document', root: Optional['Model'] = None,
- parent: Optional['Model'] = None, comm: Optional['Comm'] = None
- ) -> 'Model':
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
model = self._composite._get_model(doc, root, parent, comm)
if root is None:
root = parent = model
diff --git a/panel/widgets/button.py b/panel/widgets/button.py
index dac46589078..2ef32e49e75 100644
--- a/panel/widgets/button.py
+++ b/panel/widgets/button.py
@@ -7,6 +7,7 @@
from functools import partial
from typing import (
TYPE_CHECKING, Any, Callable, ClassVar, Dict, List, Mapping, Optional,
+ Type,
)
import param
@@ -20,9 +21,11 @@
from .base import Widget
if TYPE_CHECKING:
- from panel.reactive import JSLinkTarget
+ from bokeh.document import Document
+ from bokeh.model import Model
+ from pyviz_comms import Comm
- from ..links import Link
+ from ..links import JSLinkTarget, Link
BUTTON_TYPES: List[str] = ['default', 'primary', 'success', 'warning', 'danger','light']
@@ -44,9 +47,12 @@ class _ClickButton(_ButtonBase):
__abstract = True
- _event = 'button_click'
+ _event: ClassVar[str] = 'button_click'
- def _get_model(self, doc, root=None, parent=None, comm=None):
+ def _get_model(
+ self, doc: Document, root: Optional[Model] = None,
+ parent: Optional[Model] = None, comm: Optional[Comm] = None
+ ) -> Model:
model = super()._get_model(doc, root, parent, comm)
if comm:
model.on_event(self._event, self._comm_event)
@@ -127,19 +133,21 @@ class Button(_ClickButton):
_rename: ClassVar[Mapping[str, str | None]] = {'clicks': None, 'name': 'label', 'value': None}
- _target_transforms = {'event:button_click': None, 'value': None}
+ _target_transforms: ClassVar[Mapping[str, str | None]] = {
+ 'event:button_click': None, 'value': None
+ }
- _widget_type = _BkButton
+ _widget_type: ClassVar[Type[Model]] = _BkButton
@property
- def _linkable_params(self):
+ def _linkable_params(self) -> List[str]:
return super()._linkable_params + ['value']
def jslink(
- self, target: 'JSLinkTarget', code: Optional[Dict[str, str]] = None,
+ self, target: JSLinkTarget, code: Optional[Dict[str, str]] = None,
args: Optional[Dict[str, Any]] = None, bidirectional: bool = False,
**links: str
- ) -> 'Link':
+ ) -> Link:
"""
Links properties on the this Button to those on the
`target` object in Javascript (JS) code.
@@ -215,9 +223,9 @@ class Toggle(_ButtonBase):
_rename: ClassVar[Mapping[str, str | None]] = {'value': 'active', 'name': 'label'}
- _supports_embed = True
+ _supports_embed: ClassVar[bool] = True
- _widget_type = _BkToggle
+ _widget_type: ClassVar[Type[Model]] = _BkToggle
def _get_embed_state(self, root, values=None, max_opts=3):
return (self, self._models[root.ref['id']][0], [False, True],
@@ -252,11 +260,11 @@ class MenuButton(_ClickButton):
split = param.Boolean(default=False, doc="""
Whether to add separate dropdown area to button.""")
- _widget_type = _BkDropdown
+ _event: ClassVar[str] = 'menu_item_click'
_rename: ClassVar[Mapping[str, str | None]] = {'name': 'label', 'items': 'menu', 'clicked': None}
- _event = 'menu_item_click'
+ _widget_type: ClassVar[Type[Model]] = _BkDropdown
def _process_event(self, event):
if isinstance(event, MenuItemClick):
diff --git a/panel/widgets/debugger.py b/panel/widgets/debugger.py
index 69c3e80ac31..796d4e7b740 100644
--- a/panel/widgets/debugger.py
+++ b/panel/widgets/debugger.py
@@ -6,7 +6,9 @@
import logging
-from typing import ClassVar, Mapping
+from typing import (
+ ClassVar, Dict, List, Mapping,
+)
import param
@@ -39,7 +41,6 @@ def __init__(self, *args, only_last=True, **kwargs):
self.only_last = only_last
def format(self, record):
-
record.message = record.getMessage()
if self.usesTime():
record.asctime = self.formatTime(record, self.datefmt)
@@ -118,7 +119,7 @@ class DebuggerButtons(ReactiveHTML):
clears = param.Integer(default=0)
- _template = """
+ _template: ClassVar[str] = """