fix(loaders): render clean signatures, drop unresolvable aliases from models

- Stringify Object.signature() instead of str()-ing the bound method,
  which produced "<bound method Class.signature of ...>" reprs
- Skip alias members that cannot resolve (stdlib/third-party imports)
  while preserving resolvable package re-exports; return None for empty
  signatures (classes without __init__ args)
- Add MCP renderer regression tests for signature cleanliness, alias
  filtering, and package re-export preservation
This commit is contained in:
2026-09-15 16:53:08 +05:30
parent cd031ed5de
commit 4ec67c86c6
51 changed files with 941 additions and 2287 deletions

View File

@@ -0,0 +1,73 @@
import json
from pathlib import Path
from docforge import MCPRenderer
from docforge.loaders import GriffeLoader, discover_module_paths
def _load_docforge_bundle(tmp_path: Path) -> Path:
project_root = Path(__file__).resolve().parents[3]
loader = GriffeLoader()
paths = discover_module_paths("docforge", project_root=project_root)
project = loader.load_project(paths)
out_dir = tmp_path / "mcp"
MCPRenderer().generate_sources(project, out_dir)
return out_dir
def test_mcp_signatures_are_clean(tmp_path: Path) -> None:
out_dir = _load_docforge_bundle(tmp_path)
object_payload = json.loads(
(out_dir / "modules" / "docforge.models.object.json").read_text(
encoding="utf-8"
)
)
cls = object_payload["content"]["objects"]["DocObject"]
assert isinstance(cls["signature"], str)
assert "bound method" not in cls["signature"]
assert cls["signature"].startswith("DocObject(")
renderer_payload = json.loads(
(out_dir / "modules" / "docforge.renderers.mcp_renderer.json").read_text(
encoding="utf-8"
)
)
method = renderer_payload["content"]["objects"]["MCPRenderer"]["members"][
"generate_sources"
]
assert isinstance(method["signature"], str)
assert "bound method" not in method["signature"]
assert method["signature"].startswith("generate_sources(")
def test_mcp_skips_unresolvable_import_aliases(tmp_path: Path) -> None:
out_dir = _load_docforge_bundle(tmp_path)
renderer_payload = json.loads(
(out_dir / "modules" / "docforge.renderers.mcp_renderer.json").read_text(
encoding="utf-8"
)
)
object_names = set(renderer_payload["content"]["objects"])
assert "json" not in object_names
assert "Path" not in object_names
def test_mcp_keeps_resolvable_package_reexports(tmp_path: Path) -> None:
out_dir = _load_docforge_bundle(tmp_path)
root_payload = json.loads(
(out_dir / "modules" / "docforge.json").read_text(encoding="utf-8")
)
discover = root_payload["content"]["objects"]["discover_module_paths"]
assert discover["name"] == "discover_module_paths"
assert isinstance(discover["signature"], str)
assert "bound method" not in discover["signature"]
assert discover["signature"].startswith("discover_module_paths(")
assert discover["docstring"] is not None