fix(release): resolve an interpreter that has tomllib - #159
Merged
Conversation
`./scripts/release.sh prepare minor` fails before doing anything:
ModuleNotFoundError: No module named 'tomllib'
tomllib is stdlib only from 3.11, and this script hardcoded `python3` in every
helper -- get_version, get_pkg_name, set_version, bump_version, the changelog
update, and the publish-time changelog check. `python3` carries no version
guarantee, and this package's own requires-python is >=3.10, so the release
script could not run on the oldest Python the package claims to support.
No workflow runs this script; only a human cutting a release does, which is why
it went unnoticed. The symptom names a missing module, which reads as a broken
checkout rather than a too-old interpreter.
Resolved lazily inside cmd_prepare and cmd_publish -- not at load time, so the
commands that never touch Python (`--help`, no-args, unknown command) keep
working on a machine without a usable interpreter. Otherwise the message telling
you which interpreter you need is itself gated on having it.
The `uv` fallback is justified here because `prepare` already shells out to
`uv lock` when a uv.lock is present, so a machine able to cut a release already
has uv. Noted in the comment that CI installs with pip, so this concerns the
local release path only.
Verified as bash runs it:
PATH=/usr/bin:/bin ./scripts/release.sh --help -> prints usage
PATH=/usr/bin:/bin ./scripts/release.sh prepare minor -> error: ... python3 is Python 3.9.6
with uv available -> pkg=hotdata, minor bump 0.8.0 -> 0.9.0
No change to what a release does; only which interpreter runs it.
Ported from hotdata-dev/sdk-python-framework#58 and #60, where the script was
byte-identical. hotdata-marimo carries the same pattern and is untouched here.
anoop-narang
requested review from
rohan-hotdata
and removed request for
a team
August 11, 2026 08:44
There was a problem hiding this comment.
Correctness checks I walked through:
- Every
$PY_BINconsumer (get_version,get_pkg_name,set_version,bump_version,update_changelog, the publish-time changelog check) is only reachable fromcmd_prepare/cmd_publish, so the deferred resolution covers all of them and the empty default is genuinely unreachable. dieinside$(resolve_python)exits the subshell, but the assignment inherits status 1 andset -eis in force at that call site (acasebranch, not a condition), so the script aborts with the message rather than continuing with an emptyPY_BIN.--no-projectmatters on the uv path:set_versionrewritespyproject.toml, and uv must not try to resolve the project around it. uv's own progress output goes to stderr, so the$(get_version)captures stay clean.scripts/update_changelog.pyis pure stdlib and doesn't need 3.11, so routing it through$PY_BINis consistency rather than necessity — no behavior change there.scripts/publish-workflow.sh:41runs the sameimport tomllibin CI but undersetup-pythonpinned to 3.12, so the CI publish path is unaffected by this class of bug.
I did not execute the script; the verification runs in the description are the author's. Two non-blocking notes inline.
Resolution ran before the bump-kind check, so `prepare` with no argument died with the interpreter error instead of printing usage -- contradicting the comment above it, which is specifically about keeping the paths that need no interpreter working. Moved below the usage and `need gh` checks; nothing between them uses $PY_BIN. Same reordering in cmd_publish, so a missing `gh` reports itself rather than being pre-empted. And `--python 3.12` was an exact request: on a machine whose uv-visible interpreter is 3.11 or 3.13 it downloads a managed 3.12 mid-release, and fails altogether under UV_PYTHON_DOWNLOADS=never. Now `>=3.11`, which is the real requirement. Verified the unquoted expansion is not a redirect -- it reaches uv as a literal argument and no `=3.11` file appears -- and that uv then reuses the interpreter already present. prepare (no args) -> usage + "missing bump kind or explicit version" resolves to -> uv run --no-project --python >=3.11 python pkg=hotdata, minor bump -> 0.9.0
There was a problem hiding this comment.
Prior nits addressed. Interpreter resolution now sits after the usage/need gh checks in both commands, and the >=3.11 request avoids pinning a download mid-release. update_changelog.py is stdlib-only, so --no-project is fine for the one non-heredoc call site.
anoop-narang
added a commit
to hotdata-dev/sdk-python-framework
that referenced
this pull request
Aug 11, 2026
Both found in review of the same change ported to sdk-python (hotdata-dev/sdk-python#159), and both apply here because the script is the same. Resolution ran before the bump-kind check, so `prepare` with no argument died with the interpreter error instead of printing usage -- contradicting the comment right above it, which exists to keep the no-interpreter paths working. Moved below the usage and `need gh` checks; nothing between them uses $PY_BIN. Same in cmd_publish, so a missing `gh` reports itself. And `--python 3.12` was an exact request: on a machine whose uv-visible interpreter is 3.11 or 3.13 it downloads a managed 3.12 mid-release, and fails altogether under UV_PYTHON_DOWNLOADS=never. Now `>=3.11`. Verified the unquoted expansion is not a redirect -- uv receives it literally and no `=3.11` file appears -- and that uv reuses the interpreter already present.
anoop-narang
added a commit
to hotdata-dev/sdk-python-framework
that referenced
this pull request
Aug 11, 2026
…#60) * docs(release): justify the interpreter check from the repo, not an OS The comment rested on `python3` being 3.9 on macOS, which is where the failure showed up rather than why the code was wrong -- and a reader on another platform would take it as not applying to them. The repo-intrinsic version: this package declares requires-python >=3.10 and tomllib is stdlib only from 3.11, so the release script could not run on the oldest Python the package itself claims to support, on any OS. Also records why it stayed hidden -- CI installs 3.12 through uv, so only a human cutting a release ever ran into it. Comment only; no behaviour change. * docs(release): CI does not run this script at all "CI never sees this because it installs 3.12" was true but named the wrong shield: no workflow invokes release.sh, so the pinned interpreter is not what protects CI from this. Confirmed -- grep for release.sh across .github/workflows returns nothing. Since the point of the previous rewrite was to ground the comment in facts that stay true, this is the more durable sentence. Comment only. * fix(release): resolve after the argument checks, and ask uv for a range Both found in review of the same change ported to sdk-python (hotdata-dev/sdk-python#159), and both apply here because the script is the same. Resolution ran before the bump-kind check, so `prepare` with no argument died with the interpreter error instead of printing usage -- contradicting the comment right above it, which exists to keep the no-interpreter paths working. Moved below the usage and `need gh` checks; nothing between them uses $PY_BIN. Same in cmd_publish, so a missing `gh` reports itself. And `--python 3.12` was an exact request: on a machine whose uv-visible interpreter is 3.11 or 3.13 it downloads a managed 3.12 mid-release, and fails altogether under UV_PYTHON_DOWNLOADS=never. Now `>=3.11`. Verified the unquoted expansion is not a redirect -- uv receives it literally and no `=3.11` file appears -- and that uv reuses the interpreter already present.
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.
./scripts/release.sh prepare minorfails before doing anything:tomllib is stdlib only from 3.11, and this script hardcoded
python3in everyhelper -- get_version, get_pkg_name, set_version, bump_version, the changelog
update, and the publish-time changelog check.
python3carries no versionguarantee, and this package's own requires-python is >=3.10, so the release
script could not run on the oldest Python the package claims to support.
No workflow runs this script; only a human cutting a release does, which is why
it went unnoticed. The symptom names a missing module, which reads as a broken
checkout rather than a too-old interpreter.
Resolved lazily inside cmd_prepare and cmd_publish -- not at load time, so the
commands that never touch Python (
--help, no-args, unknown command) keepworking on a machine without a usable interpreter. Otherwise the message telling
you which interpreter you need is itself gated on having it.
The
uvfallback is justified here becausepreparealready shells out touv lockwhen a uv.lock is present, so a machine able to cut a release alreadyhas uv. Noted in the comment that CI installs with pip, so this concerns the
local release path only.
Verified as bash runs it:
No change to what a release does; only which interpreter runs it.
Ported from hotdata-dev/sdk-python-framework#58 and #60, where the script was
byte-identical. hotdata-marimo carries the same pattern and is untouched here.