Skip to content

Commit a072caf

Browse files
committed
gp-opengraph(refactor[imports]): use namespace imports for stdlib modules
why: PR #22 code review flagged three ``from <stdlib> import <name>`` import statements that violate CLAUDE.md line 457: Use namespace imports for standard library modules: `import enum` instead of `from enum import Enum` Exception: `dataclasses` module may use `from dataclasses import dataclass, field` for cleaner decorator syntax Every existing workspace package follows this — e.g. gp-sphinx's own config.py uses ``import pathlib`` / ``import tomllib`` then ``pathlib.Path(...)`` / ``tomllib.loads(...)``. what: - packages/gp-opengraph/src/gp_opengraph/__init__.py: * ``from types import NoneType`` -> ``import types`` + ``types.NoneType`` at each call site (four occurrences inside ``frozenset({...})`` literals for add_config_value). * ``from urllib.parse import urljoin, urlparse, urlsplit, urlunsplit`` -> ``import urllib.parse`` with each call qualified: ``urllib.parse.urljoin(...)``, ``urllib.parse.urlparse(...)``, ``urllib.parse.urlsplit(...)``, ``urllib.parse.urlunsplit(...)``. - packages/gp-opengraph/src/gp_opengraph/_title.py: * ``from html.parser import HTMLParser`` -> ``import html.parser``; subclass declaration becomes ``class HTMLTextParser(html.parser.HTMLParser)``. - packages/gp-opengraph/src/gp_opengraph/_meta.py: * Same HTMLParser rewrite as _title.py. Left as-is (already compliant): - ``from xml.etree import ElementTree`` in gp_sitemap — this imports a *submodule*, not a name, and is the canonical idiom (equivalent to ``import xml.etree.ElementTree as ElementTree``). CLAUDE.md's example targets ``from enum import Enum`` (name import), not submodule aliasing. - ``from collections.abc import Set`` / ``Iterable`` inside ``TYPE_CHECKING`` blocks — gp_sphinx itself does this at config.py#L17, so the convention allows type-only imports this way. No behavior change; purely an import refactor. CI gate (all green before commit): - uv run ruff check . --fix --show-fixes: clean - uv run ruff format .: no changes - uv run mypy: Success (176 source files) - uv run py.test --reruns 0 -vvv: 1199 passed, 3 skipped - just build-docs: build succeeded
1 parent 3742a34 commit a072caf

3 files changed

Lines changed: 17 additions & 15 deletions

File tree

packages/sphinx-gp-opengraph/src/sphinx_gp_opengraph/__init__.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
import logging
2323
import os
2424
import pathlib
25+
import types
2526
import typing as t
26-
from types import NoneType
27-
from urllib.parse import urljoin, urlparse, urlsplit, urlunsplit
27+
import urllib.parse
2828

2929
from docutils import nodes
3030
from sphinx.application import Sphinx
@@ -137,7 +137,7 @@ def get_tags(
137137

138138
ogp_canonical_url = config.ogp_canonical_url or ogp_site_url
139139

140-
page_url = urljoin(
140+
page_url = urllib.parse.urljoin(
141141
ogp_canonical_url,
142142
builder.get_target_uri(context["pagename"]),
143143
)
@@ -170,10 +170,10 @@ def get_tags(
170170

171171
if image_url:
172172
if "og:image" not in fields:
173-
image_url_parsed = urlparse(image_url)
173+
image_url_parsed = urllib.parse.urlparse(image_url)
174174
if not image_url_parsed.scheme:
175175
root = page_url if first_image else ogp_site_url
176-
image_url = urljoin(root, image_url_parsed.path)
176+
image_url = urllib.parse.urljoin(root, image_url_parsed.path)
177177
tags["og:image"] = image_url
178178

179179
if isinstance(ogp_image_alt, str):
@@ -204,8 +204,10 @@ def _ambient_site_url() -> str:
204204
if not rtd_canonical_url:
205205
msg = "ReadTheDocs did not provide a valid canonical URL"
206206
raise RuntimeError(msg)
207-
parsed = urlsplit(rtd_canonical_url)
208-
return urlunsplit((parsed.scheme, parsed.netloc, parsed.path, "", ""))
207+
parsed = urllib.parse.urlsplit(rtd_canonical_url)
208+
return urllib.parse.urlunsplit(
209+
(parsed.scheme, parsed.netloc, parsed.path, "", ""),
210+
)
209211

210212

211213
def _resolve_site_name(config: Config) -> str | None:
@@ -300,13 +302,13 @@ def setup(app: Sphinx) -> dict[str, t.Any]:
300302
"ogp_image",
301303
None,
302304
"html",
303-
types=frozenset({str, NoneType}),
305+
types=frozenset({str, types.NoneType}),
304306
)
305307
app.add_config_value(
306308
"ogp_image_alt",
307309
None,
308310
"html",
309-
types=frozenset({str, bool, NoneType}),
311+
types=frozenset({str, bool, types.NoneType}),
310312
)
311313
app.add_config_value(
312314
"ogp_use_first_image",
@@ -319,14 +321,14 @@ def setup(app: Sphinx) -> dict[str, t.Any]:
319321
"ogp_site_name",
320322
None,
321323
"html",
322-
types=frozenset({str, bool, NoneType}),
324+
types=frozenset({str, bool, types.NoneType}),
323325
)
324326
# Accepted-but-ignored: warned about in _warn_if_social_cards_used.
325327
app.add_config_value(
326328
"ogp_social_cards",
327329
None,
328330
"html",
329-
types=frozenset({dict, NoneType}),
331+
types=frozenset({dict, types.NoneType}),
330332
)
331333
app.add_config_value(
332334
"ogp_custom_meta_tags",

packages/sphinx-gp-opengraph/src/sphinx_gp_opengraph/_meta.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
from __future__ import annotations
1717

18-
from html.parser import HTMLParser
18+
import html.parser
1919

2020

2121
def get_meta_description(meta_tags: str) -> str | bool | None:
@@ -40,7 +40,7 @@ def get_meta_description(meta_tags: str) -> str | bool | None:
4040
return htp.meta_description
4141

4242

43-
class HTMLTextParser(HTMLParser):
43+
class HTMLTextParser(html.parser.HTMLParser):
4444
"""Flag the presence (and content) of a ``<meta name="description">``."""
4545

4646
def __init__(self) -> None:

packages/sphinx-gp-opengraph/src/sphinx_gp_opengraph/_title.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from __future__ import annotations
1313

14-
from html.parser import HTMLParser
14+
import html.parser
1515

1616

1717
def get_title(title: str) -> tuple[str, str]:
@@ -38,7 +38,7 @@ def get_title(title: str) -> tuple[str, str]:
3838
return htp.text, htp.text_outside_tags
3939

4040

41-
class HTMLTextParser(HTMLParser):
41+
class HTMLTextParser(html.parser.HTMLParser):
4242
"""Track text-inside-tags vs text-outside-tags while parsing HTML."""
4343

4444
def __init__(self) -> None:

0 commit comments

Comments
 (0)