Skip to content

Commit 72f1d97

Browse files
committed
docs: compact-index every package that re-exports from outside its subtree
The compact-index treatment was gated on top-level packages, but mcp.server.mcpserver (Icon from mcp_types) and mcp.client.auth (AuthorizationCodeResult from mcp.shared.auth) re-export across their subtree boundary too, so their index pages rendered full duplicates of canonical documentation. Register every package index for the pass; _compact_index still returns None for packages whose exports all live in their own subtree, so exactly those two indexes change. Compact stubs are titled with the last path component like every other stub (the full dotted path leaked into sibling nav rows), and the package gate keys on the __init__ module rather than the output filename so a real module named index.py cannot masquerade as a package index.
1 parent a483385 commit 72f1d97

1 file changed

Lines changed: 27 additions & 17 deletions

File tree

scripts/docs/gen_ref_pages.py

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,18 @@ def to_nav(self, title: str) -> NavItem:
6161

6262

6363
def _compact_index(package: griffe.Module, documented: set[str]) -> str | None:
64-
"""Build a compact index body for a package that re-exports another package's API.
65-
66-
mkdocstrings renders a member re-exported across a package boundary
67-
(`from other_package import y` + `__all__`) as a full duplicate of its
68-
canonical documentation whenever the other package happens to be loaded
69-
already, and silently omits it when it isn't — which of the two a package
70-
index gets depends on page rendering order. Same-package re-exports
71-
(`mcp_types` re-exporting its private `._types` module) always resolve
72-
and are unaffected, so such packages keep the plain `::: package` stub
73-
(return `None`) and their index remains the full, canonical rendering.
64+
"""Build a compact index body for a package that re-exports from outside its own subtree.
65+
66+
mkdocstrings renders a re-export whose canonical documentation lives on
67+
another page as a full duplicate of it: deterministically for aliases
68+
within one top-level package (`mcp.client.auth` re-exporting from
69+
`mcp.shared.auth`), and order-dependently across top-level packages
70+
(`from mcp_types import y` + `__all__` renders the duplicate only when
71+
the other package happens to be loaded already, and silently omits the
72+
member when it isn't). Packages whose exports all live in their own
73+
subtree (`mcp_types` re-exporting its private `._types` module) are
74+
unaffected and keep the plain `::: package` stub (return `None`): their
75+
index is itself the canonical rendering.
7476
7577
For an affected package, pin the semantics instead of inheriting the
7678
accident: every export whose canonical page exists elsewhere under the API
@@ -126,6 +128,16 @@ def _compact_index(package: griffe.Module, documented: set[str]) -> str | None:
126128
return "\n".join(body)
127129

128130

131+
def _stub(title: str, body: str) -> str:
132+
"""A stub page: explicit title frontmatter plus the page body.
133+
134+
The explicit title matters: the stubs have no H1 of their own, and a
135+
title-less page falls back to "Index"/the filename — which is what
136+
pruned nav rows, browser tabs, and search results show.
137+
"""
138+
return f'---\ntitle: "{title}"\n---\n\n{body.rstrip()}\n'
139+
140+
129141
def generate() -> list[NavItem]:
130142
"""Write `docs/api/**.md` stubs and return the API-section navigation."""
131143
if API_DIR.exists():
@@ -143,7 +155,8 @@ def generate() -> list[NavItem]:
143155
doc_path = path.relative_to(base).with_suffix(".md")
144156

145157
parts = tuple(module_path.parts)
146-
if parts[-1] == "__init__":
158+
is_package = parts[-1] == "__init__"
159+
if is_package:
147160
parts = parts[:-1]
148161
doc_path = doc_path.with_name("index.md")
149162
# A private component anywhere makes the module private: checking
@@ -153,11 +166,8 @@ def generate() -> list[NavItem]:
153166

154167
ident = ".".join(parts)
155168
documented.add(ident)
156-
# Explicit titles: the stubs have no H1 of their own, and a
157-
# title-less page falls back to "Index"/the filename — which is
158-
# what pruned nav rows, browser tabs, and search results show.
159-
stubs[API_DIR / doc_path] = f'---\ntitle: "{parts[-1]}"\n---\n\n::: {ident}\n'
160-
if len(parts) == 1:
169+
stubs[API_DIR / doc_path] = _stub(parts[-1], f"::: {ident}")
170+
if is_package:
161171
package_index[ident] = API_DIR / doc_path
162172

163173
node = root
@@ -173,7 +183,7 @@ def generate() -> list[NavItem]:
173183
module = modules[ident]
174184
assert isinstance(module, griffe.Module)
175185
if body := _compact_index(module, documented):
176-
stubs[doc_path] = f'---\ntitle: "{ident}"\n---\n\n{body}'
186+
stubs[doc_path] = _stub(ident.rpartition(".")[2], body)
177187

178188
for full_doc_path, stub in stubs.items():
179189
full_doc_path.parent.mkdir(parents=True, exist_ok=True)

0 commit comments

Comments
 (0)