Some checks failed
CI / skinny-install (bcda) (push) Successful in 28s
CI / skinny-install (bib) (push) Successful in 32s
CI / skinny-install (bls) (push) Successful in 24s
CI / skinny-install (aco) (push) Successful in 49s
CI / lint-test (push) Successful in 1m18s
CI / skinny-install (api) (push) Successful in 26s
CI / skinny-install (aco) (pull_request) Successful in 44s
CI / skinny-install (api) (pull_request) Successful in 32s
CI / skinny-install (rex) (pull_request) Successful in 27s
Infra CI / zotero (push) Successful in 6s
Infra CI / mc (push) Successful in 7s
Infra CI / zotero (pull_request) Successful in 6s
CI / skinny-install (ccw) (push) Successful in 28s
CI / skinny-install (cli) (push) Successful in 31s
CI / skinny-install (cms) (push) Successful in 29s
CI / skinny-install (conf) (push) Successful in 27s
CI / skinny-install (opps) (push) Successful in 28s
CI / skinny-install (perf) (push) Successful in 35s
CI / skinny-install (pfs) (push) Successful in 29s
CI / skinny-install (rex) (push) Successful in 32s
CI / lint-test (pull_request) Successful in 1m12s
CI / skinny-install (bcda) (pull_request) Successful in 32s
CI / skinny-install (bls) (pull_request) Successful in 29s
CI / skinny-install (bib) (pull_request) Successful in 31s
CI / skinny-install (ccw) (pull_request) Successful in 25s
CI / skinny-install (cli) (pull_request) Successful in 32s
CI / skinny-install (cms) (pull_request) Successful in 26s
CI / skinny-install (conf) (pull_request) Successful in 26s
CI / skinny-install (opps) (pull_request) Successful in 27s
CI / skinny-install (perf) (pull_request) Successful in 30s
CI / skinny-install (pfs) (pull_request) Successful in 34s
Infra CI / docs (push) Failing after 10s
Infra CI / notebooks (push) Successful in 22s
Infra CI / api (push) Successful in 10s
Infra CI / notebooks (pull_request) Successful in 6s
Infra CI / docs (pull_request) Failing after 5s
Infra CI / api (pull_request) Successful in 5s
Infra CI / mc (pull_request) Successful in 7s
- README: add Testing section with semantic coverage architecture, pre-commit smart selection rules, hook steps, forcing full suite, running tests. Update module count (14), test count (12,291), and project layout to include sem, opps, perf. - sem/__init__.py: full module docstring with architecture diagram, layer descriptions, node identity format, and usage example. - sem/hooks.py: full docstring with file classification table, test selection rules, step order, env vars, post-commit, and setup.
93 lines
2.9 KiB
Python
93 lines
2.9 KiB
Python
"""Semantic coverage orchestration.
|
|
|
|
AST-based coverage tracking that attaches Ruff diagnostics, ty type
|
|
signals, and runtime coverage data to semantic nodes (functions, branches,
|
|
exception handlers) rather than raw line numbers.
|
|
|
|
Architecture
|
|
------------
|
|
|
|
::
|
|
|
|
source .py
|
|
→ ast.parse
|
|
→ SemanticNode[] (stable IDs, no line numbers)
|
|
→ attach ruff diagnostics
|
|
→ attach ty diagnostics
|
|
→ attach coverage.py runtime data
|
|
→ rank by priority heuristic
|
|
→ next_targets()
|
|
|
|
Layers
|
|
------
|
|
|
|
1. **parse** — Walk AST, emit a ``SemanticNode`` for every function,
|
|
method, class, branch (if/elif/else), match case, exception handler,
|
|
loop, return, raise, assert, and with block.
|
|
|
|
2. **enrich** — Run ``ruff check --output-format=json`` and
|
|
``ty check --output-format=json`` as subprocesses, map each diagnostic
|
|
to the tightest-span semantic node.
|
|
|
|
3. **runtime** — Read a ``coverage.py`` JSON report and mark which nodes
|
|
were hit/missed. Attach per-test execution contexts when available.
|
|
|
|
4. **plan** — Score each uncovered node using a weighted heuristic
|
|
(branches > ty signals > partial functions > exception paths > ruff)
|
|
and return a ranked list of test targets.
|
|
|
|
5. **state** — Persist node-level tracking across runs in a JSON file.
|
|
Nodes whose source hash changes are automatically reset. Stale
|
|
entries (removed from the AST) are pruned on sync.
|
|
|
|
6. **hooks** — Pre-commit hook orchestration. Smart test selection
|
|
based on staged files: ``src/<mod>/`` changes → ``tests/<mod>/``
|
|
runs. Falls back to full suite on infrastructure changes.
|
|
|
|
Node identity
|
|
-------------
|
|
|
|
Every node has a stable ID built from its module path, qualified symbol
|
|
name, kind, and ordinal position::
|
|
|
|
aco.express.pharmacy::pharmacy_claims::branch_if[0]
|
|
sem.parse::_Collector::visit_If::branch_else[0]
|
|
|
|
Line numbers are stored as metadata in ``Span`` but never appear in the
|
|
ID. A SHA-1 hash of the source fragment detects edits — the state layer
|
|
resets a node's history when its hash changes.
|
|
|
|
Usage
|
|
-----
|
|
|
|
::
|
|
|
|
from sem import parse_module, attach_ruff, attach_coverage
|
|
from sem import rank_nodes, next_targets
|
|
|
|
nodes = parse_module(Path("src/aco/express/pharmacy.py"))
|
|
attach_ruff(nodes, Path("src/aco/express/pharmacy.py"))
|
|
attach_coverage(nodes, Path("coverage.json"), "src/aco/express/pharmacy.py")
|
|
|
|
for target in next_targets(nodes, limit=5):
|
|
print(target.node_id, target.priority, target.kind)
|
|
"""
|
|
|
|
from sem.enrich import attach_ruff, attach_ty
|
|
from sem.nodes import NodeKind, SemanticNode
|
|
from sem.parse import parse_module, parse_tree
|
|
from sem.plan import next_targets, rank_nodes
|
|
from sem.runtime import attach_coverage
|
|
|
|
__all__ = [
|
|
"NodeKind",
|
|
"SemanticNode",
|
|
"parse_module",
|
|
"parse_tree",
|
|
"attach_ruff",
|
|
"attach_ty",
|
|
"attach_coverage",
|
|
"rank_nodes",
|
|
"next_targets",
|
|
]
|