From 0fdc60463d755a1d45a520a54e8383a7bf605c44 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Mon, 17 Nov 2025 08:53:45 -0800 Subject: [PATCH 1/5] Drop required sphinx version a bit to support 3.10 --- .changelog/416cf8fe31c341adb1264feb7ef7be1e.md | 4 ++++ setup.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .changelog/416cf8fe31c341adb1264feb7ef7be1e.md diff --git a/.changelog/416cf8fe31c341adb1264feb7ef7be1e.md b/.changelog/416cf8fe31c341adb1264feb7ef7be1e.md new file mode 100644 index 0000000..7d1c574 --- /dev/null +++ b/.changelog/416cf8fe31c341adb1264feb7ef7be1e.md @@ -0,0 +1,4 @@ +--- +type: none +--- +Drop required sphinx version a bit to support 3.10 \ No newline at end of file diff --git a/setup.py b/setup.py index b07e075..8c9edde 100644 --- a/setup.py +++ b/setup.py @@ -73,7 +73,7 @@ setup( ), 'docs': ( 'myst-parser>=4.0.1', - 'Sphinx>=8.2.3', + 'Sphinx>=8.1.0', 'sphinxcontrib-mermaid>=1.0.0', 'sphinx-copybutton>=0.5.2', 'sphinx_rtd_theme', From 51dc3c1eb721e03b6371029bbcbfff18ab72c6a9 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Mon, 17 Nov 2025 09:03:21 -0800 Subject: [PATCH 2/5] Script to update .ci-config.json with current python versions --- .../7964691076224439b4c8b9bcef2e4bb6.md | 4 ++ .ci-config.json | 8 ++- script/update-python-versions | 58 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 .changelog/7964691076224439b4c8b9bcef2e4bb6.md create mode 100755 script/update-python-versions diff --git a/.changelog/7964691076224439b4c8b9bcef2e4bb6.md b/.changelog/7964691076224439b4c8b9bcef2e4bb6.md new file mode 100644 index 0000000..c62e73d --- /dev/null +++ b/.changelog/7964691076224439b4c8b9bcef2e4bb6.md @@ -0,0 +1,4 @@ +--- +type: none +--- +Script to update .ci-config.json with current python versions \ No newline at end of file diff --git a/.ci-config.json b/.ci-config.json index 65ec95d..22edf29 100644 --- a/.ci-config.json +++ b/.ci-config.json @@ -1,4 +1,10 @@ { "python_version_current": "3.14", - "python_versions_active": ["3.10", "3.11", "3.12", "3.13", "3.14"] + "python_versions_active": [ + "3.10", + "3.11", + "3.12", + "3.13", + "3.14" + ] } diff --git a/script/update-python-versions b/script/update-python-versions new file mode 100755 index 0000000..9f53891 --- /dev/null +++ b/script/update-python-versions @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +from datetime import date, datetime +from json import dump, load +from urllib.request import urlopen + +# Fetch Python version data from endoflife.date +with urlopen('https://endoflife.date/api/python.json') as response: + versions = load(response) + +# Get today's date for EOL comparison +today = date.today() + +# Filter for active versions (released and not EOL'd yet) +active_versions = [] +for version in versions: + cycle = version['cycle'] + + # Skip Python 2.x versions + if cycle.startswith('2.'): + continue + + # Check if version has been released + release_date_str = version.get('releaseDate') + if release_date_str: + release_date = datetime.strptime(release_date_str, '%Y-%m-%d').date() + if release_date > today: + # Skip pre-release versions + continue + + # Check if version is not EOL'd yet + eol_str = version.get('eol') + if eol_str: + eol_date = datetime.strptime(eol_str, '%Y-%m-%d').date() + if eol_date >= today: + active_versions.append(cycle) + +# Sort versions +active_versions.sort(key=lambda v: tuple(map(int, v.split('.')))) + +# Determine current version (the latest active version) +current_version = active_versions[-1] if active_versions else None + +# Update .ci-config.json +config_path = '.ci-config.json' +with open(config_path, 'r') as fh: + config = load(fh) + +config['python_versions_active'] = active_versions +config['python_version_current'] = current_version + +with open(config_path, 'w') as fh: + dump(config, fh, indent=2) + fh.write('\n') + +print(f'Updated {config_path}:') +print(f' Active versions: {", ".join(active_versions)}') +print(f' Current version: {current_version}') From a2e3b93e7499c51b70eb33322be2bcc8b977457b Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Mon, 17 Nov 2025 09:10:28 -0800 Subject: [PATCH 3/5] Switch to proviso for requirements.txt management --- .../fbd3d292e2be485fb0e005d97b41c994.md | 4 + requirements-dev.txt | 52 ---------- requirements-docs.txt | 26 ----- script/bootstrap | 4 - script/update-requirements | 94 +------------------ setup.py | 1 + 6 files changed, 8 insertions(+), 173 deletions(-) create mode 100644 .changelog/fbd3d292e2be485fb0e005d97b41c994.md delete mode 100644 requirements-dev.txt delete mode 100644 requirements-docs.txt diff --git a/.changelog/fbd3d292e2be485fb0e005d97b41c994.md b/.changelog/fbd3d292e2be485fb0e005d97b41c994.md new file mode 100644 index 0000000..b957c87 --- /dev/null +++ b/.changelog/fbd3d292e2be485fb0e005d97b41c994.md @@ -0,0 +1,4 @@ +--- +type: none +--- +Switch to proviso for requirements.txt management \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index e7e8b6c..0000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,52 +0,0 @@ -# DO NOT EDIT THIS FILE DIRECTLY - use ./script/update-requirements to update -Pygments==2.19.2 -SecretStorage==3.4.0 -black==24.10.0 -build==1.3.0 -certifi==2025.10.5 -cffi==2.0.0 -changelet==0.3.0 -charset-normalizer==3.4.3 -click==8.1.8; python_version<'3.10' -click==8.3.0; python_version>='3.10' -cmarkgfm==2024.11.20 -coverage==7.10.7 -cryptography==46.0.2 -docutils==0.21.2 -id==1.5.0 -iniconfig==2.1.0 -isort==6.1.0 -jaraco.classes==3.4.0 -jaraco.context==6.0.1 -jaraco.functools==4.3.0 -jeepney==0.9.0 -keyring==25.6.0 -markdown-it-py==3.0.0 -mdurl==0.1.2 -more-itertools==10.8.0 -mypy_extensions==1.1.0 -nh3==0.3.1 -packaging==25.0 -pathspec==0.12.1 -platformdirs==4.5.0 -pluggy==1.6.0 -pprintpp==0.4.0 -pycountry==24.6.1 -pycountry-convert==0.7.2 -pycparser==2.23 -pyflakes==3.4.0 -pyproject_hooks==1.2.0 -pytest==8.4.2 -pytest-cov==7.0.0 -pytest-mock==3.15.1 -pytest_network==0.0.1 -readme_renderer==44.0 -repoze.lru==0.7 -requests==2.32.5 -requests-toolbelt==1.0.0 -rfc3986==2.0.0 -rich==14.1.0 -semver==3.0.4 -twine==6.2.0 -urllib3==2.5.0 -wheel==0.45.1 diff --git a/requirements-docs.txt b/requirements-docs.txt deleted file mode 100644 index 4b0d9ce..0000000 --- a/requirements-docs.txt +++ /dev/null @@ -1,26 +0,0 @@ -# DO NOT EDIT THIS FILE DIRECTLY - use ./script/update-requirements to update -Jinja2==3.1.6 -MarkupSafe==3.0.3 -Sphinx==7.4.7; python_version=='3.9' -Sphinx==8.1.3; python_version=='3.10' -Sphinx==8.2.3; python_version>='3.11' -alabaster==0.7.16; python_version<'3.10' -alabaster==1.0.0; python_version>='3.10' -babel==2.17.0 -imagesize==1.4.1 -mdit-py-plugins==0.4.2; python_version=='3.9' -mdit-py-plugins==0.5.0; python_version>='3.10' -myst-parser==3.0.1; python_version<'3.10' -myst-parser==4.0.1; python_version>='3.10' -roman-numerals-py==3.1.0 -snowballstemmer==3.0.1 -sphinx-copybutton==0.5.2 -sphinx-rtd-theme==3.0.2 -sphinxcontrib-applehelp==2.0.0 -sphinxcontrib-devhelp==2.0.0 -sphinxcontrib-htmlhelp==2.1.0 -sphinxcontrib-jquery==4.1 -sphinxcontrib-jsmath==1.0.1 -sphinxcontrib-mermaid==1.0.0 -sphinxcontrib-qthelp==2.0.0 -sphinxcontrib-serializinghtml==2.0.0 diff --git a/script/bootstrap b/script/bootstrap index a7d85e7..3bb09e7 100755 --- a/script/bootstrap +++ b/script/bootstrap @@ -25,10 +25,6 @@ fi python -m pip install -U 'pip>=10.0.1' python -m pip install -r requirements.txt -if [ "$ENV" != "production" ]; then - python -m pip install -r requirements-dev.txt -fi - if [ -d ".git" ]; then if [ -f ".git-blame-ignore-revs" ]; then echo "" diff --git a/script/update-requirements b/script/update-requirements index da96daf..08878ff 100755 --- a/script/update-requirements +++ b/script/update-requirements @@ -1,93 +1,5 @@ -#!/usr/bin/env python3 +#!/bin/bash -from os.path import join -from subprocess import check_call, check_output -from sys import argv, stdout -from tempfile import TemporaryDirectory +set -e -with TemporaryDirectory() as tmpdir: - check_call(['python3', '-m', 'venv', tmpdir]) - - def install_and_list(target): - check_call([join(tmpdir, 'bin', 'pip'), 'install', target]) - frozen = ( - check_output([join(tmpdir, 'bin', 'pip'), 'freeze']) - .decode('utf-8') - .strip() - .split('\n') - ) - # file bit skips ourself - return set(p.split('=', 1)[0] for p in frozen if 'file' not in p) - - # base needs - frozen = install_and_list('.') - # dev needs - dev_frozen = install_and_list('.[dev]') - frozen - # docs needs - docs_frozen = install_and_list('.[docs]') - dev_frozen - frozen - - # find the installed version for each package - versions = {} - for pv in ( - check_output([join(tmpdir, 'bin', 'pip'), 'freeze']) - .decode('utf-8') - .strip() - .split('\n') - ): - if 'file' in pv: - # skip ourself - continue - p, v = pv.split('==') - versions[p] = (v,) - - -# special handling for older python versions due to libraries dropping support -# early -versions['alabaster'] = ( - "0.7.16; python_version<'3.10'", - f"{versions['alabaster'][0]}; python_version>='3.10'", -) -versions['click'] = ( - "8.1.8; python_version<'3.10'", - f"{versions['click'][0]}; python_version>='3.10'", -) -versions['myst-parser'] = ( - "3.0.1; python_version<'3.10'", - f"{versions['myst-parser'][0]}; python_version>='3.10'", -) -versions['Sphinx'] = ( - "7.4.7; python_version=='3.9'", - "8.1.3; python_version=='3.10'", - f"{versions['Sphinx'][0]}; python_version>='3.11'", -) -versions['mdit-py-plugins'] = ( - "0.4.2; python_version=='3.9'", - f"{versions['mdit-py-plugins'][0]}; python_version>='3.10'", -) - - -def write_packages(fh, packages, header, prefix=''): - fh.write(header) - for p in sorted(packages): - for v in versions[p]: - fh.write(prefix) - fh.write(p) - fh.write('==') - fh.write(v) - fh.write('\n') - - -write_packages(stdout, frozen, header='base\n', prefix=' ') -write_packages(stdout, dev_frozen, header='dev\n', prefix=' ') -write_packages(stdout, docs_frozen, header='docs\n', prefix=' ') - -header = f'# DO NOT EDIT THIS FILE DIRECTLY - use {argv[0]} to update\n' - -with open('requirements.txt', 'w') as fh: - write_packages(fh, frozen, header=header) - -with open('requirements-dev.txt', 'w') as fh: - write_packages(fh, dev_frozen, header=header) - -with open('requirements-docs.txt', 'w') as fh: - write_packages(fh, docs_frozen, header=header) +proviso --header="# DO NOT EDIT THIS FILE DIRECTLY - use ./script/update-requirements" "$@" diff --git a/setup.py b/setup.py index 8c9edde..f1c07c2 100644 --- a/setup.py +++ b/setup.py @@ -65,6 +65,7 @@ setup( 'build>=0.7.0', 'changelet', 'isort>=5.11.5', + 'proviso', 'pycountry>=19.8.18', 'pycountry-convert>=0.7.2', 'pyflakes>=2.2.0', From abd63797af0222954bc0e3440f001d9aa91a2797 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Mon, 17 Nov 2025 09:10:35 -0800 Subject: [PATCH 4/5] Updated requirements.txt --- requirements.txt | 91 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8c0476e..a98d034 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,93 @@ -# DO NOT EDIT THIS FILE DIRECTLY - use ./script/update-requirements to update -PyYAML==6.0.3 +# DO NOT EDIT THIS FILE DIRECTLY - use ./script/update-requirements +alabaster==1.0.0 +anyio==4.11.0 +babel==2.17.0 +backports-tarfile==1.2.0; python_version=='3.10' or python_version=='3.11' +black==24.10.0 +build==1.3.0 +certifi==2025.11.12 +cffi==2.0.0 +changelet==0.3.0 +charset-normalizer==3.4.4 +click==8.3.1 +coverage==7.11.3 +cryptography==46.0.3 dnspython==2.8.0 +docutils==0.21.2 +exceptiongroup==1.3.0; python_version=='3.10' fqdn==1.5.1 -idna==3.10 +h11==0.16.0 +httpcore==1.0.9 +httpx==0.28.1 +id==1.5.0 +idna==3.11 +imagesize==1.4.1 +importlib-metadata==8.7.0; python_version=='3.10' or python_version=='3.11' +iniconfig==2.3.0 +isort==7.0.0 +jaraco-classes==3.4.0 +jaraco-context==6.0.1 +jaraco-functools==4.3.0 +jeepney==0.9.0 +jinja2==3.1.6 +keyring==25.7.0 +markdown-it-py==3.0.0 +markupsafe==3.0.3 +mdit-py-plugins==0.5.0 +mdurl==0.1.2 +more-itertools==10.8.0 +mypy-extensions==1.1.0 +myst-parser==4.0.1 natsort==8.4.0 +nh3==0.3.2 +packaging==25.0 +pathspec==0.12.1 +platformdirs==4.5.0 +pluggy==1.6.0 +pprintpp==0.4.0 +proviso==0.0.1 +pycountry==24.6.1 +pycountry-convert==0.7.2 +pycparser==2.23 +pyflakes==3.4.0 +pygments==2.19.2 +pyproject-hooks==1.2.0 +pytest==9.0.1 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytest-network==0.0.1 python-dateutil==2.9.0.post0 +pyyaml==6.0.3 +readme-renderer==44.0 +repoze-lru==0.7 +requests==2.32.5 +requests-toolbelt==1.0.0 +resolvelib==1.2.1 +rfc3986==2.0.0 +rich==14.2.0 +roman-numerals-py==3.1.0; python_version=='3.11' or python_version=='3.12' or python_version=='3.13' or python_version=='3.14' +secretstorage==3.4.1 +semver==3.0.4 +setuptools==80.9.0 six==1.17.0 +sniffio==1.3.1 +snowballstemmer==3.0.1 +sphinx==8.1.3; python_version=='3.10' +sphinx==8.2.3; python_version=='3.11' or python_version=='3.12' or python_version=='3.13' or python_version=='3.14' +sphinx-copybutton==0.5.2 +sphinx-rtd-theme==3.0.2 +sphinxcontrib-applehelp==2.0.0 +sphinxcontrib-devhelp==2.0.0 +sphinxcontrib-htmlhelp==2.1.0 +sphinxcontrib-jquery==4.1 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-mermaid==1.0.0 +sphinxcontrib-qthelp==2.0.0 +sphinxcontrib-serializinghtml==2.0.0 +tomli==2.3.0; python_version=='3.10' +twine==6.2.0 +typing-extensions==4.15.0; python_version=='3.10' or python_version=='3.11' or python_version=='3.12' +unearth==0.18.1 +urllib3==2.5.0 +wheel==0.45.1 +zipp==3.23.0; python_version=='3.10' or python_version=='3.11' From 3ca8e048fc33eb37357db6a5bcdf02951a7f58c1 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Mon, 17 Nov 2025 09:18:55 -0800 Subject: [PATCH 5/5] Remove a couple more references to requirements-dev/doc --- .github/workflows/slash_commands.yml | 2 +- .readthedocs.yaml | 6 ++---- MANIFEST.in | 1 - 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/slash_commands.yml b/.github/workflows/slash_commands.yml index 83aabad..0e14bf2 100644 --- a/.github/workflows/slash_commands.yml +++ b/.github/workflows/slash_commands.yml @@ -48,7 +48,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -r requirements.txt -r requirements-dev.txt + pip install -r requirements.txt # add the changelog entry - name: Changelog Create diff --git a/.readthedocs.yaml b/.readthedocs.yaml index e3e9a21..0e58e68 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -13,7 +13,5 @@ formats: - pdf python: - install: - - requirements: requirements.txt - - requirements: requirements-dev.txt - - requirements: requirements-docs.txt + install: + - requirements: requirements.txt diff --git a/MANIFEST.in b/MANIFEST.in index 9e3dc38..524640f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,7 +3,6 @@ include CODE_OF_CONDUCT.md include CONTRIBUTING.md include LICENSE include README.md -include requirements-dev.txt include requirements.txt include script/* recursive-include docs *.png *.md