diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 174dbc17872..b1bde397283 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -275,8 +275,10 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} - name: Upload test results to Codecov if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 + uses: codecov/codecov-action@v6 with: + files: ./junit.xml + report_type: test_results token: ${{ secrets.CODECOV_TOKEN }} autobahn: @@ -360,8 +362,10 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} - name: Upload test results to Codecov if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 + uses: codecov/codecov-action@v6 with: + files: ./junit.xml + report_type: test_results token: ${{ secrets.CODECOV_TOKEN }} benchmark: @@ -627,6 +631,12 @@ jobs: make cythonize - name: Build wheels uses: pypa/cibuildwheel@v3.4.1 + with: + # `build-frontend = "build[uv]"` (pyproject.toml) requires uv to be + # available on the runner for Windows and macOS. Installing + # cibuildwheel with the `uv` extra bundles uv with it; Linux + # already has uv inside the manylinux/musllinux container. + extras: uv env: CIBW_SKIP: pp* ${{ matrix.musl == 'musllinux' && '*manylinux*' || '*musllinux*' }} CIBW_ARCHS_MACOS: x86_64 arm64 universal2 diff --git a/CHANGES/12588.contrib.rst b/CHANGES/12588.contrib.rst new file mode 100644 index 00000000000..6c8a5147e41 --- /dev/null +++ b/CHANGES/12588.contrib.rst @@ -0,0 +1,5 @@ +Added a ``CLAUDE.md`` at the repository root that imports +:file:`AGENTS.md` via Claude Code's ``@``-syntax, so the +project's LLM contributor rules load automatically when +working in Claude Code +-- by :user:`aiolibsbot`. diff --git a/CHANGES/12589.contrib.rst b/CHANGES/12589.contrib.rst new file mode 100644 index 00000000000..dc7f6400d57 --- /dev/null +++ b/CHANGES/12589.contrib.rst @@ -0,0 +1,7 @@ +Restricted the ``isal`` test dependency to CPython, since +``isal`` 1.8.0 stopped publishing PyPy wheels and the source +build requires ``nasm``, which is not available on the CI +runners. The ``parametrize_zlib_backend`` fixture already +calls ``pytest.importorskip``, so PyPy continues to exercise +the ``zlib`` and ``zlib_ng`` backends with no further +changes -- by :user:`bdraco`. diff --git a/CHANGES/12592.contrib.rst b/CHANGES/12592.contrib.rst new file mode 100644 index 00000000000..76d2f8b7035 --- /dev/null +++ b/CHANGES/12592.contrib.rst @@ -0,0 +1,6 @@ +Fixed a flakey ``test_tcp_connector_fingerprint_ok`` by aborting +the SSL shutdown on the test's TCP connector before returning. +The graceful TLS close was occasionally outliving the test event +loop on one of the CI jobs, and the teardown ``gc.collect()`` +then surfaced the still-open transport as a +``PytestUnraisableExceptionWarning`` -- by :user:`bdraco`. diff --git a/CHANGES/12595.contrib.rst b/CHANGES/12595.contrib.rst new file mode 100644 index 00000000000..54af2262fb1 --- /dev/null +++ b/CHANGES/12595.contrib.rst @@ -0,0 +1,5 @@ +Switched the ``cibuildwheel`` build frontend to ``build[uv]`` so +that ``uv`` provisions every build-isolation virtual environment +in the wheel matrix, replacing the per-ABI ``pip`` resolve with a +roughly sub-second ``uv`` resolve +-- by :user:`bdraco`. diff --git a/CHANGES/12596.contrib.rst b/CHANGES/12596.contrib.rst new file mode 100644 index 00000000000..ff96abe5bfc --- /dev/null +++ b/CHANGES/12596.contrib.rst @@ -0,0 +1,4 @@ +Switched the test-results upload step to ``codecov/codecov-action@v6`` +with ``report_type: test_results``, since +``codecov/test-results-action`` is being deprecated in favor of +``codecov-action`` -- by :user:`bdraco`. diff --git a/CHANGES/12600.contrib.rst b/CHANGES/12600.contrib.rst new file mode 100644 index 00000000000..4d361389191 --- /dev/null +++ b/CHANGES/12600.contrib.rst @@ -0,0 +1,4 @@ +Silenced the ``DeprecationWarning`` raised by ``uvloop`` 0.22+ when it +accesses the ``asyncio.AbstractEventLoopPolicy`` alias that Python 3.14 +marks for removal in 3.16, so the test suite passes against the newer +``uvloop`` release -- by :user:`bdraco`. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000000..43c994c2d36 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index ac9b0a41f2d..352b2e29a64 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -1,4 +1,5 @@ abc +ABI addons aiodns aioes diff --git a/pyproject.toml b/pyproject.toml index 7ad4f54b0c3..06f26bc6995 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -159,6 +159,13 @@ include = [ [tool.cibuildwheel] +# `build[uv]` makes cibuildwheel use `uv` for every venv it provisions, +# both on the build side (passed to `python -m build` as `--installer=uv`) +# and when materializing the build isolation environment. uv resolves and +# installs the build requirements in roughly a second; the previous +# pip-based path took noticeably longer per ABI and ran once per matrix +# cell. +build-frontend = "build[uv]" test-command = "" # don't build PyPy wheels, install from source instead skip = "pp*" diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 3638a0bc10c..8ebe46e1298 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -109,7 +109,7 @@ imagesize==2.0.0 # via sphinx iniconfig==2.3.0 # via pytest -isal==1.7.2 ; python_version < "3.14" +isal==1.7.2 ; python_version < "3.14" and implementation_name == "cpython" # via # -r requirements/lint.in # -r requirements/test-common.in diff --git a/requirements/dev.txt b/requirements/dev.txt index 806030f2a4d..fbb0de86979 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -107,7 +107,7 @@ imagesize==2.0.0 # via sphinx iniconfig==2.3.0 # via pytest -isal==1.7.2 ; python_version < "3.14" +isal==1.7.2 ; python_version < "3.14" and implementation_name == "cpython" # via # -r requirements/lint.in # -r requirements/test-common.in diff --git a/requirements/test-common.in b/requirements/test-common.in index 049916df15c..b50aed3be7f 100644 --- a/requirements/test-common.in +++ b/requirements/test-common.in @@ -1,7 +1,7 @@ blockbuster coverage freezegun -isal; python_version < "3.14" # no wheel for 3.14 +isal; python_version < "3.14" and implementation_name == "cpython" # no wheel for 3.14, no PyPy wheel for 1.8.0+ mypy; implementation_name == "cpython" pkgconfig proxy.py >= 2.4.4rc5 diff --git a/requirements/test-common.txt b/requirements/test-common.txt index 48fc596525d..94aa95d62be 100644 --- a/requirements/test-common.txt +++ b/requirements/test-common.txt @@ -50,7 +50,7 @@ idna==3.15 # yarl iniconfig==2.3.0 # via pytest -isal==1.8.0 ; python_version < "3.14" +isal==1.8.0 ; python_version < "3.14" and implementation_name == "cpython" # via -r requirements/test-common.in librt==0.11.0 # via mypy diff --git a/requirements/test-ft.txt b/requirements/test-ft.txt index 664e1eb9e5e..fcad3f25513 100644 --- a/requirements/test-ft.txt +++ b/requirements/test-ft.txt @@ -67,7 +67,7 @@ idna==3.15 # yarl iniconfig==2.3.0 # via pytest -isal==1.8.0 ; python_version < "3.14" +isal==1.8.0 ; python_version < "3.14" and implementation_name == "cpython" # via -r requirements/test-common.in librt==0.11.0 # via mypy diff --git a/requirements/test.txt b/requirements/test.txt index 26c0f57ded8..602e45e91d1 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -67,7 +67,7 @@ idna==3.15 # yarl iniconfig==2.3.0 # via pytest -isal==1.7.2 ; python_version < "3.14" +isal==1.7.2 ; python_version < "3.14" and implementation_name == "cpython" # via -r requirements/test-common.in librt==0.11.0 # via mypy diff --git a/setup.cfg b/setup.cfg index f3a5ccbfbb6..8a721800cf3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -86,6 +86,10 @@ filterwarnings = ignore:datetime.*utcnow\(\) is deprecated and scheduled for removal:DeprecationWarning:freezegun.api # Weird issue in Python 3.13+ triggered in test_multipart.py ignore:coroutine method 'aclose' of 'BodyPartReader._decode_content_async' was never awaited:RuntimeWarning + # uvloop 0.22+ accesses the deprecated asyncio.AbstractEventLoopPolicy + # alias, which Python 3.14 marks for removal in 3.16. Drop this when + # uvloop stops touching the deprecated alias. + ignore:'asyncio.AbstractEventLoopPolicy' is deprecated:DeprecationWarning:uvloop junit_suite_name = aiohttp_test_suite norecursedirs = dist docs build .tox .eggs minversion = 3.8.2 diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index 9c8e274bab3..cfc2d4529c5 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -840,6 +840,12 @@ async def handler(request: web.Request) -> web.Response: async with client.get("/") as resp: assert resp.status == 200 + # Abort the SSL shutdown explicitly so the pooled TLS transport is + # released before the test loop tears down. Otherwise a slow graceful + # close can outlive the loop, and the teardown gc.collect() finalises + # the still-open socket as an unraisable ResourceWarning. + await connector.close(abort_ssl=True) + async def test_tcp_connector_fingerprint_fail( aiohttp_server: AiohttpServer,