Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
### Thanks for contributing, make sure you address all the checklists (for details on how see [development documentation](https://virtualenv.pypa.io/en/latest/development.html#development))

- [ ] ran the linter to address style issues (`tox -e fix`)

- [ ] wrote descriptive pull request text

- [ ] ensured there are test(s) validating the fix

- [ ] added news fragment in `docs/changelog` folder

- [ ] updated/extended the documentation

- [ ] for changes to activation scripts, `pyvenv.cfg`, wheel downloads, app-data or release workflows: explained in the
PR text which outside input the change handles, such as a path, a prompt or a downloaded file, and how it stops that
input from running as code. See the
[security scope](https://github.com/pypa/virtualenv/blob/main/.github/SECURITY.md#scope).

- [ ] ran tests on Python 3.9 and 3.15 (`tox run -e 3.9,3.15`)

- [ ] linked upstream issues beside any temporary interpreter overrides

- [ ] kept the PR in draft until CI passes
25 changes: 16 additions & 9 deletions .github/workflows/check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,17 @@ jobs:
enable-cache: true
cache-dependency-glob: "pyproject.toml"
cache-suffix: ${{ matrix.py }}
- name: 🐍 Setup Python for tox
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.14"
python-version: "3.15"
activate-environment: true
- name: 📦 Install tox with this virtualenv
shell: bash
env:
MATRIX_PY: ${{ matrix.py }}
run: |
if [[ "$MATRIX_PY" == "3.13t" || "$MATRIX_PY" == "3.14t" || "$MATRIX_PY" == "3.15t" || "$MATRIX_PY" == "rp" ]]; then
uv tool install --no-managed-python --python 3.14 "tox>=4.45" --with .
uv tool install --python-preference only-managed --python 3.15 "tox>=4.45" --with .
else
uv tool install --no-managed-python --python 3.14 "tox>=4.45" --with tox-uv --with .
uv tool install --python-preference only-managed --python 3.15 "tox>=4.45" --with tox-uv --with .
fi
- name: 🧮 Resolve GraalPy release
id: graalpy
Expand All @@ -99,10 +97,17 @@ jobs:
run: echo "python-version=graalpy-$(jq --raw-output '.graalpy.tag | ltrimstr("graal-")' tasks/ci-tools.json)" >> "$GITHUB_OUTPUT"
- name: 🐍 Setup Python for test ${{ matrix.py }}
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
if: ${{ !startsWith(matrix.py, 'brew@') && matrix.py != 'rp' }}
if: ${{ !startsWith(matrix.py, 'brew@') && !startsWith(matrix.py, '3.15') && matrix.py != 'rp' }}
with:
python-version: ${{ steps.graalpy.outputs.python-version || matrix.py }}
allow-prereleases: true
- name: Setup Python 3.15 for tests
if: startsWith(matrix.py, '3.15')
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: false
python-version: ${{ matrix.py }}
activate-environment: true
- name: 🦀 Setup RustPython
if: matrix.py == 'rp'
shell: bash
Expand Down Expand Up @@ -256,11 +261,12 @@ jobs:
- name: 🚀 Install uv
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.15"
enable-cache: true
cache-dependency-glob: "pyproject.toml"
cache-suffix: coverage
- name: 📦 Install tox
run: uv tool install --python-preference only-managed --python 3.14 "tox>=4.45" --with tox-uv
run: uv tool install --python-preference only-managed --python 3.15 "tox>=4.45" --with tox-uv
- name: 📥 Download coverage data
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
Expand Down Expand Up @@ -316,11 +322,12 @@ jobs:
- name: 🚀 Install uv
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.15"
enable-cache: true
cache-dependency-glob: "pyproject.toml"
cache-suffix: ${{ matrix.tox_env }}
- name: 📦 Install tox
run: uv tool install --python-preference only-managed --python 3.14 "tox>=4.45" --with tox-uv
run: uv tool install --python-preference only-managed --python 3.15 "tox>=4.45" --with tox-uv
- name: 🏗️ Setup check suite
run: tox run -vv --notest --skip-missing-interpreters false
env:
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/pre-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ jobs:
- name: Install the locked version of uv
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.15"
version-file: tasks/release-requirements.txt
enable-cache: false
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install the locked release tooling
run: |
uv venv --python 3.14 --python-preference only-managed "$RUNNER_TEMP/release"
uv venv --python 3.15 --python-preference only-managed "$RUNNER_TEMP/release"
uv pip sync --python "$RUNNER_TEMP/release" --require-hashes tasks/release-requirements.txt
- name: Generate changelog, commit, and tag
id: release
Expand Down
14 changes: 8 additions & 6 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,22 @@ jobs:
- name: Install the locked version of uv
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.15"
version-file: tasks/release-requirements.txt
enable-cache: false
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install the locked release tooling
run: |
uv venv --python 3.14 --python-preference only-managed "$RUNNER_TEMP/tools"
uv venv --python 3.15 --python-preference only-managed "$RUNNER_TEMP/tools"
uv pip sync --python "$RUNNER_TEMP/tools" --require-hashes tasks/release-requirements.txt
- name: Pin build timestamps to the release commit for reproducible artifacts
run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV"
- name: Build sdist and wheel
run: |
uv build --python 3.14 --python-preference only-managed --sdist --wheel . --out-dir dist \
uv build --python 3.15 --python-preference only-managed --sdist --wheel . --out-dir dist \
--build-constraints tasks/release-requirements.txt --require-hashes
- name: Extract the SBOM the wheel build embedded
run: python -m zipfile -e dist/*.whl sbom-extract/ && cp sbom-extract/*.dist-info/sboms/virtualenv.cdx.json .
run: uv run --no-project --python 3.15 python -m zipfile -e dist/*.whl sbom-extract/ && cp sbom-extract/*.dist-info/sboms/virtualenv.cdx.json .
- name: Attest the SBOM against the sdist and wheel
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
Expand Down Expand Up @@ -196,11 +197,12 @@ jobs:
- name: Install the locked version of uv
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.15"
version-file: tasks/release-requirements.txt
enable-cache: false
- name: Install the locked verification tooling
run: |
uv venv --python 3.14 --python-preference only-managed "$RUNNER_TEMP/tools"
uv venv --python 3.15 --python-preference only-managed "$RUNNER_TEMP/tools"
uv pip sync --python "$RUNNER_TEMP/tools" --require-hashes tasks/release-requirements.txt
- name: Download expected distributions
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
Expand Down Expand Up @@ -269,12 +271,12 @@ jobs:
run: |
for artifact in published/*.whl published/*.tar.gz; do
installation="$RUNNER_TEMP/$(basename "$artifact")"
uv venv --python 3.14 "$installation"
uv venv --python 3.15 "$installation"
uv pip install --no-cache --python "$installation/bin/python" "$artifact"
"$installation/bin/python" -I -m virtualenv --no-download --no-periodic-update "$installation/created"
"$installation/created/bin/python" -I -m pip --version
done
uv run --no-project --python 3.14 python -I published/virtualenv.pyz \
uv run --no-project --python 3.15 python -I published/virtualenv.pyz \
--no-download --no-periodic-update "$RUNNER_TEMP/zipapp-created"
"$RUNNER_TEMP/zipapp-created/bin/python" -I -m pip --version
verify-bootstrap:
Expand Down
20 changes: 13 additions & 7 deletions .github/workflows/upgrade.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,18 @@ jobs:
- name: Install uv
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.15"
enable-cache: false # the egress allowlist above blocks the cache service
- name: Install tox
run: uv tool install --python-preference only-managed --python 3.14 "tox>=4.32" --with tox-uv
run: uv tool install --python-preference only-managed --python 3.15 "tox>=4.32" --with tox-uv
- name: Fetch upstream tags for versioning
run: git fetch --force --tags https://github.com/pypa/virtualenv.git
- name: Pin the newest CI test tools
id: ci-tools
if: github.event_name == 'workflow_dispatch' || github.event.schedule == '0 11 * * 1'
env:
GH_TOKEN: ${{ github.token }}
run: python tasks/upgrade_ci_tools.py
run: uv run --no-project --python 3.15 python tasks/upgrade_ci_tools.py
- name: Run upgrade
id: upgrade
env:
Expand All @@ -52,9 +53,9 @@ jobs:
tox run -e upgrade
# hold back releases younger than the seven days check_wheel_age.py demands of embedded wheels
UV_EXCLUDE_NEWER="7 days" uv pip compile pyproject.toml --universal --python-version 3.9 --upgrade -o pylock.zipapp.toml
if ! UV_EXCLUDE_NEWER="7 days" uv pip compile --group pyproject.toml:release --universal --python-version 3.14 \
if ! UV_EXCLUDE_NEWER="7 days" uv pip compile --group pyproject.toml:release --universal --python-version 3.15 \
--generate-hashes --upgrade -o tasks/release-requirements.txt; then
uv pip compile --group pyproject.toml:release --universal --python-version 3.14 \
uv pip compile --group pyproject.toml:release --universal --python-version 3.15 \
--generate-hashes --upgrade --no-build -o "$RUNNER_TEMP/release-requirements.txt"
echo "changed=false" >> "$GITHUB_OUTPUT"
echo "### Waiting for release dependencies to satisfy the seven-day age filter" >> "$GITHUB_STEP_SUMMARY"
Expand All @@ -77,7 +78,7 @@ jobs:
if: steps.upgrade.outputs.changed == 'true'
id: age-check
run: |
python tasks/check_wheel_age.py >> "$GITHUB_OUTPUT"
uv run --no-project --python 3.15 python tasks/check_wheel_age.py >> "$GITHUB_OUTPUT"
- name: Prepare upgrade patch
if: steps.upgrade.outputs.changed == 'true' && steps.age-check.outputs.skip == 'false'
run: git diff --cached --binary --no-ext-diff --no-textconv > "$RUNNER_TEMP/upgrade.patch"
Expand Down Expand Up @@ -106,7 +107,7 @@ jobs:
egress-policy: block
disable-sudo-and-containers: true
allowed-endpoints: >-
api.github.com:443 github.com:443
api.github.com:443 github.com:443 release-assets.githubusercontent.com:443 releases.astral.sh:443
- name: Checkout trusted generator revision
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand All @@ -118,8 +119,13 @@ jobs:
with:
name: upgrade-patch
path: ${{ runner.temp }}/upgrade-patch
- name: Install uv
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.15"
enable-cache: false
- name: Validate and apply upgrade patch
run: python tasks/apply_upgrade_patch.py "$RUNNER_TEMP/upgrade-patch/upgrade.patch"
run: uv run --no-project --python 3.15 python tasks/apply_upgrade_patch.py "$RUNNER_TEMP/upgrade-patch/upgrade.patch"
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
Expand Down
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
default_language_version:
python: python3.15
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ build:
tools: {}
commands:
- curl -LsSf https://astral.sh/uv/install.sh | sh
- ~/.local/bin/uv tool install tox --with tox-uv -p 3.14 --managed-python
- ~/.local/bin/uv tool install tox --with tox-uv -p 3.15 --managed-python
- ~/.local/bin/tox run -e docs --
12 changes: 6 additions & 6 deletions docs/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ To run tests locally execute:

tox -e py

This will run the test suite for the same Python version as under which ``tox`` is installed. Alternatively you can
specify a specific version of python by using the ``pyNN`` format, such as: ``py314``, ``pypy3``, etc.
This runs the test suite on Python 3.15. Select another supported interpreter with its environment name, such as
``3.9``, ``3.14`` or ``pypy3.11``.

``tox`` has been configured to forward any additional arguments it is given to ``pytest``. This enables the use of
pytest's `rich CLI <https://docs.pytest.org/en/latest/usage.html#specifying-tests-selecting-tests>`_. As an example, you
Expand All @@ -75,7 +75,7 @@ tests are run; so even if all tests succeed locally for you, they may still fail

The tests under ``tests/tasks`` cover the build and CI tooling, ``hatch_build.py`` and the scripts in ``tasks/``. Their
outcome does not depend on the interpreter, so the interpreter environments skip them and one environment runs them on
CPython 3.14:
CPython 3.15:

.. code-block:: console

Expand Down Expand Up @@ -111,7 +111,7 @@ locally, run:
tox -e type

This uses `ty <https://docs.astral.sh/ty/>`_ (Astral's Rust-based type checker) to validate annotations against Python
3.14. A second environment checks compatibility with the minimum supported version:
3.15. A second environment checks compatibility with the minimum supported version:

.. code-block:: console

Expand Down Expand Up @@ -342,8 +342,8 @@ virtualenv is distributed under the MIT License, and everything in the repositor
embedded wheels above, so a wheel bump updates it with no extra step. ``tasks/cyclonedx_to_spdx.py`` renders that
document as SPDX 2.3 with the standard library alone. ``tox r -e readme`` builds a wheel and validates its SBOM and
the SPDX rendering; the release workflow runs ``tox r -e spdx`` to write ``virtualenv.spdx.json`` from
``virtualenv.cdx.json`` and check it with ``pyspdxtools``. Both envs run on Python 3.14 because ``spdx-tools`` fails
to import on 3.15.
``virtualenv.cdx.json`` and check it with ``pyspdxtools``. Both environments run on Python 3.15 with a Beartype
prerelease that fixes its `removed typing API import <https://github.com/beartype/beartype/issues/618>`_.
- ``tasks/zipapp_sbom.py`` describes a built ``virtualenv.pyz`` from the archive itself: virtualenv, the embedded
wheels, and each bundled dependency with the Python versions that load it, down to a SHA-256 per file. It reuses the
helpers in ``hatch_build.py``, writes ``virtualenv.pyz.cdx.json`` next to the zipapp and adds the same file to the
Expand Down
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ type = [
docs = [
"furo>=2025.12.19",
"pre-commit-uv>=4.2",
"proselint>=0.14",
"sphinx!=7.3,>=7.4.7",
"sphinx-argparse>=0.4",
"sphinx-autodoc-typehints>=3.6.2",
Expand All @@ -147,6 +146,7 @@ docs = [
"sphinxcontrib-mermaid>=2",
"sphinxcontrib-towncrier>=0.2.1a0",
"towncrier>=26.9",
"uv>=0.12.22",
]
coverage = [
"covdefaults>=2.3",
Expand Down Expand Up @@ -185,6 +185,8 @@ release = [
{ include-group = "sbom" },
]
sbom = [
# The stable release still imports a removed typing API: https://github.com/beartype/beartype/issues/618
"beartype>=0.23.0rc2; python_version>='3.15'",
"cyclonedx-python-lib[json-validation]>=11.12",
"spdx-tools>=0.8.5",
]
Expand Down
12 changes: 7 additions & 5 deletions tasks/release-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This file was autogenerated by uv via the following command:
# uv pip compile --group pyproject.toml:release --universal --python-version 3.14 --generate-hashes -o tasks/release-requirements.txt
# uv pip compile --group pyproject.toml:release --universal --python-version 3.15 --generate-hashes -o tasks/release-requirements.txt
alabaster==1.0.0 \
--hash=sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e \
--hash=sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b
Expand All @@ -22,10 +22,12 @@ babel==2.18.0 \
--hash=sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d \
--hash=sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35
# via sphinx
beartype==0.22.9 \
--hash=sha256:8f82b54aa723a2848a56008d18875f91c1db02c32ef6a62319a002e3e25a975f \
--hash=sha256:d16c9bbc61ea14637596c5f6fbff2ee99cbe3573e46a716401734ef50c3060c2
# via spdx-tools
beartype==0.23.0rc2 \
--hash=sha256:d589e5c6cf1859e4cf355db52ddcd08e2eca98784d7d73dc5f4491f423f94ee5 \
--hash=sha256:fffbb5aa86562b034038f2c90da71cac463247374c89981c937685f47a75223c
# via
# virtualenv (pyproject.toml:release)
# spdx-tools
black==26.5.1 \
--hash=sha256:0e48b87e03bf109288e55cfceadcfa15ff5470aca2851a851950ed2926f450d7 \
--hash=sha256:1037d5ac7b7b310b2632ad867ec8d0e4c4819dcdb0b820f63135da746a24e418 \
Expand Down
Loading
Loading