From c1b4e68a3087ae0240adc476518ca39f94a02c9d Mon Sep 17 00:00:00 2001 From: Matthias Bach Date: Tue, 30 Jun 2026 14:03:52 +0200 Subject: [PATCH 1/7] Add an AGENTS.md for easier offloading of work to Copilot --- AGENTS.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..bc4bb72 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,12 @@ +# Agents + +Use these project-specific defaults when making future changes: + +- Run tests with `pytest`. +- Use `tox` to run the full test matrix across supported Python versions. +- Keep `core-requirements.txt` for runtime dependencies and `extra-test-requirements.txt` for test-only dependencies. +- Regenerate `requirements.txt` from those inputs with `tox -e compile`. Use `tox -e compile -- --upgrade` to upgrade dependencies to the latest compatible versions. +- When changing supported Python versions, keep `tox.ini`, GitHub workflows, and `setup.py` trove classifiers in sync. +- Keep `.python-version` set to the lowest supported Python version so Dependabot and single-version tooling pick it up correctly. +- Keep `base_python` in the `compile` environment in `tox.ini` set to the lowest supported Python version so that `tox -e compile` works correctly. +- When changing supported Python versions, recompile the `requirements.txt` file with `tox -e compile -- --upgrade` to ensure that compatible versions of dependencies are used. From b7462804031e64ceb8009d0372f8b8f74a95f678 Mon Sep 17 00:00:00 2001 From: Matthias Bach Date: Tue, 30 Jun 2026 15:38:56 +0200 Subject: [PATCH 2/7] Add a tox configuration for easier local testing --- .gitignore | 1 + tox.toml | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 tox.toml diff --git a/.gitignore b/.gitignore index f265e23..71a2e15 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,6 @@ venv*/ build tests/fixture/package/dist dist/ +tox/ README.html diff --git a/tox.toml b/tox.toml new file mode 100644 index 0000000..dd334f0 --- /dev/null +++ b/tox.toml @@ -0,0 +1,14 @@ +min_version = "4.0" +env_list = ["3.9", "3.10", "3.11", "3.12", "3.13"] + +[env_run_base] +description = "run tests on {base_python}" +deps = ["-r requirements.txt", "--no-deps"] +commands = [["pytest", "--no-cov"]] + +[env.compile] +description = "compile dependencies" +skip_install = true +deps = ["pip-tools"] +commands = [["pip-compile", "--no-emit-index-url", "--strip-extras", "--unsafe-package", "pip", { replace = "posargs", extend = true }]] +base_python = "3.9" From 5395f7079c29600f00e30335a30fba94eff22c29 Mon Sep 17 00:00:00 2001 From: Matthias Bach Date: Tue, 30 Jun 2026 16:37:06 +0200 Subject: [PATCH 3/7] Consistently use our default Python version --- .github/workflows/publish.yml | 2 +- .github/workflows/stage.yml | 2 +- .github/workflows/tests.yml | 13 ++++++++----- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4e51bc8..90328f9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -17,7 +17,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: '3.x' + python-version-file: .python-version - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/stage.yml b/.github/workflows/stage.yml index 0927695..5db184a 100644 --- a/.github/workflows/stage.yml +++ b/.github/workflows/stage.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: '3.x' + python-version-file: .python-version - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 29afee9..714ac60 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,7 +21,6 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | - python -m pip install --upgrade pip python -m pip install -r requirements.txt if [ "${{ matrix.python-version }}" != "3.13" ]; then # workaround for TheKevJames/coveralls-python#523 python -m pip install coveralls @@ -45,9 +44,13 @@ jobs: coveralls: name: Indicate completion to coveralls.io needs: test - runs-on: ubuntu-latest - container: python:3-slim + runs-on: ubuntu-slim steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version-file: .python-version - name: Finished run: | python -m pip install coveralls @@ -55,13 +58,13 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} check_packaging: - runs-on: ubuntu-latest + runs-on: ubuntu-slim steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: - python-version: '3.x' + python-version-file: .python-version - name: Verify packaging run: | python -m pip install build twine From 214b90fd9811240bbffea403cb3791f63ad540d1 Mon Sep 17 00:00:00 2001 From: Matthias Bach Date: Tue, 30 Jun 2026 17:07:52 +0200 Subject: [PATCH 4/7] Drop no longe required coveralls compatibility workaround --- .github/workflows/tests.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 714ac60..70ee9d2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,17 +22,11 @@ jobs: - name: Install dependencies run: | python -m pip install -r requirements.txt - if [ "${{ matrix.python-version }}" != "3.13" ]; then # workaround for TheKevJames/coveralls-python#523 - python -m pip install coveralls - fi + python -m pip install coveralls python -m pip freeze - name: Test with pytest run: | - if [ "${{ matrix.python-version }}" == "3.13" ]; then - pytest --no-cov # workaround for TheKevJames/coveralls-python#523 - else - pytest - fi + pytest - name: Upload coverage data if: matrix.python-version != '3.13' # workaround for TheKevJames/coveralls-python#523 run: | From d6de58ef8a029121faef6aa5304a245d57e903f7 Mon Sep 17 00:00:00 2001 From: Matthias Bach Date: Tue, 30 Jun 2026 17:50:58 +0200 Subject: [PATCH 5/7] Drop support for Python 3.9 Python 3.9 is EOL since 2025-10-31. Dependabot has now also stopped supporting it. --- .github/workflows/tests.yml | 2 +- .python-version | 2 +- CHANGELOG.rst | 1 + requirements.txt | 2 +- setup.py | 2 +- tox.toml | 4 ++-- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 70ee9d2..95c2427 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] + python-version: ['3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} diff --git a/.python-version b/.python-version index bd28b9c..c8cfe39 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.9 +3.10 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5f767ca..6659a58 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,7 @@ Unreleased ---------- - Add official support for Python 3.12 and 3.13. +- Drop support for Python 3.9. - Drop support for Python 3.8. 0.7.0 diff --git a/requirements.txt b/requirements.txt index 44ce9cf..20e313f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.9 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # pip-compile --no-emit-index-url --strip-extras --unsafe-package=pip diff --git a/setup.py b/setup.py index 79c30e1..3b5f2d9 100644 --- a/setup.py +++ b/setup.py @@ -22,6 +22,7 @@ long_description=readme, long_description_content_type='text/x-rst', license='new BSD', + python_requires='>=3.10', setup_requires=[ 'setuptools_scm', ], @@ -42,7 +43,6 @@ 'License :: OSI Approved :: BSD License', 'Topic :: System :: Archiving :: Packaging', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', diff --git a/tox.toml b/tox.toml index dd334f0..6eaf190 100644 --- a/tox.toml +++ b/tox.toml @@ -1,5 +1,5 @@ min_version = "4.0" -env_list = ["3.9", "3.10", "3.11", "3.12", "3.13"] +env_list = ["3.10", "3.11", "3.12", "3.13"] [env_run_base] description = "run tests on {base_python}" @@ -11,4 +11,4 @@ description = "compile dependencies" skip_install = true deps = ["pip-tools"] commands = [["pip-compile", "--no-emit-index-url", "--strip-extras", "--unsafe-package", "pip", { replace = "posargs", extend = true }]] -base_python = "3.9" +base_python = "3.10" From 19934e7670cb3dc7482389886948aa74e5f827b4 Mon Sep 17 00:00:00 2001 From: Matthias Bach Date: Tue, 30 Jun 2026 17:53:47 +0200 Subject: [PATCH 6/7] Update tested dependencies after updating minimum supported Python version --- requirements.txt | 100 +++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 51 deletions(-) diff --git a/requirements.txt b/requirements.txt index 20e313f..62c12ab 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,50 +4,50 @@ # # pip-compile --no-emit-index-url --strip-extras --unsafe-package=pip # -alabaster==0.7.16 +alabaster==1.0.0 # via sphinx -anyio==4.9.0 +anyio==4.14.1 # via httpx -argon2-cffi==23.1.0 +argon2-cffi==25.1.0 # via # devpi-server # passlib -argon2-cffi-bindings==21.2.0 +argon2-cffi-bindings==25.1.0 # via argon2-cffi -attrs==25.3.0 +attrs==26.1.0 # via devpi-server -babel==2.17.0 +babel==2.18.0 # via sphinx -build==1.2.2.post1 +build==1.5.0 # via # check-manifest # devpi-client -certifi==2025.1.31 +certifi==2026.6.17 # via # httpcore # httpx # requests -cffi==1.17.1 +cffi==2.0.0 # via argon2-cffi-bindings -charset-normalizer==3.4.1 +charset-normalizer==3.4.7 # via requests -check-manifest==0.50 +check-manifest==0.51 # via devpi-client -coverage==7.8.0 +coverage==7.14.3 # via pytest-cov defusedxml==0.7.1 # via devpi-server -devpi-client==7.2.0 +devpi-client==7.3.0 # via -r core-requirements.txt -devpi-common==4.0.4 +devpi-common==4.1.1 # via # devpi-client # devpi-server -devpi-server==6.20.0 +devpi-server==6.20.2 # via -r extra-test-requirements.txt docutils==0.21.2 # via sphinx -exceptiongroup==1.2.2 +exceptiongroup==1.3.1 # via # anyio # pytest @@ -59,19 +59,14 @@ httpx==0.28.1 # via devpi-server hupper==1.12.1 # via pyramid -idna==3.15 +idna==3.18 # via # anyio # httpx # requests -imagesize==1.4.1 +imagesize==2.0.0 # via sphinx -importlib-metadata==8.6.1 - # via - # build - # setuptools-scm - # sphinx -iniconfig==2.1.0 +iniconfig==2.3.0 # via # devpi-client # pytest @@ -85,17 +80,18 @@ lazy==1.6 # devpi-server legacy-cgi==2.6.4 # via -r extra-test-requirements.txt -markupsafe==3.0.2 +markupsafe==3.0.3 # via jinja2 mock==5.2.0 # via -r requirements.in -packaging==25.0 +packaging==26.2 # via # build # packaging-legacy # pytest # setuptools-scm # sphinx + # vcs-versioning packaging-legacy==23.0.post0 # via devpi-common passlib==1.7.4 @@ -110,45 +106,47 @@ plaster==1.1.2 # pyramid plaster-pastedeploy==1.0.1 # via pyramid -platformdirs==4.3.7 +platformdirs==4.10.0 # via # devpi-client # devpi-server -pluggy==1.5.0 +pluggy==1.6.0 # via # devpi-client # devpi-server # pytest + # pytest-cov py==1.11.0 # via devpi-server -pycparser==2.22 +pycparser==3.0 # via cffi pygments==2.20.0 - # via sphinx + # via + # pytest + # sphinx pyproject-hooks==1.2.0 # via build -pyramid==2.0.2 +pyramid==2.1 # via devpi-server -pytest==8.3.5 +pytest==9.1.1 # via # -r requirements.in # pytest-cov -pytest-cov==6.1.1 +pytest-cov==7.1.0 # via -r requirements.in python-dateutil==2.9.0.post0 # via strictyaml -repoze-lru==0.7 +repoze-lru==0.8 # via devpi-server -requests==2.32.4 +requests==2.34.2 # via # -r core-requirements.txt + # devpi-client # devpi-common # devpi-server # sphinx -ruamel-yaml==0.18.10 +ruamel-yaml==0.19.1 # via devpi-server -ruamel-yaml-clib==0.2.12 - # via ruamel-yaml setuptools==81.0.0 # via # check-manifest @@ -156,16 +154,13 @@ setuptools==81.0.0 # pyramid # setuptools-scm # zope-deprecation - # zope-interface -setuptools-scm==8.3.1 +setuptools-scm==10.2.0 # via -r requirements.in six==1.17.0 # via python-dateutil -sniffio==1.3.1 - # via anyio -snowballstemmer==2.2.0 +snowballstemmer==3.1.1 # via sphinx -sphinx==7.4.7 +sphinx==8.1.3 # via -r requirements.in sphinxcontrib-applehelp==2.0.0 # via sphinx @@ -183,7 +178,7 @@ strenum==0.4.15 # via devpi-server strictyaml==1.7.3 # via devpi-server -tomli==2.2.1 +tomli==2.4.1 # via # build # check-manifest @@ -192,6 +187,7 @@ tomli==2.2.1 # pytest # setuptools-scm # sphinx + # vcs-versioning translationstring==1.4 # via pyramid twitter-common-contextutil==0.3.11 @@ -200,21 +196,23 @@ twitter-common-dirutil==0.3.11 # via twitter-common-contextutil twitter-common-lang==0.3.11 # via twitter-common-dirutil -typing-extensions==4.13.2 +typing-extensions==4.15.0 # via # anyio + # exceptiongroup # setuptools-scm -urllib3==2.6.3 + # vcs-versioning +urllib3==2.7.0 # via requests +vcs-versioning==2.2.2 + # via setuptools-scm venusian==3.1.1 # via pyramid waitress==3.0.2 # via devpi-server webob==1.8.10 # via pyramid -zipp==3.21.0 - # via importlib-metadata -zope-deprecation==5.1 +zope-deprecation==6.0 # via pyramid -zope-interface==7.2 +zope-interface==8.5 # via pyramid From 9ff4e90ea20d5d076c0a6f94290b5d96374acd7e Mon Sep 17 00:00:00 2001 From: Matthias Bach Date: Tue, 30 Jun 2026 18:23:07 +0200 Subject: [PATCH 7/7] Verify support for Python 3.14 --- .github/workflows/tests.yml | 2 +- CHANGELOG.rst | 2 +- setup.py | 1 + tox.toml | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 95c2427..765a368 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.10', '3.11', '3.12', '3.13'] + python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6659a58..7374e30 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,7 +1,7 @@ Unreleased ---------- -- Add official support for Python 3.12 and 3.13. +- Add official support for Python 3.12, 3.13 and 3.14. - Drop support for Python 3.9. - Drop support for Python 3.8. diff --git a/setup.py b/setup.py index 3b5f2d9..daa3f9b 100644 --- a/setup.py +++ b/setup.py @@ -47,5 +47,6 @@ 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: 3.13', + 'Programming Language :: Python :: 3.14', ], ) diff --git a/tox.toml b/tox.toml index 6eaf190..fe7f476 100644 --- a/tox.toml +++ b/tox.toml @@ -1,5 +1,5 @@ min_version = "4.0" -env_list = ["3.10", "3.11", "3.12", "3.13"] +env_list = ["3.10", "3.11", "3.12", "3.13", "3.14"] [env_run_base] description = "run tests on {base_python}"