Skip to content

Commit

Permalink
More types
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Nov 17, 2024
1 parent 6e38a3c commit 2158148
Show file tree
Hide file tree
Showing 16 changed files with 66 additions and 91 deletions.
86 changes: 29 additions & 57 deletions panel/command/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,25 @@
from bokeh.util.strings import nice_join

from .. import __version__
from ..config import config
from .bundle import Bundle
from .compile import Compile
from .convert import Convert
from .oauth_secret import OAuthSecret
from .serve import Serve

description = """\
Found a Bug or Have a Feature Request?
Open an issue at: https://github.com/holoviz/panel/issues
Have a Question?
Ask on our Discord chat server: https://discord.gg/rb6gPXbdAr
Need Help?
Ask a question on our forum: https://discourse.holoviz.org
For more information, see the documentation at: https://panel.holoviz.org """


def transform_cmds(argv):
"""
Expand Down Expand Up @@ -51,77 +64,36 @@ def transform_cmds(argv):

def main(args: list[str] | None = None):
from bokeh.command.subcommands import all as bokeh_commands
bokeh_commands = bokeh_commands + [OAuthSecret, Compile, Convert, Bundle]

description = """\
Found a Bug or Have a Feature Request?
Open an issue at: https://github.com/holoviz/panel/issues
Have a Question?
Ask on our Discord chat server: https://discord.gg/rb6gPXbdAr
Need Help?
Ask a question on our forum: https://discourse.holoviz.org
For more information, see the documentation at: https://panel.holoviz.org """

parser = argparse.ArgumentParser(
prog="panel", epilog="See '<command> --help' to read about a specific subcommand.",
description=description, formatter_class=argparse.RawTextHelpFormatter
)

parser.add_argument('-v', '--version', action='version', version=__version__)

subs = parser.add_subparsers(help="Sub-commands")

for cls in bokeh_commands:
if cls is BkServe:
subparser = subs.add_parser(Serve.name, help=Serve.help)
serve_subcommand = Serve(parser=subparser)
subparser.set_defaults(invoke=serve_subcommand.invoke)
elif cls is Compile:
subparser = subs.add_parser(Compile.name, help=Compile.help)
compile_subcommand = Compile(parser=subparser)
subparser.set_defaults(invoke=compile_subcommand.invoke)
elif cls is Convert:
subparser = subs.add_parser(Convert.name, help=Convert.help)
convert_subcommand = Convert(parser=subparser)
subparser.set_defaults(invoke=convert_subcommand.invoke)
elif cls is Bundle:
subparser = subs.add_parser(Bundle.name, help=Bundle.help)
bundle_subcommand = Bundle(parser=subparser)
subparser.set_defaults(invoke=bundle_subcommand.invoke)
else:
subs.add_parser(cls.name, help=cls.help)
commands = list(bokeh_commands)
for command in commands:
if command is not BkServe:
subs.add_parser(command.name, help=command.help)
for extra in (Bundle, Compile, Convert, OAuthSecret, Serve):
commands.append(extra)
subparser = subs.add_parser(extra.name, help=extra.help)
subcommand = extra(parser=subparser)
subparser.set_defaults(invoke=subcommand.invoke)

if len(sys.argv) == 1:
all_commands = sorted([c.name for c in bokeh_commands])
all_commands = sorted([c.name for c in commands])
die(f"ERROR: Must specify subcommand, one of: {nice_join(all_commands)}")

if sys.argv[1] in ('--help', '-h'):
parser = parser.parse_args(sys.argv[1:])
parser.invoke(args)
sys.exit()

