diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 98deaf12..af9803ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,10 +22,10 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - python-version: ["3.9", "3.13"] + python-version: ["3.10", "3.13"] include: - os: ubuntu-latest - python-version: "pypy-3.9" + python-version: "pypy-3.10" - os: macos-latest python-version: "3.10" - os: ubuntu-latest @@ -125,7 +125,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python-version: ["3.9"] + python-version: ["3.10"] steps: - name: Checkout uses: actions/checkout@v4 @@ -156,7 +156,7 @@ jobs: uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 with: dependency_type: minimum - python_version: "3.9" + python_version: "3.10" - name: List installed packages run: | diff --git a/.github/workflows/downstream.yml b/.github/workflows/downstream.yml index 378bfaac..42d85a30 100644 --- a/.github/workflows/downstream.yml +++ b/.github/workflows/downstream.yml @@ -95,7 +95,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install System Packages run: | @@ -127,7 +127,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: "x64" - name: Install System Packages run: | diff --git a/ipykernel/iostream.py b/ipykernel/iostream.py index cb4fc052..b53ed035 100644 --- a/ipykernel/iostream.py +++ b/ipykernel/iostream.py @@ -15,9 +15,10 @@ import warnings from binascii import b2a_hex from collections import defaultdict, deque +from collections.abc import Callable from io import StringIO, TextIOBase from threading import local -from typing import Any, Callable +from typing import Any import zmq from anyio import sleep diff --git a/ipykernel/ipkernel.py b/ipykernel/ipkernel.py index 5c450169..37b1bfb5 100644 --- a/ipykernel/ipkernel.py +++ b/ipykernel/ipkernel.py @@ -168,7 +168,7 @@ def __init__(self, **kwargs): if hasattr(gc, "callbacks"): # while `gc.callbacks` exists since Python 3.3, pypy does not - # implement it even as of 3.9. + # implement it even as of 3.10. gc.callbacks.append(self._clean_thread_parent_frames) help_links = List( diff --git a/ipykernel/jsonutil.py b/ipykernel/jsonutil.py index e45f06e5..d40661c7 100644 --- a/ipykernel/jsonutil.py +++ b/ipykernel/jsonutil.py @@ -156,7 +156,7 @@ def json_clean(obj): # pragma: no cover for k, v in obj.items(): out[str(k)] = json_clean(v) return out - if isinstance(obj, (datetime, date)): + if isinstance(obj, datetime | date): return obj.strftime(ISO8601) # we don't understand it, it's probably an unserializable object diff --git a/ipykernel/thread.py b/ipykernel/thread.py index a66cb2a4..b97aa77c 100644 --- a/ipykernel/thread.py +++ b/ipykernel/thread.py @@ -2,10 +2,10 @@ from __future__ import annotations -from collections.abc import Awaitable +from collections.abc import Awaitable, Callable from queue import Queue from threading import Event, Thread -from typing import Any, Callable +from typing import Any from anyio import create_task_group, run, to_thread from anyio.abc import TaskGroup diff --git a/pyproject.toml b/pyproject.toml index 613b8e20..cdf635ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3", ] -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = [ "debugpy>=1.8.1", "ipython>=7.23.1", diff --git a/tests/conftest.py b/tests/conftest.py index 2c266555..a3bd6089 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,8 +1,9 @@ import asyncio import logging import os +from collections.abc import Callable from math import inf -from typing import Any, Callable, no_type_check +from typing import Any, no_type_check from unittest.mock import MagicMock import pytest diff --git a/tests/test_kernel.py b/tests/test_kernel.py index 2b379eb8..861f1b5f 100644 --- a/tests/test_kernel.py +++ b/tests/test_kernel.py @@ -635,7 +635,7 @@ def ensure_datetime(arg): # Check messages are processed in order, one at a time, and of a sensible duration. previous_end = None - for reply, sleep in zip(replies, sleeps): + for reply, sleep in zip(replies, sleeps, strict=False): start = ensure_datetime(reply["metadata"]["started"]) end = ensure_datetime(reply["header"]["date"]) diff --git a/tests/test_subshells.py b/tests/test_subshells.py index 0b1c1f1a..a0c61b4a 100644 --- a/tests/test_subshells.py +++ b/tests/test_subshells.py @@ -156,7 +156,7 @@ def test_run_concurrently_sequence(are_subshells, overlap): ] msgs = [] - for subshell_id, code in zip(subshell_ids, codes): + for subshell_id, code in zip(subshell_ids, codes, strict=False): msg = kc.session.msg("execute_request", {"code": code}) msg["header"]["subshell_id"] = subshell_id kc.shell_channel.send(msg) @@ -191,7 +191,7 @@ def test_run_concurrently_timing(include_main_shell): # Identical times for both subshells is a harder test as preparing and sending # the execute_reply messages may overlap. msgs = [] - for id, sleep in zip(subshell_ids, times): + for id, sleep in zip(subshell_ids, times, strict=False): code = f"b.wait(); time.sleep({sleep})" msg = kc.session.msg("execute_request", {"code": code}) msg["header"]["subshell_id"] = id @@ -231,7 +231,9 @@ def test_execution_count(): # Prepare messages times = (0.2, 0.1, 0.4, 0.15) # Sleep seconds msgs = [] - for i, (id, sleep) in enumerate(zip((None, subshell_id, None, subshell_id), times)): + for i, (id, sleep) in enumerate( + zip((None, subshell_id, None, subshell_id), times, strict=False) + ): code = f"b.wait(); time.sleep({sleep})" if i < 2 else f"time.sleep({sleep})" msg = kc.session.msg("execute_request", {"code": code}) msg["header"]["subshell_id"] = id