Repository navigation
Support Python 3.10 through 3.14, and publish to PyPI on release - #236
Merged
Merged
Conversation
Barbara could not be installed on Python 3.12+ at all, which blocked setting up projects that depend on it for env configuration. Three separate blockers: - `from typing.re import Pattern` in variables.py. The `typing.re` namespace was removed in 3.12; use `re.Pattern` directly. - `pyyaml = "==5.*"` resolved to 5.4.1, which has no 3.12+ wheels and whose sdist fails to build against Cython 3. Widened to allow 6.x and re-locked, since `poetry lock --no-update` preserved the broken pin. - `poetry-version` was a runtime dependency used only to supply `barb --version`. It works by parsing pyproject.toml, which is absent from an installed wheel, so it was already unreliable. Replaced with importlib.metadata and dropped the dependency. Also widened click to allow 8.x, un-pinned the dev dependencies from their majors, and fixed the build backend: `poetry.masonry.api` is no longer provided by current poetry-core. Dropped 3.8 and 3.9, both past PSF end-of-life, and extended the CI matrix to 3.14. Poetry in CI moves to 1.8.3 to match the lockfile generator. flake8 and black hooks are bumped because flake8 6.0.0 crashes on 3.12+ (`module 'ast' has no attribute 'Str'`) and black 23.1.0 rejects py312 and later as target versions.
GitCommitVariable.generate() caught CalledProcessError, which covers running outside a repository, but not FileNotFoundError from the git binary being absent entirely. That surfaced as an unhandled traceback in the Docker image, and would do the same on any host without git. Catch OSError as well and cover both fallback paths with tests.
The in-progress version on this branch could not build: - `curl | python -` to install poetry, but curl is not present in python:*-slim, so the layer failed outright. - DIST_DIR was referenced in ENV without being re-declared as an ARG after FROM, so PYTHONPATH resolved against an empty string. - Poetry was installed twice, once via pip and once via the installer. - The cache mount targeted POETRY_HOME, mounting over the poetry install itself. - `poetry install --no-dev` is deprecated in poetry 1.8. - ENTRYPOINT was commented out, so the image did nothing when run. Replaced with a two-stage build: the builder produces a wheel, the runtime installs it and keeps only the result. git is installed in the runtime stage because the @@GIT_COMMIT@@ template variable shells out to it. Verified: builds clean, `barb --version` and `--help` work, and generating an env-file against a mounted repository resolves real commit hashes for both @@GIT_COMMIT:7@@ and @@GIT_COMMIT:40@@.
Adds a release-triggered workflow that builds the wheel and sdist and uploads them to PyPI. Authentication uses PyPI Trusted Publishing, so there is no long-lived API token stored as a repository secret and nothing to rotate; the job exchanges a short-lived OIDC token instead, which is why the publish job requests `id-token: write`. Publishing is split into a separate job bound to a `pypi` environment, so release approval and the ability to mint the OIDC token can be gated there rather than being available to the build job. The build job refuses to publish when the release tag disagrees with the version in pyproject.toml, so a mistagged release fails loudly instead of uploading a surprise version. Also bumps the action versions in the existing workflows. setup-python v2 cannot reliably provision 3.13 or 3.14, and actionlint reports the v2 actions as too old to run on current runners, both of which would undermine the matrix this branch just widened.
mverteuil
force-pushed
the
modernize-python-support
branch
from
August 11, 2026 18:29
7ea8b0e to
f4e4eea
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Barbara could not be installed on Python 3.12 or newer at all, which blocks anyone using it to manage env configuration on a current interpreter. There is no workaround available on the consuming side — the package itself needed fixing.
What was wrong
Three independent blockers, not one:
from typing.re import Patterninbarbara/variables.py. Thetyping.renamespace was removed in 3.12. This is the error people hit first, but fixing it alone is not enough.pyyamlresolved to 5.4.1, which publishes no 3.12+ wheels and whose sdist fails to build against Cython 3 ('build_ext' object has no attribute 'cython_sources'). The install dies here even with the import fixed. Master's widened>=5,<7range now permits 6.x, but the lockfile still pinned 5.4.1.poetry-versionwas a runtime dependency, used only to supplybarb --version. It works by parsingpyproject.toml, which is not present in an installed wheel, so it was already unreliable regardless of Python version.Also fixed along the way: the build backend was
poetry.masonry.api, which current poetry-core no longer provides.Changes
Python support
re.Patterninstead oftyping.re.Pattern.barb --versionnow readsimportlib.metadata;poetry-versiondependency dropped.clickto allow 8.x andpython-dotenvto allow 1.x. Dev dependencies un-pinned from their majors, keeping the floors Dependabot established.poetry lock --no-updatewas insufficient — it preserved the broken pyyaml 5.4.1 pin.module 'ast' has no attribute 'Str') and black 23.1.0 → 25.9.0 (23.1 rejectspy312and later as target versions). The black bump reformats nothing.setup-python@v2cannot reliably provision 3.13 or 3.14, and actionlint reports the v2 actions as too old to run on current runners — both would have undermined the widened matrix.PyPI publishing
New
publish.yml, triggered when a GitHub Release is published. It builds the wheel and sdist and uploads them using PyPI Trusted Publishing, so there is no long-lived API token stored as a repository secret and nothing to rotate — the job exchanges a short-lived OIDC token instead. Publishing is a separate job bound to apypienvironment so approval can be gated there, and the build job refuses to publish when the release tag disagrees with the version inpyproject.toml.Two fixes beyond the original scope
A real bug in
GitCommitVariable.generate(). It caughtCalledProcessError, which covers running outside a repository, but notFileNotFoundErrorfrom thegitbinary being missing entirely. That is an unhandled traceback on any host without git. Now catchesOSErrortoo, with tests for both fallback paths.The Dockerfile could not build. It used
curl(absent frompython:*-slim), referencedDIST_DIRinENVwithout re-declaring it as anARGafterFROM, installed poetry twice, mounted a cache over the poetry install, used the deprecated--no-dev, and hadENTRYPOINTcommented out. Replaced with a two-stage build that produces a wheel and installs it into a clean runtime, withgitpresent so@@GIT_COMMIT@@works.Verification
barb --versionand--helpwork;barb -zagainstexamples/env-local.ymlproduces a correct env-file.@@GIT_COMMIT:7@@and@@GIT_COMMIT:40@@.publish.ymlpasses actionlint and yamllint; the tag guard was exercised locally against matching,v-prefixed and mismatched tags.Before the first release
Trusted Publishing needs one-time setup that cannot be done from this repo. Until both steps are done, the publish workflow will fail at the upload step.
barbaraproject, go to Publishing and add a GitHub publisher: ownermathsucks, repositorybarbara, workflow filenamepublish.yml, environmentpypi.pypi. Add a required reviewer if you want releases to pause for approval.Then publishing a GitHub Release tagged
v2.4.0(or2.4.0) ships it. Nothing needs to go into repository secrets.