Fix the CI conda cache, the Snakefile f-strings, and blastp calls that fail but exit zero - #108
Closed
mrubash1 wants to merge 3 commits into
Closed
Fix the CI conda cache, the Snakefile f-strings, and blastp calls that fail but exit zero#108mrubash1 wants to merge 3 commits into
mrubash1 wants to merge 3 commits into
Conversation
Two rules built an output path from an f-string that mixed an
interpolated value with an escaped snakemake wildcard:
f"{ANALYSIS_NAME}_aggregated_features_{{plotting_mode}}.html"
The doubled braces are there so that the f-string renders the literal
`{plotting_mode}` that snakemake needs as a wildcard. That is easy to
misread, and a formatter can silently change what it means: running
`make format` under Python 3.12 or later rewrites the doubled braces to
single ones, which turns the wildcard into an interpolation of a name
that does not exist. (Python 3.12 changed how f-strings are tokenized,
see PEP 701; the versions of snakefmt and black pinned here predate it.)
Concatenating a plain string avoids the escaping entirely, produces a
byte-identical path, and cannot be rewritten this way. Verified that the
DAG still resolves the same targets, with the wildcards expanding to
`..._aggregated_features_pca_umap.html` and
`..._P60709_distribution_analysis.svg` as before, and that
`snakefmt --check` now passes under both Python 3.9 (which CI uses) and
Python 3.12+, where it previously wanted to rewrite the file.
Note that the doubled braces elsewhere in the Snakefile are not affected:
they appear in a plain (non-f) string and in a shell block, neither of
which a formatter rewrites.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WLpJZQ4W4XsL9NUUjjsry9
The `restore-keys` never matched anything: they begin with "snakemake-conda-" while the key begins with "conda-". Correcting the prefix would be worse than removing them. A `restore-keys` match still leaves `cache-hit` false, so the env creation step runs regardless, and that step begins by deleting `.snakemake/conda`. Making the prefix match would therefore download a stale multi-gigabyte cache only to discard it -- strictly slower than the broken prefix that never matched anything. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WLpJZQ4W4XsL9NUUjjsry9
When the remote server refuses to queue a request, `blastp -remote` reports the error on
stderr, writes an empty results file, and still exits zero:
$ blastp -remote -db nr ... ; echo $?
Error: [blastp] bad_request: Could not queue request: DB operation failed.
0
`_run_blast_remote` printed that stderr but returned the zero exit code unchanged, so the
caller treated the failure as a success. The word-size backoff was therefore never
attempted -- which is the situation it exists for -- and the empty results file surfaced
later in `extract_blast_hits.py` as a misleading "no hits were returned".
Failure is now determined by `blast_call_failed`, which also treats an error on stderr as
a failure. An empty results file is deliberately not treated as a failure, because a query
that legitimately has no hits produces one too.
This affects the `remote` backend only; the `www` backend does not shell out to blastp.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WLpJZQ4W4XsL9NUUjjsry9
mrubash1
force-pushed
the
mr/ci-cache-and-smoke-test
branch
from
August 17, 2026 03:18
a884cd4 to
ee4f874
Compare
ahmedhosny
approved these changes
Aug 17, 2026
ahmedhosny
left a comment
Contributor
There was a problem hiding this comment.
Looks good. Three independent, well-justified fixes:
- Dropping the conda
restore-keysis correct: they never matched (snakemake-conda-vsconda-), and a working prefix would still download a stale cache only for the next step to delete.snakemake/conda. blast_call_failedtreatsblastp -remotestderrError:as a failure even when the process exits 0, which is what unblocks the word-size backoff. An empty results file is correctly not treated as failure. This only affects theremotebackend.- Building wildcard output paths without f-strings avoids PEP 701 rewriting the doubled braces under Python 3.12+.
I merged main into this work (conflicts with #107 in blast_utils.py / tests: kept both sides) and opened a follow-up from the resolved branch so it can land on current main.
Merged
3 tasks
Contributor
|
Thanks — this LGTM. After merging #107, this branch conflicted in Landing the resolved branch as #109 so it can merge onto current |
Contributor
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.
Four small, independent fixes. This replaces #101, which was cut down after #103 landed: the
analysis.ymlmatplotlib and setuptools pins are dropped because #103 took them verbatim, and thepython=3.9.16pins are dropped for the reason below.The conda env cache
restore-keysnever matchedThe key begins with
conda-while therestore-keysbegin withsnakemake-conda-, so they never matched anything.Correcting the prefix would be worse than removing them. A
restore-keysmatch still leavescache-hitfalse, so the env creation step runs regardless — and that step begins by deleting.snakemake/conda. Making the prefix match would therefore download a stale multi-gigabyte cache only to discard it: strictly slower than the broken prefix that never matched at all.blastpcalls that fail but exit zeroWhen the remote server refuses to queue a request,
blastp -remotereports the error on stderr, writes an empty results file, and still exits zero:_run_blast_remoteprinted that stderr but returned the zero exit code unchanged, so the caller treated the failure as a success. The word-size backoff was therefore never attempted — which is the situation it exists for — and the empty results file surfaced later inextract_blast_hits.pyas a misleading "no hits were returned".Failure is now determined by
blast_call_failed, which also treats an error on stderr as a failure. An empty results file is deliberately not treated as a failure, because a query that legitimately has no hits produces one too.This affects the
remotebackend only; thewwwbackend does not shell out toblastp.Build the wildcard output paths without f-strings
Nested braces inside an f-string (
f"{ANALYSIS_NAME}_{{plotting_mode}}.html") tokenise differently under PEP 701 on Python 3.12+, andsnakefmtthen rewrites the Snakefile incorrectly. Building the paths without f-strings avoids depending on the interpreter version that happens to run the linter.On the python pins, and the mamba pin, that are not here
The earlier version of this branch also added
python=3.9.16toanalysis.yml,plotting.ymlandpandas.yml, and pinnedmamba=1.4.2incartography_test.yml. Both are dropped, and the reason is worth recording because the first diagnosis was wrong.The python pins were initially suspected of causing a large regression in env creation time. They were not the cause. The mamba pin was. Pinning
mamba=1.4.2pullsconda 23.3.1andlibmamba 1.4.2into the outer test environment, and the workflow then runssnakemake --conda-frontend condaagainst that older conda and its classic solver. Measured on CI:mainanalysis.ymlcreationanalysis.ymlis byte-identical between the two, so the ~25x difference is entirely the solver that the outer environment supplies. The same pin was present on the earlier #101 and #102 branches and explains their env-creation failures too, which had been misattributed to the python pins.The mamba pin was also fixing a path CI does not use: it exists to make
--conda-frontend mambawork, and this workflow deliberately uses--conda-frontend conda. If that is worth solving it wants a different fix -- pinning conda rather than mamba -- and its own PR, with the timing above as the evidence.The python pins are dropped on their own merits rather than as suspects: CI is green on
mainwithout them, since #103's targeted matplotlib and setuptools pins address the actual import failure. If they are still wanted for drift prevention, that is a separate PR.With no
envs/change left in this branch, the conda cache key now matchesmain, so this PR restores the cache hit instead of forcing a full env creation.Testing
ruffandsnakefmtclean under CI's pinned versions on Python 3.9; unit tests pass, including four new ones covering the exit-zero case.