Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable strict type checking #7497

Merged
merged 34 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b7037ec
Align types of linked_properties
philippjfr Nov 14, 2024
6e2479b
Begin typing everything
philippjfr Nov 15, 2024
d887943
More typing
philippjfr Nov 15, 2024
19b786f
More fixes
philippjfr Nov 15, 2024
e051df1
Add Tabulator types
philippjfr Nov 15, 2024
95e0b52
More types
philippjfr Nov 15, 2024
750a217
Small fix
philippjfr Nov 15, 2024
9e602c9
More types
philippjfr Nov 15, 2024
396ad6d
More types
philippjfr Nov 16, 2024
71912de
Upgrade type definitions and apply pyupgrade
philippjfr Nov 16, 2024
52bef7c
More updates
philippjfr Nov 16, 2024
b865a10
Update type imports for generics
philippjfr Nov 16, 2024
d9e1f1f
Add more types
philippjfr Nov 16, 2024
949b37c
More minor fixes
philippjfr Nov 16, 2024
6e38a3c
More types
philippjfr Nov 17, 2024
2158148
More types
philippjfr Nov 17, 2024
5264b2f
More types
philippjfr Nov 17, 2024
60b9eb4
More types
philippjfr Nov 17, 2024
ef2fd79
Fix up type error
philippjfr Nov 17, 2024
4b8da9b
Fix tests
philippjfr Nov 17, 2024
04ca6fe
Apply suggestions from code review
philippjfr Nov 17, 2024
19d68bf
Fix up type
philippjfr Nov 17, 2024
5218def
fix textual tests
philippjfr Nov 17, 2024
c867531
Merge branch 'main' into linked_props_types
philippjfr Nov 18, 2024
1a7f4d1
Fix JupyterServerContext
philippjfr Nov 18, 2024
197ff5a
Back out of JupyterServerContext
philippjfr Nov 18, 2024
daa8493
Address review comments
philippjfr Nov 18, 2024
060f415
revert version upgrade
philippjfr Nov 18, 2024
46c1107
Apply suggestions from code review
philippjfr Dec 2, 2024
770be06
Resolve review comments
philippjfr Dec 2, 2024
8c7443a
Small fix
philippjfr Dec 2, 2024
875aeca
Fix types
philippjfr Dec 2, 2024
b8253e3
Another fix
philippjfr Dec 2, 2024
16bd060
Merge branch 'main' into linked_props_types
philippjfr Dec 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix tests
  • Loading branch information
