Skip to content

Commit 26cfaf4

Browse files
committed
Improve type annotations
1 parent 7f3c66a commit 26cfaf4

File tree

6 files changed

+67
-64
lines changed

6 files changed

+67
-64
lines changed

docs/script/generate_social_card_previews.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from sphinxext.opengraph.socialcards import (
1616
MAX_CHAR_DESCRIPTION,
1717
MAX_CHAR_PAGE_TITLE,
18+
create_social_card_objects,
1819
render_social_card,
1920
)
2021

@@ -31,7 +32,7 @@
3132
}
3233

3334
print("Generating previews of social media cards...")
34-
plt_objects = None
35+
plt_objects = create_social_card_objects(**kwargs_fig)
3536
embed_text = []
3637
for perm in range(20):
3738
# Create dummy text description and pagetitle for this iteration
@@ -54,7 +55,6 @@
5455
description=desc,
5556
siteurl="sphinxext-opengraph.readthedocs.io",
5657
plt_objects=plt_objects,
57-
kwargs_fig=kwargs_fig,
5858
)
5959

6060
path_examples_page_folder = PROJECT_ROOT / "docs"

sphinxext/opengraph/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from typing import Any
1616

1717
from sphinx.application import Sphinx
18+
from sphinx.util.typing import ExtensionMetadata
1819

1920
try:
2021
from sphinxext.opengraph.socialcards import (
@@ -277,7 +278,7 @@ def html_page_context(
277278
context["metatags"] += get_tags(app, context, doctree, app.config)
278279

279280

280-
def setup(app: Sphinx) -> dict[str, Any]:
281+
def setup(app: Sphinx) -> ExtensionMetadata:
281282
# ogp_site_url="" allows relative by default, even though it's not
282283
# officially supported by OGP.
283284
app.add_config_value("ogp_site_url", "", "html")
@@ -295,6 +296,8 @@ def setup(app: Sphinx) -> dict[str, Any]:
295296
app.connect("html-page-context", html_page_context)
296297

297298
return {
299+
"version": __version__,
300+
"env_version": 1,
298301
"parallel_read_safe": True,
299302
"parallel_write_safe": True,
300303
}

sphinxext/opengraph/descriptionparser.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def __init__(
2020
*,
2121
desc_len: int,
2222
known_titles: Set[str] = frozenset(),
23-
):
23+
) -> None:
2424
super().__init__(document)
2525
self.description = ""
2626
self.desc_len = desc_len
@@ -36,12 +36,8 @@ def dispatch_visit(self, node: nodes.Element) -> None:
3636
if self.stop:
3737
raise nodes.StopTraversal
3838

39-
# Skip comments
40-
if isinstance(node, nodes.Invisible):
41-
raise nodes.SkipNode
42-
43-
# Skip all admonitions
44-
if isinstance(node, nodes.Admonition):
39+
# Skip comments & all admonitions
40+
if isinstance(node, (nodes.Admonition, nodes.Invisible)):
4541
raise nodes.SkipNode
4642

4743
# Mark start of nested lists
@@ -107,7 +103,7 @@ def get_description(
107103
doctree: nodes.document,
108104
description_length: int,
109105
known_titles: Set[str] = frozenset(),
110-
):
106+
) -> str:
111107
mcv = DescriptionParser(
112108
doctree, desc_len=description_length, known_titles=known_titles
113109
)

