From d8113a5c1d838b8d5d1606d0f69e7a065843992b Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 9 Oct 2024 14:11:32 -0500 Subject: [PATCH 01/14] Manual search for 3.8 changes --- .github/workflows/autodeps.yml | 6 +++--- .github/workflows/ci.yml | 16 ++++++++-------- .github/workflows/release.yml | 2 +- README.rst | 2 +- check.sh | 2 +- docs/source/index.rst | 2 +- docs/source/tutorial.rst | 2 +- pyproject.toml | 9 ++++----- src/trio/_channel.py | 4 +--- src/trio/_tests/check_type_completeness.py | 2 +- src/trio/_tests/test_repl.py | 2 +- test-requirements.txt | 4 +--- 12 files changed, 24 insertions(+), 29 deletions(-) diff --git a/.github/workflows/autodeps.yml b/.github/workflows/autodeps.yml index 0e28de2687..1182d38782 100644 --- a/.github/workflows/autodeps.yml +++ b/.github/workflows/autodeps.yml @@ -24,13 +24,13 @@ jobs: - name: Setup python uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" - name: Bump dependencies run: | python -m pip install -U pip pre-commit python -m pip install -r test-requirements.txt - uv pip compile --universal --python-version=3.8 --upgrade test-requirements.in -o test-requirements.txt + uv pip compile --universal --python-version=3.9 --upgrade test-requirements.in -o test-requirements.txt uv pip compile --universal --python-version=3.11 --upgrade docs-requirements.in -o docs-requirements.txt pre-commit autoupdate --jobs 0 @@ -43,7 +43,7 @@ jobs: - name: uv run: | - uv pip compile --universal --python-version=3.8 test-requirements.in -o test-requirements.txt + uv pip compile --universal --python-version=3.9 test-requirements.in -o test-requirements.txt uv pip compile --universal --python-version=3.11 docs-requirements.in -o docs-requirements.txt - name: Commit changes and create automerge PR diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 074943ec63..b4e5d77c3e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,23 +18,23 @@ jobs: strategy: fail-fast: false matrix: - python: ['pypy-3.10', '3.8', '3.9', '3.10', '3.11', '3.12'] + python: ['pypy-3.10', '3.9', '3.10', '3.11', '3.12', '3.13'] arch: ['x86', 'x64'] lsp: [''] lsp_extract_file: [''] extra_name: [''] include: - - python: '3.8' + - python: '3.9' arch: 'x64' lsp: 'https://raw.githubusercontent.com/python-trio/trio-ci-assets/master/komodia-based-vpn-setup.zip' lsp_extract_file: 'komodia-based-vpn-setup.exe' extra_name: ', with Komodia LSP' - - python: '3.8' + - python: '3.9' arch: 'x64' lsp: 'https://www.proxifier.com/download/legacy/ProxifierSetup342.exe' lsp_extract_file: '' extra_name: ', with IFS LSP' - #- python: '3.8' + #- python: '3.9' # arch: 'x64' # lsp: 'http://download.pctools.com/mirror/updates/9.0.0.2308-SDavfree-lite_en.exe' # lsp_extract_file: '' @@ -87,7 +87,7 @@ jobs: strategy: fail-fast: false matrix: - python: ['pypy-3.10', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] + python: ['pypy-3.10', '3.9', '3.10', '3.11', '3.12', '3.13'] check_formatting: ['0'] no_test_requirements: ['0'] extra_name: [''] @@ -96,7 +96,7 @@ jobs: check_formatting: '1' extra_name: ', check formatting' # separate test run that doesn't install test-requirements.txt - - python: '3.8' + - python: '3.9' no_test_requirements: '1' extra_name: ', no test-requirements' continue-on-error: >- @@ -143,7 +143,7 @@ jobs: strategy: fail-fast: false matrix: - python: ['pypy-3.10', '3.8', '3.9', '3.10', '3.11', '3.12'] + python: ['pypy-3.10', '3.9', '3.10', '3.11', '3.12', '3.13'] continue-on-error: >- ${{ ( @@ -203,7 +203,7 @@ jobs: strategy: fail-fast: false matrix: - python: ['3.8', '3.12'] + python: ['3.9', '3.12'] steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4997b1f675..a40da4c3af 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" - run: python -m pip install build - run: python -m build diff --git a/README.rst b/README.rst index 65f6df8946..e3620546a0 100644 --- a/README.rst +++ b/README.rst @@ -92,7 +92,7 @@ demonstration of implementing the "Happy Eyeballs" algorithm in an older library versus Trio. **Cool, but will it work on my system?** Probably! As long as you have -some kind of Python 3.8-or-better (CPython or `currently maintained versions of +some kind of Python 3.9-or-better (CPython or `currently maintained versions of PyPy3 `__ are both fine), and are using Linux, macOS, Windows, or FreeBSD, then Trio will work. Other environments might work too, but those diff --git a/check.sh b/check.sh index a4fb2e4e2a..b659675968 100755 --- a/check.sh +++ b/check.sh @@ -78,7 +78,7 @@ fi # Check pip compile is consistent echo "::group::Pip Compile - Tests" -uv pip compile --universal --python-version=3.8 test-requirements.in -o test-requirements.txt +uv pip compile --universal --python-version=3.9 test-requirements.in -o test-requirements.txt echo "::endgroup::" echo "::group::Pip Compile - Docs" uv pip compile --universal --python-version=3.11 docs-requirements.in -o docs-requirements.txt diff --git a/docs/source/index.rst b/docs/source/index.rst index 1caf5c043b..b89bc4533c 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -45,7 +45,7 @@ Vital statistics: * Supported environments: We test on - - Python: 3.8+ (CPython and PyPy) + - Python: 3.9+ (CPython and PyPy) - Windows, macOS, Linux (glibc and musl), FreeBSD Other environments might also work; give it a try and see. diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst index c7218d873b..3ae9bb4597 100644 --- a/docs/source/tutorial.rst +++ b/docs/source/tutorial.rst @@ -88,7 +88,7 @@ Okay, ready? Let's get started. Before you begin ---------------- -1. Make sure you're using Python 3.8 or newer. +1. Make sure you're using Python 3.9 or newer. 2. ``python3 -m pip install --upgrade trio`` (or on Windows, maybe ``py -3 -m pip install --upgrade trio`` – `details diff --git a/pyproject.toml b/pyproject.toml index ff4aa34600..b759ec25fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,6 @@ classifiers = [ "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -35,7 +34,7 @@ classifiers = [ "Topic :: System :: Networking", "Typing :: Typed", ] -requires-python = ">=3.8" +requires-python = ">=3.9" dependencies = [ # attrs 19.2.0 adds `eq` option to decorators # attrs 20.1.0 adds @frozen @@ -75,7 +74,7 @@ include-package-data = true version = {attr = "trio._version.__version__"} [tool.black] -target-version = ['py38'] +target-version = ['py39'] force-exclude = ''' ( ^/docs/source/reference-.* @@ -159,7 +158,7 @@ combine-as-imports = true fixture-parentheses = false [tool.mypy] -python_version = "3.8" +python_version = "3.9" files = ["src/trio/", "docs/source/*.py"] # Be flexible about dependencies that don't have stubs yet (like pytest) @@ -184,7 +183,7 @@ disallow_untyped_defs = true check_untyped_defs = true [tool.pyright] -pythonVersion = "3.8" +pythonVersion = "3.9" reportUnnecessaryTypeIgnoreComment = true typeCheckingMode = "strict" diff --git a/src/trio/_channel.py b/src/trio/_channel.py index 41a7fc6824..4007c55177 100644 --- a/src/trio/_channel.py +++ b/src/trio/_channel.py @@ -5,7 +5,6 @@ from typing import ( TYPE_CHECKING, Generic, - Tuple, # only needed for typechecking on <3.9 ) import attrs @@ -93,8 +92,7 @@ def _open_memory_channel( # it could replace the normal function header if TYPE_CHECKING: # written as a class so you can say open_memory_channel[int](5) - # Need to use Tuple instead of tuple due to CI check running on 3.8 - class open_memory_channel(Tuple["MemorySendChannel[T]", "MemoryReceiveChannel[T]"]): + class open_memory_channel(tuple[MemorySendChannel[T], MemoryReceiveChannel[T]]): def __new__( # type: ignore[misc] # "must return a subtype" cls, max_buffer_size: int | float, # noqa: PYI041 diff --git a/src/trio/_tests/check_type_completeness.py b/src/trio/_tests/check_type_completeness.py index 48e4df0bd9..ea53aa0e37 100755 --- a/src/trio/_tests/check_type_completeness.py +++ b/src/trio/_tests/check_type_completeness.py @@ -32,7 +32,7 @@ def run_pyright(platform: str) -> subprocess.CompletedProcess[bytes]: "pyright", # Specify a platform and version to keep imported modules consistent. f"--pythonplatform={platform}", - "--pythonversion=3.8", + "--pythonversion=3.9", "--verifytypes=trio", "--outputjson", "--ignoreexternal", diff --git a/src/trio/_tests/test_repl.py b/src/trio/_tests/test_repl.py index d585276b9d..f988707d1d 100644 --- a/src/trio/_tests/test_repl.py +++ b/src/trio/_tests/test_repl.py @@ -42,7 +42,7 @@ def test_build_raw_input() -> None: # In 3.10 or later, types.FunctionType (used internally) will automatically # attach __builtins__ to the function objects. However we need to explicitly -# include it for 3.8 & 3.9 +# include it for 3.9 support def build_locals() -> dict[str, object]: return {"__builtins__": __builtins__} diff --git a/test-requirements.txt b/test-requirements.txt index a544456455..314eaf4b94 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --universal --python-version=3.8 test-requirements.in -o test-requirements.txt +# uv pip compile --universal --python-version=3.9 test-requirements.in -o test-requirements.txt alabaster==0.7.13 # via sphinx astor==0.8.1 @@ -109,8 +109,6 @@ pyright==1.1.382.post1 # via -r test-requirements.in pytest==8.3.3 # via -r test-requirements.in -pytz==2024.2 ; python_full_version < '3.9' - # via babel requests==2.32.3 # via sphinx ruff==0.6.8 From 8e0894db415cdb3b701cf8fae1346f6675a3dc7d Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 9 Oct 2024 15:05:45 -0500 Subject: [PATCH 02/14] Autofixes --- src/trio/_core/_instrumentation.py | 7 +++++-- src/trio/_core/_io_kqueue.py | 3 ++- src/trio/_core/_io_windows.py | 3 +-- src/trio/_core/_tests/test_guest_mode.py | 4 +--- src/trio/_core/_tests/test_instrumentation.py | 3 ++- src/trio/_core/_tests/test_io.py | 5 +++-- src/trio/_core/_tests/test_ki.py | 3 ++- src/trio/_core/_tests/test_run.py | 9 ++++++--- src/trio/_core/_tests/test_thread_cache.py | 3 ++- src/trio/_core/_tests/type_tests/nursery_start.py | 2 +- src/trio/_core/_tests/type_tests/run.py | 3 ++- src/trio/_dtls.py | 5 +---- src/trio/_file_io.py | 3 +-- src/trio/_highlevel_serve_listeners.py | 3 ++- src/trio/_socket.py | 3 +-- ...est_deprecate_strict_exception_groups_false.py | 2 +- .../_tests/test_highlevel_open_tcp_listeners.py | 3 ++- src/trio/_tests/test_highlevel_open_tcp_stream.py | 3 ++- src/trio/_tests/test_highlevel_serve_listeners.py | 3 ++- src/trio/_tests/test_highlevel_socket.py | 2 +- src/trio/_tests/test_ssl.py | 5 +---- src/trio/_tests/test_subprocess.py | 3 +-- src/trio/_tests/test_threads.py | 9 ++------- src/trio/_tests/test_timeouts.py | 15 +++++++++++---- src/trio/_tests/test_tracing.py | 4 +++- src/trio/_util.py | 4 +--- src/trio/testing/_check_streams.py | 7 ++----- src/trio/testing/_fake_net.py | 2 +- src/trio/testing/_memory_streams.py | 3 ++- src/trio/testing/_raises_group.py | 5 ++--- 30 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/trio/_core/_instrumentation.py b/src/trio/_core/_instrumentation.py index c1063b0e3e..905e81c37a 100644 --- a/src/trio/_core/_instrumentation.py +++ b/src/trio/_core/_instrumentation.py @@ -1,6 +1,9 @@ +from __future__ import annotations + import logging import types -from typing import Any, Callable, Dict, Sequence, TypeVar +from collections.abc import Callable, Sequence +from typing import Any, TypeVar from .._abc import Instrument @@ -17,7 +20,7 @@ def _public(fn: F) -> F: return fn -class Instruments(Dict[str, Dict[Instrument, None]]): +class Instruments(dict[str, dict[Instrument, None]]): """A collection of `trio.abc.Instrument` organized by hook. Instrumentation calls are rather expensive, and we don't want a diff --git a/src/trio/_core/_io_kqueue.py b/src/trio/_core/_io_kqueue.py index 13f95b22b2..f75db936ba 100644 --- a/src/trio/_core/_io_kqueue.py +++ b/src/trio/_core/_io_kqueue.py @@ -3,8 +3,9 @@ import errno import select import sys +from collections.abc import Callable, Iterator from contextlib import contextmanager -from typing import TYPE_CHECKING, Callable, Iterator, Literal +from typing import TYPE_CHECKING, Literal import attrs import outcome diff --git a/src/trio/_core/_io_windows.py b/src/trio/_core/_io_windows.py index 0bc3b33378..474b4321ae 100644 --- a/src/trio/_core/_io_windows.py +++ b/src/trio/_core/_io_windows.py @@ -4,12 +4,11 @@ import itertools import socket import sys +from collections.abc import Callable, Iterator from contextlib import contextmanager from typing import ( TYPE_CHECKING, Any, - Callable, - Iterator, Literal, TypeVar, cast, diff --git a/src/trio/_core/_tests/test_guest_mode.py b/src/trio/_core/_tests/test_guest_mode.py index 1a8b230e78..5beee4b22e 100644 --- a/src/trio/_core/_tests/test_guest_mode.py +++ b/src/trio/_core/_tests/test_guest_mode.py @@ -11,14 +11,12 @@ import time import traceback import warnings +from collections.abc import AsyncGenerator, Awaitable, Callable from functools import partial from math import inf from typing import ( TYPE_CHECKING, Any, - AsyncGenerator, - Awaitable, - Callable, NoReturn, TypeVar, ) diff --git a/src/trio/_core/_tests/test_instrumentation.py b/src/trio/_core/_tests/test_instrumentation.py index 5e6cecae65..9dc2d23355 100644 --- a/src/trio/_core/_tests/test_instrumentation.py +++ b/src/trio/_core/_tests/test_instrumentation.py @@ -1,6 +1,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Container, Iterable, NoReturn +from collections.abc import Container, Iterable +from typing import TYPE_CHECKING, NoReturn import attrs import pytest diff --git a/src/trio/_core/_tests/test_io.py b/src/trio/_core/_tests/test_io.py index 7060262edf..62153d2814 100644 --- a/src/trio/_core/_tests/test_io.py +++ b/src/trio/_core/_tests/test_io.py @@ -2,8 +2,9 @@ import random import socket as stdlib_socket +from collections.abc import Awaitable, Callable from contextlib import suppress -from typing import TYPE_CHECKING, Awaitable, Callable, Tuple, TypeVar +from typing import TYPE_CHECKING, TypeVar import pytest @@ -39,7 +40,7 @@ def drain_socket(sock: stdlib_socket.socket) -> None: WaitSocket = Callable[[stdlib_socket.socket], Awaitable[object]] -SocketPair = Tuple[stdlib_socket.socket, stdlib_socket.socket] +SocketPair = tuple[stdlib_socket.socket, stdlib_socket.socket] RetT = TypeVar("RetT") diff --git a/src/trio/_core/_tests/test_ki.py b/src/trio/_core/_tests/test_ki.py index e4241fc762..a28c53d2af 100644 --- a/src/trio/_core/_tests/test_ki.py +++ b/src/trio/_core/_tests/test_ki.py @@ -4,7 +4,8 @@ import inspect import signal import threading -from typing import TYPE_CHECKING, AsyncIterator, Callable, Iterator +from collections.abc import AsyncIterator, Callable, Iterator +from typing import TYPE_CHECKING import outcome import pytest diff --git a/src/trio/_core/_tests/test_run.py b/src/trio/_core/_tests/test_run.py index 9d2eab787d..213311ab04 100644 --- a/src/trio/_core/_tests/test_run.py +++ b/src/trio/_core/_tests/test_run.py @@ -2505,9 +2505,12 @@ async def crasher() -> NoReturn: old_flags = gc.get_debug() try: - with RaisesGroup( - Matcher(ValueError, "^this is a crash$"), - ), _core.CancelScope() as outer: + with ( + RaisesGroup( + Matcher(ValueError, "^this is a crash$"), + ), + _core.CancelScope() as outer, + ): async with _core.open_nursery() as nursery: gc.collect() gc.set_debug(gc.DEBUG_SAVEALL) diff --git a/src/trio/_core/_tests/test_thread_cache.py b/src/trio/_core/_tests/test_thread_cache.py index ee301d17fd..412d07b82a 100644 --- a/src/trio/_core/_tests/test_thread_cache.py +++ b/src/trio/_core/_tests/test_thread_cache.py @@ -2,9 +2,10 @@ import threading import time +from collections.abc import Iterator from contextlib import contextmanager from queue import Queue -from typing import TYPE_CHECKING, Iterator, NoReturn +from typing import TYPE_CHECKING, NoReturn import pytest diff --git a/src/trio/_core/_tests/type_tests/nursery_start.py b/src/trio/_core/_tests/type_tests/nursery_start.py index b286b76ff2..720a52e6af 100644 --- a/src/trio/_core/_tests/type_tests/nursery_start.py +++ b/src/trio/_core/_tests/type_tests/nursery_start.py @@ -1,6 +1,6 @@ """Test variadic generic typing for Nursery.start[_soon]().""" -from typing import Awaitable, Callable +from collections.abc import Awaitable, Callable from trio import TASK_STATUS_IGNORED, Nursery, TaskStatus diff --git a/src/trio/_core/_tests/type_tests/run.py b/src/trio/_core/_tests/type_tests/run.py index 6d2124102b..0ace7d4e9a 100644 --- a/src/trio/_core/_tests/type_tests/run.py +++ b/src/trio/_core/_tests/type_tests/run.py @@ -1,6 +1,7 @@ from __future__ import annotations -from typing import Sequence, overload +from collections.abc import Sequence +from typing import overload import trio from typing_extensions import assert_type diff --git a/src/trio/_dtls.py b/src/trio/_dtls.py index 62b01292a8..428854f6b3 100644 --- a/src/trio/_dtls.py +++ b/src/trio/_dtls.py @@ -16,15 +16,12 @@ import struct import warnings import weakref +from collections.abc import Awaitable, Callable, Iterable, Iterator from itertools import count from typing import ( TYPE_CHECKING, Any, - Awaitable, - Callable, Generic, - Iterable, - Iterator, TypeVar, Union, ) diff --git a/src/trio/_file_io.py b/src/trio/_file_io.py index 8038ff6234..76c17086dd 100644 --- a/src/trio/_file_io.py +++ b/src/trio/_file_io.py @@ -1,6 +1,7 @@ from __future__ import annotations import io +from collections.abc import Callable, Iterable from functools import partial from typing import ( IO, @@ -8,9 +9,7 @@ Any, AnyStr, BinaryIO, - Callable, Generic, - Iterable, TypeVar, Union, overload, diff --git a/src/trio/_highlevel_serve_listeners.py b/src/trio/_highlevel_serve_listeners.py index 71521546d3..0a85c8ecb0 100644 --- a/src/trio/_highlevel_serve_listeners.py +++ b/src/trio/_highlevel_serve_listeners.py @@ -3,7 +3,8 @@ import errno import logging import os -from typing import Any, Awaitable, Callable, NoReturn, TypeVar +from collections.abc import Awaitable, Callable +from typing import Any, NoReturn, TypeVar import trio diff --git a/src/trio/_socket.py b/src/trio/_socket.py index 6dbe9c0c4b..21748418bd 100644 --- a/src/trio/_socket.py +++ b/src/trio/_socket.py @@ -4,13 +4,12 @@ import select import socket as _stdlib_socket import sys +from collections.abc import Awaitable, Callable from operator import index from socket import AddressFamily, SocketKind from typing import ( TYPE_CHECKING, Any, - Awaitable, - Callable, Literal, SupportsIndex, TypeVar, diff --git a/src/trio/_tests/test_deprecate_strict_exception_groups_false.py b/src/trio/_tests/test_deprecate_strict_exception_groups_false.py index ccf34d72ed..7e575aa92e 100644 --- a/src/trio/_tests/test_deprecate_strict_exception_groups_false.py +++ b/src/trio/_tests/test_deprecate_strict_exception_groups_false.py @@ -1,4 +1,4 @@ -from typing import Awaitable, Callable +from collections.abc import Awaitable, Callable import pytest diff --git a/src/trio/_tests/test_highlevel_open_tcp_listeners.py b/src/trio/_tests/test_highlevel_open_tcp_listeners.py index 6e2abf112a..96f08061fc 100644 --- a/src/trio/_tests/test_highlevel_open_tcp_listeners.py +++ b/src/trio/_tests/test_highlevel_open_tcp_listeners.py @@ -3,8 +3,9 @@ import errno import socket as stdlib_socket import sys +from collections.abc import Sequence from socket import AddressFamily, SocketKind -from typing import TYPE_CHECKING, Any, Sequence, overload +from typing import TYPE_CHECKING, Any, overload import attrs import pytest diff --git a/src/trio/_tests/test_highlevel_open_tcp_stream.py b/src/trio/_tests/test_highlevel_open_tcp_stream.py index 81d2b403bb..8b3bcf7a2a 100644 --- a/src/trio/_tests/test_highlevel_open_tcp_stream.py +++ b/src/trio/_tests/test_highlevel_open_tcp_stream.py @@ -2,8 +2,9 @@ import socket import sys +from collections.abc import Sequence from socket import AddressFamily, SocketKind -from typing import TYPE_CHECKING, Any, Sequence +from typing import TYPE_CHECKING, Any import attrs import pytest diff --git a/src/trio/_tests/test_highlevel_serve_listeners.py b/src/trio/_tests/test_highlevel_serve_listeners.py index 6ecd42694f..4322461db4 100644 --- a/src/trio/_tests/test_highlevel_serve_listeners.py +++ b/src/trio/_tests/test_highlevel_serve_listeners.py @@ -1,8 +1,9 @@ from __future__ import annotations import errno +from collections.abc import Awaitable, Callable from functools import partial -from typing import TYPE_CHECKING, Awaitable, Callable, NoReturn +from typing import TYPE_CHECKING, NoReturn import attrs diff --git a/src/trio/_tests/test_highlevel_socket.py b/src/trio/_tests/test_highlevel_socket.py index 735353ab7e..6348ec9045 100644 --- a/src/trio/_tests/test_highlevel_socket.py +++ b/src/trio/_tests/test_highlevel_socket.py @@ -3,7 +3,7 @@ import errno import socket as stdlib_socket import sys -from typing import Sequence +from collections.abc import Sequence import pytest diff --git a/src/trio/_tests/test_ssl.py b/src/trio/_tests/test_ssl.py index 7197a47cc3..50627a713d 100644 --- a/src/trio/_tests/test_ssl.py +++ b/src/trio/_tests/test_ssl.py @@ -5,16 +5,13 @@ import ssl import sys import threading +from collections.abc import AsyncIterator, Awaitable, Callable, Iterator from contextlib import asynccontextmanager, contextmanager, suppress from functools import partial from ssl import SSLContext from typing import ( TYPE_CHECKING, Any, - AsyncIterator, - Awaitable, - Callable, - Iterator, NoReturn, ) diff --git a/src/trio/_tests/test_subprocess.py b/src/trio/_tests/test_subprocess.py index d65a07614a..e31a74d66a 100644 --- a/src/trio/_tests/test_subprocess.py +++ b/src/trio/_tests/test_subprocess.py @@ -6,6 +6,7 @@ import signal import subprocess import sys +from collections.abc import AsyncIterator, Callable from contextlib import asynccontextmanager from functools import partial from pathlib import Path as SyncPath @@ -14,8 +15,6 @@ TYPE_CHECKING, Any, AsyncContextManager, - AsyncIterator, - Callable, NoReturn, ) diff --git a/src/trio/_tests/test_threads.py b/src/trio/_tests/test_threads.py index f2f1cf7815..b49a1ee3d0 100644 --- a/src/trio/_tests/test_threads.py +++ b/src/trio/_tests/test_threads.py @@ -7,16 +7,11 @@ import threading import time import weakref +from collections.abc import AsyncGenerator, Awaitable, Callable from functools import partial from typing import ( TYPE_CHECKING, - AsyncGenerator, - Awaitable, - Callable, - List, NoReturn, - Tuple, - Type, TypeVar, Union, ) @@ -52,7 +47,7 @@ from ..lowlevel import Task -RecordType = List[Tuple[str, Union[threading.Thread, Type[BaseException]]]] +RecordType = list[tuple[str, Union[threading.Thread, type[BaseException]]]] T = TypeVar("T") diff --git a/src/trio/_tests/test_timeouts.py b/src/trio/_tests/test_timeouts.py index 574e1db1a4..eacdbbbf82 100644 --- a/src/trio/_tests/test_timeouts.py +++ b/src/trio/_tests/test_timeouts.py @@ -1,5 +1,8 @@ +from __future__ import annotations + import time -from typing import Awaitable, Callable, Protocol, TypeVar +from collections.abc import Awaitable, Callable +from typing import Protocol, TypeVar import outcome import pytest @@ -132,9 +135,13 @@ async def task() -> None: @slow async def test_fail_after_fails_even_if_shielded() -> None: async def task() -> None: - with pytest.raises(TooSlowError), _core.CancelScope() as outer, fail_after( - TARGET, - shield=True, + with ( + pytest.raises(TooSlowError), + _core.CancelScope() as outer, + fail_after( + TARGET, + shield=True, + ), ): outer.cancel() # The outer scope is cancelled, but this task is protected by the diff --git a/src/trio/_tests/test_tracing.py b/src/trio/_tests/test_tracing.py index 5cf758c6b6..9cbb1f7caf 100644 --- a/src/trio/_tests/test_tracing.py +++ b/src/trio/_tests/test_tracing.py @@ -1,4 +1,6 @@ -from typing import AsyncGenerator +from __future__ import annotations + +from collections.abc import AsyncGenerator import trio diff --git a/src/trio/_util.py b/src/trio/_util.py index 3af8b5cfde..e7c15b5da0 100644 --- a/src/trio/_util.py +++ b/src/trio/_util.py @@ -7,15 +7,13 @@ import signal import threading from abc import ABCMeta +from collections.abc import Awaitable, Callable, Sequence from functools import update_wrapper from typing import ( TYPE_CHECKING, Any, - Awaitable, - Callable, Generic, NoReturn, - Sequence, TypeVar, final as std_final, ) diff --git a/src/trio/testing/_check_streams.py b/src/trio/testing/_check_streams.py index 335c9c1ea5..3bf5442814 100644 --- a/src/trio/testing/_check_streams.py +++ b/src/trio/testing/_check_streams.py @@ -3,14 +3,11 @@ import random import sys +from collections.abc import Awaitable, Callable, Generator from contextlib import contextmanager, suppress from typing import ( TYPE_CHECKING, - Awaitable, - Callable, - Generator, Generic, - Tuple, TypeVar, ) @@ -31,7 +28,7 @@ Res1 = TypeVar("Res1", bound=AsyncResource) Res2 = TypeVar("Res2", bound=AsyncResource) -StreamMaker: TypeAlias = Callable[[], Awaitable[Tuple[Res1, Res2]]] +StreamMaker: TypeAlias = Callable[[], Awaitable[tuple[Res1, Res2]]] class _ForceCloseBoth(Generic[Res1, Res2]): diff --git a/src/trio/testing/_fake_net.py b/src/trio/testing/_fake_net.py index ed0f6980f7..57dfb0c4ee 100644 --- a/src/trio/testing/_fake_net.py +++ b/src/trio/testing/_fake_net.py @@ -14,10 +14,10 @@ import os import socket import sys +from collections.abc import Iterable from typing import ( TYPE_CHECKING, Any, - Iterable, NoReturn, TypeVar, Union, diff --git a/src/trio/testing/_memory_streams.py b/src/trio/testing/_memory_streams.py index 26ddde8565..c81789b2b4 100644 --- a/src/trio/testing/_memory_streams.py +++ b/src/trio/testing/_memory_streams.py @@ -1,7 +1,8 @@ from __future__ import annotations import operator -from typing import TYPE_CHECKING, Awaitable, Callable, TypeVar +from collections.abc import Awaitable, Callable +from typing import TYPE_CHECKING, TypeVar from .. import _core, _util from .._highlevel_generic import StapledStream diff --git a/src/trio/testing/_raises_group.py b/src/trio/testing/_raises_group.py index 627663ffb5..940c35cf01 100644 --- a/src/trio/testing/_raises_group.py +++ b/src/trio/testing/_raises_group.py @@ -2,14 +2,13 @@ import re import sys +from collections.abc import Callable, Sequence +from re import Pattern from typing import ( TYPE_CHECKING, - Callable, ContextManager, Generic, Literal, - Pattern, - Sequence, cast, overload, ) From 02f78f5a6818e76ce10cbcbfec42616f60ad5f19 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 9 Oct 2024 15:21:43 -0500 Subject: [PATCH 03/14] Automatic unsafe fixes --- src/trio/_channel.py | 2 +- src/trio/_core/_asyncgens.py | 3 +-- src/trio/_core/_entry_queue.py | 5 +++-- src/trio/_core/_generated_io_kqueue.py | 5 +++-- src/trio/_core/_generated_io_windows.py | 8 ++++++-- src/trio/_core/_io_kqueue.py | 3 ++- src/trio/_core/_io_windows.py | 3 ++- src/trio/_core/_tests/test_instrumentation.py | 3 ++- src/trio/_core/_tests/test_ki.py | 3 ++- src/trio/_core/_tests/test_thread_cache.py | 3 ++- src/trio/_core/_tests/type_tests/nursery_start.py | 5 ++++- src/trio/_core/_tests/type_tests/run.py | 6 ++++-- src/trio/_dtls.py | 2 +- src/trio/_path.py | 3 +-- src/trio/_socket.py | 3 +-- src/trio/_subprocess.py | 10 +--------- src/trio/_tests/test_highlevel_open_tcp_listeners.py | 3 ++- src/trio/_tests/test_highlevel_open_tcp_stream.py | 3 ++- src/trio/_tests/test_highlevel_serve_listeners.py | 3 ++- src/trio/_tests/test_highlevel_socket.py | 5 ++++- src/trio/_tests/test_path.py | 6 +++--- src/trio/_tests/test_socket.py | 8 ++++---- src/trio/_tests/test_ssl.py | 3 ++- src/trio/_tests/test_subprocess.py | 5 ++--- src/trio/_tests/test_threads.py | 3 ++- src/trio/_tests/test_timeouts.py | 6 ++++-- src/trio/_tests/test_tracing.py | 5 ++++- src/trio/_tests/type_tests/path.py | 8 ++++---- src/trio/_tools/gen_exports.py | 8 +++++--- src/trio/testing/_fake_net.py | 2 +- src/trio/testing/_raises_group.py | 9 ++++++--- 31 files changed, 83 insertions(+), 61 deletions(-) diff --git a/src/trio/_channel.py b/src/trio/_channel.py index 4007c55177..cb7df95ff6 100644 --- a/src/trio/_channel.py +++ b/src/trio/_channel.py @@ -92,7 +92,7 @@ def _open_memory_channel( # it could replace the normal function header if TYPE_CHECKING: # written as a class so you can say open_memory_channel[int](5) - class open_memory_channel(tuple[MemorySendChannel[T], MemoryReceiveChannel[T]]): + class open_memory_channel(tuple["MemorySendChannel[T]", "MemoryReceiveChannel[T]"]): def __new__( # type: ignore[misc] # "must return a subtype" cls, max_buffer_size: int | float, # noqa: PYI041 diff --git a/src/trio/_core/_asyncgens.py b/src/trio/_core/_asyncgens.py index 77f1c7eced..21102ea7d8 100644 --- a/src/trio/_core/_asyncgens.py +++ b/src/trio/_core/_asyncgens.py @@ -17,10 +17,9 @@ if TYPE_CHECKING: from types import AsyncGeneratorType - from typing import Set _WEAK_ASYNC_GEN_SET = weakref.WeakSet[AsyncGeneratorType[object, NoReturn]] - _ASYNC_GEN_SET = Set[AsyncGeneratorType[object, NoReturn]] + _ASYNC_GEN_SET = set[AsyncGeneratorType[object, NoReturn]] else: _WEAK_ASYNC_GEN_SET = weakref.WeakSet _ASYNC_GEN_SET = set diff --git a/src/trio/_core/_entry_queue.py b/src/trio/_core/_entry_queue.py index 8534bc07dc..28e478d0e8 100644 --- a/src/trio/_core/_entry_queue.py +++ b/src/trio/_core/_entry_queue.py @@ -2,7 +2,8 @@ import threading from collections import deque -from typing import TYPE_CHECKING, Callable, NoReturn, Tuple +from collections.abc import Callable +from typing import TYPE_CHECKING, NoReturn import attrs @@ -16,7 +17,7 @@ PosArgsT = TypeVarTuple("PosArgsT") Function = Callable[..., object] -Job = Tuple[Function, Tuple[object, ...]] +Job = tuple[Function, tuple[object, ...]] @attrs.define diff --git a/src/trio/_core/_generated_io_kqueue.py b/src/trio/_core/_generated_io_kqueue.py index eb230597b3..202dd8704a 100644 --- a/src/trio/_core/_generated_io_kqueue.py +++ b/src/trio/_core/_generated_io_kqueue.py @@ -4,13 +4,14 @@ from __future__ import annotations import sys -from typing import TYPE_CHECKING, Callable, ContextManager +from typing import TYPE_CHECKING, Callable from ._ki import LOCALS_KEY_KI_PROTECTION_ENABLED from ._run import GLOBAL_RUN_CONTEXT if TYPE_CHECKING: import select + from contextlib import AbstractContextManager from .. import _core from .._file_io import _HasFileNo @@ -44,7 +45,7 @@ def current_kqueue() -> select.kqueue: def monitor_kevent( ident: int, filter: int, -) -> ContextManager[_core.UnboundedQueue[select.kevent]]: +) -> AbstractContextManager[_core.UnboundedQueue[select.kevent]]: """TODO: these are implemented, but are currently more of a sketch than anything real. See `#26 `__. diff --git a/src/trio/_core/_generated_io_windows.py b/src/trio/_core/_generated_io_windows.py index 1cad305a03..d06bb19e0e 100644 --- a/src/trio/_core/_generated_io_windows.py +++ b/src/trio/_core/_generated_io_windows.py @@ -4,12 +4,14 @@ from __future__ import annotations import sys -from typing import TYPE_CHECKING, ContextManager +from typing import TYPE_CHECKING from ._ki import LOCALS_KEY_KI_PROTECTION_ENABLED from ._run import GLOBAL_RUN_CONTEXT if TYPE_CHECKING: + from contextlib import AbstractContextManager + from typing_extensions import Buffer from .._file_io import _HasFileNo @@ -196,7 +198,9 @@ def current_iocp() -> int: raise RuntimeError("must be called from async context") from None -def monitor_completion_key() -> ContextManager[tuple[int, UnboundedQueue[object]]]: +def monitor_completion_key() -> ( + AbstractContextManager[tuple[int, UnboundedQueue[object]]] +): """TODO: these are implemented, but are currently more of a sketch than anything real. See `#26 `__ and `#52 diff --git a/src/trio/_core/_io_kqueue.py b/src/trio/_core/_io_kqueue.py index f75db936ba..6c440920d3 100644 --- a/src/trio/_core/_io_kqueue.py +++ b/src/trio/_core/_io_kqueue.py @@ -3,7 +3,6 @@ import errno import select import sys -from collections.abc import Callable, Iterator from contextlib import contextmanager from typing import TYPE_CHECKING, Literal @@ -15,6 +14,8 @@ from ._wakeup_socketpair import WakeupSocketpair if TYPE_CHECKING: + from collections.abc import Callable, Iterator + from typing_extensions import TypeAlias from .._core import Abort, RaiseCancelT, Task, UnboundedQueue diff --git a/src/trio/_core/_io_windows.py b/src/trio/_core/_io_windows.py index 474b4321ae..80b62d4777 100644 --- a/src/trio/_core/_io_windows.py +++ b/src/trio/_core/_io_windows.py @@ -4,7 +4,6 @@ import itertools import socket import sys -from collections.abc import Callable, Iterator from contextlib import contextmanager from typing import ( TYPE_CHECKING, @@ -40,6 +39,8 @@ ) if TYPE_CHECKING: + from collections.abc import Callable, Iterator + from typing_extensions import Buffer, TypeAlias from .._file_io import _HasFileNo diff --git a/src/trio/_core/_tests/test_instrumentation.py b/src/trio/_core/_tests/test_instrumentation.py index 9dc2d23355..4f7cda5c69 100644 --- a/src/trio/_core/_tests/test_instrumentation.py +++ b/src/trio/_core/_tests/test_instrumentation.py @@ -1,6 +1,5 @@ from __future__ import annotations -from collections.abc import Container, Iterable from typing import TYPE_CHECKING, NoReturn import attrs @@ -10,6 +9,8 @@ from .tutil import check_sequence_matches if TYPE_CHECKING: + from collections.abc import Container, Iterable + from ...lowlevel import Task diff --git a/src/trio/_core/_tests/test_ki.py b/src/trio/_core/_tests/test_ki.py index a28c53d2af..8582cc0b21 100644 --- a/src/trio/_core/_tests/test_ki.py +++ b/src/trio/_core/_tests/test_ki.py @@ -4,7 +4,6 @@ import inspect import signal import threading -from collections.abc import AsyncIterator, Callable, Iterator from typing import TYPE_CHECKING import outcome @@ -24,6 +23,8 @@ from ...testing import wait_all_tasks_blocked if TYPE_CHECKING: + from collections.abc import AsyncIterator, Callable, Iterator + from ..._core import Abort, RaiseCancelT diff --git a/src/trio/_core/_tests/test_thread_cache.py b/src/trio/_core/_tests/test_thread_cache.py index 412d07b82a..1e3841ee0d 100644 --- a/src/trio/_core/_tests/test_thread_cache.py +++ b/src/trio/_core/_tests/test_thread_cache.py @@ -2,7 +2,6 @@ import threading import time -from collections.abc import Iterator from contextlib import contextmanager from queue import Queue from typing import TYPE_CHECKING, NoReturn @@ -14,6 +13,8 @@ from .tutil import gc_collect_harder, slow if TYPE_CHECKING: + from collections.abc import Iterator + from outcome import Outcome diff --git a/src/trio/_core/_tests/type_tests/nursery_start.py b/src/trio/_core/_tests/type_tests/nursery_start.py index 720a52e6af..4ce03b2721 100644 --- a/src/trio/_core/_tests/type_tests/nursery_start.py +++ b/src/trio/_core/_tests/type_tests/nursery_start.py @@ -1,9 +1,12 @@ """Test variadic generic typing for Nursery.start[_soon]().""" -from collections.abc import Awaitable, Callable +from typing import TYPE_CHECKING from trio import TASK_STATUS_IGNORED, Nursery, TaskStatus +if TYPE_CHECKING: + from collections.abc import Awaitable, Callable + async def task_0() -> None: ... diff --git a/src/trio/_core/_tests/type_tests/run.py b/src/trio/_core/_tests/type_tests/run.py index 0ace7d4e9a..5c51b91496 100644 --- a/src/trio/_core/_tests/type_tests/run.py +++ b/src/trio/_core/_tests/type_tests/run.py @@ -1,11 +1,13 @@ from __future__ import annotations -from collections.abc import Sequence -from typing import overload +from typing import TYPE_CHECKING, overload import trio from typing_extensions import assert_type +if TYPE_CHECKING: + from collections.abc import Sequence + async def sleep_sort(values: Sequence[float]) -> list[float]: return [1] diff --git a/src/trio/_dtls.py b/src/trio/_dtls.py index 428854f6b3..a8ce3c3023 100644 --- a/src/trio/_dtls.py +++ b/src/trio/_dtls.py @@ -16,7 +16,6 @@ import struct import warnings import weakref -from collections.abc import Awaitable, Callable, Iterable, Iterator from itertools import count from typing import ( TYPE_CHECKING, @@ -34,6 +33,7 @@ from ._util import NoPublicConstructor, final if TYPE_CHECKING: + from collections.abc import Awaitable, Callable, Iterable, Iterator from types import TracebackType # See DTLSEndpoint.__init__ for why this is imported here diff --git a/src/trio/_path.py b/src/trio/_path.py index 3663831a23..2c9dfff292 100644 --- a/src/trio/_path.py +++ b/src/trio/_path.py @@ -222,8 +222,7 @@ def __repr__(self) -> str: group = _wrap_method(pathlib.Path.group) if sys.platform != "win32" or sys.version_info >= (3, 12): is_mount = _wrap_method(pathlib.Path.is_mount) - if sys.version_info >= (3, 9): - readlink = _wrap_method_path(pathlib.Path.readlink) + readlink = _wrap_method_path(pathlib.Path.readlink) rename = _wrap_method_path(pathlib.Path.rename) replace = _wrap_method_path(pathlib.Path.replace) resolve = _wrap_method_path(pathlib.Path.resolve) diff --git a/src/trio/_socket.py b/src/trio/_socket.py index 21748418bd..ec8d3d3f13 100644 --- a/src/trio/_socket.py +++ b/src/trio/_socket.py @@ -4,7 +4,6 @@ import select import socket as _stdlib_socket import sys -from collections.abc import Awaitable, Callable from operator import index from socket import AddressFamily, SocketKind from typing import ( @@ -25,7 +24,7 @@ from . import _core if TYPE_CHECKING: - from collections.abc import Iterable + from collections.abc import Awaitable, Callable, Iterable from types import TracebackType from typing_extensions import Buffer, Concatenate, ParamSpec, Self, TypeAlias diff --git a/src/trio/_subprocess.py b/src/trio/_subprocess.py index 263225ffca..3ba1ac4f17 100644 --- a/src/trio/_subprocess.py +++ b/src/trio/_subprocess.py @@ -32,15 +32,7 @@ # Sphinx cannot parse the stringified version -if sys.version_info >= (3, 9): - StrOrBytesPath: TypeAlias = Union[str, bytes, os.PathLike[str], os.PathLike[bytes]] -else: - StrOrBytesPath: TypeAlias = Union[ - str, - bytes, - "os.PathLike[str]", - "os.PathLike[bytes]", - ] +StrOrBytesPath: TypeAlias = Union[str, bytes, os.PathLike[str], os.PathLike[bytes]] # Linux-specific, but has complex lifetime management stuff so we hard-code it diff --git a/src/trio/_tests/test_highlevel_open_tcp_listeners.py b/src/trio/_tests/test_highlevel_open_tcp_listeners.py index 96f08061fc..a95d51994d 100644 --- a/src/trio/_tests/test_highlevel_open_tcp_listeners.py +++ b/src/trio/_tests/test_highlevel_open_tcp_listeners.py @@ -3,7 +3,6 @@ import errno import socket as stdlib_socket import sys -from collections.abc import Sequence from socket import AddressFamily, SocketKind from typing import TYPE_CHECKING, Any, overload @@ -27,6 +26,8 @@ from exceptiongroup import BaseExceptionGroup if TYPE_CHECKING: + from collections.abc import Sequence + from typing_extensions import Buffer diff --git a/src/trio/_tests/test_highlevel_open_tcp_stream.py b/src/trio/_tests/test_highlevel_open_tcp_stream.py index 8b3bcf7a2a..7fd776ab06 100644 --- a/src/trio/_tests/test_highlevel_open_tcp_stream.py +++ b/src/trio/_tests/test_highlevel_open_tcp_stream.py @@ -2,7 +2,6 @@ import socket import sys -from collections.abc import Sequence from socket import AddressFamily, SocketKind from typing import TYPE_CHECKING, Any @@ -20,6 +19,8 @@ from trio.testing import Matcher, RaisesGroup if TYPE_CHECKING: + from collections.abc import Sequence + from trio.testing import MockClock if sys.version_info < (3, 11): diff --git a/src/trio/_tests/test_highlevel_serve_listeners.py b/src/trio/_tests/test_highlevel_serve_listeners.py index 4322461db4..0ce82e7846 100644 --- a/src/trio/_tests/test_highlevel_serve_listeners.py +++ b/src/trio/_tests/test_highlevel_serve_listeners.py @@ -1,7 +1,6 @@ from __future__ import annotations import errno -from collections.abc import Awaitable, Callable from functools import partial from typing import TYPE_CHECKING, NoReturn @@ -20,6 +19,8 @@ ) if TYPE_CHECKING: + from collections.abc import Awaitable, Callable + import pytest from trio._channel import MemoryReceiveChannel, MemorySendChannel diff --git a/src/trio/_tests/test_highlevel_socket.py b/src/trio/_tests/test_highlevel_socket.py index 6348ec9045..f2fcf98a3b 100644 --- a/src/trio/_tests/test_highlevel_socket.py +++ b/src/trio/_tests/test_highlevel_socket.py @@ -3,7 +3,7 @@ import errno import socket as stdlib_socket import sys -from collections.abc import Sequence +from typing import TYPE_CHECKING import pytest @@ -16,6 +16,9 @@ ) from .test_socket import setsockopt_tests +if TYPE_CHECKING: + from collections.abc import Sequence + async def test_SocketStream_basics() -> None: # stdlib socket bad (even if connected) diff --git a/src/trio/_tests/test_path.py b/src/trio/_tests/test_path.py index bbe502afd6..9b72cb77b3 100644 --- a/src/trio/_tests/test_path.py +++ b/src/trio/_tests/test_path.py @@ -2,7 +2,7 @@ import os import pathlib -from typing import TYPE_CHECKING, Type, Union +from typing import TYPE_CHECKING, Union import pytest @@ -51,8 +51,8 @@ async def test_magic() -> None: assert bytes(path) == b"test" -EitherPathType = Union[Type[trio.Path], Type[pathlib.Path]] -PathOrStrType = Union[EitherPathType, Type[str]] +EitherPathType = Union[type[trio.Path], type[pathlib.Path]] +PathOrStrType = Union[EitherPathType, type[str]] cls_pairs: list[tuple[EitherPathType, EitherPathType]] = [ (trio.Path, pathlib.Path), (pathlib.Path, trio.Path), diff --git a/src/trio/_tests/test_socket.py b/src/trio/_tests/test_socket.py index f2c2ee955e..dca049a925 100644 --- a/src/trio/_tests/test_socket.py +++ b/src/trio/_tests/test_socket.py @@ -8,7 +8,7 @@ import tempfile from pathlib import Path from socket import AddressFamily, SocketKind -from typing import TYPE_CHECKING, Any, Callable, List, Tuple, Union +from typing import TYPE_CHECKING, Any, Callable, Union import attrs import pytest @@ -23,14 +23,14 @@ from .._highlevel_socket import SocketStream - GaiTuple: TypeAlias = Tuple[ + GaiTuple: TypeAlias = tuple[ AddressFamily, SocketKind, int, str, - Union[Tuple[str, int], Tuple[str, int, int, int]], + Union[tuple[str, int], tuple[str, int, int, int]], ] - GetAddrInfoResponse: TypeAlias = List[GaiTuple] + GetAddrInfoResponse: TypeAlias = list[GaiTuple] else: GaiTuple: object GetAddrInfoResponse = object diff --git a/src/trio/_tests/test_ssl.py b/src/trio/_tests/test_ssl.py index 50627a713d..0bd6d02683 100644 --- a/src/trio/_tests/test_ssl.py +++ b/src/trio/_tests/test_ssl.py @@ -5,7 +5,6 @@ import ssl import sys import threading -from collections.abc import AsyncIterator, Awaitable, Callable, Iterator from contextlib import asynccontextmanager, contextmanager, suppress from functools import partial from ssl import SSLContext @@ -53,6 +52,8 @@ ) if TYPE_CHECKING: + from collections.abc import AsyncIterator, Awaitable, Callable, Iterator + from typing_extensions import TypeAlias from trio._core import MockClock diff --git a/src/trio/_tests/test_subprocess.py b/src/trio/_tests/test_subprocess.py index e31a74d66a..4a870ed7a5 100644 --- a/src/trio/_tests/test_subprocess.py +++ b/src/trio/_tests/test_subprocess.py @@ -7,14 +7,13 @@ import subprocess import sys from collections.abc import AsyncIterator, Callable -from contextlib import asynccontextmanager +from contextlib import AbstractAsyncContextManager, asynccontextmanager from functools import partial from pathlib import Path as SyncPath from signal import Signals from typing import ( TYPE_CHECKING, Any, - AsyncContextManager, NoReturn, ) @@ -114,7 +113,7 @@ async def run_process_in_nursery(*args: Any, **kwargs: Any) -> AsyncIterator[Pro ids=["open_process", "run_process in nursery"], ) -BackgroundProcessType: TypeAlias = Callable[..., AsyncContextManager[Process]] +BackgroundProcessType: TypeAlias = Callable[..., AbstractAsyncContextManager[Process]] @background_process_param diff --git a/src/trio/_tests/test_threads.py b/src/trio/_tests/test_threads.py index b49a1ee3d0..e683aa05c7 100644 --- a/src/trio/_tests/test_threads.py +++ b/src/trio/_tests/test_threads.py @@ -7,7 +7,6 @@ import threading import time import weakref -from collections.abc import AsyncGenerator, Awaitable, Callable from functools import partial from typing import ( TYPE_CHECKING, @@ -43,6 +42,8 @@ from ..testing import wait_all_tasks_blocked if TYPE_CHECKING: + from collections.abc import AsyncGenerator, Awaitable, Callable + from outcome import Outcome from ..lowlevel import Task diff --git a/src/trio/_tests/test_timeouts.py b/src/trio/_tests/test_timeouts.py index eacdbbbf82..dbec679f70 100644 --- a/src/trio/_tests/test_timeouts.py +++ b/src/trio/_tests/test_timeouts.py @@ -1,8 +1,7 @@ from __future__ import annotations import time -from collections.abc import Awaitable, Callable -from typing import Protocol, TypeVar +from typing import TYPE_CHECKING, Protocol, TypeVar import outcome import pytest @@ -23,6 +22,9 @@ ) from ..testing import assert_checkpoints +if TYPE_CHECKING: + from collections.abc import Awaitable, Callable + T = TypeVar("T") diff --git a/src/trio/_tests/test_tracing.py b/src/trio/_tests/test_tracing.py index 9cbb1f7caf..52ea9bfa40 100644 --- a/src/trio/_tests/test_tracing.py +++ b/src/trio/_tests/test_tracing.py @@ -1,9 +1,12 @@ from __future__ import annotations -from collections.abc import AsyncGenerator +from typing import TYPE_CHECKING import trio +if TYPE_CHECKING: + from collections.abc import AsyncGenerator + async def coro1(event: trio.Event) -> None: event.set() diff --git a/src/trio/_tests/type_tests/path.py b/src/trio/_tests/type_tests/path.py index 5c7300fab5..6ea6717a6e 100644 --- a/src/trio/_tests/type_tests/path.py +++ b/src/trio/_tests/type_tests/path.py @@ -4,7 +4,7 @@ import os import pathlib import sys -from typing import IO, Any, BinaryIO, List, Tuple +from typing import IO, Any, BinaryIO import trio from trio._file_io import AsyncIOWrapper @@ -35,7 +35,7 @@ def operator_checks(text: str, tpath: trio.Path, ppath: pathlib.Path) -> None: def sync_attrs(path: trio.Path) -> None: - assert_type(path.parts, Tuple[str, ...]) + assert_type(path.parts, tuple[str, ...]) assert_type(path.drive, str) assert_type(path.root, str) assert_type(path.anchor, str) @@ -43,7 +43,7 @@ def sync_attrs(path: trio.Path) -> None: assert_type(path.parent, trio.Path) assert_type(path.name, str) assert_type(path.suffix, str) - assert_type(path.suffixes, List[str]) + assert_type(path.suffixes, list[str]) assert_type(path.stem, str) assert_type(path.as_posix(), str) assert_type(path.as_uri(), str) @@ -141,4 +141,4 @@ async def open_results(path: trio.Path, some_int: int, some_str: str) -> None: assert_type(await file_text.read(), str) assert_type(await file_text.write("test"), int) # TODO: report mypy bug: equiv to https://github.com/microsoft/pyright/issues/6833 - assert_type(await file_text.readlines(), List[str]) + assert_type(await file_text.readlines(), list[str]) diff --git a/src/trio/_tools/gen_exports.py b/src/trio/_tools/gen_exports.py index 91969d6bfe..9ed84d16a8 100755 --- a/src/trio/_tools/gen_exports.py +++ b/src/trio/_tools/gen_exports.py @@ -253,7 +253,7 @@ def gen_public_wrappers_source(file: File) -> str: func = astor.to_source(method, indent_with=" " * 4) if is_cm: # pragma: no cover - func = func.replace("->Iterator", "->ContextManager") + func = func.replace("->Iterator", "->AbstractContextManager") # Create export function body template = TEMPLATE.format( @@ -386,9 +386,10 @@ def main() -> None: # pragma: no cover """ IMPORTS_KQUEUE = """\ -from typing import Callable, ContextManager, TYPE_CHECKING +from typing import Callable, TYPE_CHECKING if TYPE_CHECKING: + from contextlib import AbstractContextManager import select from .. import _core @@ -397,9 +398,10 @@ def main() -> None: # pragma: no cover """ IMPORTS_WINDOWS = """\ -from typing import TYPE_CHECKING, ContextManager +from typing import TYPE_CHECKING if TYPE_CHECKING: + from contextlib import AbstractContextManager from .._file_io import _HasFileNo from ._windows_cffi import Handle, CData from typing_extensions import Buffer diff --git a/src/trio/testing/_fake_net.py b/src/trio/testing/_fake_net.py index 57dfb0c4ee..60bdb1ed3c 100644 --- a/src/trio/testing/_fake_net.py +++ b/src/trio/testing/_fake_net.py @@ -14,7 +14,6 @@ import os import socket import sys -from collections.abc import Iterable from typing import ( TYPE_CHECKING, Any, @@ -31,6 +30,7 @@ if TYPE_CHECKING: import builtins + from collections.abc import Iterable from socket import AddressFamily, SocketKind from types import TracebackType diff --git a/src/trio/testing/_raises_group.py b/src/trio/testing/_raises_group.py index 940c35cf01..2048a100fc 100644 --- a/src/trio/testing/_raises_group.py +++ b/src/trio/testing/_raises_group.py @@ -2,11 +2,10 @@ import re import sys -from collections.abc import Callable, Sequence +from contextlib import AbstractContextManager from re import Pattern from typing import ( TYPE_CHECKING, - ContextManager, Generic, Literal, cast, @@ -22,6 +21,7 @@ # sphinx will *only* work if we use types.TracebackType, and import # *inside* TYPE_CHECKING. No other combination works..... import types + from collections.abc import Callable, Sequence from _pytest._code.code import ExceptionChainRepr, ReprExceptionInfo, Traceback from typing_extensions import TypeGuard, TypeVar @@ -277,7 +277,10 @@ def __str__(self) -> str: @final -class RaisesGroup(ContextManager[ExceptionInfo[BaseExceptionGroup[E]]], SuperClass[E]): +class RaisesGroup( + AbstractContextManager[ExceptionInfo[BaseExceptionGroup[E]]], + SuperClass[E], +): """Contextmanager for checking for an expected `ExceptionGroup`. This works similar to ``pytest.raises``, and a version of it will hopefully be added upstream, after which this can be deprecated and removed. See https://github.com/pytest-dev/pytest/issues/11538 From 35b3deef5cc4e51adfe7be235956d44a82629199 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 9 Oct 2024 15:52:51 -0500 Subject: [PATCH 04/14] Add newsfragment --- newsfragments/3106.removal.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 newsfragments/3106.removal.rst diff --git a/newsfragments/3106.removal.rst b/newsfragments/3106.removal.rst new file mode 100644 index 0000000000..ee023242d0 --- /dev/null +++ b/newsfragments/3106.removal.rst @@ -0,0 +1 @@ +Drop support for Python 3.8. (`#3104 `__) From eec38242d7bfc2a2dccc8bad72af3f7bca1f1d5f Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 9 Oct 2024 15:57:33 -0500 Subject: [PATCH 05/14] Run dedicated ci runs that were previously 3.12 on 3.13 --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4e5d77c3e..024444e07a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,7 +92,7 @@ jobs: no_test_requirements: ['0'] extra_name: [''] include: - - python: '3.12' + - python: '3.13' check_formatting: '1' extra_name: ', check formatting' # separate test run that doesn't install test-requirements.txt @@ -203,7 +203,7 @@ jobs: strategy: fail-fast: false matrix: - python: ['3.9', '3.12'] + python: ['3.9', '3.13'] steps: - name: Checkout uses: actions/checkout@v4 @@ -212,7 +212,7 @@ jobs: with: python-version: '${{ matrix.python }}' cache: pip - # setuptools is needed to get distutils on 3.12, which cythonize requires + # setuptools is needed to get distutils on 3.13, which cythonize requires - name: install trio and setuptools run: python -m pip install --upgrade pip . setuptools From 822f81a18e68865c0d4dd38596d619d5b5c4e3cd Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 9 Oct 2024 16:10:05 -0500 Subject: [PATCH 06/14] Sort imports in gen_exports --- src/trio/_core/_generated_io_kqueue.py | 3 ++- src/trio/_tools/gen_exports.py | 12 +++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/trio/_core/_generated_io_kqueue.py b/src/trio/_core/_generated_io_kqueue.py index 202dd8704a..b2bdfc5763 100644 --- a/src/trio/_core/_generated_io_kqueue.py +++ b/src/trio/_core/_generated_io_kqueue.py @@ -4,13 +4,14 @@ from __future__ import annotations import sys -from typing import TYPE_CHECKING, Callable +from typing import TYPE_CHECKING from ._ki import LOCALS_KEY_KI_PROTECTION_ENABLED from ._run import GLOBAL_RUN_CONTEXT if TYPE_CHECKING: import select + from collections.abc import Callable from contextlib import AbstractContextManager from .. import _core diff --git a/src/trio/_tools/gen_exports.py b/src/trio/_tools/gen_exports.py index 9ed84d16a8..5c8b72c48b 100755 --- a/src/trio/_tools/gen_exports.py +++ b/src/trio/_tools/gen_exports.py @@ -386,15 +386,16 @@ def main() -> None: # pragma: no cover """ IMPORTS_KQUEUE = """\ -from typing import Callable, TYPE_CHECKING +from typing import TYPE_CHECKING if TYPE_CHECKING: - from contextlib import AbstractContextManager import select + from collections.abc import Callable + from contextlib import AbstractContextManager from .. import _core - from ._traps import Abort, RaiseCancelT from .._file_io import _HasFileNo + from ._traps import Abort, RaiseCancelT """ IMPORTS_WINDOWS = """\ @@ -402,11 +403,12 @@ def main() -> None: # pragma: no cover if TYPE_CHECKING: from contextlib import AbstractContextManager - from .._file_io import _HasFileNo - from ._windows_cffi import Handle, CData + from typing_extensions import Buffer + from .._file_io import _HasFileNo from ._unbounded_queue import UnboundedQueue + from ._windows_cffi import Handle, CData """ From dd753253815a6b6625b37e787a80583aa5186943 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 9 Oct 2024 16:22:36 -0500 Subject: [PATCH 07/14] Revert upgrading cython to 3.13 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 024444e07a..0551ab2612 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -203,7 +203,7 @@ jobs: strategy: fail-fast: false matrix: - python: ['3.9', '3.13'] + python: ['3.9', '3.12'] steps: - name: Checkout uses: actions/checkout@v4 @@ -212,7 +212,7 @@ jobs: with: python-version: '${{ matrix.python }}' cache: pip - # setuptools is needed to get distutils on 3.13, which cythonize requires + # setuptools is needed to get distutils on 3.12, which cythonize requires - name: install trio and setuptools run: python -m pip install --upgrade pip . setuptools From 6499b69ed44db51474d84cf06ca94eac4eb663f8 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 9 Oct 2024 18:21:17 -0500 Subject: [PATCH 08/14] Undo formatting that leads to crashes if you run 3.9 in a special mode Co-authored-by: Spencer Brown --- src/trio/_core/_tests/test_run.py | 13 +++++++------ src/trio/_tests/test_timeouts.py | 14 +++++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/trio/_core/_tests/test_run.py b/src/trio/_core/_tests/test_run.py index 213311ab04..e14a4bcf9b 100644 --- a/src/trio/_core/_tests/test_run.py +++ b/src/trio/_core/_tests/test_run.py @@ -2505,12 +2505,13 @@ async def crasher() -> NoReturn: old_flags = gc.get_debug() try: - with ( - RaisesGroup( - Matcher(ValueError, "^this is a crash$"), - ), - _core.CancelScope() as outer, - ): + # fmt: off + # Remove after 3.9 unsupported, black formats in a way that breaks if + # you do `-X oldparser` + with RaisesGroup( + Matcher(ValueError, "^this is a crash$"), + ), _core.CancelScope() as outer: + # fmt: on async with _core.open_nursery() as nursery: gc.collect() gc.set_debug(gc.DEBUG_SAVEALL) diff --git a/src/trio/_tests/test_timeouts.py b/src/trio/_tests/test_timeouts.py index dbec679f70..463c974fb7 100644 --- a/src/trio/_tests/test_timeouts.py +++ b/src/trio/_tests/test_timeouts.py @@ -137,14 +137,14 @@ async def task() -> None: @slow async def test_fail_after_fails_even_if_shielded() -> None: async def task() -> None: - with ( - pytest.raises(TooSlowError), - _core.CancelScope() as outer, - fail_after( - TARGET, - shield=True, - ), + # fmt: off + # Remove after 3.9 unsupported, black formats in a way that breaks if + # you do `-X oldparser + with pytest.raises(TooSlowError), _core.CancelScope() as outer, fail_after( + TARGET, + shield=True, ): + # fmt: on outer.cancel() # The outer scope is cancelled, but this task is protected by the # shield, so it manages to get to sleep until deadline is met From 8dec4d45663f765dfa1535e771b0dfdd95108d55 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 9 Oct 2024 18:39:14 -0500 Subject: [PATCH 09/14] Add test path that had comment about it for 3.8 bugs --- src/trio/_tests/test_path.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/trio/_tests/test_path.py b/src/trio/_tests/test_path.py index 9b72cb77b3..2c47a2c5c2 100644 --- a/src/trio/_tests/test_path.py +++ b/src/trio/_tests/test_path.py @@ -76,14 +76,12 @@ async def test_cmp_magic(cls_a: EitherPathType, cls_b: EitherPathType) -> None: assert not b == None # noqa -# upstream python3.8 bug: we should also test (pathlib.Path, trio.Path), but -# __*div__ does not properly raise NotImplementedError like the other comparison -# magic, so trio.Path's implementation does not get dispatched cls_pairs_str: list[tuple[PathOrStrType, PathOrStrType]] = [ (trio.Path, pathlib.Path), (trio.Path, trio.Path), (trio.Path, str), (str, trio.Path), + (pathlib.Path, trio.Path), ] From f241abdf545c2bbcccf945169219161fa1c3a3d3 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 9 Oct 2024 18:43:58 -0500 Subject: [PATCH 10/14] Revert "Add test path that had comment about it for 3.8 bugs" This reverts commit 8dec4d45663f765dfa1535e771b0dfdd95108d55. --- src/trio/_tests/test_path.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/trio/_tests/test_path.py b/src/trio/_tests/test_path.py index 2c47a2c5c2..9b72cb77b3 100644 --- a/src/trio/_tests/test_path.py +++ b/src/trio/_tests/test_path.py @@ -76,12 +76,14 @@ async def test_cmp_magic(cls_a: EitherPathType, cls_b: EitherPathType) -> None: assert not b == None # noqa +# upstream python3.8 bug: we should also test (pathlib.Path, trio.Path), but +# __*div__ does not properly raise NotImplementedError like the other comparison +# magic, so trio.Path's implementation does not get dispatched cls_pairs_str: list[tuple[PathOrStrType, PathOrStrType]] = [ (trio.Path, pathlib.Path), (trio.Path, trio.Path), (trio.Path, str), (str, trio.Path), - (pathlib.Path, trio.Path), ] From 978bd8e8942496720d15f8e6c479ee77f87f56f2 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 16 Oct 2024 19:41:16 -0500 Subject: [PATCH 11/14] Changes from code review Co-authored-by: A5rocks --- pyproject.toml | 1 - src/trio/_tests/test_timeouts.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b759ec25fa..5a377a105f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,6 @@ include-package-data = true version = {attr = "trio._version.__version__"} [tool.black] -target-version = ['py39'] force-exclude = ''' ( ^/docs/source/reference-.* diff --git a/src/trio/_tests/test_timeouts.py b/src/trio/_tests/test_timeouts.py index 463c974fb7..bad439530c 100644 --- a/src/trio/_tests/test_timeouts.py +++ b/src/trio/_tests/test_timeouts.py @@ -139,7 +139,7 @@ async def test_fail_after_fails_even_if_shielded() -> None: async def task() -> None: # fmt: off # Remove after 3.9 unsupported, black formats in a way that breaks if - # you do `-X oldparser + # you do `-X oldparser` with pytest.raises(TooSlowError), _core.CancelScope() as outer, fail_after( TARGET, shield=True, From c2d595404a2979bd7d7e9ddb123c512425b96c95 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:34:00 -0500 Subject: [PATCH 12/14] Try to run cython tests with different versions Co-authored-by: Spencer Brown --- .github/workflows/ci.yml | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0551ab2612..256d94f859 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -203,7 +203,15 @@ jobs: strategy: fail-fast: false matrix: - python: ['3.9', '3.12'] + include: + - python: '3.9' + cython: '2' + - python: '3.9' + cython: '3' + - python: '3.11' + cython: '2' + - python: '3.13' + cython: '3' steps: - name: Checkout uses: actions/checkout@v4 @@ -216,18 +224,16 @@ jobs: - name: install trio and setuptools run: python -m pip install --upgrade pip . setuptools - - name: install cython<3 - run: python -m pip install "cython<3" - - name: compile pyx file - run: cythonize -i tests/cython/test_cython.pyx - - name: import & run module - run: python -c 'import tests.cython.test_cython' + - name: install cython & compile pyx file + run: | + if [ "${{ matrix.cython }}" == "2" ]; then + python -m pip install "cython<3" + cythonize -i tests/cython/test_cython.pyx + elif [ "${{ matrix.cython }}" == "3" ]; then + python -m pip install "cython>=3" + cythonize --inplace tests/cython/test_cython.pyx + fi - - name: install cython>=3 - run: python -m pip install "cython>=3" - - name: compile pyx file - # different cython version should trigger a re-compile, but --force just in case - run: cythonize --inplace --force tests/cython/test_cython.pyx - name: import & run module run: python -c 'import tests.cython.test_cython' From 0b31dfc0b227a641acb244c6af9582337d9ef879 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Sun, 20 Oct 2024 22:51:29 -0500 Subject: [PATCH 13/14] Add comments explaining cython workflow version choices Co-authored-by: jakkdl Co-authored-by: Spencer Brown --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 256d94f859..601bf15de9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -204,13 +204,13 @@ jobs: fail-fast: false matrix: include: - - python: '3.9' + - python: '3.9' # We support running on cython 2 and 3 for 3.9 cython: '2' - python: '3.9' cython: '3' - - python: '3.11' + - python: '3.11' # 3.11 is the last version Cy2 supports cython: '2' - - python: '3.13' + - python: '3.13' # We support running cython3 on 3.13 cython: '3' steps: - name: Checkout From 507dee3f4005ed6c7ffa541ff5395db8c643ad72 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Sun, 20 Oct 2024 22:58:12 -0500 Subject: [PATCH 14/14] Get rid of if block, use cython versions in matrix string Co-authored-by: Spencer Brown --- .github/workflows/ci.yml | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 601bf15de9..10965e132b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -205,13 +205,13 @@ jobs: matrix: include: - python: '3.9' # We support running on cython 2 and 3 for 3.9 - cython: '2' + cython: '<3' # cython 2 - python: '3.9' - cython: '3' - - python: '3.11' # 3.11 is the last version Cy2 supports - cython: '2' - - python: '3.13' # We support running cython3 on 3.13 - cython: '3' + cython: '>=3' # cython 3 (or greater) + - python: '3.11' # 3.11 is the last version Cy2 supports + cython: '<3' # cython 2 + - python: '3.13' # We support running cython3 on 3.13 + cython: '>=3' # cython 3 (or greater) steps: - name: Checkout uses: actions/checkout@v4 @@ -226,13 +226,8 @@ jobs: - name: install cython & compile pyx file run: | - if [ "${{ matrix.cython }}" == "2" ]; then - python -m pip install "cython<3" - cythonize -i tests/cython/test_cython.pyx - elif [ "${{ matrix.cython }}" == "3" ]; then - python -m pip install "cython>=3" - cythonize --inplace tests/cython/test_cython.pyx - fi + python -m pip install "cython${{ matrix.cython }}" + cythonize --inplace tests/cython/test_cython.pyx - name: import & run module run: python -c 'import tests.cython.test_cython'