fix: restore lineqlist2str, which CNApy imports at startup - #76
Merged
Conversation
lineqlist2str was removed in 53f98ad as dead code. It had no caller in this repository or its tests, which is what I checked, and that was the wrong test: CNApy imports it in gui_elements/strain_design_dialog.py, and main_window.py imports that module at startup, so the removal turns CNApy into an ImportError on launch rather than a broken corner of one dialog. 1.19 is already published to PyPI and to the cnapy channel, and CNApy requires straindesign>=1.18 with cnapy as its highest-priority channel, so any fresh install resolves the broken version. This restores the function verbatim; it was a removal and not a rename, distinct from lineqlist2mat and from linexprdict2str, which it calls. Of the nine names 1.19 removed, this is the only one CNApy uses: modules_coeff2float, remove_redundant_bounds, lineq2mat, get_rids, the nullspace alias, compression_backend, compress_model_efmtool and suppressed_reactions are all unused there. CNApy's efmtool and jpype imports come from efmtool_link, its own dependency, and are unaffected. test_13_public_api.py pins the names CNApy imports. Grepping this repository cannot see a downstream consumer, so the check has to be written down rather than rediscovered. Also quote the version in conda-recipe/meta.yaml. Rendered unquoted, a version like 1.19 is YAML for a floating-point number; conda-build tolerates it but the conda-forge linter rejects it, and the two recipes should not disagree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The hardcoded list of names CNApy imports goes stale the moment CNApy imports something new, and nothing in this repository can notice: a downstream consumer is invisible to grep here. So read CNApy instead of installing it. The test fetches its source, walks the AST for every `from straindesign ... import`, and asserts each name is still exported. Installing CNApy was the obvious alternative and is a bad trade: it depends on Qt and PyQtWebEngine, on cplex, which this matrix already cannot install on macOS or 3.13, and on jpype, which is the JVM binding removed in #72 and the reason those tests were Windows-only. That would drag all of it back into twenty jobs to test one import list. It is marked `downstream` and skipped unless --downstream is passed, following the existing --medium and --large convention, and the workflow passes the flag only on the quarterly schedule. It needs network and tracks a branch we do not control, so it reports drift rather than gating pull requests. The static list stays. It runs everywhere, offline and unconditionally, and it is the layer that would have blocked the removal in the first place. Verified against ffad74b, before the restore: the AST check fails there, as do both static guards. A test that cannot fail is decoration. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
The regression
lineqlist2strwas removed in 53f98ad (#72) as dead code. It had no caller in this repository or its tests — which is what I checked, and it was the wrong test.CNApy imports it, at startup:
Because
main_windowimports that module eagerly, this is an ImportError on CNApy launch, not a broken corner of one dialog.It is already shipped: 1.19 went to PyPI and the cnapy channel, and CNApy requires
straindesign>=1.18withcnapyas its highest-priority channel — so any fresh CNApy install resolves the broken version.The fix
Restored verbatim. This was a removal, not a rename: it is distinct from
lineqlist2mat(list → matrices) and fromlinexprdict2str(dict → string), which it calls internally and which still exists.Blast radius — only this one
All nine names removed in 1.19, checked against CNApy:
lineqlist2strmodules_coeff2float,remove_redundant_bounds,lineq2mat,get_ridsnullspacealias,compression_backend,compress_model_efmtool,suppressed_reactionsCNApy's
efmtool/jpypeimports come fromefmtool_link, its own dependency, and are unaffected by the efmtool removal.Regression guard
tests/test_13_public_api.pypins the names CNApy imports, plus a behavioural test oflineqlist2str. Grepping this repository cannot see a downstream consumer, so the check has to be written down rather than rediscovered. Verified it fails against currentmainand passes here.Also
Quote the version in
conda-recipe/meta.yaml. Rendered unquoted, a version like1.19is YAML for a floating-point number — conda-build tolerates it, but the conda-forge linter rejects it, and the two recipes shouldn't disagree.Verified for a 1.19.1 release
Simulated the full workflow at
1.19.1:update_version.py× 3 files1.19.1in pyproject, meta.yaml, conf.pypython -m buildtwine check dist/*conda render conda-recipe/1.19.1,lineqlist2strpresent and correct1.19 < 1.19.1✅No float-parsing issue: three-component versions are never float-parseable, and the recipe now quotes the value regardless.
🤖 Generated with Claude Code