From 3bd84be7944b5f9ec7d1999fd95a4daf2582a952 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 3 Nov 2023 07:43:43 -0500 Subject: [PATCH 1/3] clean up typing config --- .pre-commit-config.yaml | 10 ++++++++ ipykernel/comm/comm.py | 2 +- ipykernel/comm/manager.py | 2 +- ipykernel/connect.py | 4 ++- ipykernel/eventloops.py | 4 +-- ipykernel/iostream.py | 2 +- ipykernel/ipkernel.py | 2 +- ipykernel/kernelapp.py | 4 +-- ipykernel/kernelbase.py | 5 ++-- ipykernel/pylab/backend_inline.py | 2 +- ipykernel/pylab/config.py | 2 +- pyproject.toml | 41 ++++++------------------------- 12 files changed, 34 insertions(+), 46 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3f9c01b8..9154035d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -39,6 +39,16 @@ repos: - id: prettier types_or: [yaml, html, json] + - repo: https://github.com/pre-commit/mirrors-mypy + rev: "v1.6.1" + hooks: + - id: mypy + files: ipykernel + stages: [manual] + args: ["--install-types", "--non-interactive"] + additional_dependencies: + ["traitlets>=5.13", "ipython>=8.16.1", "jupyter_client>=8.5"] + - repo: https://github.com/adamchainz/blacken-docs rev: "1.16.0" hooks: diff --git a/ipykernel/comm/comm.py b/ipykernel/comm/comm.py index 186b4fe7..bb9b077d 100644 --- a/ipykernel/comm/comm.py +++ b/ipykernel/comm/comm.py @@ -16,7 +16,7 @@ # this is the class that will be created if we do comm.create_comm -class BaseComm(comm.base_comm.BaseComm): +class BaseComm(comm.base_comm.BaseComm): # type:ignore[misc] """The base class for comms.""" kernel: Optional["Kernel"] = None diff --git a/ipykernel/comm/manager.py b/ipykernel/comm/manager.py index 7b0de693..7e485063 100644 --- a/ipykernel/comm/manager.py +++ b/ipykernel/comm/manager.py @@ -14,7 +14,7 @@ logger = logging.getLogger("ipykernel.comm") -class CommManager(comm.base_comm.CommManager, traitlets.config.LoggingConfigurable): +class CommManager(comm.base_comm.CommManager, traitlets.config.LoggingConfigurable): # type:ignore[misc] """A comm manager.""" kernel = traitlets.Instance("ipykernel.kernelbase.Kernel") diff --git a/ipykernel/connect.py b/ipykernel/connect.py index 3336ced0..9f851caa 100644 --- a/ipykernel/connect.py +++ b/ipykernel/connect.py @@ -88,7 +88,9 @@ def get_connection_info( return info_str -def connect_qtconsole(connection_file: str | None = None, argv: list[str] | None = None) -> Popen: +def connect_qtconsole( + connection_file: str | None = None, argv: list[str] | None = None +) -> Popen[Any]: """Connect a qtconsole to the current kernel. This is useful for connecting a second qtconsole to a kernel, or to a diff --git a/ipykernel/eventloops.py b/ipykernel/eventloops.py index f954505d..bf1e3d0d 100644 --- a/ipykernel/eventloops.py +++ b/ipykernel/eventloops.py @@ -168,7 +168,7 @@ def wake(): # We have to put the wx.Timer in a wx.Frame for it to fire properly. # We make the Frame hidden when we create it in the main app below. - class TimerFrame(wx.Frame): + class TimerFrame(wx.Frame): # type:ignore[misc] def __init__(self, func): wx.Frame.__init__(self, None, -1) self.timer = wx.Timer(self) @@ -182,7 +182,7 @@ def on_timer(self, event): # We need a custom wx.App to create our Frame subclass that has the # wx.Timer to defer back to the tornado event loop. - class IPWxApp(wx.App): + class IPWxApp(wx.App): # type:ignore[misc] def OnInit(self): self.frame = TimerFrame(wake) self.frame.Show(False) diff --git a/ipykernel/iostream.py b/ipykernel/iostream.py index 1f1d1a7c..3588e588 100644 --- a/ipykernel/iostream.py +++ b/ipykernel/iostream.py @@ -69,7 +69,7 @@ def __init__(self, socket, pipe=False): self._event_pipes: Dict[threading.Thread, Any] = {} self._event_pipe_gc_lock: threading.Lock = threading.Lock() self._event_pipe_gc_seconds: float = 10 - self._event_pipe_gc_task: Optional[asyncio.Task] = None + self._event_pipe_gc_task: Optional[asyncio.Task[Any]] = None self._setup_event_pipe() self.thread = threading.Thread(target=self._thread_main, name="IOPub") self.thread.daemon = True diff --git a/ipykernel/ipkernel.py b/ipykernel/ipkernel.py index 4b2cc53d..6e358c7d 100644 --- a/ipykernel/ipkernel.py +++ b/ipykernel/ipkernel.py @@ -147,7 +147,7 @@ def __init__(self, **kwargs): if _use_appnope() and self._darwin_app_nap: # Disable app-nap as the kernel is not a gui but can have guis - import appnope + import appnope # type:ignore[import-untyped] appnope.nope() diff --git a/ipykernel/kernelapp.py b/ipykernel/kernelapp.py index af962901..57ae6f9c 100644 --- a/ipykernel/kernelapp.py +++ b/ipykernel/kernelapp.py @@ -10,10 +10,10 @@ import signal import sys import traceback +import typing as t from functools import partial from io import FileIO, TextIOWrapper from logging import StreamHandler -from typing import Optional import zmq from IPython.core.application import ( # type:ignore[attr-defined] @@ -132,7 +132,7 @@ class IPKernelApp(BaseIPythonApplication, InteractiveShellApp, ConnectionFileMix poller = Any() # don't restrict this even though current pollers are all Threads heartbeat = Instance(Heartbeat, allow_none=True) - context: Optional[zmq.Context] = Any() # type:ignore[assignment] + context: t.Optional[zmq.Context[t.Any]] = Any() # type:ignore[assignment] shell_socket = Any() control_socket = Any() debugpy_socket = Any() diff --git a/ipykernel/kernelbase.py b/ipykernel/kernelbase.py index 8f3c0a50..a66e647b 100644 --- a/ipykernel/kernelbase.py +++ b/ipykernel/kernelbase.py @@ -1044,7 +1044,8 @@ async def usage_request(self, stream, ident, parent): # Ensure 1) self.processes is updated to only current subprocesses # and 2) we reuse processes when possible (needed for accurate CPU) self.processes = { - process.pid: self.processes.get(process.pid, process) for process in all_processes + process.pid: self.processes.get(process.pid, process) + for process in all_processes # type:ignore[call-overload,misc] } reply_content["kernel_cpu"] = sum( [ @@ -1062,7 +1063,7 @@ async def usage_request(self, stream, ident, parent): cpu_percent = psutil.cpu_percent() # https://psutil.readthedocs.io/en/latest/index.html?highlight=cpu#psutil.cpu_percent # The first time cpu_percent is called it will return a meaningless 0.0 value which you are supposed to ignore. - if cpu_percent is not None and cpu_percent != 0.0: + if cpu_percent is not None and cpu_percent != 0.0: # type:ignore[redundant-expr] reply_content["host_cpu_percent"] = cpu_percent reply_content["cpu_count"] = psutil.cpu_count(logical=True) reply_content["host_virtual_memory"] = dict(psutil.virtual_memory()._asdict()) diff --git a/ipykernel/pylab/backend_inline.py b/ipykernel/pylab/backend_inline.py index 18e0222a..cc389cca 100644 --- a/ipykernel/pylab/backend_inline.py +++ b/ipykernel/pylab/backend_inline.py @@ -5,7 +5,7 @@ import warnings -from matplotlib_inline.backend_inline import * # analysis: ignore # noqa F401 +from matplotlib_inline.backend_inline import * # type:ignore[import-untyped] # analysis: ignore # noqa F401 warnings.warn( "`ipykernel.pylab.backend_inline` is deprecated, directly " diff --git a/ipykernel/pylab/config.py b/ipykernel/pylab/config.py index 56557b1e..afd44d19 100644 --- a/ipykernel/pylab/config.py +++ b/ipykernel/pylab/config.py @@ -5,7 +5,7 @@ import warnings -from matplotlib_inline.config import * # analysis: ignore # noqa F401 +from matplotlib_inline.config import * # type:ignore[import-untyped] # analysis: ignore # noqa F401 warnings.warn( "`ipykernel.pylab.config` is deprecated, directly use `matplotlib_inline.config`", diff --git a/pyproject.toml b/pyproject.toml index c06ebb18..db15f6a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -111,51 +111,26 @@ matrix.qt.features = [ ] [tool.hatch.envs.typing] -features = ["test"] -dependencies = ["mypy>=1.6.0", "traitlets>=5.13.0", "ipython>=8.16.1", "jupyter_client>=8.5"] +dependencies = ["pre-commit"] +detached = true [tool.hatch.envs.typing.scripts] -test = "mypy --install-types --non-interactive {args}" +test = "pre-commit run --all-files --hook-stage manual mypy" [tool.hatch.envs.lint] -dependencies = ["mdformat>0.7", "ruff==0.1.3"] +dependencies = ["pre-commit"] detached = true [tool.hatch.envs.lint.scripts] -style = [ - "ruff {args:.}", - "ruff format {args:.}", - "mdformat --check {args:docs *.md}" -] -fmt = [ - "ruff --fix {args:.}", - "ruff format {args:.}", - "mdformat {args:docs *.md}" -] +build = ["pre-commit run --all-files ruff"] [tool.mypy] files = "ipykernel" -check_untyped_defs = true -disallow_incomplete_defs = true -disallow_untyped_decorators = true +strict = true +disable_error_code = ["no-untyped-def", "no-untyped-call", "import-not-found"] enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] follow_imports = "normal" -ignore_missing_imports = true -no_implicit_optional = true -no_implicit_reexport = true pretty = true -show_error_context = true show_error_codes = true -strict_equality = true -strict_optional = true -warn_unused_configs = true -warn_redundant_casts = true -warn_return_any = true warn_unreachable = true -warn_unused_ignores = true - -[[tool.mypy.overrides]] -module = "tests.*" -disable_error_code = ["ignore-without-code"] -warn_unreachable = false [tool.pytest.ini_options] minversion = "6.0" @@ -340,4 +315,4 @@ toplevel = ["ipykernel/", "ipykernel_launcher.py"] ignore = ["W002"] [tool.repo-review] -ignore = ["PY007", "PP308", "GH102", "PC140", "MY101"] +ignore = ["PY007", "PP308", "GH102", "MY101"] From ccff24db8d9402591e3078de847e6d430358598a Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 3 Nov 2023 07:53:22 -0500 Subject: [PATCH 2/3] typing fixes --- .pre-commit-config.yaml | 7 ++++++- ipykernel/kernelbase.py | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9154035d..946d63fd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,7 +47,12 @@ repos: stages: [manual] args: ["--install-types", "--non-interactive"] additional_dependencies: - ["traitlets>=5.13", "ipython>=8.16.1", "jupyter_client>=8.5"] + [ + "traitlets>=5.13", + "ipython>=8.16.1", + "jupyter_client>=8.5", + "appnope", + ] - repo: https://github.com/adamchainz/blacken-docs rev: "1.16.0" diff --git a/ipykernel/kernelbase.py b/ipykernel/kernelbase.py index a66e647b..79ecddb3 100644 --- a/ipykernel/kernelbase.py +++ b/ipykernel/kernelbase.py @@ -1044,8 +1044,8 @@ async def usage_request(self, stream, ident, parent): # Ensure 1) self.processes is updated to only current subprocesses # and 2) we reuse processes when possible (needed for accurate CPU) self.processes = { - process.pid: self.processes.get(process.pid, process) - for process in all_processes # type:ignore[call-overload,misc] + process.pid: self.processes.get(process.pid, process) # type:ignore[misc,call-overload] + for process in all_processes } reply_content["kernel_cpu"] = sum( [ From 1d35e77352ca0286dc4261a5d7c4c9354e65ff04 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 3 Nov 2023 09:02:19 -0500 Subject: [PATCH 3/3] typing fixes --- .github/workflows/ci.yml | 2 +- ipykernel/kernelapp.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8187aa0d..64bf5fb6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,7 +84,7 @@ jobs: - name: Run Linters run: | hatch run typing:test - hatch run lint:style + hatch run lint:build pipx run interrogate -vv . pipx run doc8 --max-line-length=200 diff --git a/ipykernel/kernelapp.py b/ipykernel/kernelapp.py index 57ae6f9c..5bfcccbf 100644 --- a/ipykernel/kernelapp.py +++ b/ipykernel/kernelapp.py @@ -2,6 +2,7 @@ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. +from __future__ import annotations import atexit import errno @@ -132,7 +133,7 @@ class IPKernelApp(BaseIPythonApplication, InteractiveShellApp, ConnectionFileMix poller = Any() # don't restrict this even though current pollers are all Threads heartbeat = Instance(Heartbeat, allow_none=True) - context: t.Optional[zmq.Context[t.Any]] = Any() # type:ignore[assignment] + context: zmq.Context[t.Any] | None = Any() # type:ignore[assignment] shell_socket = Any() control_socket = Any() debugpy_socket = Any()