philippjfr committed Nov 17, 2024
commit 4b8da9b192dcd16e3ec971142e4a82855a2a62dd
7 changes: 3 additions & 4 deletions panel/pane/deckgl.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,10 +278,9 @@ def _get_model(
self, doc: Document, root: Model | None = None,
parent: Model | None = None, comm: Comm | None = None
) -> Model:
if self._bokeh_model is None:
DeckGL._bokeh_model = lazy_load(
'panel.models.deckgl', 'DeckGLPlot', isinstance(comm, JupyterComm), root
)
DeckGL._bokeh_model = lazy_load(
'panel.models.deckgl', 'DeckGLPlot', isinstance(comm, JupyterComm), root
)
properties = self._get_properties(doc)
data = properties.pop('data')
sources: list[ColumnDataSource] = []
Expand Down
7 changes: 3 additions & 4 deletions panel/pane/echarts.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,9 @@ def _get_model(
self, doc: Document, root: Model | None = None,
parent: Model | None = None, comm: Comm | None = None
) -> Model:
if self._bokeh_model is None:
ECharts._bokeh_model = lazy_load(
'panel.models.echarts', 'ECharts', isinstance(comm, JupyterComm), root
)
ECharts._bokeh_model = lazy_load(
'panel.models.echarts', 'ECharts', isinstance(comm, JupyterComm), root
)
model = super()._get_model(doc, root, parent, comm)
self._register_events('echarts_event', model=model, doc=doc, comm=comm)
return model
Expand Down
7 changes: 3 additions & 4 deletions panel/pane/perspective.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,10 +477,9 @@ def _get_model(
self, doc: Document, root: Model | None = None,
parent: Model | None = None, comm: Comm | None = None
) -> Model:
if not self._bokeh_model:
Perspective._bokeh_model = lazy_load(
'panel.models.perspective', 'Perspective', isinstance(comm, JupyterComm), root
)
Perspective._bokeh_model = lazy_load(
'panel.models.perspective', 'Perspective', isinstance(comm, JupyterComm), root
)
model = super()._get_model(doc, root, parent, comm)
self._register_events('perspective-click', model=model, doc=doc, comm=comm)
return model
Expand Down
7 changes: 3 additions & 4 deletions panel/pane/plotly.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,9 @@ def _get_model(
self, doc: Document, root: Model | None = None,
parent: Model | None = None, comm: Comm | None = None
) -> Model:
if not self._bokeh_model:
Plotly._bokeh_model = lazy_load(
'panel.models.plotly', 'PlotlyPlot', isinstance(comm, JupyterComm), root
)
Plotly._bokeh_model = lazy_load(
hoxbro marked this conversation as resolved.
Show resolved Hide resolved
'panel.models.plotly', 'PlotlyPlot', isinstance(comm, JupyterComm), root
)
model = super()._get_model(doc, root, parent, comm)
self._register_events('plotly_event', model=model, doc=doc, comm=comm)
return model
Expand Down
7 changes: 3 additions & 4 deletions panel/pane/vega.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,9 @@ def _get_model(
self, doc: Document, root: Model | None = None,
parent: Model | None = None, comm: Comm | None = None
) -> Model:
if self._bokeh_model is None:
Vega._bokeh_model = lazy_load(
'panel.models.vega', 'VegaPlot', isinstance(comm, JupyterComm), root
)
Vega._bokeh_model = lazy_load(
'panel.models.vega', 'VegaPlot', isinstance(comm, JupyterComm), root
)
model = super()._get_model(doc, root, parent, comm)
self._register_events('vega_event', model=model, doc=doc, comm=comm)
return model
Expand Down
7 changes: 3 additions & 4 deletions panel/pane/vizzu.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,9 @@ def _get_model(
self, doc: Document, root: Model | None = None,
parent: Model | None = None, comm: Comm | None = None
) -> Model:
if self._bokeh_model is None:
Vizzu._bokeh_model = lazy_load(
'panel.models.vizzu', 'VizzuChart', isinstance(comm, JupyterComm), root
)
Vizzu._bokeh_model = lazy_load(
'panel.models.vizzu', 'VizzuChart', isinstance(comm, JupyterComm), root
)
model = super()._get_model(doc, root, parent, comm)
self._register_events('vizzu_event', model=model, doc=doc, comm=comm)
return model
Expand Down
6 changes: 4 additions & 2 deletions panel/template/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ class BaseTemplate(param.Parameterized, MimeRenderMixin, ServableMixin, Resource
#############

# pathlib.Path pointing to local CSS file(s)
_css: ClassVar[list[os.PathLike | str]] = []
_css: ClassVar[list[Path | str]] = []

# pathlib.Path pointing to local JS file(s)
_js: ClassVar[os.PathLike | str | list[Path | str] | None] = None
_js: ClassVar[Path | str | list[Path | str] | None] = None

# External resources
_resources = {
Expand Down Expand Up @@ -392,6 +392,8 @@ def resolve_resources(

# CSS files
base_css = self._css
if not isinstance(base_css, list):
base_css = [base_css] if base_css else []
for css in base_css:
tmpl_name = name
for scls in cls.__mro__[1:]:
Expand Down
9 changes: 4 additions & 5 deletions panel/widgets/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,11 +383,10 @@ def _get_model(
self, doc: Document, root: Model | None = None,
parent: Model | None = None, comm: Comm | None = None
) -> Model:
if self._widget_type is None:
FileDropper._widget_type = lazy_load(
'panel.models.file_dropper', 'FileDropper', isinstance(comm, JupyterComm), root,
ext='filedropper'
)
FileDropper._widget_type = lazy_load(
'panel.models.file_dropper', 'FileDropper', isinstance(comm, JupyterComm), root,
ext='filedropper'
)
model = super()._get_model(doc, root, parent, comm)
self._register_events('delete_event', 'upload_event', model=model, doc=doc, comm=comm)
return model
Expand Down
7 changes: 3 additions & 4 deletions panel/widgets/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,9 +335,8 @@ class JSONEditor(Widget):
}

def _get_model(self, doc, root=None, parent=None, comm=None):
if self._widget_type is None:
JSONEditor._widget_type = lazy_load(
"panel.models.jsoneditor", "JSONEditor", isinstance(comm, JupyterComm)
)
JSONEditor._widget_type = lazy_load(
"panel.models.jsoneditor", "JSONEditor", isinstance(comm, JupyterComm)
)
model = super()._get_model(doc, root, parent, comm)
return model
2 changes: 1 addition & 1 deletion panel/widgets/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ def _process_param_change(self, msg: dict[str, Any]) -> dict[str, Any]:
}
else:
options = {
group: [str(v) for v in self.groups[group]]
group: [str(v) for v in self.groups[group]] # type: ignore
for group in groups.keys()
}
msg['options'] = options
Expand Down
66 changes: 33 additions & 33 deletions panel/widgets/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from functools import partial
from types import FunctionType, MethodType
from typing import (
TYPE_CHECKING, Any, ClassVar, Literal, Sequence, TypedDict,
TYPE_CHECKING, Any, ClassVar, Literal, Sequence, TypedDict, cast,
)

import numpy as np
Expand All @@ -27,7 +27,7 @@

from ..io.resources import CDN_DIST, CSS_URLS
from ..io.state import state
from ..reactive import Reactive, ReactiveData, TDataColumn
from ..reactive import Reactive, ReactiveData
from ..util import (
BOKEH_GE_3_6, clone_model, datetime_as_utctimestamp, isdatetime, lazy_load,
styler_update, updating,
Expand All @@ -47,34 +47,35 @@
from ..models.tabulator import (
CellClickEvent, SelectionEvent, TableEditEvent,
)
from ..reactive import TDataColumn

class FilterSpec(TypedDict, total=False):
headerFilter: str | bool
headerFilterParams: dict[str, Any]
headerFilterFunc: str
headerFilterPlaceholder: str

class ColumnSpec(TypedDict, total=False):
editable: bool
editor: str | CellEditor
editorParams: dict[str, Any]
field: str
frozen: bool
headerHozAlign: Literal["center", "left", "right"]
headerSort: bool
headerTooltip: str
hozAlign: Literal["center", "left", "right"]
formatter: str | CellFormatter
formatterParams: dict[str, Any]
sorter: str
title: str
titleFormatter: str | CellFormatter
titleFormatterParams: dict[str, Any]
width: str | int

class GroupSpec(TypedDict):
columns: list[ColumnSpec]
title: str
class ColumnSpec(TypedDict, total=False):
editable: bool
editor: str | CellEditor
editorParams: dict[str, Any]
field: str
frozen: bool
headerHozAlign: Literal["center", "left", "right"]
headerSort: bool
headerTooltip: str
hozAlign: Literal["center", "left", "right"]
formatter: str | CellFormatter
formatterParams: dict[str, Any]
sorter: str
title: str
titleFormatter: str | CellFormatter
titleFormatterParams: dict[str, Any]
width: str | int

class GroupSpec(TypedDict):
columns: Sequence[ColumnSpec]
title: str


def _convert_datetime_array_ignore_list(v):
Expand Down Expand Up @@ -1851,10 +1852,9 @@ def _get_model(
self, doc: Document, root: Model | None = None,
parent: Model | None = None, comm: Comm | None = None
) -> Model:
if self._widget_type is None:
Tabulator._widget_type = lazy_load(
'panel.models.tabulator', 'DataTabulator', isinstance(comm, JupyterComm), root
)
Tabulator._widget_type = lazy_load(
'panel.models.tabulator', 'DataTabulator', isinstance(comm, JupyterComm), root
)
model = super()._get_model(doc, root, parent, comm)
root = root or model
self._child_panels, removed, expanded = self._get_children()
Expand Down Expand Up @@ -1935,7 +1935,7 @@ def _get_filter_spec(self, column: TableColumn) -> FilterSpec:
def _config_columns(self, column_objs: list[TableColumn]) -> Sequence[ColumnSpec | GroupSpec]:
column_objs = list(column_objs)
groups: dict[str, GroupSpec] = {}
columns: list[ColumnSpec] = []
columns: Sequence[ColumnSpec | GroupSpec] = []
selectable = self.selectable
if self.row_content:
columns.append({
Expand Down Expand Up @@ -1988,7 +1988,7 @@ def _config_columns(self, column_objs: list[TableColumn]) -> Sequence[ColumnSpec
elif not self.sortable:
col_dict['headerSort'] = self.sortable
if isinstance(self.text_align, str):
col_dict['hozAlign'] = self.text_align
col_dict['hozAlign'] = self.text_align # type: ignore
elif field in self.text_align:
col_dict['hozAlign'] = self.text_align[field]
if isinstance(self.header_align, str):
Expand Down Expand Up @@ -2052,7 +2052,7 @@ def _config_columns(self, column_objs: list[TableColumn]) -> Sequence[ColumnSpec
if isinstance(index, tuple):
if columns:
children = columns
last = children[-1]
last = cast(GroupSpec, children[-1])
for group in index[:-1]:
if 'title' in last and last['title'] == group:
new = False
Expand All @@ -2063,7 +2063,7 @@ def _config_columns(self, column_objs: list[TableColumn]) -> Sequence[ColumnSpec
'columns': [],
'title': group,
})
last = children[-1]
last = cast(GroupSpec, children[-1])
if new:
children = last['columns']
children.append(col_dict)
Expand All @@ -2073,7 +2073,7 @@ def _config_columns(self, column_objs: list[TableColumn]) -> Sequence[ColumnSpec
if group in groups:
groups[group]['columns'].append(col_dict)
continue
group_dict = {
group_dict: GroupSpec = {
'title': group,
'columns': [col_dict]
}
Expand All @@ -2083,7 +2083,7 @@ def _config_columns(self, column_objs: list[TableColumn]) -> Sequence[ColumnSpec
columns.append(col_dict)
return columns

def _get_configuration(self, columns: list[dict[str, Any]]) -> dict[str, Any]:
def _get_configuration(self, columns: list[TableColumn]) -> dict[str, Any]:
"""
Returns the Tabulator configuration.
"""
Expand Down
7 changes: 3 additions & 4 deletions panel/widgets/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,9 @@ def write(self, __s):
return len(self.output)

def _get_model(self, doc, root=None, parent=None, comm=None):
if self._widget_type is None:
Terminal._widget_type = lazy_load(
'panel.models.terminal', 'Terminal', isinstance(comm, JupyterComm), root
)
Terminal._widget_type = lazy_load(
'panel.models.terminal', 'Terminal', isinstance(comm, JupyterComm), root
)
model = super()._get_model(doc, root, parent, comm)
model.output = self.output
self._register_events('keystroke', model=model, doc=doc, comm=comm)
Expand Down
9 changes: 4 additions & 5 deletions panel/widgets/texteditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,8 @@ def _get_model(
self, doc: Document, root: Model | None = None,
parent: Model | None = None, comm: Comm | None = None
) -> Model:
if self._widget_type is None:
TextEditor._widget_type = lazy_load(
'panel.models.quill', 'QuillInput', isinstance(comm, JupyterComm),
root, ext='texteditor'
)
TextEditor._widget_type = lazy_load(
'panel.models.quill', 'QuillInput', isinstance(comm, JupyterComm),
root, ext='texteditor'
)
return super()._get_model(doc, root, parent, comm)
41 changes: 21 additions & 20 deletions panel/widgets/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from collections.abc import Iterable, Mapping
from inspect import Parameter
from numbers import Integral, Number, Real
from numbers import Integral, Real
from typing import Any

empty = Parameter.empty
Expand Down Expand Up @@ -37,18 +37,19 @@ def get_interact_value(self):


def _get_min_max_value(
min: Number, max: Number, value: Number | None = None, step: Number | None = None
) -> tuple[Number, Number, Number]:
minimum: int | float, maximum: int | float, value: int | float | None = None, step: int | float | None = None
) -> tuple[int | float, int | float, int | float]:
"""Return min, max, value given input values with possible None."""
# Either min and max need to be given, or value needs to be given
if value is None:
if min is None or max is None:
raise ValueError(f'unable to infer range, value from: ({min}, {max}, {value})')
diff = max - min
value = min + (diff / 2)
if minimum is None or max is maximum:
raise ValueError(f'unable to infer range, value from: ({minimum}, {maximum}, {value})')

diff = maximum - minimum
value = minimum + (diff / 2)
# Ensure that value has the same type as diff
if not isinstance(value, type(diff)):
value = min + (diff // 2)
value = minimum + (diff // 2)
else: # value is not None
if not isinstance(value, Real):
raise TypeError(f'expected a real number, got: {value!r}')
Expand All @@ -60,25 +61,25 @@ def _get_min_max_value(
vrange = (-value, 3*value)
else:
vrange = (3*value, -value)
if min is None:
min = vrange[0]
if max is None:
max = vrange[1]
if minimum is None:
minimum = vrange[0]
if maximum is None:
maximum = vrange[1]
if step is not None:
# ensure value is on a step
tick = int((value - min) / step)
value = min + tick * step
if not min <= value <= max:
raise ValueError(f'value must be between min and max (min={min}, value={value}, max={max})')
return min, max, value
tick = int((value - minimum) / step)
value = minimum + tick * step
if not (minimum <= value <= maximum):
raise ValueError(f'value must be between min and max (min={minimum}, value={value}, max={maximum})')
return minimum, maximum, value


def _matches(o: str, pattern: str) -> bool:
def _matches(o: tuple[Any, ...], pattern: tuple[type, ...]) -> bool:
"""Match a pattern of types in a sequence."""
if not len(o) == len(pattern):
return False
comps = zip(o,pattern)
return all(isinstance(obj,kind) for obj,kind in comps)
comps = zip(o, pattern)
return all(isinstance(obj, kind) for obj, kind in comps)


class widget(param.ParameterizedFunction):
Expand Down
Loading