coverage.store.model¶
Coverage data model.
This is the core of the coverage module — everything else feeds into or reads from these types. The model is deliberately independent of gcov, lcov, or coverage.py internals.
Coverage tiers are names — free-form strings like "system",
"unit", "manual", or anything a user wires up on the command
line. LineHits and BranchHits store per-tier counts in dicts
keyed by tier name, so adding a new tier requires no changes to the
model. A CoverageStore also carries a tier_order list that
defines the precedence of tiers for presentation purposes (first =
highest precedence).
-
otto.coverage.store.model.TIER_SYSTEM =
'system'¶ Conventional tier name used by the merged .gcda pipeline.
Any string is a valid tier name; this constant spares callers a string literal when they mean the canonical system-coverage tier.
- class otto.coverage.store.model.LineHits(counts: dict[str, int] = <factory>)¶
Bases:
objectPer-tier hit counts for a single line.
Counts are a dict keyed by tier name. Absent keys mean zero hits for that tier.
- class otto.coverage.store.model.BranchHits(block: int, branch: int, hits: ~otto.coverage.store.model.LineHits = <factory>, reachable: dict[str, bool] = <factory>)¶
Bases:
objectPer-tier hit counts and reachability for one branch.
Reachability is tri-state per tier:
key present, value
True→ observed as reachable at least oncekey present, value
False→ observed only as unreachable (lcov-)key absent → no data yet for that tier
Once a tier sees the branch as reachable it stays reachable for that tier — merges only flip
False→True, never the other way.- property branch_id : tuple[int, int]¶
(block, branch)tuple that uniquely identifies this branch within a line.
- set_reachable(tier: str, reachable: bool) None¶
Record a reachability observation for tier.
If the tier was already marked reachable, keep it reachable. Otherwise adopt the new value.
-
is_reachable(tier: str | None =
None) bool | None¶ Reachability for tier, or combined across all tiers when None.
Returns
Noneif no data has been recorded for the requested tier (or for any tier whentieris None).
-
is_hit_for(tier: str | None =
None) bool¶ Return True if this branch was taken at least once in tier.
- merge(other: BranchHits) None¶
Merge other into this branch, accumulating hits and updating reachability.
- class otto.coverage.store.model.LineRecord(line_number: int, hits: ~otto.coverage.store.model.LineHits = <factory>, branches: list[~otto.coverage.store.model.BranchHits] = <factory>, commit_hash: str | None = None, commit_author: str | None = None, commit_summary: str | None = None)¶
Bases:
objectCoverage data for a single source line.
- branches : list[BranchHits]¶
- merge(other: LineRecord) None¶
Merge other into this line record, accumulating hits and branch data.
- class otto.coverage.store.model.FileRecord(path: ~pathlib.Path, lines: dict[int, ~otto.coverage.store.model.LineRecord] = <factory>)¶
Bases:
objectCoverage data for a single source file.
- lines : dict[int, LineRecord]¶
- get_or_create_line(line_number: int) LineRecord¶
Return the
LineRecordfor line_number, creating it if absent.
- merge(other: FileRecord) None¶
Merge other into this file record, combining per-line hits and branches.
-
line_coverage_pct(tier: str | None =
None) float¶ Line coverage percentage, optionally filtered by tier.
-
branch_coverage_pct(tier: str | None =
None, conservative: bool =True) float¶ Branch coverage percentage.
conservative=True (default): denominator is only branches where
is_reachable(tier)isTrue. Matches genhtml behaviour.conservative=False: denominator is all branches seen in any
.infofile.
- sorted_lines() Iterator[LineRecord]¶
Yield
LineRecordobjects in ascending line-number order.
-
class otto.coverage.store.model.CoverageStore(tier_order: list[str] | None =
None)¶ Bases:
objectCentral store for all coverage data across all files, hosts, and tiers.
tier_orderholds the user-defined precedence of tiers — first entry is highest precedence. Downstream renderers iterate this list to drive column ordering and the winner-take-all row coloring used by the annotated source view.- register_tier(tier: str) None¶
Append tier to the tier order if not already present.
Loaders call this when they see a new tier so the store’s
tier_orderlist stays in sync with the data without requiring every call site to pre-declare every tier.
- get_or_create_file(path: Path) FileRecord¶
Return the
FileRecordfor path, creating it if absent.Resolves path to its canonical form when the file exists on disk, so duplicate entries from different relative or symlinked references to the same file are collapsed to one record.
- merge_file(record: FileRecord) None¶
Merge record into the store, accumulating data for an existing path or inserting it.
- files() Iterator[FileRecord]¶
Yield all
FileRecordobjects in sorted path order.
-
overall_branch_pct(tier: str | None =
None, conservative: bool =True) float¶ Overall branch coverage percentage across all files.
- classmethod load(path: Path) CoverageStore¶
Deserialise a store from JSON.