From 2b7c4cfc0828dd20724afb8d8212836e32c743f6 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Fri, 26 Jun 2026 05:23:57 -0400 Subject: [PATCH 1/4] Make the test suite work with 3.15 --- .github/workflows/ci.yml | 6 +++--- src/trio/_core/_tests/test_thread_cache.py | 14 +++++++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1bdb7a8bbc..2139f72940 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -168,7 +168,7 @@ jobs: strategy: fail-fast: false matrix: - python: ['3.10', '3.11', '3.12', '3.13', '3.14', '3.14t'] + python: ['3.10', '3.11', '3.12', '3.13', '3.14', '3.14t', '3.15-dev'] arch: ['x86', 'x64'] lsp: [''] lsp_extract_file: [''] @@ -242,7 +242,7 @@ jobs: strategy: fail-fast: false matrix: - python: ['pypy-3.11', '3.10', '3.11', '3.12', '3.13', '3.14', '3.14t'] + python: ['pypy-3.11', '3.10', '3.11', '3.12', '3.13', '3.14', '3.14t', '3.15-dev'] check_formatting: ['0'] no_test_requirements: ['0'] extra_name: [''] @@ -320,7 +320,7 @@ jobs: strategy: fail-fast: false matrix: - python: ['pypy-3.11', '3.10', '3.11', '3.12', '3.13', '3.14', '3.14t'] + python: ['pypy-3.11', '3.10', '3.11', '3.12', '3.13', '3.14', '3.14t', '3.15-dev'] continue-on-error: >- ${{ ( diff --git a/src/trio/_core/_tests/test_thread_cache.py b/src/trio/_core/_tests/test_thread_cache.py index 3abdd59e43..27f5d2921a 100644 --- a/src/trio/_core/_tests/test_thread_cache.py +++ b/src/trio/_core/_tests/test_thread_cache.py @@ -1,8 +1,10 @@ from __future__ import annotations import os +import sys import threading import time +import warnings from contextlib import contextmanager from queue import Queue from typing import TYPE_CHECKING, NoReturn @@ -210,7 +212,17 @@ def foo() -> None: start_thread_soon(foo, lambda _: done.set()) done.wait() - child_pid = os.fork() + with warnings.catch_warnings(record=True) as emitted: + # TODO: remove this extra filter once we drop 3.14. See + # https://github.com/python-trio/trio/issues/3355. + warnings.simplefilter("default") + child_pid = os.fork() + + if child_pid != 0 and sys.version_info >= (3, 12): + # the warning is only emitted in the parent + assert len(emitted) == 1 + assert isinstance(emitted[0].message, DeprecationWarning) + assert "fork() may lead to" in str(emitted[0].message) # try using it done = threading.Event() From 1af65a9a65d8714d5f0284abcc8e925346c85ced Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sat, 27 Jun 2026 04:33:06 -0400 Subject: [PATCH 2/4] Try passing CI --- src/trio/_tests/test_exports.py | 4 ++++ src/trio/socket.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 17ca27aa59..f70da41b0d 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -426,6 +426,10 @@ def lookup_symbol(symbol: str) -> dict[str, Any]: # type: ignore[misc, explicit extra = {e for e in extra if not e.endswith("AttrsAttributes__")} assert len(extra) == before - 1 + if issubclass(class_, trio.Path) and sys.version_info >= (3, 15): + # needs a typeshed update for https://github.com/python/typeshed/pull/15737 + extra.remove("is_reserved") + if attrs.has(class_): # dynamically created attribute by attrs? missing.remove("__attrs_props__") diff --git a/src/trio/socket.py b/src/trio/socket.py index 64519c3db1..4aee184331 100644 --- a/src/trio/socket.py +++ b/src/trio/socket.py @@ -253,6 +253,33 @@ CAN_ERR_FLAG as CAN_ERR_FLAG, CAN_ERR_MASK as CAN_ERR_MASK, CAN_ISOTP as CAN_ISOTP, + CAN_ISOTP_CHK_PAD_DATA as CAN_ISOTP_CHK_PAD_DATA, + CAN_ISOTP_CHK_PAD_LEN as CAN_ISOTP_CHK_PAD_LEN, + CAN_ISOTP_DEFAULT_EXT_ADDRESS as CAN_ISOTP_DEFAULT_EXT_ADDRESS, + CAN_ISOTP_DEFAULT_FLAGS as CAN_ISOTP_DEFAULT_FLAGS, + CAN_ISOTP_DEFAULT_FRAME_TXTIME as CAN_ISOTP_DEFAULT_FRAME_TXTIME, + CAN_ISOTP_DEFAULT_LL_MTU as CAN_ISOTP_DEFAULT_LL_MTU, + CAN_ISOTP_DEFAULT_LL_TX_DL as CAN_ISOTP_DEFAULT_LL_TX_DL, + CAN_ISOTP_DEFAULT_LL_TX_FLAGS as CAN_ISOTP_DEFAULT_LL_TX_FLAGS, + CAN_ISOTP_DEFAULT_PAD_CONTENT as CAN_ISOTP_DEFAULT_PAD_CONTENT, + CAN_ISOTP_DEFAULT_RECV_BS as CAN_ISOTP_DEFAULT_RECV_BS, + CAN_ISOTP_DEFAULT_RECV_STMIN as CAN_ISOTP_DEFAULT_RECV_STMIN, + CAN_ISOTP_DEFAULT_RECV_WFTMAX as CAN_ISOTP_DEFAULT_RECV_WFTMAX, + CAN_ISOTP_EXTEND_ADDR as CAN_ISOTP_EXTEND_ADDR, + CAN_ISOTP_FORCE_RXSTMIN as CAN_ISOTP_FORCE_RXSTMIN, + CAN_ISOTP_FORCE_TXSTMIN as CAN_ISOTP_FORCE_TXSTMIN, + CAN_ISOTP_HALF_DUPLEX as CAN_ISOTP_HALF_DUPLEX, + CAN_ISOTP_LISTEN_MODE as CAN_ISOTP_LISTEN_MODE, + CAN_ISOTP_LL_OPTS as CAN_ISOTP_LL_OPTS, + CAN_ISOTP_OPTS as CAN_ISOTP_OPTS, + CAN_ISOTP_RECV_FC as CAN_ISOTP_RECV_FC, + CAN_ISOTP_RX_EXT_ADDR as CAN_ISOTP_RX_EXT_ADDR, + CAN_ISOTP_RX_PADDING as CAN_ISOTP_RX_PADDING, + CAN_ISOTP_RX_STMIN as CAN_ISOTP_RX_STMIN, + CAN_ISOTP_SF_BROADCAST as CAN_ISOTP_SF_BROADCAST, + CAN_ISOTP_TX_PADDING as CAN_ISOTP_TX_PADDING, + CAN_ISOTP_TX_STMIN as CAN_ISOTP_TX_STMIN, + CAN_ISOTP_WAIT_TX_DONE as CAN_ISOTP_WAIT_TX_DONE, CAN_J1939 as CAN_J1939, CAN_RAW as CAN_RAW, CAN_RAW_ERR_FILTER as CAN_RAW_ERR_FILTER, @@ -400,6 +427,7 @@ IPV6_CHECKSUM as IPV6_CHECKSUM, IPV6_DONTFRAG as IPV6_DONTFRAG, IPV6_DSTOPTS as IPV6_DSTOPTS, + IPV6_HDRINCL as IPV6_HDRINCL, IPV6_HOPLIMIT as IPV6_HOPLIMIT, IPV6_HOPOPTS as IPV6_HOPOPTS, IPV6_JOIN_GROUP as IPV6_JOIN_GROUP, @@ -575,6 +603,7 @@ SOL_ALG as SOL_ALG, SOL_BLUETOOTH as SOL_BLUETOOTH, SOL_CAN_BASE as SOL_CAN_BASE, + SOL_CAN_ISOTP as SOL_CAN_ISOTP, SOL_CAN_RAW as SOL_CAN_RAW, SOL_HCI as SOL_HCI, SOL_IP as SOL_IP, From ce4d5684332ed1b0d327518b599954051a47322f Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sat, 27 Jun 2026 04:43:51 -0400 Subject: [PATCH 3/4] Final touches --- newsfragments/3456.feature.rst | 2 ++ pyproject.toml | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 newsfragments/3456.feature.rst diff --git a/newsfragments/3456.feature.rst b/newsfragments/3456.feature.rst new file mode 100644 index 0000000000..bfb84b3d9d --- /dev/null +++ b/newsfragments/3456.feature.rst @@ -0,0 +1,2 @@ +Support Python 3.15, as of beta 3. Things may still change and so this +support may break in the future. diff --git a/pyproject.toml b/pyproject.toml index 4e50a217ec..436cca6a77 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -233,6 +233,8 @@ filterwarnings = [ 'ignore:You are using cryptography on a 32-bit Python on a 64-bit Windows Operating System. Cryptography will be significantly faster if you switch to using a 64-bit Python.:UserWarning', # https://github.com/berkerpeksag/astor/issues/217 'ignore:ast.Num is deprecated:DeprecationWarning:astor', + # https://github.com/coveragepy/coveragepy/issues/2208 + 'ignore:Module globals; __loader__ != __spec__.loader:DeprecationWarning', ] junit_family = "xunit2" markers = ["redistributors_should_skip: tests that should be skipped by downstream redistributors"] From 687af3944683cc560dbc29745eff5aece81c2429 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 26 Jul 2026 09:44:27 +0900 Subject: [PATCH 4/4] PR review Co-authored-by: jakkdl --- newsfragments/3456.feature.rst | 2 +- pyproject.toml | 2 -- src/trio/_core/_tests/test_thread_cache.py | 6 +++--- test-requirements.in | 2 +- test-requirements.txt | 2 +- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/newsfragments/3456.feature.rst b/newsfragments/3456.feature.rst index bfb84b3d9d..c0024829fb 100644 --- a/newsfragments/3456.feature.rst +++ b/newsfragments/3456.feature.rst @@ -1,2 +1,2 @@ -Support Python 3.15, as of beta 3. Things may still change and so this +Support Python 3.15, as of beta 4. Things may still change and so this support may break in the future. diff --git a/pyproject.toml b/pyproject.toml index 10b9867508..fc9153674e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -234,8 +234,6 @@ filterwarnings = [ 'ignore:You are using cryptography on a 32-bit Python on a 64-bit Windows Operating System. Cryptography will be significantly faster if you switch to using a 64-bit Python.:UserWarning', # https://github.com/berkerpeksag/astor/issues/217 'ignore:ast.Num is deprecated:DeprecationWarning:astor', - # https://github.com/coveragepy/coveragepy/issues/2208 - 'ignore:Module globals; __loader__ != __spec__.loader:DeprecationWarning', ] junit_family = "xunit2" markers = ["redistributors_should_skip: tests that should be skipped by downstream redistributors"] diff --git a/src/trio/_core/_tests/test_thread_cache.py b/src/trio/_core/_tests/test_thread_cache.py index 27f5d2921a..1baddad89f 100644 --- a/src/trio/_core/_tests/test_thread_cache.py +++ b/src/trio/_core/_tests/test_thread_cache.py @@ -213,9 +213,9 @@ def foo() -> None: done.wait() with warnings.catch_warnings(record=True) as emitted: - # TODO: remove this extra filter once we drop 3.14. See - # https://github.com/python-trio/trio/issues/3355. - warnings.simplefilter("default") + if sys.version_info < (3, 15): + # https://github.com/python-trio/trio/issues/3355 + warnings.simplefilter("default") child_pid = os.fork() if child_pid != 0 and sys.version_info >= (3, 12): diff --git a/test-requirements.in b/test-requirements.in index 272da6a34c..11a1bee5a7 100644 --- a/test-requirements.in +++ b/test-requirements.in @@ -1,6 +1,6 @@ # For tests pytest >= 8.4 # for pytest.RaisesGroup -coverage >= 7.2.5 +coverage >= 7.15.0 async_generator >= 1.9 pyright pyOpenSSL >= 22.0.0 # for the ssl + DTLS tests diff --git a/test-requirements.txt b/test-requirements.txt index b20fbc4cdd..02404ee66f 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -38,7 +38,7 @@ colorama==0.4.6 ; sys_platform == 'win32' # pylint # pytest # sphinx -coverage==7.14.3 +coverage==7.15.2 # via -r test-requirements.in cryptography==48.0.0 # via