Defer the box-tree imports in cli/impl so the modules import from the wheel - #253
Merged
Conversation
danielrmerskine
force-pushed
the
de/impl-lazy-box-imports
branch
from
August 13, 2026 19:44
ecc8b13 to
21354ba
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.
Closes #241.
What was wrong
cli/impl/box_config.py:13andcli/impl/power/enable_disable.py:6importedlager.*atmodule scope. That package lives under
box/and is not shipped in thelager-cliwheel, soboth modules raised
ModuleNotFoundErroron any clean pip install. They worked only wherebox/happened to be onsys.path— dev checkouts via the test PYTHONPATH convention, andboxes.
Why this is a small fix and not a code move
Worth stating up front, because the issue offered "move the needed code under
cli/" as anoption and that would have been a mistake:
cli/core/net_helpers.py:683-698,cli/commands/box/config.py:84-102). The CLI never imports them — the coupling is a filenamestring passed to
get_impl_path(), not an import.get_impl_path()resolves them from theinstalled package on disk. Excluding them would break
lager logicandlager box-configona pip install.
Netundercli/would have dragged 100 modules, ~28.6k lines and 18 hardware SDKs into a CLI wheelwhose
install_requiresis 16 pure-Python packages.The fix is the pattern already in the tree two directories over:
cli/impl/measurement/scope.pyimports
Net/NetTypeinsideget_rigol_net()andget_source_net()rather than at modulescope. Both defective files now do the same.
box_config.py'ssys.path.insert('/app/lager')moved inside
__main__alongside its import, since it is meaningless off-box.The import path is deliberately unchanged (
from lager.nets.net import Net, NetType, notfrom lager import ...), so on-box resolution is byte-for-byte what it was. Only the timingmoved.
The regression test matters more than the fix
The fix itself is six lines moved. What makes it stick is
test_impl_host_importable.py, whichimports every
cli/implmodule — discovered from disk, not hardcoded — in a subprocess withbox/stripped fromsys.pathand ameta_pathfinder that raises on anylagerimport.That subprocess isolation is the point. The unit suites run with
box/onPYTHONPATH(
unit-tests.yml), which is exactly what hid this defect from every existing test. A same-processtest would have passed regardless of whether the bug was present.
Fault-injected to confirm it is not tautological: restoring the module-level import makes it fail
with
cli.impl.power.enable_disable does not import without the box tree, and the failure messagepoints at the scope.py precedent. Restoring the fix makes it pass.
Also in here
Two comments in
box/lager/http_handlers/usb_scanner.pyinstructed the reader to mirror changesinto
cli/impl/query_instruments.py, which was deleted in the :9000 migration. Following them wasimpossible. One is dropped, the other now records that this is the only remaining copy. The
neighbouring "Extracted from…" / "previously the … script executed over :5000" comments are
untouched — those are accurate history rather than stale instructions.
Verified
twine check(both artifacts PASSED) → wheel into afresh venv → import walk. 177 modules walked, 31 failures, 0 unexpected. All 31 are the
vendored-elftools entries that Remove the vendored elftools tree and the unreachable GDB source-archive path #249 removes; the two
cli.implfailures are gone.still failed, or had the entries been left behind after the fix, the gate would have failed.
unit (cli): 1232 passed, 2 xfailed (was 1224 + 2; +8 from the new test).tools/check_coverage_counts.pypasses, including the per-file inventory row.unit (box)reports as platform-gated here (7 tests need
/procandflock(1); this is macOS) — untouchedby this change and checked on Linux CI.
ruff --select E9,F63,F7,F82clean.Note for whoever merges second
This and #249 both edit
tools/packaging_import_baseline.txt, and this, #249 and #251 all add a## [Unreleased]CHANGELOG section. The baseline hunks are disjoint (elftools block vscli.implblock) and should auto-merge; the CHANGELOG sections will want a trivial manual merge into one.
Once both this and #249 land, the baseline holds no functional entries at all — only the
cli.setupnote explaining why that one is deliberately unlisted.