test: extend orphan sweep to public class methods

Co-authored-by: Copilot App <[email protected]>
This commit is contained in:
Jim Lancaster
2026-08-23 18:52:06 -05:00
co-authored by Copilot App
parent 6c3eac0a44
commit c52d41ec33
+77 -7
View File
@@ -6,10 +6,10 @@ guard makes that sweep reproducible: it locks the current set of unreferenced pu
definitions, so a newly stranded function fails the build instead of accumulating definitions, so a newly stranded function fails the build instead of accumulating
silently, and deleting a known orphan requires deleting its entry here. silently, and deleting a known orphan requires deleting its entry here.
The sweep is intentionally conservative. It only considers module-level public The sweep is intentionally conservative. It considers module-level public
definitions, and it honours the dynamic-wiring exceptions the skill calls out: definitions and public methods on public classes, and honours the dynamic-wiring
framework route registration, string-based entrypoint references, and use from exceptions the skill calls out: framework route registration, string-based
`tests/` or `tools/`. entrypoint references, and use from `tests/` or `tools/`.
""" """
from __future__ import annotations from __future__ import annotations
@@ -36,6 +36,62 @@ KNOWN_ORPHANS: dict[str, str] = {
"Uncertain - follow-up: confirm whether the benchmarking entrypoint is still " "Uncertain - follow-up: confirm whether the benchmarking entrypoint is still "
"intended before removing." "intended before removing."
), ),
"DocumentService.is_document_type_referenced": (
"Read helper currently bypassed by callers in favor of direct delete guards. "
"Retained for now to preserve service API stability during cleanup."
),
"DocumentService.is_tag_referenced": (
"Read helper currently bypassed by callers in favor of direct delete guards. "
"Retained for now to preserve service API stability during cleanup."
),
"DocumentService.read_document": (
"Public CRUD read method currently unused by runtime routes, but retained as "
"part of the service API shape for downstream call sites."
),
"DocumentService.read_document_type": (
"Public CRUD read method currently unused by runtime routes, but retained as "
"part of the service API shape for downstream call sites."
),
"DocumentService.read_tag": (
"Public CRUD read method currently unused by runtime routes, but retained as "
"part of the service API shape for downstream call sites."
),
"JSONBCompat.load_dialect_impl": (
"SQLAlchemy type hook is invoked by ORM internals via subclass protocol rather "
"than direct in-repo references; keep this implementation method."
),
"JobService.delete_job": (
"Legacy delete method retained as a compatibility shim while guarded deletion "
"flows migrate fully to delete_job_with_guardrails."
),
"JobService.update_job": (
"Legacy update method retained for compatibility while route and workflow "
"callers continue converging on narrower state-transition APIs."
),
"PeopleService.is_person_role_referenced": (
"Reference-check helper currently not called by route workflows, but kept with "
"the service surface while role-management cleanup remains in progress."
),
"PeopleService.read_person": (
"Public CRUD read method currently unused by runtime routes, but retained as "
"part of the service API shape for downstream call sites."
),
"PeopleService.read_person_role": (
"Public CRUD read method currently unused by runtime routes, but retained as "
"part of the service API shape for downstream call sites."
),
"Settings.normalize_provider_models": (
"Pydantic model-level validator is executed by framework hooks using decorator "
"registration and therefore has no direct symbolic call site."
),
"Settings.validate_provider_models_input": (
"Pydantic field validator is executed by framework hooks using decorator "
"registration and therefore has no direct symbolic call site."
),
"SourceService.read_job_source_for_job": (
"Public read helper currently unused by runtime flows, but retained as part of "
"the SourceService API pending endpoint consolidation."
),
"dispose_all_engines": ( "dispose_all_engines": (
"Engine lifecycle helper in db/engine.py. Uncertain - follow-up: operational " "Engine lifecycle helper in db/engine.py. Uncertain - follow-up: operational "
"teardown utility with no runtime or test caller." "teardown utility with no runtime or test caller."
@@ -61,7 +117,7 @@ def _is_registered_with_framework(node: ast.FunctionDef | ast.AsyncFunctionDef |
def _public_definitions() -> dict[str, str]: def _public_definitions() -> dict[str, str]:
"""Public module-level definitions, mapped to `path:line`.""" """Public definitions mapped to `path:line` (module-level + class methods)."""
definitions: dict[str, str] = {} definitions: dict[str, str] = {}
for path in _source_files(): for path in _source_files():
tree = ast.parse(path.read_text(encoding="utf-8")) tree = ast.parse(path.read_text(encoding="utf-8"))
@@ -71,6 +127,15 @@ def _public_definitions() -> dict[str, str]:
if node.name.startswith("_") or _is_registered_with_framework(node): if node.name.startswith("_") or _is_registered_with_framework(node):
continue continue
definitions[node.name] = f"{path.relative_to(PROJECT_ROOT).as_posix()}:{node.lineno}" definitions[node.name] = f"{path.relative_to(PROJECT_ROOT).as_posix()}:{node.lineno}"
if isinstance(node, ast.ClassDef):
for method in node.body:
if not isinstance(method, ast.FunctionDef | ast.AsyncFunctionDef):
continue
if method.name.startswith("_"):
continue
definitions[f"{node.name}.{method.name}"] = (
f"{path.relative_to(PROJECT_ROOT).as_posix()}:{method.lineno}"
)
return definitions return definitions
@@ -107,14 +172,19 @@ def _orphans() -> dict[str, str]:
for name, location in definitions.items() for name, location in definitions.items()
# A definition is referenced if its name is used directly, or appears inside a # A definition is referenced if its name is used directly, or appears inside a
# string such as "transcription.__main__:create_cli_app". # string such as "transcription.__main__:create_cli_app".
if name not in names and name not in literal_blob if (
name not in names
and name not in literal_blob
and name.split(".")[-1] not in names
and name.split(".")[-1] not in literal_blob
)
} }
def test_public_definitions_are_discovered(): def test_public_definitions_are_discovered():
"""Guard the guard: the sweep is meaningless if nothing is scanned.""" """Guard the guard: the sweep is meaningless if nothing is scanned."""
definitions = _public_definitions() definitions = _public_definitions()
assert len(definitions) >= 260 assert len(definitions) >= 420
assert "create_app" in definitions assert "create_app" in definitions