if len(sys.argv) > 1 and any(sys.argv[1] == c.name for c in bokeh_commands):
elif len(sys.argv) > 1 and any(sys.argv[1] == c.name for c in commands):
sys.argv = transform_cmds(sys.argv)
if sys.argv[1] == 'serve':
args = parser.parse_args(sys.argv[1:])
if sys.argv[1] in ('bundle', 'compile', 'convert', 'serve', 'help'):
parsed_args = parser.parse_args(sys.argv[1:])
try:
ret = args.invoke(args)
ret = parsed_args.invoke(parsed_args)
except Exception as e:
if config.dev:
raise e
die("ERROR: " + str(e))
elif sys.argv[1] == 'oauth-secret':
ret = OAuthSecret(parser).invoke(args)
elif sys.argv[1] == 'convert':
args = parser.parse_args(sys.argv[1:])
ret = Convert(parser).invoke(args)
elif sys.argv[1] == 'bundle':
args = parser.parse_args(sys.argv[1:])
ret = Bundle(parser).invoke(args)
elif sys.argv[1] == 'compile':
args = parser.parse_args(sys.argv[1:])
ret = Compile(parser).invoke(args)
else:
ret = bokeh_entry_point()
else:
Expand Down
2 changes: 1 addition & 1 deletion panel/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ class CounterButton(pn.custom.ReactComponent):
@classproperty # type: ignore
def _exports__(cls) -> ExportSpec:
imports = cls._importmap.get('imports', {})
exports = {
exports: dict[str, list[str | tuple[str, ...]]] = {
"react": ["*React"],
"react-dom/client": [("createRoot",)]
}
Expand Down
5 changes: 3 additions & 2 deletions panel/pane/deckgl.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def _process_data(cls, data):
return {col: np.asarray(vals) for col, vals in columns.items()}

@classmethod
def _update_sources(cls, json_data, sources):
def _update_sources(cls, json_data, sources: list[ColumnDataSource]):
layers = json_data.get('layers', [])

# Create index of sources by columns
Expand Down Expand Up @@ -284,7 +284,8 @@ def _get_model(
)
properties = self._get_properties(doc)
data = properties.pop('data')
properties['data_sources'] = sources = []
sources: list[ColumnDataSource] = []
properties['data_sources'] = sources
self._update_sources(data, sources)
properties['layers'] = data.pop('layers', [])
properties['initialViewState'] = data.pop('initialViewState', {})
Expand Down
2 changes: 1 addition & 1 deletion panel/pane/echarts.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def _process_param_change(self, params):
props['sizing_mode'] = 'stretch_both'
return props

def _get_properties(self, document: Document):
def _get_properties(self, document: Document | None) -> dict[str, Any]:
props = super()._get_properties(document)
props['event_config'] = {
event: list(queries) for event, queries in self._py_callbacks.items()
Expand Down
2 changes: 1 addition & 1 deletion panel/pane/equation.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def applies(cls, obj: Any) -> float | bool | None:
else:
return False

def _get_model_type(self, root: Model, comm: Comm | None) -> type[Model]:
def _get_model_type(self, root: Model | None, comm: Comm | None) -> type[Model]:
module = self.renderer
if module is None:
if 'panel.models.mathjax' in sys.modules and 'panel.models.katex' not in sys.modules:
Expand Down
4 changes: 2 additions & 2 deletions panel/pane/ipywidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class IPyLeaflet(IPyWidget):
'fixed', 'stretch_width', 'stretch_height', 'stretch_both',
'scale_width', 'scale_height', 'scale_both', None])

priority: float | bool | None = 0.7
priority: ClassVar[float | bool | None] = 0.7

