diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b56bd08c..75025355 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: fail-fast: false matrix: os: [ windows-latest, ubuntu-latest ] - python: [ "3.8", "3.10", "3.11", "3.12", "pypy-3.11" ] + python: [ "3.10", "3.11", "3.12", "3.13", "3.14", "pypy-3.11" ] steps: - uses: actions/checkout@v5 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2daf0219..71750f1e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,11 +3,11 @@ repos: rev: v2.4.1 hooks: - id: codespell -- repo: https://github.com/asottile/blacken-docs +- repo: https://github.com/adamchainz/blacken-docs rev: 1.20.0 hooks: - id: blacken-docs - additional_dependencies: [black==22.12.0] + additional_dependencies: [black==25.11.0] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: @@ -15,7 +15,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.14.4 hooks: - - id: ruff + - id: ruff-check args: [ --fix ] exclude: "^doc/" - id: ruff-format diff --git a/CHANGELOG.rst b/CHANGELOG.rst index cf852a95..a7af6272 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,8 @@ +2.2.0 (UNRELEASED) +------------------ + +* `#380 `__: Add support for Python 3.13 and 3.14, and drop EOL 3.8 and 3.9. + 2.1.2 (2025-11-11) ------------------ diff --git a/doc/install.rst b/doc/install.rst index e7bb7038..adbb9341 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -1,7 +1,7 @@ Info in a nutshell ==================== -**Pythons**: 3.8+, PyPy 3 +**Pythons**: 3.10+, PyPy 3 **Operating systems**: Linux, Windows, OSX, Unix diff --git a/pyproject.toml b/pyproject.toml index eb202ee9..c527642b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ dynamic = ["version"] description = "execnet: rapid multi-Python deployment" readme = {"file" = "README.rst", "content-type" = "text/x-rst"} license = "MIT" -requires-python = ">=3.8" +requires-python = ">=3.10" authors = [ { name = "holger krekel and others" }, ] @@ -22,11 +22,11 @@ classifiers = [ "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries", @@ -96,7 +96,7 @@ include = [ ] [tool.mypy] -python_version = "3.8" +python_version = "3.10" mypy_path = ["src"] files = ["src", "testing"] strict = true diff --git a/src/execnet/gateway.py b/src/execnet/gateway.py index 645de0fc..1d3eb59d 100644 --- a/src/execnet/gateway.py +++ b/src/execnet/gateway.py @@ -9,9 +9,9 @@ import linecache import textwrap import types +from collections.abc import Callable from typing import TYPE_CHECKING from typing import Any -from typing import Callable from . import gateway_base from .gateway_base import IO diff --git a/src/execnet/gateway_base.py b/src/execnet/gateway_base.py index bdee89af..e1a5fe38 100644 --- a/src/execnet/gateway_base.py +++ b/src/execnet/gateway_base.py @@ -18,12 +18,12 @@ import traceback import weakref from _thread import interrupt_main +from collections.abc import Callable +from collections.abc import Iterator +from collections.abc import MutableSet from io import BytesIO from typing import Any -from typing import Callable -from typing import Iterator from typing import Literal -from typing import MutableSet from typing import Protocol from typing import cast from typing import overload diff --git a/src/execnet/multi.py b/src/execnet/multi.py index c4f35813..1ea07eee 100644 --- a/src/execnet/multi.py +++ b/src/execnet/multi.py @@ -8,15 +8,15 @@ import atexit import types +from collections.abc import Callable +from collections.abc import Iterable +from collections.abc import Iterator +from collections.abc import Sequence from functools import partial from threading import Lock from typing import TYPE_CHECKING from typing import Any -from typing import Callable -from typing import Iterable -from typing import Iterator from typing import Literal -from typing import Sequence from typing import overload from . import gateway_bootstrap diff --git a/src/execnet/rsync.py b/src/execnet/rsync.py index 2b5698d8..c12a739a 100644 --- a/src/execnet/rsync.py +++ b/src/execnet/rsync.py @@ -8,9 +8,9 @@ import os import stat +from collections.abc import Callable from hashlib import md5 from queue import Queue -from typing import Callable from typing import Literal import execnet.rsync_remote diff --git a/testing/conftest.py b/testing/conftest.py index d9667ac1..c75f96c7 100644 --- a/testing/conftest.py +++ b/testing/conftest.py @@ -2,10 +2,10 @@ import shutil import sys +from collections.abc import Callable +from collections.abc import Generator +from collections.abc import Iterator from functools import lru_cache -from typing import Callable -from typing import Generator -from typing import Iterator import pytest diff --git a/testing/test_basics.py b/testing/test_basics.py index 427ded3c..1756ec34 100644 --- a/testing/test_basics.py +++ b/testing/test_basics.py @@ -6,11 +6,11 @@ import subprocess import sys import textwrap +from collections.abc import Callable from dataclasses import dataclass from io import BytesIO from pathlib import Path from typing import Any -from typing import Callable import pytest diff --git a/testing/test_gateway.py b/testing/test_gateway.py index bd527ffe..634f237a 100644 --- a/testing/test_gateway.py +++ b/testing/test_gateway.py @@ -9,8 +9,8 @@ import shutil import signal import sys +from collections.abc import Callable from textwrap import dedent -from typing import Callable import pytest @@ -635,7 +635,7 @@ def test_main_thread_only_concurrent_remote_exec_deadlock( True, execnet.gateway_base.MAIN_THREAD_ONLY_DEADLOCK_TEXT, ) - for expected, ch in zip(expected_results, channels): + for expected, ch in zip(expected_results, channels, strict=True): try: res = ch.receive() except execnet.RemoteError as e: diff --git a/testing/test_multi.py b/testing/test_multi.py index e1dc40d1..81e4525b 100644 --- a/testing/test_multi.py +++ b/testing/test_multi.py @@ -5,8 +5,8 @@ from __future__ import annotations import gc +from collections.abc import Callable from time import sleep -from typing import Callable import pytest diff --git a/testing/test_termination.py b/testing/test_termination.py index 3d14d999..ca119304 100644 --- a/testing/test_termination.py +++ b/testing/test_termination.py @@ -4,7 +4,7 @@ import signal import subprocess import sys -from typing import Callable +from collections.abc import Callable import pytest from test_gateway import TESTTIMEOUT diff --git a/testing/test_xspec.py b/testing/test_xspec.py index 3e5041be..f837b07a 100644 --- a/testing/test_xspec.py +++ b/testing/test_xspec.py @@ -4,8 +4,8 @@ import shutil import subprocess import sys +from collections.abc import Callable from pathlib import Path -from typing import Callable import pytest diff --git a/tox.ini b/tox.ini index 115070df..5880696d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist=py{38,39,310,311,312,pypy311},docs,linting +envlist=py{310,311,312,313,314,py311},docs,linting isolated_build = true [testenv]