From 920da733e1a31082a040c65fbaaabeabf31ac5fa Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Fri, 24 Oct 2025 10:06:25 +0200 Subject: [PATCH 1/4] update pre-commit and related --- .pre-commit-config.yaml | 21 ++++++++++----------- pyproject.toml | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3acbeb4a9..214d4cf10 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ ci: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: check-case-conflict - id: check-ast @@ -22,16 +22,15 @@ repos: - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.33.2 + rev: 0.34.1 hooks: - id: check-github-workflows - - repo: https://github.com/executablebooks/mdformat - rev: 0.7.22 + - repo: https://github.com/hukkin/mdformat + rev: 1.0.0 hooks: - id: mdformat - additional_dependencies: - [mdformat-gfm, mdformat-frontmatter, mdformat-footnote] + additional_dependencies: [mdformat-footnote] - repo: https://github.com/pre-commit/mirrors-prettier rev: "v4.0.0-alpha.8" @@ -40,7 +39,7 @@ repos: types_or: [yaml, html, json] - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.17.0" + rev: "v1.18.2" hooks: - id: mypy files: ipykernel @@ -55,7 +54,7 @@ repos: ] - repo: https://github.com/adamchainz/blacken-docs - rev: "1.19.1" + rev: "1.20.0" hooks: - id: blacken-docs additional_dependencies: [black==23.7.0] @@ -74,16 +73,16 @@ repos: - id: rst-inline-touching-normal - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.12.4 + rev: v0.14.2 hooks: - - id: ruff + - id: ruff-check types_or: [python, jupyter] args: ["--fix", "--show-fixes"] - id: ruff-format types_or: [python, jupyter] - repo: https://github.com/scientific-python/cookie - rev: "2025.05.02" + rev: "2025.10.20" hooks: - id: sp-repo-review additional_dependencies: ["repo-review[cli]"] diff --git a/pyproject.toml b/pyproject.toml index c979015df..524b6ef22 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -120,7 +120,7 @@ dependencies = ["pre-commit"] detached = true [tool.hatch.envs.lint.scripts] build = [ - "pre-commit run --all-files ruff", + "pre-commit run --all-files ruff-check", "pre-commit run --all-files ruff-format" ] From 9cd626bc6dfdff15959b8680a32469959372590f Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Fri, 24 Oct 2025 10:07:32 +0200 Subject: [PATCH 2/4] ruff-check unsafe-fixes --- ipykernel/debugger.py | 2 +- ipykernel/inprocess/client.py | 2 +- ipykernel/inprocess/ipkernel.py | 2 +- tests/inprocess/test_kernel.py | 6 +++--- tests/test_async.py | 2 +- tests/test_embed_kernel.py | 2 +- tests/test_io.py | 2 +- tests/test_kernel.py | 26 +++++++++++++------------- tests/test_message_spec.py | 10 +++++----- 9 files changed, 27 insertions(+), 27 deletions(-) diff --git a/ipykernel/debugger.py b/ipykernel/debugger.py index 64320e631..cfa976107 100644 --- a/ipykernel/debugger.py +++ b/ipykernel/debugger.py @@ -429,7 +429,7 @@ def start(self): (self.shell_socket.getsockopt(ROUTING_ID)), ) - ident, msg = self.session.recv(self.shell_socket, mode=0) + _ident, msg = self.session.recv(self.shell_socket, mode=0) self.debugpy_initialized = msg["content"]["status"] == "ok" # Don't remove leading empty lines when debugging so the breakpoints are correctly positioned diff --git a/ipykernel/inprocess/client.py b/ipykernel/inprocess/client.py index ffe044826..d18eec12e 100644 --- a/ipykernel/inprocess/client.py +++ b/ipykernel/inprocess/client.py @@ -206,7 +206,7 @@ def _dispatch_to_kernel(self, msg): else: loop = asyncio.get_event_loop() # type:ignore[unreachable] loop.run_until_complete(kernel.dispatch_shell(msg_parts)) - idents, reply_msg = self.session.recv(stream, copy=False) + _idents, reply_msg = self.session.recv(stream, copy=False) self.shell_channel.call_handlers_later(reply_msg) def get_shell_msg(self, block=True, timeout=None): diff --git a/ipykernel/inprocess/ipkernel.py b/ipykernel/inprocess/ipkernel.py index 62c15036b..b68bec442 100644 --- a/ipykernel/inprocess/ipkernel.py +++ b/ipykernel/inprocess/ipkernel.py @@ -135,7 +135,7 @@ def _io_dispatch(self, change): """Called when a message is sent to the IO socket.""" assert self.iopub_socket.io_thread is not None assert self.session is not None - ident, msg = self.session.recv(self.iopub_socket.io_thread.socket, copy=False) + _ident, msg = self.session.recv(self.iopub_socket.io_thread.socket, copy=False) for frontend in self.frontends: assert frontend is not None frontend.iopub_channel.call_handlers(msg) diff --git a/tests/inprocess/test_kernel.py b/tests/inprocess/test_kernel.py index 33692e85f..b965d9b89 100644 --- a/tests/inprocess/test_kernel.py +++ b/tests/inprocess/test_kernel.py @@ -57,7 +57,7 @@ def test_pylab(kc): """Does %pylab work in the in-process kernel?""" _ = pytest.importorskip("matplotlib", reason="This test requires matplotlib") kc.execute("%pylab") - out, err = assemble_output(kc.get_iopub_msg) + out, _err = assemble_output(kc.get_iopub_msg) assert "matplotlib" in out @@ -85,7 +85,7 @@ def test_stdout(kc): kc = BlockingInProcessKernelClient(kernel=kernel, session=kernel.session) kernel.frontends.append(kc) kc.execute('print("bar")') - out, err = assemble_output(kc.get_iopub_msg) + out, _err = assemble_output(kc.get_iopub_msg) assert out == "bar\n" @@ -102,7 +102,7 @@ def test_capfd(kc): kernel.frontends.append(kc) kc.execute("import os") kc.execute('os.system("echo capfd")') - out, err = assemble_output(kc.iopub_channel) + out, _err = assemble_output(kc.iopub_channel) assert out == "capfd\n" diff --git a/tests/test_async.py b/tests/test_async.py index 5a8445466..4e9b9ad46 100644 --- a/tests/test_async.py +++ b/tests/test_async.py @@ -23,7 +23,7 @@ def _setup_env(): def test_async_await(): flush_channels(KC) - msg_id, content = execute("import asyncio; await asyncio.sleep(0.1)", KC) + _msg_id, content = execute("import asyncio; await asyncio.sleep(0.1)", KC) assert content["status"] == "ok", content diff --git a/tests/test_embed_kernel.py b/tests/test_embed_kernel.py index 8e70f8b4c..d6ad44614 100644 --- a/tests/test_embed_kernel.py +++ b/tests/test_embed_kernel.py @@ -64,7 +64,7 @@ def connection_file_ready(connection_file): time.sleep(0.1) if kernel.poll() is not None: - o, e = kernel.communicate() + _o, e = kernel.communicate() raise OSError("Kernel failed to start:\n%s" % e) if not os.path.exists(connection_file): diff --git a/tests/test_io.py b/tests/test_io.py index 0e23b4b14..c7320af84 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -222,7 +222,7 @@ def test_echo_watch(ctx): print(f"{p.stderr}=", file=sys.stderr) assert p.returncode == 0 while s.poll(timeout=100): - ident, msg = session.recv(s) + _ident, msg = session.recv(s) assert msg is not None # for type narrowing if msg["header"]["msg_type"] == "stream" and msg["content"]["name"] == "stdout": stdout_chunks.append(msg["content"]["text"]) diff --git a/tests/test_kernel.py b/tests/test_kernel.py index cbdbceddd..f6342743c 100644 --- a/tests/test_kernel.py +++ b/tests/test_kernel.py @@ -34,8 +34,8 @@ def _check_master(kc, expected=True, stream="stdout"): execute(kc=kc, code="import sys") flush_channels(kc) - msg_id, content = execute(kc=kc, code="print(sys.%s._is_master_process())" % stream) - stdout, stderr = assemble_output(kc.get_iopub_msg) + _msg_id, _content = execute(kc=kc, code="print(sys.%s._is_master_process())" % stream) + stdout, _stderr = assemble_output(kc.get_iopub_msg) assert stdout.strip() == repr(expected) @@ -51,7 +51,7 @@ def _check_status(content): def test_simple_print(): """simple print statement in kernel""" with kernel() as kc: - msg_id, content = execute(kc=kc, code="print('hi')") + _msg_id, _content = execute(kc=kc, code="print('hi')") stdout, stderr = assemble_output(kc.get_iopub_msg) assert stdout == "hi\n" assert stderr == "" @@ -251,7 +251,7 @@ def test_capture_fd(): """simple print statement in kernel""" with kernel() as kc: iopub = kc.iopub_channel - msg_id, content = execute(kc=kc, code="import os; os.system('echo capsys')") + _msg_id, _content = execute(kc=kc, code="import os; os.system('echo capsys')") stdout, stderr = assemble_output(iopub) assert stdout == "capsys\n" assert stderr == "" @@ -262,7 +262,7 @@ def test_capture_fd(): def test_subprocess_peek_at_stream_fileno(): with kernel() as kc: iopub = kc.iopub_channel - msg_id, content = execute( + _msg_id, _content = execute( kc=kc, code="import subprocess, sys; subprocess.run(['python', '-c', 'import os; os.system(\"echo CAP1\"); print(\"CAP2\")'], stderr=sys.stderr)", ) @@ -275,7 +275,7 @@ def test_subprocess_peek_at_stream_fileno(): def test_sys_path(): """test that sys.path doesn't get messed up by default""" with kernel() as kc: - msg_id, content = execute(kc=kc, code="import sys; print(repr(sys.path))") + _msg_id, _content = execute(kc=kc, code="import sys; print(repr(sys.path))") stdout, stderr = assemble_output(kc.get_iopub_msg) # for error-output on failure sys.stderr.write(stderr) @@ -288,7 +288,7 @@ def test_sys_path_profile_dir(): """test that sys.path doesn't get messed up when `--profile-dir` is specified""" with new_kernel(["--profile-dir", locate_profile("default")]) as kc: - msg_id, content = execute(kc=kc, code="import sys; print(repr(sys.path))") + _msg_id, _content = execute(kc=kc, code="import sys; print(repr(sys.path))") stdout, stderr = assemble_output(kc.get_iopub_msg) # for error-output on failure sys.stderr.write(stderr) @@ -323,7 +323,7 @@ def test_subprocess_print(): ] ) - msg_id, content = execute(kc=kc, code=code) + _msg_id, _content = execute(kc=kc, code=code) stdout, stderr = assemble_output(kc.get_iopub_msg) assert stdout.count("hello") == np, stdout for n in range(np): @@ -347,7 +347,7 @@ def test_subprocess_noprint(): ] ) - msg_id, content = execute(kc=kc, code=code) + _msg_id, _content = execute(kc=kc, code=code) stdout, stderr = assemble_output(kc.get_iopub_msg) assert stdout == "" assert stderr == "" @@ -373,7 +373,7 @@ def test_subprocess_error(): ] ) - msg_id, content = execute(kc=kc, code=code) + _msg_id, _content = execute(kc=kc, code=code) stdout, stderr = assemble_output(kc.get_iopub_msg) assert stdout == "" assert "ValueError" in stderr @@ -400,7 +400,7 @@ def test_raw_input(): kc.input(text) reply = kc.get_shell_msg(timeout=TIMEOUT) assert reply["content"]["status"] == "ok" - stdout, stderr = assemble_output(kc.get_iopub_msg) + stdout, _stderr = assemble_output(kc.get_iopub_msg) assert stdout == text + "\n" @@ -555,7 +555,7 @@ def test_unc_paths(): kc.execute(code="ls") reply = kc.get_shell_msg(timeout=TIMEOUT) assert reply["content"]["status"] == "ok" - out, err = assemble_output(kc.get_iopub_msg) + out, _err = assemble_output(kc.get_iopub_msg) assert "unc.txt" in out kc.execute(code="cd") @@ -774,7 +774,7 @@ def test_shutdown_subprocesses(): """Kernel exits after polite shutdown_request""" with new_kernel() as kc: km = kc.parent - msg_id, reply = execute( + _msg_id, reply = execute( f"from {__name__} import _start_children\n_start_children()", kc=kc, user_expressions={ diff --git a/tests/test_message_spec.py b/tests/test_message_spec.py index b35861cb3..497027d91 100644 --- a/tests/test_message_spec.py +++ b/tests/test_message_spec.py @@ -426,7 +426,7 @@ def test_non_execute_stop_on_error(): def test_user_expressions(): flush_channels() - msg_id, reply = execute(code="x=1", user_expressions=dict(foo="x+1")) + _msg_id, reply = execute(code="x=1", user_expressions=dict(foo="x+1")) user_expressions = reply["user_expressions"] assert user_expressions == { "foo": { @@ -440,7 +440,7 @@ def test_user_expressions(): def test_user_expressions_fail(): flush_channels() - msg_id, reply = execute(code="x=0", user_expressions=dict(foo="nosuchname")) + _msg_id, reply = execute(code="x=0", user_expressions=dict(foo="nosuchname")) user_expressions = reply["user_expressions"] foo = user_expressions["foo"] assert foo["status"] == "error" @@ -572,7 +572,7 @@ def test_single_payload(): transform) should avoid setting multiple set_next_input). """ flush_channels() - msg_id, reply = execute( + _msg_id, reply = execute( code="ip = get_ipython()\nfor i in range(3):\n ip.set_next_input('Hello There')\n" ) payload = reply["payload"] @@ -635,7 +635,7 @@ def test_history_search(): def test_stream(): flush_channels() - msg_id, reply = execute("print('hi')") + msg_id, _reply = execute("print('hi')") stdout = KC.get_iopub_msg(timeout=TIMEOUT) validate_message(stdout, "stream", msg_id) @@ -646,7 +646,7 @@ def test_stream(): def test_display_data(): flush_channels() - msg_id, reply = execute("from IPython.display import display; display(1)") + msg_id, _reply = execute("from IPython.display import display; display(1)") display = KC.get_iopub_msg(timeout=TIMEOUT) validate_message(display, "display_data", parent=msg_id) From 921073f5bc0f18a86f3b293dc8d17ec54adcd63f Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Fri, 24 Oct 2025 10:08:03 +0200 Subject: [PATCH 3/4] last fix --- tests/test_kernel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_kernel.py b/tests/test_kernel.py index f6342743c..7fc4d44d2 100644 --- a/tests/test_kernel.py +++ b/tests/test_kernel.py @@ -548,7 +548,7 @@ def test_unc_paths(): kc.execute(f"cd {unc_file_path:s}") reply = kc.get_shell_msg(timeout=TIMEOUT) assert reply["content"]["status"] == "ok" - out, err = assemble_output(kc.get_iopub_msg) + out, _err = assemble_output(kc.get_iopub_msg) assert unc_file_path in out flush_channels(kc) From a10a4ebb4f6785c5c44983b1efca083e625a90a1 Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Fri, 24 Oct 2025 11:10:51 +0200 Subject: [PATCH 4/4] ignores --- ipykernel/pylab/backend_inline.py | 2 +- ipykernel/pylab/config.py | 2 +- ipykernel/zmqshell.py | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ipykernel/pylab/backend_inline.py b/ipykernel/pylab/backend_inline.py index fdeece28c..2ce3716b8 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 * # type:ignore[import-untyped] # noqa: F403 # analysis: ignore +from matplotlib_inline.backend_inline import * # noqa: F403 # analysis: ignore warnings.warn( "`ipykernel.pylab.backend_inline` is deprecated, directly " diff --git a/ipykernel/pylab/config.py b/ipykernel/pylab/config.py index 0048bbf84..8c3a63ab4 100644 --- a/ipykernel/pylab/config.py +++ b/ipykernel/pylab/config.py @@ -5,7 +5,7 @@ import warnings -from matplotlib_inline.config import * # type:ignore[import-untyped] # noqa: F403 # analysis: ignore +from matplotlib_inline.config import * # noqa: F403 # analysis: ignore warnings.warn( "`ipykernel.pylab.config` is deprecated, directly use `matplotlib_inline.config`", diff --git a/ipykernel/zmqshell.py b/ipykernel/zmqshell.py index 04c06a463..b70b1e5fd 100644 --- a/ipykernel/zmqshell.py +++ b/ipykernel/zmqshell.py @@ -352,7 +352,7 @@ def edit(self, parameter_s="", last_call=None): payload = {"source": "edit_magic", "filename": filename, "line_number": lineno} assert self.shell is not None - self.shell.payload_manager.write_payload(payload) + self.shell.payload_manager.write_payload(payload) # type: ignore[unreachable] # A few magics that are adapted to the specifics of using pexpect and a # remote terminal @@ -361,7 +361,7 @@ def edit(self, parameter_s="", last_call=None): def clear(self, arg_s): """Clear the terminal.""" assert self.shell is not None - if os.name == "posix": + if os.name == "posix": # type: ignore[unreachable] self.shell.system("clear") else: self.shell.system("cls") @@ -383,7 +383,7 @@ def less(self, arg_s): if arg_s.endswith(".py"): assert self.shell is not None - cont = self.shell.pycolorize(openpy.read_py_file(arg_s, skip_encoding_cookie=False)) + cont = self.shell.pycolorize(openpy.read_py_file(arg_s, skip_encoding_cookie=False)) # type: ignore[unreachable] else: with open(arg_s) as fid: cont = fid.read() @@ -398,7 +398,7 @@ def less(self, arg_s): def man(self, arg_s): """Find the man page for the given command and display in pager.""" assert self.shell is not None - page.page(self.shell.getoutput("man %s | col -b" % arg_s, split=False)) + page.page(self.shell.getoutput("man %s | col -b" % arg_s, split=False)) # type: ignore[unreachable] @line_magic def connect_info(self, arg_s):