Surfaced by #777's cross-review, which tried to add a visible HAS_MYPY gate to tests/vendor/test_vendor_reg_apptype_generator_unit.py and could not.
mypy has no MODULE_PROVIDERS entry. Confirmed on origin/main (110381b63): grep -n "'mypy'" tests/_dependency_gates.py returns nothing. It ships in Pipfile [dev-packages] and in no pyproject.toml extra, so nothing in the provider table describes it.
Consequence: a skipUnless-shaped gate on mypy cannot be added at all. Measured — adding HAS_MYPY = importlib.util.find_spec('mypy') is not None plus @unittest.skipUnless to that test file alone, touching nothing else, makes python -m unittest tests.test_tier_guard.DependencyGateCoverageTests report Ran 9 tests ... FAILED (failures=2, errors=4). Root cause is a bare KeyError: 'mypy' at tests/_dependency_gates.py:682:
providers = MODULE_PROVIDERS[module.partition('.')[0]]
unconditional, and upstream of any DEPENDENCY_GATE_EXCLUSIONS filtering — so no in-test exclusion rescues it. The same bare subscript appears at :635 and :1315.
Two defects, not one.
- The missing entry.
mypy needs a MODULE_PROVIDERS entry, and probably a DEPENDENCY_GATE_EXCLUSIONS one too, since mypy is a lint-tier tool and gating a test on it should not demand it be added to a pytest install line.
- The diagnostic. A missing entry surfaces as an opaque
KeyError from a table lookup, with nothing naming the fix. _gates_of (:1008-1021) walks only node.decorator_list for skipUnless calls, so the guard's whole purpose is to audit gates — and the first thing it does with an unrecognised one is crash. It should say which module is unknown and that a MODULE_PROVIDERS entry is what it wants. Compare :1239-1241, which already produces exactly that kind of message for a related case.
Why this matters beyond mypy. #777 was pushed into the inline try/except ImportError: self.skipTest(...) form instead, which works but is invisible to the guard by construction — it is not a decorator, so _gates_of never sees it. That is the "dark test" hazard #745 named and #766 records another instance of: the guard can only audit the gate shape that this table makes possible. Every tool in [dev-packages] but no extra has the same hole.
Blocked on #774, which owns tests/_dependency_gates.py (head 1b63e9899, worker live). Checkable blocker: #774 merged.
Surfaced by #777's cross-review, which tried to add a visible
HAS_MYPYgate totests/vendor/test_vendor_reg_apptype_generator_unit.pyand could not.mypyhas noMODULE_PROVIDERSentry. Confirmed onorigin/main(110381b63):grep -n "'mypy'" tests/_dependency_gates.pyreturns nothing. It ships inPipfile [dev-packages]and in nopyproject.tomlextra, so nothing in the provider table describes it.Consequence: a
skipUnless-shaped gate on mypy cannot be added at all. Measured — addingHAS_MYPY = importlib.util.find_spec('mypy') is not Noneplus@unittest.skipUnlessto that test file alone, touching nothing else, makespython -m unittest tests.test_tier_guard.DependencyGateCoverageTestsreportRan 9 tests ... FAILED (failures=2, errors=4). Root cause is a bareKeyError: 'mypy'attests/_dependency_gates.py:682:unconditional, and upstream of any
DEPENDENCY_GATE_EXCLUSIONSfiltering — so no in-test exclusion rescues it. The same bare subscript appears at:635and:1315.Two defects, not one.
mypyneeds aMODULE_PROVIDERSentry, and probably aDEPENDENCY_GATE_EXCLUSIONSone too, sincemypyis a lint-tier tool and gating a test on it should not demand it be added to a pytest install line.KeyErrorfrom a table lookup, with nothing naming the fix._gates_of(:1008-1021) walks onlynode.decorator_listforskipUnlesscalls, so the guard's whole purpose is to audit gates — and the first thing it does with an unrecognised one is crash. It should say which module is unknown and that aMODULE_PROVIDERSentry is what it wants. Compare:1239-1241, which already produces exactly that kind of message for a related case.Why this matters beyond mypy. #777 was pushed into the inline
try/except ImportError: self.skipTest(...)form instead, which works but is invisible to the guard by construction — it is not a decorator, so_gates_ofnever sees it. That is the "dark test" hazard #745 named and #766 records another instance of: the guard can only audit the gate shape that this table makes possible. Every tool in[dev-packages]but no extra has the same hole.Blocked on #774, which owns
tests/_dependency_gates.py(head1b63e9899, worker live). Checkable blocker: #774 merged.