test: gate test_isort_clean.py visibly and put isort on the test extra - #786
Conversation
tests/project/test_isort_clean.py gated on isort with a try/except ImportError inside setUpClass, which tests/_dependency_gates.py cannot see -- _gates_of() walks a decorator list and never a function body -- and isort was in no pyproject.toml extra. So it reported OK (skipped=1) on every CI leg and the dependency-gate guard could not tell (#766, the third instance of the hazard #745 exists to stop). * replace the setUpClass skip with a module-level HAS_ISORT and a class-level @unittest.skipUnless, so gated_scopes() counts the gate * add MODULE_PROVIDERS['isort'] so the flag resolves instead of raising * add isort to pyproject.toml's test extra, closing the gap rather than excluding it: lint.yml installs no isort and its own header says so, so unlike mypy's gate (#779) there is no existing check to defer to * pin the outcome in tests/test_tier_guard.py, with a doctored_pyproject helper and a falsifiability test that drops the requirement on a copy and requires the three gaps back No unit-tests.yml change needed: every pytest job's install line already builds on .[test]. dependency_gate_gaps() is 18 before and after, gated_scopes() 250 -> 251, and test_tier_guard.py goes 100 passed / 524 subtests to 102 / 529 under both pytest and unittest.
|
Cross-review at The central asymmetry holds, and the reviewer sharpened why. One correction to the PR's reasoning, which I verified. The body rejects a new All four gap states reproduced exactly. A ( The anti-rot claim was tested by injection, not assumed: adding a fake Class-level The second new test is not a tautology, which I had asked about. Once its fixture assertion passes it goes on to assert real behaviour — Counts reproduced under both runners: 102 passed / 529 subtests, |
#812) `make isort` runs its four recipe lines through `pipenv run`, which resolves against `Pipfile`'s `[dev-packages]` -- and isort was not listed there, next to the `mypy` and `pylint` it sits beside in the Makefile. So a `pipenv install --dev` environment could not run the recipe, and #786's fix put isort on the `test` extra only, leaving the two declarations disagreeing about a tool the Makefile needs. - Pipfile: add `isort = "*"` between `bandit` and `mypy`, bare like its neighbours. Additive only -- the `pyproject.toml` extra serves consumers of the published package, `Pipfile` this repo's dev environment. - tests/project/test_isort_clean.py: its docstring recorded the gap as still open ("isort remains absent from Pipfile"), which this change makes stale. Audited every executable the Makefile invokes against `[dev-packages]`: isort was the only omission. build, twine, pytest, coverage, sphinx, sphinx-autobuild, vermin, pylint, mypy and bandit are all present. Closes #810
make pylint,make mypy,make isort)make testpasses, and a test case covers the changedocs/source/changelog/and regeneratedCHANGELOG.md, if the change is user-visible — N/A — changelog centralised in docs(changelog): shared 1.5.0 changelog — long-lived, merges last (#610, #616, #617, #618, #620) #657What is the purpose of your pull request?
fix— corrects a defectfeat— adds a featureperf— changes performance, not behaviourrefactor— changes neither behaviour nor performancetest— tests onlydocs— documentation onlyci— workflows or build toolingchore— anything elseDescription of your pull request and other information
Closes #766.
tests/project/test_isort_clean.pyskipped on every CI leg, in thetry/except ImportErrorinsidesetUpClassshape_gates_of()cannot see — the thirdinstance of the hazard #745 exists to stop. Fixed with a module-level
HAS_ISORTplus aclass-level
@unittest.skipUnless,MODULE_PROVIDERS['isort'], andisortin thetestextra.
Install line, not an exclusion — and
isortis not inlint.yml's install line. Thatline is
pip install -U vermin pylint mypy bandit(lint.yml:187), and the workflow's ownheader records the omission as deliberate: isort appears only in
cron-vendor.yml, as aformatter that rewrites the generated constants, not as a check. So #779's argument for
declining mypy — a pytest leg would be a second copy of a check
lint.ymlalready runs(
make mypy RUN=,lint.yml:223) — has no isort counterpart. Excluding it would have leftmake isort's verdict, and the target-resolving globs wrong three times over (#757, #765,#767), verified nowhere. It is cheap: pure-Python wheel, all four lines measure ~1.5s, and
the check passes on
0419c1c97today.unit-tests.ymlneeded no edit — every pytest job'sinstall line already builds on
.[test].Gap report.
dependency_gate_gaps()is 18 before and 18 after, which is the rightoutcome but needs the middle state to be meaningful: gate +
MODULE_PROVIDERSand notest-extra entry gives 21 — three newHAS_ISORTgaps ontest,engine-testsandgate, exactly what #766 predicted a visible gate would do. Adding isort to the extra takesit back to 18 with the gate now counted:
gated_scopes()250 → 251, so the guard sees thegate and finds nothing to report, rather than not seeing it.
HAS_ISORTtherefore gets noDEPENDENCY_GATE_EXCLUSIONSentry.Tests.
test_tier_guard.py100 passed / 524 subtests → 102 / 529, identical underpytestandpython -m unittest. The +5 subtests:test_every_gated_flag_is_classified250→251 (one per gate),
test_the_suite_scan_only_looks_at_modules_pytest_collects115→116(one per gate-holding module), and 3 in the new coverage test. Both new tests fail against
0419c1c97.tests/project/test_isort_clean.pynow runs — 1 passed / 4 subtests, wasOK (skipped=1). Nopcapkit/file is touched, sopcapkitline coverage is unchanged byconstruction; what this raises is test execution.