@classmethod
def applies(cls, obj: Any) -> float | bool | None:
Expand Down Expand Up @@ -123,7 +123,7 @@ def _get_ipywidget(
return super()._get_ipywidget(widget, doc, root, comm, **kwargs)


_ipywidget_classes = {}
_ipywidget_classes: dict[str, type[param.Parameterized]] = {}

def _ipywidget_transform(obj):
"""
Expand Down
8 changes: 4 additions & 4 deletions panel/pane/markup.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,8 @@ def _transform_object(self, obj: Any) -> dict[str, Any]:
if 'dask' in module:
html = obj.to_html(max_rows=self.max_rows).replace('border="1"', '')
elif 'style' in module:
classes = ' '.join(classes)
html = obj.to_html(table_attributes=f'class="{classes}"')
class_string = ' '.join(classes)
html = obj.to_html(table_attributes=f'class="{class_string}"')
else:
kwargs = {p: getattr(self, p) for p in self._rerender_params
if p not in HTMLBasePane.param and p not in ('_object', 'text_align')}
Expand Down Expand Up @@ -460,7 +460,7 @@ def _transform_object(self, obj: Any) -> dict[str, Any]:
html = markdown.markdown(
obj,
extensions=self.extensions,
output_format='html5',
output_format='xhtml',
**self.renderer_options
)
else:
Expand Down Expand Up @@ -511,7 +511,7 @@ class JSON(HTMLBasePane):

_applies_kw: ClassVar[bool] = True

_bokeh_model: ClassVar[Model] = _BkJSON
_bokeh_model: ClassVar[type[Model]] = _BkJSON

_rename: ClassVar[Mapping[str, str | None]] = {
"object": "text", "encoder": None, "style": "styles"
Expand Down
12 changes: 7 additions & 5 deletions panel/pane/media.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,20 @@ def applies(cls, obj: Any) -> float | bool | None:
return True
return False

def _to_np_int16(self, data: np.ndarray):
def _to_np_int16(self, data: np.ndarray) -> np.ndarray:
dtype = data.dtype

if dtype in (np.float32, np.float64):
data = (data * 32768.0).astype(np.int16)

return data

def _to_buffer(self, data: np.ndarray|TensorLike):
if isinstance(data, TensorLike):
data = data.numpy()
data = self._to_np_int16(data)
def _to_buffer(self, data: np.ndarray | TensorLike):
if isinstance(data, np.ndarray):
values = data
elif isinstance(data, TensorLike):
values = data.numpy()
data = self._to_np_int16(values)

from scipy.io import wavfile
buffer = BytesIO()
Expand Down
2 changes: 1 addition & 1 deletion panel/pane/plotly.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def _update(self, ref: str, model: Model) -> None:
except Exception:
update_frames = True

updates = {}
updates: dict[str, Any] = {}
if self.sizing_mode is self.param.sizing_mode.default and 'autosize' in layout:
autosize = layout.get('autosize')
styles = dict(model.styles)
Expand Down
2 changes: 1 addition & 1 deletion panel/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ def parse_timedelta(time_str: str) -> dt.timedelta | None:
return dt.timedelta(**time_params)


def fullpath(path: AnyStr | os.PathLike) -> AnyStr | os.PathLike:
def fullpath(path: AnyStr | os.PathLike) -> AnyStr:
"""Expanduser and then abspath for a given path
"""
return os.path.abspath(os.path.expanduser(path))
Expand Down
4 changes: 2 additions & 2 deletions panel/widgets/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class IconMixin(Widget):
__abstract = True

def __init__(self, **params) -> None:
self._rename = dict(self._rename, **IconMixin._rename)
type(self)._rename = dict(self._rename, **IconMixin._rename)
super().__init__(**params)

def _process_param_change(self, params):
Expand Down Expand Up @@ -289,7 +289,7 @@ class Toggle(_ButtonBase, IconMixin):
'value': 'active', 'name': 'label',
}

_supports_embed: ClassVar[bool] = True
_supports_embed: bool = True

_widget_type: ClassVar[type[Model]] = _BkToggle

Expand Down
6 changes: 3 additions & 3 deletions panel/widgets/file_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ def __init__(self, directory: AnyStr | os.PathLike | None = None, **params):
self.link(self._selector, size='size')

# Set up state
self._stack = []
self._cwd = None
self._stack: list[str] = []
self._cwd: str | None = None
self._position = -1
self._update_files(True)

Expand Down Expand Up @@ -203,7 +203,7 @@ def _update_files(
self, event: param.parameterized.Event | None = None, refresh: bool = False
):
path = fullpath(self._directory.value)
refresh = refresh or (event and getattr(event, 'obj', None) is self._reload)
refresh = bool(refresh or (event and getattr(event, 'obj', None) is self._reload))
if refresh:
path = self._cwd
elif not os.path.isdir(path):
Expand Down
4 changes: 2 additions & 2 deletions panel/widgets/indicators.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
try:
from tqdm.asyncio import tqdm as _tqdm
except ImportError:
_tqdm = None
_tqdm = None # type: ignore

RED = "#d9534f"
GREEN = "#5cb85c"
Expand Down Expand Up @@ -1221,7 +1221,7 @@ def _process_param_change(self, msg):



class ptqdm(_tqdm or object):
class ptqdm(_tqdm or object): # type: ignore

def __init__(self, *args, **kwargs):
if _tqdm is None:
Expand Down
6 changes: 3 additions & 3 deletions panel/widgets/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,8 @@ def _process_event(self, event: DeleteEvent | UploadEvent):
return

buffers = self._file_buffer.pop(name)
file_buffer = b''.join(buffers)
if data['type'].startswith('text/'):
file_buffer: bytes | str = b''.join(buffers)
if data['type'].startswith('text/') and isinstance(file_buffer, bytes):
try:
file_buffer = file_buffer.decode('utf-8')
except UnicodeDecodeError:
Expand Down Expand Up @@ -1487,7 +1487,7 @@ class _BooleanWidget(Widget):
value = param.Boolean(default=False, doc="""
The current value""")

_supports_embed: ClassVar[bool] = True
_supports_embed: bool = True

_rename: ClassVar[Mapping[str, str | None]] = {'value': 'active', 'name': 'label'}

Expand Down
2 changes: 1 addition & 1 deletion panel/widgets/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class Player(PlayerBase):
value_throttled = param.Integer(default=0, constant=True, doc="""
Current throttled player value.""")

_supports_embed: ClassVar[bool] = True
_supports_embed: bool = True

def __init__(self, **params):
if 'length' in params:
Expand Down
10 changes: 5 additions & 5 deletions panel/widgets/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class SingleSelectBase(SelectBase):

_allows_none: ClassVar[bool] = False

_supports_embed: ClassVar[bool] = True
_supports_embed: bool = True

__abstract = True

Expand Down Expand Up @@ -275,7 +275,7 @@ def _process_param_change(self, msg: dict[str, Any]) -> dict[str, Any]:
groups_provided = 'groups' in msg
msg = super()._process_param_change(msg)
if groups_provided or 'options' in msg and self.groups:
groups = self.groups
groups: dict[str, list[str | tuple[str, str]]] = self.groups
if (all(isinstance(values, dict) for values in groups.values()) is False
and all(isinstance(values, list) for values in groups.values()) is False):
raise ValueError(
Expand Down Expand Up @@ -737,7 +737,7 @@ class _MultiSelectBase(SingleSelectBase):
description = param.String(default=None, doc="""
An HTML string describing the function of this component.""")

_supports_embed: ClassVar[bool] = False
_supports_embed: bool = False

__abstract = True

Expand Down Expand Up @@ -1049,7 +1049,7 @@ class RadioButtonGroup(_RadioGroupBase, _ButtonBase, TooltipMixin):
'value': "source.labels[value]", 'button_style': None, 'description': None
}

_supports_embed: ClassVar[bool] = True
_supports_embed: bool = True

_widget_type: ClassVar[type[Model]] = _BkRadioButtonGroup

Expand Down Expand Up @@ -1077,7 +1077,7 @@ class RadioBoxGroup(_RadioGroupBase):
Whether the items be arrange vertically (``False``) or
horizontally in-line (``True``).""")

_supports_embed: ClassVar[bool] = True
_supports_embed: bool = True

_widget_type: ClassVar[type[Model]] = _BkRadioBoxGroup

Expand Down

0 comments on commit 2158148

Please sign in to comment.