Skip to content

Commit b850021

Browse files
authored
test(docs[sphinx_fonts]) add tests and fix download failure bugs (#1023)
why: sphinx_fonts.py had zero test coverage, and two latent bugs were discovered during test development — font-face entries emitted for failed downloads, and partial files poisoning the cache. what: Test suite (21 functions, 545 lines) - _cache_dir: path construction - _cdn_url: parametrized URL formatting, template structure - _download_font: cached hit, success, URLError, OSError, partial cleanup - _on_builder_inited: non-html skip, empty fonts, font processing, download failure skip, explicit subset, preload match/no-match, fallbacks and CSS variables - _on_html_page_context: with/without app attributes - setup: return metadata, config values, event connections Bug fixes in sphinx_fonts.py - Move font_faces.append() inside if _download_font() block to skip font-face entries when download fails (was emitting CSS pointing to missing files) - Add dest.unlink() in except block to remove partial .woff2 files left by interrupted downloads (was poisoning cache) Docstrings - Add docstrings to SetupDict and setup() for ruff D101/D103
1 parent 9c0caa1 commit b850021

2 files changed

Lines changed: 558 additions & 8 deletions

File tree

docs/_ext/sphinx_fonts.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626

2727
class SetupDict(t.TypedDict):
28+
"""Return type for Sphinx extension setup()."""
29+
2830
version: str
2931
parallel_read_safe: bool
3032
parallel_write_safe: bool
@@ -61,6 +63,8 @@ def _download_font(url: str, dest: pathlib.Path) -> bool:
6163
urllib.request.urlretrieve(url, dest)
6264
logger.info("downloaded font: %s", dest.name)
6365
except (urllib.error.URLError, OSError):
66+
if dest.exists():
67+
dest.unlink()
6468
logger.warning("failed to download font: %s", url)
6569
return False
6670
return True
@@ -93,14 +97,14 @@ def _on_builder_inited(app: Sphinx) -> None:
9397
url = _cdn_url(package, version, font_id, subset, weight, style)
9498
if _download_font(url, cached):
9599
shutil.copy2(cached, fonts_dir / filename)
96-
font_faces.append(
97-
{
98-
"family": font["family"],
99-
"style": style,
100-
"weight": str(weight),
101-
"filename": filename,
102-
}
103-
)
100+
font_faces.append(
101+
{
102+
"family": font["family"],
103+
"style": style,
104+
"weight": str(weight),
105+
"filename": filename,
106+
}
107+
)
104108

105109
preload_hrefs: list[str] = []
106110
preload_specs: list[tuple[str, int, str]] = app.config.sphinx_font_preload
@@ -135,6 +139,7 @@ def _on_html_page_context(
135139

136140

137141
def setup(app: Sphinx) -> SetupDict:
142+
"""Register config values, events, and return extension metadata."""
138143
app.add_config_value("sphinx_fonts", [], "html")
139144
app.add_config_value("sphinx_font_fallbacks", [], "html")
140145
app.add_config_value("sphinx_font_css_variables", {}, "html")

0 commit comments

Comments
 (0)