From 966e0a41fc61e7850378ae672e28202eb29b10b0 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sun, 22 Oct 2023 10:05:14 -0500 Subject: [PATCH] Update lint deps and add more typing (#1156) --- ipykernel/connect.py | 20 +++++++++++++------- ipykernel/kernelapp.py | 1 + ipykernel/kernelspec.py | 41 ++++++++++++++++++++++++++--------------- ipykernel/zmqshell.py | 1 + pyproject.toml | 4 ++-- 5 files changed, 43 insertions(+), 24 deletions(-) diff --git a/ipykernel/connect.py b/ipykernel/connect.py index 25571649..3336ced0 100644 --- a/ipykernel/connect.py +++ b/ipykernel/connect.py @@ -2,17 +2,21 @@ """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. +from __future__ import annotations import json import sys from subprocess import PIPE, Popen -from typing import Any, Dict +from typing import TYPE_CHECKING, Any import jupyter_client from jupyter_client import write_connection_file +if TYPE_CHECKING: + from ipykernel.kernelapp import IPKernelApp -def get_connection_file(app=None): + +def get_connection_file(app: IPKernelApp | None = None) -> str: """Return the path to the connection file of an app Parameters @@ -46,7 +50,9 @@ def _find_connection_file(connection_file): return jupyter_client.find_connection_file(connection_file) -def get_connection_info(connection_file=None, unpack=False): +def get_connection_info( + connection_file: str | None = None, unpack: bool = False +) -> str | dict[str, Any]: """Return the connection information for the current Kernel. Parameters @@ -77,12 +83,12 @@ def get_connection_info(connection_file=None, unpack=False): info = json.loads(info_str) # ensure key is bytes: info["key"] = info.get("key", "").encode() - return info + return info # type:ignore[no-any-return] return info_str -def connect_qtconsole(connection_file=None, argv=None): +def connect_qtconsole(connection_file: str | None = None, argv: list[str] | None = None) -> Popen: """Connect a qtconsole to the current kernel. This is useful for connecting a second qtconsole to a kernel, or to a @@ -111,13 +117,13 @@ def connect_qtconsole(connection_file=None, argv=None): cmd = ";".join(["from qtconsole import qtconsoleapp", "qtconsoleapp.main()"]) - kwargs: Dict[str, Any] = {} + kwargs: dict[str, Any] = {} # Launch the Qt console in a separate session & process group, so # interrupting the kernel doesn't kill it. kwargs["start_new_session"] = True return Popen( - [sys.executable, "-c", cmd, "--existing", cf, *argv], # noqa + [sys.executable, "-c", cmd, "--existing", cf, *argv], # noqa: S603 stdout=PIPE, stderr=PIPE, close_fds=(sys.platform != "win32"), diff --git a/ipykernel/kernelapp.py b/ipykernel/kernelapp.py index dae72def..de4682f8 100644 --- a/ipykernel/kernelapp.py +++ b/ipykernel/kernelapp.py @@ -275,6 +275,7 @@ def write_connection_file(self): # original file had port number 0, we update with the actual port # used. existing_connection_info = get_connection_info(cf, unpack=True) + assert isinstance(existing_connection_info, dict) connection_info = dict(existing_connection_info, **connection_info) if connection_info == existing_connection_info: self.log.debug("Connection file %s with current information already exists", cf) diff --git a/ipykernel/kernelspec.py b/ipykernel/kernelspec.py index 320afff9..6404c2a1 100644 --- a/ipykernel/kernelspec.py +++ b/ipykernel/kernelspec.py @@ -3,6 +3,8 @@ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. +from __future__ import annotations + import errno import json import os @@ -10,6 +12,7 @@ import stat import sys import tempfile +from typing import Any from jupyter_client.kernelspec import KernelSpecManager from traitlets import Unicode @@ -27,7 +30,11 @@ RESOURCES = pjoin(os.path.dirname(__file__), "resources") -def make_ipkernel_cmd(mod="ipykernel_launcher", executable=None, extra_arguments=None): +def make_ipkernel_cmd( + mod: str = "ipykernel_launcher", + executable: str | None = None, + extra_arguments: list[str] | None = None, +) -> list[str]: """Build Popen command list for launching an IPython kernel. Parameters @@ -52,7 +59,7 @@ def make_ipkernel_cmd(mod="ipykernel_launcher", executable=None, extra_arguments return arguments -def get_kernel_dict(extra_arguments=None): +def get_kernel_dict(extra_arguments: list[str] | None = None) -> dict[str, Any]: """Construct dict for kernel.json""" return { "argv": make_ipkernel_cmd(extra_arguments=extra_arguments), @@ -62,7 +69,11 @@ def get_kernel_dict(extra_arguments=None): } -def write_kernel_spec(path=None, overrides=None, extra_arguments=None): +def write_kernel_spec( + path: str | None = None, + overrides: dict[str, Any] | None = None, + extra_arguments: list[str] | None = None, +) -> str: """Write a kernel spec directory to `path` If `path` is not specified, a temporary directory is created. @@ -93,14 +104,14 @@ def write_kernel_spec(path=None, overrides=None, extra_arguments=None): def install( - kernel_spec_manager=None, - user=False, - kernel_name=KERNEL_NAME, - display_name=None, - prefix=None, - profile=None, - env=None, -): + kernel_spec_manager: KernelSpecManager | None = None, + user: bool = False, + kernel_name: str = KERNEL_NAME, + display_name: str | None = None, + prefix: str | None = None, + profile: str | None = None, + env: dict[str, str] | None = None, +) -> str: """Install the IPython kernelspec for Jupyter Parameters @@ -136,7 +147,7 @@ def install( # kernel_name is specified and display_name is not # default display_name to kernel_name display_name = kernel_name - overrides = {} + overrides: dict[str, Any] = {} if display_name: overrides["display_name"] = display_name if profile: @@ -154,7 +165,7 @@ def install( ) # cleanup afterward shutil.rmtree(path) - return dest + return dest # type:ignore[no-any-return] # Entrypoint @@ -167,13 +178,13 @@ class InstallIPythonKernelSpecApp(Application): name = Unicode("ipython-kernel-install") - def initialize(self, argv=None): + def initialize(self, argv: list[str] | None = None) -> None: """Initialize the app.""" if argv is None: argv = sys.argv[1:] self.argv = argv - def start(self): + def start(self) -> None: """Start the app.""" import argparse diff --git a/ipykernel/zmqshell.py b/ipykernel/zmqshell.py index 617c37a6..d381a5c9 100644 --- a/ipykernel/zmqshell.py +++ b/ipykernel/zmqshell.py @@ -378,6 +378,7 @@ def connect_info(self, arg_s): if jupyter_runtime_dir() == os.path.dirname(connection_file): connection_file = os.path.basename(connection_file) + assert isinstance(info, str) print(info + "\n") print( f"Paste the above JSON into a file, and connect with:\n" diff --git a/pyproject.toml b/pyproject.toml index f34c5482..8f9ac894 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -112,12 +112,12 @@ matrix.qt.features = [ [tool.hatch.envs.typing] features = ["test"] -dependencies = ["mypy>=1.5.1", "traitlets>=5.11.2", "ipython>=8.16.1"] +dependencies = ["mypy>=1.6.0", "traitlets>=5.11.2", "ipython>=8.16.1"] [tool.hatch.envs.typing.scripts] test = "mypy --install-types --non-interactive {args}" [tool.hatch.envs.lint] -dependencies = ["black==23.3.0", "mdformat>0.7", "ruff==0.0.287"] +dependencies = ["black==23.3.0", "mdformat>0.7", "ruff==0.1.1"] detached = true [tool.hatch.envs.lint.scripts] style = [