sphinxext/opengraph/metaparser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ class HTMLTextParser(HTMLParser):
88
Parse HTML into text
99
"""
1010

11-
def __init__(self):
11+
def __init__(self) -> None:
1212
super().__init__()
1313
self.meta_description = None
1414

15-
def handle_starttag(self, tag, attrs) -> None:
15+
def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
1616
# For example:
1717
# attrs = [("content", "My manual description"), ("name", "description")]
1818
if ("name", "description") in attrs:

sphinxext/opengraph/socialcards.py

Lines changed: 50 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,23 @@
44

55
import hashlib
66
from pathlib import Path
7+
from typing import TYPE_CHECKING
78

89
import matplotlib
10+
import matplotlib.font_manager
911
import matplotlib.image as mpimg
1012
from matplotlib import pyplot as plt
1113
from sphinx.util import logging
1214

15+
if TYPE_CHECKING:
16+
from typing import TypeAlias
17+
18+
from matplotlib.figure import Figure
19+
from matplotlib.text import Text
20+
from sphinx.application import Sphinx
21+
22+
PltObjects: TypeAlias = tuple[Figure, Text, Text, Text, Text]
23+
1324
matplotlib.use("agg")
1425

1526
LOGGER = logging.getLogger(__name__)
@@ -38,17 +49,23 @@
3849
# They must be defined here otherwise Sphinx errors when trying to pickle them.
3950
# They are dependent on the `multiple` variable defined when the figure is created.
4051
# Because they are depending on the figure size and renderer used to generate them.
41-
def _set_page_title_line_width():
52+
def _set_page_title_line_width() -> int:
4253
return 825
4354

4455

45-
def _set_description_line_width():
56+
def _set_description_line_width() -> int:
4657
return 1000
4758

4859

4960
def create_social_card(
50-
app, config_social, site_name, page_title, description, url_text, page_path
51-
):
61+
app: Sphinx,
62+
config_social: dict[str, bool | str],
63+
site_name: str,
64+
page_title: str,
65+
description: str,
66+
url_text: str,
67+
page_path: str,
68+
) -> Path:
5269
"""Create a social preview card according to page metadata.
5370
5471
This uses page metadata and calls a render function to generate the image.
@@ -75,22 +92,20 @@ def create_social_card(
7592
# This is because we hash the values of the text + images in the social card.
7693
# If the hash doesn't change, it means the output should be the same.
7794
if path_image.exists():
78-
return
95+
return path_images_relative / filename_image
7996

8097
# These kwargs are used to generate the base figure image
81-
kwargs_fig = {}
98+
kwargs_fig: dict[str, str | Path | None] = {}
8299

83100
# Large image to the top right
84-
if config_social.get("image"):
85-
kwargs_fig["image"] = Path(app.builder.srcdir) / config_social.get("image")
101+
if cs_image := config_social.get("image"):
102+
kwargs_fig["image"] = Path(app.builder.srcdir) / cs_image
86103
elif app.config.html_logo:
87104
kwargs_fig["image"] = Path(app.builder.srcdir) / app.config.html_logo
88105

89106
# Mini image to the bottom right
90-
if config_social.get("image_mini"):
91-
kwargs_fig["image_mini"] = Path(app.builder.srcdir) / config_social.get(
92-
"image_mini"
93-
)
107+
if cs_image_mini := config_social.get("image_mini"):
108+
kwargs_fig["image_mini"] = Path(app.builder.srcdir) / cs_image_mini
94109
else:
95110
kwargs_fig["image_mini"] = (
96111
Path(__file__).parent / "_static/sphinx-logo-shadow.png"
@@ -119,18 +134,19 @@ def create_social_card(
119134
kwargs_fig[config] = config_social.get(config)
120135

121136
# Generate the image and store the matplotlib objects so that we can re-use them
122-
if hasattr(app.env, "ogp_social_card_plt_objects"):
137+
try:
123138
plt_objects = app.env.ogp_social_card_plt_objects
124-
else:
125-
plt_objects = None
139+
except AttributeError:
140+
# If objects is None it means this is the first time plotting.
141+
# Create the figure objects and return them so that we re-use them later.
142+
plt_objects = create_social_card_objects(**kwargs_fig)
126143
plt_objects = render_social_card(
127144
path_image,
128145
site_name,
129146
page_title,
130147
description,
131148
url_text,
132149
plt_objects,
133-
kwargs_fig,
134150
)
135151
app.env.ogp_social_card_plt_objects = plt_objects
136152

@@ -140,27 +156,15 @@ def create_social_card(
140156

141157

142158
def render_social_card(
143-
path,
144-
site_title=None,
145-
page_title=None,
146-
description=None,
147-
siteurl=None,
148-
plt_objects=None,
149-
kwargs_fig=None,
150-
):
159+
path: Path,
160+
site_title: str,
161+
page_title: str,
162+
description: str,
163+
siteurl: str,
164+
plt_objects: PltObjects,
165+
) -> PltObjects:
151166
"""Render a social preview card with Matplotlib and write to disk."""
152-
# If objects is None it means this is the first time plotting.
153-
# Create the figure objects and return them so that we re-use them later.
154-
if plt_objects is None:
155-
(
156-
fig,
157-
txt_site_title,
158-
txt_page_title,
159-
txt_description,
160-
txt_url,
161-
) = create_social_card_objects(**kwargs_fig)
162-
else:
163-
fig, txt_site_title, txt_page_title, txt_description, txt_url = plt_objects
167+
fig, txt_site_title, txt_page_title, txt_description, txt_url = plt_objects
164168

165169
# Update the matplotlib text objects with new text from this page
166170
txt_site_title.set_text(site_title)
@@ -174,16 +178,16 @@ def render_social_card(
174178

175179

176180
def create_social_card_objects(
177-
image=None,
178-
image_mini=None,
179-
page_title_color="#2f363d",
180-
description_color="#585e63",
181-
site_title_color="#585e63",
182-
site_url_color="#2f363d",
183-
background_color="white",
184-
line_color="#5A626B",
185-
font=None,
186-
):
181+
image: Path | None = None,
182+
image_mini: Path | None = None,
183+
page_title_color: str = "#2f363d",
184+
description_color: str = "#585e63",
185+
site_title_color: str = "#585e63",
186+
site_url_color: str = "#2f363d",
187+
background_color: str = "white",
188+
line_color: str = "#5A626B",
189+
font: str | None = None,
190+
) -> PltObjects:
187191
"""Create the Matplotlib objects for the first time."""
188192
# If no font specified, load the Roboto Flex font as a fallback
189193
if font is None:

sphinxext/opengraph/titleparser.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,27 @@ class HTMLTextParser(HTMLParser):
88
Parse HTML into text
99
"""
1010

11-
def __init__(self):
11+
def __init__(self) -> None:
1212
super().__init__()
1313
# All text found
1414
self.text = ""
1515
# Only text outside of html tags
1616
self.text_outside_tags = ""
1717
self.level = 0
1818

19-
def handle_starttag(self, tag, attrs) -> None:
19+
def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
2020
self.level += 1
2121

22-
def handle_endtag(self, tag) -> None:
22+
def handle_endtag(self, tag: str) -> None:
2323
self.level -= 1
2424

25-
def handle_data(self, data) -> None:
25+
def handle_data(self, data: str) -> None:
2626
self.text += data
2727
if self.level == 0:
2828
self.text_outside_tags += data
2929

3030

31-
def get_title(title: str):
31+
def get_title(title: str) -> tuple[str, str]:
3232
htp = HTMLTextParser()
3333
htp.feed(title)
3434
htp.close()

0 commit comments

Comments
 (0)