Add docs, tested examples, and a story for SEP-990 identity assertion (#3004)
This commit is contained in:
parent
24717cc8eb
commit
3b78f86886
1 changed files with 937 additions and 49 deletions
|
|
@ -39,32 +39,6 @@ symbol is still exported.
|
|||
_INCLUDE_DIRECTIVE = re.compile(r"(?:--8<--\s*\"|<!-- snippet-source\s+)(docs_src/[^\s\"]+)")
|
||||
"""A `--8<-- "docs_src/..."` mkdocs include or a `<!-- snippet-source docs_src/... -->` README marker."""
|
||||
|
||||
_TYPOGRAPHIC_NON_ASCII = re.compile("[\u2014\u2013\u2192\u2026\u2018\u2019\u201c\u201d\u00a0\u2264\u2265\u00a7]")
|
||||
"""Typographic characters the documentation never uses: em/en dash, arrow, ellipsis, curly
|
||||
quotes, no-break space, comparison signs, section sign. They are written as escapes so this
|
||||
file satisfies the very check it implements.
|
||||
|
||||
Plain ASCII punctuation is a deliberate style rule, and one of these is also a real bug: a U+2026
|
||||
inside a fenced example breaks the fence linter on Windows, where the example source is piped to
|
||||
ruff in the platform encoding rather than UTF-8. Emoji are not banned; this is about typography.
|
||||
"""
|
||||
|
||||
BOOK_PAGES = sorted(
|
||||
{
|
||||
REPO_ROOT / "README.v2.md",
|
||||
REPO_ROOT / "docs" / "index.md",
|
||||
REPO_ROOT / "docs" / "installation.md",
|
||||
*(REPO_ROOT / "docs" / "tutorial").rglob("*.md"),
|
||||
*(REPO_ROOT / "docs" / "run").rglob("*.md"),
|
||||
*(REPO_ROOT / "docs" / "client").rglob("*.md"),
|
||||
*(REPO_ROOT / "docs" / "advanced").rglob("*.md"),
|
||||
}
|
||||
)
|
||||
"""Every page of the tutorial book plus the README: the files this directory's tests stand behind."""
|
||||
|
||||
DOCS_TEST_FILES = sorted(Path(__file__).parent.glob("*.py"))
|
||||
"""This directory itself. The prose in these modules' docstrings follows the same typography rule."""
|
||||
|
||||
|
||||
def _rel(path: Path) -> str:
|
||||
"""A repo-relative path, used as the parametrize id so failures name the file."""
|
||||
|
|
@ -92,11 +66,6 @@ def _retired_names_used(source: str) -> list[str]:
|
|||
return [name for name in RETIRED_NAMES if name in source]
|
||||
|
||||
|
||||
def _typographic_chars(text: str) -> list[str]:
|
||||
"""Every banned typographic character in `text`, in order of appearance."""
|
||||
return _TYPOGRAPHIC_NON_ASCII.findall(text)
|
||||
|
||||
|
||||
def _referenced_examples() -> set[str]:
|
||||
"""Every `docs_src/...` path that some docs page or the README actually includes.
|
||||
|
||||
|
|
@ -133,12 +102,6 @@ def test_retired_name_detector() -> None:
|
|||
assert _retired_names_used("from mcp.server import MCPServer") == []
|
||||
|
||||
|
||||
def test_typographic_char_detector() -> None:
|
||||
"""The detector flags banned typography and allows plain ASCII and emoji."""
|
||||
assert _typographic_chars("a \u2014 b \u2192 c\u2026") == ["\u2014", "\u2192", "\u2026"]
|
||||
assert _typographic_chars("plain ASCII with a \u2728 emoji is fine") == []
|
||||
|
||||
|
||||
@pytest.mark.parametrize("path", EXAMPLE_FILES, ids=_rel)
|
||||
def test_example_imports(path: Path) -> None:
|
||||
"""The example imports cleanly against the current SDK.
|
||||
|
|
@ -165,13 +128,6 @@ def test_example_avoids_retired_api(path: Path) -> None:
|
|||
assert not _retired_names_used(path.read_text(encoding="utf-8")), f"{_rel(path)} uses a retired API"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("path", [*BOOK_PAGES, *EXAMPLE_FILES, *DOCS_TEST_FILES], ids=_rel)
|
||||
def test_page_uses_plain_ascii_punctuation(path: Path) -> None:
|
||||
"""A page, example, or docs test never uses em-dashes, arrows, ellipses, or other typographic non-ASCII."""
|
||||
found = _typographic_chars(path.read_text(encoding="utf-8"))
|
||||
assert not found, f"{_rel(path)} contains non-ASCII typography: {sorted(set(found))}"
|
||||
|
||||
|
||||
def test_every_example_is_included_by_a_page() -> None:
|
||||
"""Every `docs_src/` example is shown by at least one docs page or the README.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue