From 77793b1d38cf5f8bbe8f45e5282b95dfee1461a8 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Fri, 5 Jun 2026 17:57:12 -0700 Subject: [PATCH 01/12] Test with pytest 9.x --- tox.ini | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tox.ini b/tox.ini index 9deb574..71de7b3 100644 --- a/tox.ini +++ b/tox.ini @@ -5,10 +5,10 @@ isolated_build = true envlist = py38-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} py39-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - py310-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - py311-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - py312-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - py313-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + py310-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + py311-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + py312-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + py313-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} static publish @@ -16,10 +16,10 @@ envlist = python = 3.8: py38-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} 3.9: py39-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - 3.10: py310-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - 3.11: py311-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - 3.12: py312-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x}, static, publish - 3.13: py313-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + 3.10: py310-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + 3.11: py311-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + 3.12: py312-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x}, static, publish + 3.13: py313-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} [testenv] constrain_package_deps = true @@ -28,6 +28,8 @@ deps = pytest7.x: pytest ~= 7.0 pytest8.0: pytest ~= 8.0.0 pytest8.x: pytest ~= 8.0 + pytest9.0: pytest ~= 9.0.0 + pytest9.x: pytest ~= 9.0 mypy1.0: mypy ~= 1.0.0 mypy1.x: mypy ~= 1.0 xdist1.x: pytest-xdist ~= 1.0 @@ -36,9 +38,9 @@ deps = xdist3.0: pytest-xdist ~= 3.0.0 xdist3.x: pytest-xdist ~= 3.0 - packaging ~= 21.3 - pytest-cov ~= 4.1.0 - pytest-randomly ~= 3.4 + packaging ~= 26.2 + pytest-cov ~= 5.0.0 + pytest-randomly ~= 3.15 setenv = COVERAGE_FILE = .coverage.{envname} commands = pytest -p no:mypy {posargs:--cov pytest_mypy --cov-branch --cov-fail-under 100 --cov-report term-missing -n auto} From 80b28069b085e511a147858bcfd29492dd167d33 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Fri, 5 Jun 2026 18:05:17 -0700 Subject: [PATCH 02/12] Test with mypy 2.x --- tox.ini | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tox.ini b/tox.ini index 71de7b3..1c55ee7 100644 --- a/tox.ini +++ b/tox.ini @@ -5,10 +5,10 @@ isolated_build = true envlist = py38-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} py39-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - py310-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - py311-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - py312-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - py313-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + py310-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + py311-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + py312-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + py313-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} static publish @@ -16,10 +16,10 @@ envlist = python = 3.8: py38-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} 3.9: py39-pytest{7.0, 7.x, 8.0, 8.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - 3.10: py310-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - 3.11: py311-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} - 3.12: py312-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x}, static, publish - 3.13: py313-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + 3.10: py310-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + 3.11: py311-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + 3.12: py312-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x}, static, publish + 3.13: py313-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} [testenv] constrain_package_deps = true @@ -32,6 +32,8 @@ deps = pytest9.x: pytest ~= 9.0 mypy1.0: mypy ~= 1.0.0 mypy1.x: mypy ~= 1.0 + mypy2.0: mypy ~= 2.0.0 + mypy2.x: mypy ~= 2.0 xdist1.x: pytest-xdist ~= 1.0 xdist2.0: pytest-xdist ~= 2.0.0 xdist2.x: pytest-xdist ~= 2.0 From 7a3635b7944029c9fa9e413241e9f67038966886 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Fri, 5 Jun 2026 18:11:36 -0700 Subject: [PATCH 03/12] Test with python 3.14 --- .github/workflows/validation.yml | 2 +- pyproject.toml | 1 + tox.ini | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index dd36e5f..867ab1c 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -5,7 +5,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 diff --git a/pyproject.toml b/pyproject.toml index be63658..8df1d06 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Testing", ] diff --git a/tox.ini b/tox.ini index 1c55ee7..dc21d84 100644 --- a/tox.ini +++ b/tox.ini @@ -9,6 +9,7 @@ envlist = py311-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} py312-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} py313-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + py314-pytest{9.0, 9.x}-mypy{2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} static publish @@ -20,6 +21,7 @@ python = 3.11: py311-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} 3.12: py312-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x}, static, publish 3.13: py313-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} + 3.14: py314-pytest{7.0, 7.x, 8.0, 8.x, 9.0, 9.x}-mypy{1.0, 1.x, 2.0, 2.x}-xdist{1.x, 2.0, 2.x, 3.0, 3.x} [testenv] constrain_package_deps = true From 120ccebb8ccc96e6671cfdb3f100bca70d6ea1a6 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Fri, 5 Jun 2026 19:10:24 -0700 Subject: [PATCH 04/12] Update publishing deps --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index dc21d84..8f0f0ee 100644 --- a/tox.ini +++ b/tox.ini @@ -56,8 +56,8 @@ testpaths = tests passenv = TWINE_* constrain_package_deps = false deps = - build[virtualenv] ~= 1.0.0 - twine ~= 5.0.0 + build[virtualenv] ~= 1.5.0 + twine ~= 6.2.0 commands = {envpython} -m build --outdir {envtmpdir} . twine {posargs:check} {envtmpdir}/* From 830b9f08bd0abb65294012946484074f67de22d0 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Fri, 5 Jun 2026 19:17:35 -0700 Subject: [PATCH 05/12] Update static deps --- tox.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index 8f0f0ee..b27e4a8 100644 --- a/tox.ini +++ b/tox.ini @@ -65,10 +65,10 @@ commands = [testenv:static] basepython = py312 # pytest.Node.from_parent uses typing.Self deps = - bandit ~= 1.7.0 + bandit ~= 1.9.0 black ~= 24.2.0 - flake8 ~= 7.0.0 - mypy ~= 1.11.0 + flake8 ~= 7.3.0 + mypy ~= 2.1.0 pytest-xdist >= 3.6.0 # needed for type-checking commands = black --check src tests From ea39679587be2a7bd0fd33e787371d91ccc3c55f Mon Sep 17 00:00:00 2001 From: David Tucker Date: Fri, 5 Jun 2026 19:16:48 -0700 Subject: [PATCH 06/12] Update black --- tests/test_pytest_mypy.py | 7 ++----- tox.ini | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/test_pytest_mypy.py b/tests/test_pytest_mypy.py index 1ad7153..172f463 100644 --- a/tests/test_pytest_mypy.py +++ b/tests/test_pytest_mypy.py @@ -8,7 +8,6 @@ import pytest_mypy - MYPY_VERSION = Version(mypy.version.__version__) PYTEST_VERSION = Version(pytest.__version__) PYTHON_VERSION = Version( @@ -699,12 +698,10 @@ def test_mypy_report_style(testdir, xdist_args): """Verify that --mypy-report-style functions correctly.""" module_name = "unmistakable_module_name" testdir.makepyfile( - **{ - module_name: """ + **{module_name: """ def pyfunc(x: int) -> str: return x * 2 - """ - }, + """}, ) result = testdir.runpytest_subprocess("--mypy-report-style", "no-path", *xdist_args) mypy_file_checks = 1 diff --git a/tox.ini b/tox.ini index b27e4a8..efdc083 100644 --- a/tox.ini +++ b/tox.ini @@ -66,12 +66,12 @@ commands = basepython = py312 # pytest.Node.from_parent uses typing.Self deps = bandit ~= 1.9.0 - black ~= 24.2.0 + black ~= 26.5.0 flake8 ~= 7.3.0 mypy ~= 2.1.0 pytest-xdist >= 3.6.0 # needed for type-checking commands = - black --check src tests + black --check --target-version py38 src tests flake8 src tests mypy --strict src bandit --recursive src From 9805d7d5dcba86b9edd1ea75a7954b84caa74726 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Fri, 5 Jun 2026 19:22:58 -0700 Subject: [PATCH 07/12] Rename the build CI job to tox --- .github/workflows/validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index 867ab1c..134ee98 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -1,7 +1,7 @@ name: Validation on: [push, pull_request] jobs: - build: + tox: runs-on: ubuntu-20.04 strategy: matrix: From 405e5510a241ade4d3fe5fabbbc4781ea9eda6a8 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Sat, 6 Jun 2026 09:16:03 -0700 Subject: [PATCH 08/12] Use ubuntu-latest in the Validation workflow --- .github/workflows/validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index 134ee98..f9655d9 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -2,7 +2,7 @@ name: Validation on: [push, pull_request] jobs: tox: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: matrix: python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] From 1189dab053e57dce4ccb3678a6161a4678c1eba3 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Sat, 6 Jun 2026 09:19:16 -0700 Subject: [PATCH 09/12] Use .yaml instead of .yml for workflows --- .github/workflows/{publication.yml => publication.yaml} | 0 .github/workflows/{validation.yml => validation.yaml} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{publication.yml => publication.yaml} (100%) rename .github/workflows/{validation.yml => validation.yaml} (100%) diff --git a/.github/workflows/publication.yml b/.github/workflows/publication.yaml similarity index 100% rename from .github/workflows/publication.yml rename to .github/workflows/publication.yaml diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yaml similarity index 100% rename from .github/workflows/validation.yml rename to .github/workflows/validation.yaml From fd3899662cea58bd8fb3e17f54da9c744ee3c94d Mon Sep 17 00:00:00 2001 From: David Tucker Date: Sat, 6 Jun 2026 09:22:19 -0700 Subject: [PATCH 10/12] Update workflow deps --- .github/workflows/publication.yaml | 4 ++-- .github/workflows/validation.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publication.yaml b/.github/workflows/publication.yaml index f38db8f..7ca8be1 100644 --- a/.github/workflows/publication.yaml +++ b/.github/workflows/publication.yaml @@ -6,8 +6,8 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 with: python-version: '3.8' - run: python -m pip install --upgrade tox-gh-actions diff --git a/.github/workflows/validation.yaml b/.github/workflows/validation.yaml index f9655d9..764a1c9 100644 --- a/.github/workflows/validation.yaml +++ b/.github/workflows/validation.yaml @@ -7,8 +7,8 @@ jobs: matrix: python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - run: python -m pip install --upgrade tox-gh-actions From 11ac78a8369a9f4df5fe6953780fcc6c3c67e99f Mon Sep 17 00:00:00 2001 From: David Tucker Date: Sat, 6 Jun 2026 09:25:33 -0700 Subject: [PATCH 11/12] Upload when a Release is published, not created --- .github/workflows/publication.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publication.yaml b/.github/workflows/publication.yaml index 7ca8be1..a3a7b9c 100644 --- a/.github/workflows/publication.yaml +++ b/.github/workflows/publication.yaml @@ -1,7 +1,7 @@ name: Publication on: release: - types: [created] + types: [published] jobs: deploy: runs-on: ubuntu-latest From 4c7d3292d7a121f55a4d8df802fc3fe098861804 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Sun, 7 Jun 2026 10:33:28 -0700 Subject: [PATCH 12/12] Special-case TypedDict DeprecationWarning --- tests/test_pytest_mypy.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_pytest_mypy.py b/tests/test_pytest_mypy.py index 172f463..b621a81 100644 --- a/tests/test_pytest_mypy.py +++ b/tests/test_pytest_mypy.py @@ -81,6 +81,12 @@ def test_mypy_encoding_warnings(testdir, monkeypatch): mypy_status_check = 1 mypy_checks = mypy_file_checks + mypy_status_check expected_warnings = 2 # https://github.com/python/mypy/issues/14603 + if MYPY_VERSION < Version("1.5"): + # DeprecationWarning: mypy_extensions.TypedDict is deprecated, + # and will be removed in a future version. + # Use typing.TypedDict or typing_extensions.TypedDict instead. + # https://github.com/python/mypy/pull/15494 + expected_warnings += 1 result.assert_outcomes(passed=mypy_checks, warnings=expected_warnings)