Skip to content
Open
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
70 changes: 70 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,76 @@ jobs:
files: ./coverage.xml
verbose: true

build-uv:
needs: [package]

runs-on: ${{ matrix.os }}
timeout-minutes: 45
permissions:
contents: read

strategy:
fail-fast: false
matrix:
name: [
"windows-py310",

"ubuntu-py310",

"macos-py310",
]

include:
- name: "windows-py310"
python: "3.10"
os: windows-latest
tox_env: "py310"

- name: "ubuntu-py310"
python: "3.10"
os: ubuntu-latest
tox_env: "py310"

- name: "macos-py310"
python: "3.10"
os: macos-latest
tox_env: "py310"
xfail: true

continue-on-error: ${{ matrix.xfail && true || false }}

steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
persist-credentials: false

- name: Download Package
uses: actions/download-artifact@v5
with:
name: Packages
path: dist

- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
check-latest: true
allow-prereleases: true

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox>=4 tox-uv>=1 coverage

- name: Test
shell: bash
env:
UV_RESOLUTION: lowest-direct
UV_PYTHON_PREFERENCE: only-managed
run: tox run -e ${{ matrix.tox_env }} --installpkg `find dist/*.tar.gz`


check: # This job does nothing and is only used for the branch protection
if: always()

Expand Down
3 changes: 3 additions & 0 deletions changelog/13177.packaging.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Raised minimal versions of ``exceptiongroup``, ``iniconfig`` and ``pygments`` following uv powered test runs using the ``lowest-direct`` resolution strategy.

-- by :user:`sgaist`
20 changes: 10 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,21 @@ dynamic = [
]
dependencies = [
"colorama>=0.4; sys_platform=='win32'",
"exceptiongroup>=1; python_version<'3.11'",
"iniconfig>=1.0.1",
"exceptiongroup>=1.1; python_version<'3.11'",
"iniconfig>=2",
"packaging>=22",
"pluggy>=1.5,<2",
"pygments>=2.7.2",
"pygments>=2.14",
"tomli>=1; python_version<'3.11'",
]
optional-dependencies.dev = [
"argcomplete",
"attrs>=19.2",
"hypothesis>=3.56",
"mock",
"requests",
"setuptools",
"xmlschema",
"argcomplete>=3.5",
"attrs>=21",
"hypothesis>=5",
"mock>=5",
"requests>=2.26",
"setuptools>=80",
"xmlschema>=3",
]
Comment on lines 48 to 65
Copy link
Member

@bluetech bluetech Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these changes needed? Is it from testing with lowest-direct?

For the dev deps I don't mind much, perhaps except for attrs and mock which we use for testing pytest integration features so being able to test with older versions is somewhat useful.

But for the runtime dependencies, how did you determine the lower bounds?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct, lowest-direct showed that the oldest version it could get were sometimes using obsolete APIs.

My first tries were to slowly bump the versions of the dependencies that were posing problems. Since some of them were a bit less cooperative, I went to check which years the packages had releases around Python 3.10 initial release. So, in the absolute, I would say it's worth revisiting them to ensure I did not miss something.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your method sounds good to me (cc @RonnyPfannschmidt on iniconfig).

Could you add a packaging changelog entry detailing the changes to the lower bounds of exceptiongroup, iniconfig and pygments?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done but I may have been a bit short

urls.Changelog = "https://docs.pytest.org/en/stable/changelog.html"
urls.Contact = "https://docs.pytest.org/en/stable/contact.html"
Expand Down
29 changes: 20 additions & 9 deletions testing/acceptance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1642,12 +1642,23 @@ def test_fail_call():
result = pytester.runpytest()
assert result.ret == ExitCode.TESTS_FAILED
result.assert_outcomes(failed=1, passed=1, errors=2)
result.stdout.fnmatch_lines(
[
"=* short test summary info =*",
"FAILED test_it.py::test_fail_call - StopIteration: 3",
"ERROR test_it.py::test_fail_setup - StopIteration: 1",
"ERROR test_it.py::test_fail_teardown - StopIteration: 2",
"=* 1 failed, 1 passed, 2 errors in * =*",
]
)

# uv managed python versions do not raise the same exception with regard to
# StopIteration.
# See PEP-0479
runtime_errors = {
"FAILED test_it.py::test_fail_call - RuntimeError: generator raised StopIteration",
"ERROR test_it.py::test_fail_setup - RuntimeError: generator raised StopIteration",
"ERROR test_it.py::test_fail_teardown - RuntimeError: generator raised StopIte...",
}
got_runtime_errors = runtime_errors.issubset(result.outlines)

stopiteration_errors = {
"FAILED test_it.py::test_fail_call - StopIteration: 3",
"ERROR test_it.py::test_fail_setup - StopIteration: 1",
"ERROR test_it.py::test_fail_teardown - StopIteration: 2",
}

got_stopiteration_errors = stopiteration_errors.issubset(result.outlines)

assert got_runtime_errors or got_stopiteration_errors
28 changes: 28 additions & 0 deletions tox-uv.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[tox]
requires =
tox>=4
tox-uv>=1
isolated_build = True
distshare = {homedir}/.tox/uv-distshare
envlist =
py310

[testenv]
description =
run the tests
under `{basepython}`
uv_resolution = lowest-direct
uv_python_preference = only-managed
commands =
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest {posargs:{env:_PYTEST_TOX_DEFAULT_POSARGS:}} --maxfail=1 --pdb
passenv =
PYTEST_ADDOPTS
TERM
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST
CI
setenv =
_PYTEST_TOX_DEFAULT_POSARGS={env:_PYTEST_TOX_POSARGS_DOCTESTING:} {env:_PYTEST_TOX_POSARGS_LSOF:} {env:_PYTEST_TOX_POSARGS_XDIST:} {env:_PYTEST_FILES:}

extras = dev
deps =
{env:_PYTEST_TOX_EXTRA_DEP:}