# Generated by tools/gen_stubs.py from the package source. Do not edit. # `make stubs` regenerates; test/test_stubs.py refuses any difference. """The language-neutral half of the `code`-facts ingest. An ingest has two halves. One READS a tree and knows a language: what a function is, what a call looks like, where a dependency is declared. The other turns whatever was read into a DKE Python program that records it — subject ids, the row tables, the header, the CLI, the stderr report. Only the first half is language-specific, and this module is the second half. A reader supplies a `Language` and a `collect` function; everything below here is the same whatever the reader read. Adding a language is therefore a walker, not a second copy of the emitter — which matters because the parts that are easy to get subtly wrong (a subject that changes between runs, a Call.callee that is not a Function subject, an optional cell written as an empty string) live HERE, are guarded once, and cannot drift per language. Nothing in this file talks to the network and nothing spawns a process. The readers must hold to that too; `test_ingest.py` asserts it over every module in this directory rather than over one of them.""" import argparse import hashlib import re import sys import time from dataclasses import dataclass, field from pathlib import Path, PurePosixPath from typing import Callable from dke.factwriter import FactProgram, Ids, sanitize MODULE: ... EXIT_OK: ... EXIT_NO_SUCH_PATH: ... EXIT_NOTHING_TO_READ: ... @dataclass class Function: qual: str name: str module: str lines: int branches: int loops: int is_test: bool = False @dataclass class Klass: qual: str name: str module: str methods: int @dataclass class Call: caller_qual: str callee_qual: str site: str @dataclass class UnresolvedCall: """A call whose TARGET COULD NOT BE NAMED — the inventory of the hole. CODE-MODULE-UNRESOLVED-CALL-SITES. Dropping an unresolvable edge is right and does not change: a missing edge is a known gap, a guessed edge is a wrong answer the queries cannot tell from a fact. But dropping the edge also dropped the observation that a dispatch site EXISTS, so `uncalled()`'s caveat — a call we could not see leaves its callee looking uncalled — was prose a reader met once and could never query. This records the site WITHOUT inventing an edge: we assert that a call happened here and that its target was not determined. That is a fact, as true as a resolved call. ONLY the unnameable case belongs here, and the distinction is load-bearing. A walker drops a call for two different reasons: the target could not be named at all (dispatch through a variable, a handler table, `getattr`), or the target WAS named and simply lies outside the ingested set (a stdlib or third-party call). Only the first can make an INGESTED function look uncalled, because only an unnameable target might have been one of them — an external call resolves to a name that is not a Function subject and can never suppress one. Recording the second here would inflate the inventory with sites that say nothing about how far `uncalled()` can be trusted, which is the one question this kind exists to answer.""" caller_qual: str site: str text: str @dataclass class Rationale: """A reason the author WROTE DOWN, attached to what it explains. CODE-MODULE-RATIONALE-FACTS. Every other kind this producer emits is something a reader could recompute from the source — structure. The reason the structure is shaped that way is written down in most codebases and reached the store nowhere, which is a strange gap in a product whose whole argument is that reasoning should be explicit and inspectable. STATED, never inferred. `Counterpart` is the precedent: two functions that have to agree is "a claim about intent, and only a reader knows it", so the reader states it and the engine holds the consequences. The comparable that motivated this reaches for an LLM to infer intent instead; a stated fact does not rot silently and an inferred one does. THE MARKER SET IS A DECISION, not a discovery, and it is OURS rather than the module's — a customer's producer chooses its own. `WHY:` and `NOTE:` and nothing else, on the precedent of CODE-COMPLEXITY-COUNTING-UNDEFINED, where what counts as a branch was made the producer's stated decision rather than a hidden one. Both require the author to have typed a prefix, which is what makes this opt-in: a convention wide enough to sweep ordinary comments would turn every line in the tree into a fact and the query into noise, and that is the failure mode worth more than the coverage. `TODO:` is deliberately NOT a marker. It records an intention, not a reason, and this tree's own CLAUDE.md bans bare TODOs outright — reading them as rationale would import a convention the codebase rejects.""" subject: str marker: str text: str site: str def rationale_marker(comment_body: str) -> tuple[str, str] | None: """(marker, text) if this comment body opens with a marker, else None. Takes the body with its delimiters already stripped, because what those look like is the language's business and what counts as a marker is not.""" ... def enclosing_definition(line: int, spans: list[tuple[str, int, int]]) -> str | None: """The qualified name whose body contains `line`, innermost first. Attribution is by CONTAINMENT and nothing else. A comment sitting above a definition reads to a human as being about it, and attaching it that way was considered and rejected: the line before a `def` is just as often the tail of the previous one, and a rule that is right most of the time produces facts nobody can tell from the wrong ones. Unattached rationale is dropped rather than guessed at, which is the same call the call graph makes about an edge. Innermost wins so a marker inside a nested function belongs to that function rather than to the one around it.""" ... @dataclass class Import: importer: str imported: str @dataclass class Dependency: name: str version: str direct: bool | None pinned: bool @dataclass class Facts: functions: list[Function] = field(default_factory=list) classes: list[Klass] = field(default_factory=list) calls: list[Call] = field(default_factory=list) unresolved: list[UnresolvedCall] = field(default_factory=list) rationale: list[Rationale] = field(default_factory=list) imports: list[Import] = field(default_factory=list) deps: list[Dependency] = field(default_factory=list) dep_files: list[str] = field(default_factory=list) seen_deps: set[str] = field(default_factory=set) calls_seen: int = 0 calls_resolved: int = 0 files_found: int = 0 files_excluded: int = 0 files_parsed: int = 0 files_failed: list[tuple[str, str]] = field(default_factory=list) tested: dict[str, str] = field(default_factory=dict) test_files: int = 0 @dataclass class Language: """What a reader is, from the emitter's side. `tag` is the value written to `code.Function.language` and `code.Class.language`. It is what lets one store hold facts about more than one language and still be sliceable — and what lets a reader of those facts see that two producers were involved before comparing numbers that may be on different scales.""" tag: str name: str prog: str extensions: tuple[str, ...] caveats: list[str] collect: Callable[[list[Path], list[str]], Facts] def path_in_test_dir(path: str) -> bool: """True when some directory on the way to `path` is `test` or `tests`. Shared because it is a directory-layout convention rather than a language one. Each reader layers its own file-NAME and callable-name rules on top, which are the parts a language actually decides.""" ... def reached_by_tests(facts: Facts) -> dict[str, str]: """Qualified function name → the name of a test that reaches it. TRANSITIVE over the recorded call graph, not direct-only. A test almost never calls the function under test at depth 1 — it calls an entry point which calls it — so a direct-only rule would leave `untested` nearly as universal as writing nothing, which is the defect this exists to fix. The claim being recorded is therefore "a test was seen to reach this", NOT "this is covered". Reaching is not executing: a branch may never be taken, and the call graph under it is a lower bound, so a function reported as untested may simply be reached a way the source does not show. That is why `untested` is a candidate list, in the same register as `uncalled()`. Deterministic: roots and the frontier are processed in sorted order, so the test recorded for a function reached by several is always the same one.""" ... def emit(facts: Facts, ids: Ids, lang: Language, *, stamp: int | None=None, load_key: str | None=None) -> str: """Render the facts as a DKE Python program. `stamp` and `load_key` belong to the load marker (`FactProgram.load_marker`) and both default: the stamp to the wall clock in milliseconds, the key to this reader's language TAG — `python`, `cpp` — which is the same token the facts themselves carry in `language`, so a reader asking whether the last Python load finished spells it exactly as they spell everything else. It defaulted to `name` for one commit, which is the prose spelling (`Python`, `C++`): every unit test passed, because they supply their own key, and what caught it was running the producer over a real tree and finding a cell the published README's own example does not name. Keying on the LANGUAGE rather than on the tree is deliberate and is the weaker half of this: a `code` store holds one codebase that may be several languages, so "did the last Python load finish" is the question a reader has, and two Python trees loaded into one store share a marker. The key is a parameter so a caller that knows the tree can say so; `emit` is not given the root and will not infer one.""" ... def absence_coverage(facts: Facts) -> list[tuple[str, int, int, str, str]]: """(field, recorded, total functions, queries flattened at zero, extra note). Counted from `facts` rather than from the emitted program, and counted the same way the tables write: `test` only where a test name is non-empty, `called` only where some call resolves to this function, `explained` only where a rationale attaches to a FUNCTION (one on a class is a real fact and not this one).""" ... def import_root(imported: str) -> str: """The top-level name an import reaches for. `requests.adapters` uses `requests`; `boost/asio.hpp` uses `boost`. A dependency query matching on the full name would call a dependency used only through a submodule unused. Splitting on both separators keeps this one function rather than one per language, since the answer is the same idea in each.""" ... def run(lang: Language, argv: list[str] | None=None) -> int: """The shared CLI: walk, emit, report, and say plainly what was read.""" ...