From 779bd3c82c19d56e60e9129a7d0c63132a312b98 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Wed, 17 Sep 2025 13:46:53 +0530 Subject: [PATCH 1/8] add 3.14t CI --- .github/workflows/ci-cd.yml | 15 +++- requirements/base-ft.in | 3 + requirements/base-ft.txt | 48 +++++++++++ requirements/test-common.in | 17 ++++ requirements/test-common.txt | 113 ++++++++++++++++++++++++++ requirements/test-ft.in | 2 + requirements/test-ft.txt | 150 +++++++++++++++++++++++++++++++++++ requirements/test.in | 19 +---- 8 files changed, 346 insertions(+), 21 deletions(-) create mode 100644 requirements/base-ft.in create mode 100644 requirements/base-ft.txt create mode 100644 requirements/test-common.in create mode 100644 requirements/test-common.txt create mode 100644 requirements/test-ft.in create mode 100644 requirements/test-ft.txt diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 7efa2196cb5..22ac99934f9 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -156,6 +156,9 @@ jobs: pyver: "3.14" experimental: true no-extensions: 'Y' + - os: ubuntu + pyver: "3.14t" + experimental: true fail-fast: true runs-on: ${{ matrix.os }}-latest continue-on-error: ${{ matrix.experimental }} @@ -182,12 +185,18 @@ jobs: path: ${{ steps.pip-cache.outputs.dir }} restore-keys: | pip-ci-${{ runner.os }}-${{ matrix.pyver }}-${{ matrix.no-extensions }}- - - name: Update pip, wheel, setuptools, build, twine + - name: Update pip, wheel, setuptools, build run: | - python -m pip install -U pip wheel setuptools build twine + python -m pip install -U pip wheel setuptools build - name: Install dependencies + env: + DEPENDENCY_GROUP: >- + test${{ endsWith(matrix.pyver, 't') && '-ft' || '' }} run: | - python -m pip install -r requirements/test.in -c requirements/test.txt + python -Im pip install -r requirements/${DEPENDENCY_GROUP}.in -c requirements/${DEPENDENCY_GROUP}.txt + - name: Set PYTHON_GIL=0 for free-threading builds + if: ${{ endsWith(matrix.pyver, 't') }} + run: echo "PYTHON_GIL=0" >> $GITHUB_ENV - name: Restore llhttp generated files if: ${{ matrix.no-extensions == '' }} uses: actions/download-artifact@v5 diff --git a/requirements/base-ft.in b/requirements/base-ft.in new file mode 100644 index 00000000000..ce0b78f92ee --- /dev/null +++ b/requirements/base-ft.in @@ -0,0 +1,3 @@ +-r runtime-deps.in + +gunicorn \ No newline at end of file diff --git a/requirements/base-ft.txt b/requirements/base-ft.txt new file mode 100644 index 00000000000..15c562571be --- /dev/null +++ b/requirements/base-ft.txt @@ -0,0 +1,48 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --allow-unsafe --output-file=requirements/base-ft.txt --strip-extras requirements/base-ft.in +# +aiodns==3.5.0 + # via -r requirements/runtime-deps.in +aiohappyeyeballs==2.6.1 + # via -r requirements/runtime-deps.in +aiosignal==1.4.0 + # via -r requirements/runtime-deps.in +async-timeout==5.0.1 ; python_version < "3.11" + # via -r requirements/runtime-deps.in +brotli==1.1.0 ; platform_python_implementation == "CPython" + # via -r requirements/runtime-deps.in +cffi==2.0.0 + # via pycares +frozenlist==1.7.0 + # via + # -r requirements/runtime-deps.in + # aiosignal +gunicorn==23.0.0 + # via -r requirements/base-ft.in +idna==3.10 + # via yarl +multidict==6.6.4 + # via + # -r requirements/runtime-deps.in + # yarl +packaging==25.0 + # via gunicorn +propcache==0.3.2 + # via + # -r requirements/runtime-deps.in + # yarl +pycares==4.11.0 + # via aiodns +pycparser==2.23 + # via cffi +typing-extensions==4.15.0 + # via + # aiosignal + # multidict +yarl==1.20.1 + # via -r requirements/runtime-deps.in +zstandard==0.25.0 ; platform_python_implementation == "CPython" and python_version < "3.14" + # via -r requirements/runtime-deps.in diff --git a/requirements/test-common.in b/requirements/test-common.in new file mode 100644 index 00000000000..c010f61fa8a --- /dev/null +++ b/requirements/test-common.in @@ -0,0 +1,17 @@ +blockbuster +coverage +freezegun +isal; python_version < "3.14" # no wheel for 3.14 +mypy; implementation_name == "cpython" +pkgconfig +proxy.py >= 2.4.4rc5 +pytest +pytest-cov +pytest-mock +pytest-xdist +pytest_codspeed +python-on-whales +setuptools-git +trustme; platform_machine != "i686" # no 32-bit wheels +wait-for-it +zlib_ng diff --git a/requirements/test-common.txt b/requirements/test-common.txt new file mode 100644 index 00000000000..1084e634ddd --- /dev/null +++ b/requirements/test-common.txt @@ -0,0 +1,113 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --allow-unsafe --output-file=requirements/test-common.txt --strip-extras requirements/test-common.in +# +annotated-types==0.7.0 + # via pydantic +blockbuster==1.5.25 + # via -r requirements/test-common.in +cffi==2.0.0 + # via + # cryptography + # pytest-codspeed +click==8.2.1 + # via wait-for-it +coverage==7.10.6 + # via + # -r requirements/test-common.in + # pytest-cov +cryptography==46.0.1 + # via trustme +exceptiongroup==1.3.0 + # via pytest +execnet==2.1.1 + # via pytest-xdist +forbiddenfruit==0.1.4 + # via blockbuster +freezegun==1.5.5 + # via -r requirements/test-common.in +idna==3.10 + # via trustme +iniconfig==2.1.0 + # via pytest +isal==1.8.0 ; python_version < "3.14" + # via -r requirements/test-common.in +markdown-it-py==4.0.0 + # via rich +mdurl==0.1.2 + # via markdown-it-py +mypy==1.18.1 ; implementation_name == "cpython" + # via -r requirements/test-common.in +mypy-extensions==1.1.0 + # via mypy +packaging==25.0 + # via pytest +pathspec==0.12.1 + # via mypy +pkgconfig==1.5.5 + # via -r requirements/test-common.in +pluggy==1.6.0 + # via + # pytest + # pytest-cov +proxy-py==2.4.10 + # via -r requirements/test-common.in +pycparser==2.23 + # via cffi +pydantic==2.12.0a1 + # via python-on-whales +pydantic-core==2.37.2 + # via pydantic +pygments==2.19.2 + # via + # pytest + # rich +pytest==8.4.2 + # via + # -r requirements/test-common.in + # pytest-codspeed + # pytest-cov + # pytest-mock + # pytest-xdist +pytest-codspeed==4.0.0 + # via -r requirements/test-common.in +pytest-cov==7.0.0 + # via -r requirements/test-common.in +pytest-mock==3.15.1 + # via -r requirements/test-common.in +pytest-xdist==3.8.0 + # via -r requirements/test-common.in +python-dateutil==2.9.0.post0 + # via freezegun +python-on-whales==0.78.0 + # via -r requirements/test-common.in +rich==14.1.0 + # via pytest-codspeed +setuptools-git==1.2 + # via -r requirements/test-common.in +six==1.17.0 + # via python-dateutil +tomli==2.2.1 + # via + # coverage + # mypy + # pytest +trustme==1.2.1 ; platform_machine != "i686" + # via -r requirements/test-common.in +typing-extensions==4.15.0 + # via + # cryptography + # exceptiongroup + # mypy + # pydantic + # pydantic-core + # python-on-whales + # typing-inspection +typing-inspection==0.4.1 + # via pydantic +wait-for-it==2.3.0 + # via -r requirements/test-common.in +zlib-ng==1.0.0 + # via -r requirements/test-common.in diff --git a/requirements/test-ft.in b/requirements/test-ft.in new file mode 100644 index 00000000000..882c7e17ab7 --- /dev/null +++ b/requirements/test-ft.in @@ -0,0 +1,2 @@ +-r base-ft.in +-r test-common.in \ No newline at end of file diff --git a/requirements/test-ft.txt b/requirements/test-ft.txt new file mode 100644 index 00000000000..fd522842db9 --- /dev/null +++ b/requirements/test-ft.txt @@ -0,0 +1,150 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --allow-unsafe --output-file=requirements/test-ft.txt --strip-extras requirements/test-ft.in +# +aiodns==3.5.0 + # via -r requirements/runtime-deps.in +aiohappyeyeballs==2.6.1 + # via -r requirements/runtime-deps.in +aiosignal==1.4.0 + # via -r requirements/runtime-deps.in +annotated-types==0.7.0 + # via pydantic +async-timeout==5.0.1 ; python_version < "3.11" + # via -r requirements/runtime-deps.in +blockbuster==1.5.25 + # via -r requirements/test-common.in +brotli==1.1.0 ; platform_python_implementation == "CPython" + # via -r requirements/runtime-deps.in +cffi==2.0.0 + # via + # cryptography + # pycares + # pytest-codspeed +click==8.2.1 + # via wait-for-it +coverage==7.10.6 + # via + # -r requirements/test-common.in + # pytest-cov +cryptography==46.0.1 + # via trustme +exceptiongroup==1.3.0 + # via pytest +execnet==2.1.1 + # via pytest-xdist +forbiddenfruit==0.1.4 + # via blockbuster +freezegun==1.5.5 + # via -r requirements/test-common.in +frozenlist==1.7.0 + # via + # -r requirements/runtime-deps.in + # aiosignal +gunicorn==23.0.0 + # via -r requirements/base-ft.in +idna==3.10 + # via + # trustme + # yarl +iniconfig==2.1.0 + # via pytest +isal==1.8.0 ; python_version < "3.14" + # via -r requirements/test-common.in +markdown-it-py==4.0.0 + # via rich +mdurl==0.1.2 + # via markdown-it-py +multidict==6.6.4 + # via + # -r requirements/runtime-deps.in + # yarl +mypy==1.18.1 ; implementation_name == "cpython" + # via -r requirements/test-common.in +mypy-extensions==1.1.0 + # via mypy +packaging==25.0 + # via + # gunicorn + # pytest +pathspec==0.12.1 + # via mypy +pkgconfig==1.5.5 + # via -r requirements/test-common.in +pluggy==1.6.0 + # via + # pytest + # pytest-cov +propcache==0.3.2 + # via + # -r requirements/runtime-deps.in + # yarl +proxy-py==2.4.10 + # via -r requirements/test-common.in +pycares==4.11.0 + # via aiodns +pycparser==2.23 + # via cffi +pydantic==2.12.0a1 + # via python-on-whales +pydantic-core==2.37.2 + # via pydantic +pygments==2.19.2 + # via + # pytest + # rich +pytest==8.4.2 + # via + # -r requirements/test-common.in + # pytest-codspeed + # pytest-cov + # pytest-mock + # pytest-xdist +pytest-codspeed==4.0.0 + # via -r requirements/test-common.in +pytest-cov==7.0.0 + # via -r requirements/test-common.in +pytest-mock==3.15.1 + # via -r requirements/test-common.in +pytest-xdist==3.8.0 + # via -r requirements/test-common.in +python-dateutil==2.9.0.post0 + # via freezegun +python-on-whales==0.78.0 + # via -r requirements/test-common.in +rich==14.1.0 + # via pytest-codspeed +setuptools-git==1.2 + # via -r requirements/test-common.in +six==1.17.0 + # via python-dateutil +tomli==2.2.1 + # via + # coverage + # mypy + # pytest +trustme==1.2.1 ; platform_machine != "i686" + # via -r requirements/test-common.in +typing-extensions==4.15.0 + # via + # aiosignal + # cryptography + # exceptiongroup + # multidict + # mypy + # pydantic + # pydantic-core + # python-on-whales + # typing-inspection +typing-inspection==0.4.1 + # via pydantic +wait-for-it==2.3.0 + # via -r requirements/test-common.in +yarl==1.20.1 + # via -r requirements/runtime-deps.in +zlib-ng==1.0.0 + # via -r requirements/test-common.in +zstandard==0.25.0 ; platform_python_implementation == "CPython" and python_version < "3.14" + # via -r requirements/runtime-deps.in diff --git a/requirements/test.in b/requirements/test.in index d6274f6d80d..ae94c183b7c 100644 --- a/requirements/test.in +++ b/requirements/test.in @@ -1,19 +1,2 @@ -r base.in - -blockbuster -coverage -freezegun -isal; python_version < "3.14" # no wheel for 3.14 -mypy; implementation_name == "cpython" -pkgconfig -proxy.py >= 2.4.4rc5 -pytest -pytest-cov -pytest-mock -pytest-xdist -pytest_codspeed -python-on-whales -setuptools-git -trustme; platform_machine != "i686" # no 32-bit wheels -wait-for-it -zlib_ng +-r test-common.in \ No newline at end of file From 8d68c710d17a2922b120a851a9f1f0a8cd559fe8 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Wed, 17 Sep 2025 13:48:56 +0530 Subject: [PATCH 2/8] lint --- requirements/base-ft.in | 2 +- requirements/test-ft.in | 2 +- requirements/test.in | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/base-ft.in b/requirements/base-ft.in index ce0b78f92ee..2b0cbf7d0c2 100644 --- a/requirements/base-ft.in +++ b/requirements/base-ft.in @@ -1,3 +1,3 @@ -r runtime-deps.in -gunicorn \ No newline at end of file +gunicorn diff --git a/requirements/test-ft.in b/requirements/test-ft.in index 882c7e17ab7..b85406e5d7b 100644 --- a/requirements/test-ft.in +++ b/requirements/test-ft.in @@ -1,2 +1,2 @@ -r base-ft.in --r test-common.in \ No newline at end of file +-r test-common.in diff --git a/requirements/test.in b/requirements/test.in index ae94c183b7c..d37efd6b841 100644 --- a/requirements/test.in +++ b/requirements/test.in @@ -1,2 +1,2 @@ -r base.in --r test-common.in \ No newline at end of file +-r test-common.in From 8ea3f30e1cf6d62a0ded0c66b191a291032c26e1 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Wed, 17 Sep 2025 13:54:27 +0530 Subject: [PATCH 3/8] lint --- .github/workflows/ci-cd.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 22ac99934f9..3f795be270b 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -190,8 +190,7 @@ jobs: python -m pip install -U pip wheel setuptools build - name: Install dependencies env: - DEPENDENCY_GROUP: >- - test${{ endsWith(matrix.pyver, 't') && '-ft' || '' }} + DEPENDENCY_GROUP: test${{ endsWith(matrix.pyver, 't') && '-ft' || '' }} run: | python -Im pip install -r requirements/${DEPENDENCY_GROUP}.in -c requirements/${DEPENDENCY_GROUP}.txt - name: Set PYTHON_GIL=0 for free-threading builds From 044224213f65404b7aa21de3e0551ed5d7da697c Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Wed, 17 Sep 2025 13:59:51 +0530 Subject: [PATCH 4/8] revert back to simpler if --- .github/workflows/ci-cd.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 3f795be270b..be07fca6e01 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -189,10 +189,13 @@ jobs: run: | python -m pip install -U pip wheel setuptools build - name: Install dependencies - env: - DEPENDENCY_GROUP: test${{ endsWith(matrix.pyver, 't') && '-ft' || '' }} + if: ${{ endsWith(matrix.pyver, 't') }} + run: | + python -Im pip install -r requirements/test-ft.in -c requirements/test-ft.txt + - name: Install dependencies + if: ${{ !endsWith(matrix.pyver, 't') }} run: | - python -Im pip install -r requirements/${DEPENDENCY_GROUP}.in -c requirements/${DEPENDENCY_GROUP}.txt + python -Im pip install -r requirements/test.in -c requirements/test.txt - name: Set PYTHON_GIL=0 for free-threading builds if: ${{ endsWith(matrix.pyver, 't') }} run: echo "PYTHON_GIL=0" >> $GITHUB_ENV From a533f357810ae60333e7744514d70c59b8e5d51d Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Wed, 17 Sep 2025 14:07:15 +0530 Subject: [PATCH 5/8] add news --- CHANGES/11466.contrib.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGES/11466.contrib.rst diff --git a/CHANGES/11466.contrib.rst b/CHANGES/11466.contrib.rst new file mode 100644 index 00000000000..07c5f40c82e --- /dev/null +++ b/CHANGES/11466.contrib.rst @@ -0,0 +1 @@ +Added free-threading CI job for CPython 3.14 -- by :user:`kumaraditya303`. From 83168c829a6b86a327eded65d1b6f357a88c79b5 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Wed, 17 Sep 2025 14:12:24 +0530 Subject: [PATCH 6/8] fix normal builds --- requirements/test.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/test.txt b/requirements/test.txt index e35299832e2..c0c28b82890 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -87,9 +87,9 @@ pycares==4.11.0 # via aiodns pycparser==2.23 # via cffi -pydantic==2.11.9 +pydantic==2.12.0a1 # via python-on-whales -pydantic-core==2.33.2 +pydantic-core==2.37.2 # via pydantic pygments==2.19.2 # via From fb06047336b9142ee00739d95398ec6d40809a8b Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Wed, 17 Sep 2025 18:38:01 +0530 Subject: [PATCH 7/8] use dependency groups --- .github/workflows/ci-cd.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index be07fca6e01..6976ee2bf1f 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -189,13 +189,10 @@ jobs: run: | python -m pip install -U pip wheel setuptools build - name: Install dependencies - if: ${{ endsWith(matrix.pyver, 't') }} - run: | - python -Im pip install -r requirements/test-ft.in -c requirements/test-ft.txt - - name: Install dependencies - if: ${{ !endsWith(matrix.pyver, 't') }} + env: + DEPENDENCY_GROUP: test${{ endsWith(matrix.pyver, 't') && '-ft' || '' }} run: | - python -Im pip install -r requirements/test.in -c requirements/test.txt + python -Im pip install -r requirements/${{ env.DEPENDENCY_GROUP }}.in -c requirements/${{ env.DEPENDENCY_GROUP }}.txt - name: Set PYTHON_GIL=0 for free-threading builds if: ${{ endsWith(matrix.pyver, 't') }} run: echo "PYTHON_GIL=0" >> $GITHUB_ENV From 359fbc5047267b2214e38908f2ea7a89d0c61aef Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 17 Sep 2025 08:59:22 -0500 Subject: [PATCH 8/8] Apply suggestions from code review --- .github/workflows/ci-cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 6976ee2bf1f..8152946c902 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -185,9 +185,9 @@ jobs: path: ${{ steps.pip-cache.outputs.dir }} restore-keys: | pip-ci-${{ runner.os }}-${{ matrix.pyver }}-${{ matrix.no-extensions }}- - - name: Update pip, wheel, setuptools, build + - name: Update pip, wheel, setuptools, build, twine run: | - python -m pip install -U pip wheel setuptools build + python -m pip install -U pip wheel setuptools build twine - name: Install dependencies env: DEPENDENCY_GROUP: test${{ endsWith(matrix.pyver, 't') && '-ft' || '' }}