Skip to content

Commit 1624e2c

Browse files
committed
ci: Update lint/type-checking
1 parent cc3d6a4 commit 1624e2c

13 files changed

Lines changed: 66 additions & 51 deletions

File tree

config/ruff.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ ignore = [
1818
"EM101", # String literal when raising exception
1919
"EM102", # f-string when raising exception
2020
"ERA001", # Commented out code
21+
"FIX", # TODO, FIXME, etc.
2122
"G004", # Logging statement uses f-string
2223
"PLR0911", # Too many return statements
2324
"PLR0912", # Too many branches
2425
"PLR0913", # Too many arguments to function call
2526
"PLR0915", # Too many statements
2627
"SLF001", # Private member accessed
2728
"S704", # Unsafe use of `markupsafe.Markup`
29+
"TD002", # Missing author in TODO
30+
"TD003", # Missing issue link for TODO
2831
"TRY003", # Avoid specifying long messages outside the exception class
2932
]
3033

config/ty.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[src]
2+
exclude = ["tests/fixtures"]

duties.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,13 @@ def check_types(ctx: Context) -> None:
7979
"""Check that the code is correctly typed."""
8080
py = f"{sys.version_info.major}.{sys.version_info.minor}"
8181
ctx.run(
82-
tools.ty.check(*PY_SRC_LIST, color=True, error_on_warning=True, python_version=py),
82+
tools.ty.check(
83+
*PY_SRC_LIST,
84+
config_file="config/ty.toml",
85+
color=True,
86+
error_on_warning=True,
87+
python_version=py,
88+
),
8389
title=pyprefix("Type-checking"),
8490
)
8591

src/mkdocstrings/_internal/download.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1+
from __future__ import annotations
2+
13
import base64
24
import gzip
35
import os
46
import re
57
import urllib.parse
68
import urllib.request
7-
from collections.abc import Mapping
8-
from typing import BinaryIO, Optional
9+
from typing import TYPE_CHECKING, BinaryIO
910

1011
from mkdocstrings._internal.loggers import get_logger
1112

13+
if TYPE_CHECKING:
14+
from collections.abc import Mapping
15+
16+
1217
_logger = get_logger("mkdocstrings")
1318

1419
# Regex pattern for an environment variable in the form ${ENV_VAR}.
@@ -25,11 +30,11 @@ def _download_url_with_gz(url: str) -> bytes:
2530
with urllib.request.urlopen(req) as resp: # noqa: S310
2631
content: BinaryIO = resp
2732
if "gzip" in resp.headers.get("content-encoding", ""):
28-
content = gzip.GzipFile(fileobj=resp) # type: ignore[assignment]
33+
content = gzip.GzipFile(fileobj=resp) # ty: ignore[invalid-assignment]
2934
return content.read()
3035

3136

32-
def _expand_env_vars(credential: str, url: str, env: Optional[Mapping[str, str]] = None) -> str:
37+
def _expand_env_vars(credential: str, url: str, env: Mapping[str, str] | None = None) -> str:
3338
"""A safe implementation of environment variable substitution.
3439
3540
It only supports the following forms: `${ENV_VAR}`.

src/mkdocstrings/_internal/extension.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def _process_block(
189189
if "locale" in signature(handler.render).parameters:
190190
render = partial(handler.render, locale=self._handlers._locale)
191191
else:
192-
render = handler.render # type: ignore[assignment]
192+
render = handler.render
193193
try:
194194
rendered = render(data, options)
195195
except TemplateNotFound as exc:
@@ -301,7 +301,7 @@ def _remove_duplicated_headings(self, parent: Element) -> None:
301301

302302
class _TocLabelsTreeProcessor(Treeprocessor):
303303
def run(self, root: Element) -> None: # noqa: ARG002
304-
self._override_toc_labels(self.md.toc_tokens) # type: ignore[attr-defined]
304+
self._override_toc_labels(self.md.toc_tokens) # ty: ignore[unresolved-attribute]
305305

306306
def _override_toc_labels(self, tokens: list[dict[str, Any]]) -> None:
307307
for token in tokens:
@@ -349,7 +349,7 @@ def extendMarkdown(self, md: Markdown) -> None: # noqa: N802 (casing: parent me
349349

350350
# Zensical integration: get the current page from the Zensical-specific preprocessor.
351351
if "zensical_current_page" in md.preprocessors:
352-
self._autorefs.current_page = md.preprocessors["zensical_current_page"] # type: ignore[assignment]
352+
self._autorefs.current_page = md.preprocessors["zensical_current_page"]
353353

354354
md.parser.blockprocessors.register(
355355
AutoDocProcessor(md, handlers=self._handlers, autorefs=self._autorefs),
@@ -389,7 +389,7 @@ def extendMarkdown(self, md: Markdown) -> None: # noqa: N802 (casing: parent me
389389

390390
def _split_configs(markdown_extensions: list[str | dict]) -> tuple[list[str | Extension], dict[str, Any]]:
391391
# Split markdown extensions and their configs from mkdocs.yml
392-
mdx: list[str] = []
392+
mdx: list[str | Extension] = []
393393
mdx_config: dict[str, Any] = {}
394394
for item in markdown_extensions:
395395
if isinstance(item, str):
@@ -399,7 +399,7 @@ def _split_configs(markdown_extensions: list[str | dict]) -> tuple[list[str | Ex
399399
mdx.append(key)
400400
mdx_config[key] = value
401401
break # Only one item per dict
402-
return mdx, mdx_config # type: ignore[return-value]
402+
return mdx, mdx_config
403403

404404

405405
class _ToolConfig:

src/mkdocstrings/_internal/handlers/base.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -150,16 +150,14 @@ def __init__(
150150

151151
# add extended theme templates
152152
extended_templates_dirs = self.get_extended_templates_dirs(self.name)
153-
for templates_dir in extended_templates_dirs:
154-
paths.append(templates_dir / self.theme)
153+
paths.extend(templates_dir / self.theme for templates_dir in extended_templates_dirs)
155154

156155
# add fallback theme templates
157156
if self.fallback_theme and self.fallback_theme != self.theme:
158157
paths.append(themes_dir / self.fallback_theme)
159158

160159
# add fallback theme of extended templates
161-
for templates_dir in extended_templates_dirs:
162-
paths.append(templates_dir / self.fallback_theme)
160+
paths.extend(templates_dir / self.fallback_theme for templates_dir in extended_templates_dirs)
163161

164162
for path in paths:
165163
css_path = path / "style.css"
@@ -361,24 +359,24 @@ def do_convert_markdown(
361359
global _markdown_conversion_layer # noqa: PLW0603
362360
_markdown_conversion_layer += 1
363361
treeprocessors = self.md.treeprocessors
364-
treeprocessors[HeadingShiftingTreeprocessor.name].shift_by = heading_level # type: ignore[attr-defined]
365-
treeprocessors[IdPrependingTreeprocessor.name].id_prefix = html_id and html_id + "--" # type: ignore[attr-defined]
366-
treeprocessors[ParagraphStrippingTreeprocessor.name].strip = strip_paragraph # type: ignore[attr-defined]
362+
treeprocessors[HeadingShiftingTreeprocessor.name].shift_by = heading_level
363+
treeprocessors[IdPrependingTreeprocessor.name].id_prefix = html_id and html_id + "--"
364+
treeprocessors[ParagraphStrippingTreeprocessor.name].strip = strip_paragraph
367365
if BacklinksTreeProcessor.name in treeprocessors:
368-
treeprocessors[BacklinksTreeProcessor.name].initial_id = html_id # type: ignore[attr-defined]
366+
treeprocessors[BacklinksTreeProcessor.name].initial_id = html_id
369367
if autoref_hook and AutorefsInlineProcessor.name in self.md.inlinePatterns:
370-
self.md.inlinePatterns[AutorefsInlineProcessor.name].hook = autoref_hook # type: ignore[attr-defined]
368+
self.md.inlinePatterns[AutorefsInlineProcessor.name].hook = autoref_hook # ty: ignore[unresolved-attribute]
371369

372370
try:
373371
return Markup(self.md.convert(text))
374372
finally:
375-
treeprocessors[HeadingShiftingTreeprocessor.name].shift_by = 0 # type: ignore[attr-defined]
376-
treeprocessors[IdPrependingTreeprocessor.name].id_prefix = "" # type: ignore[attr-defined]
377-
treeprocessors[ParagraphStrippingTreeprocessor.name].strip = False # type: ignore[attr-defined]
373+
treeprocessors[HeadingShiftingTreeprocessor.name].shift_by = 0
374+
treeprocessors[IdPrependingTreeprocessor.name].id_prefix = ""
375+
treeprocessors[ParagraphStrippingTreeprocessor.name].strip = False
378376
if BacklinksTreeProcessor.name in treeprocessors:
379-
treeprocessors[BacklinksTreeProcessor.name].initial_id = None # type: ignore[attr-defined]
377+
treeprocessors[BacklinksTreeProcessor.name].initial_id = None
380378
if AutorefsInlineProcessor.name in self.md.inlinePatterns:
381-
self.md.inlinePatterns[AutorefsInlineProcessor.name].hook = None # type: ignore[attr-defined]
379+
self.md.inlinePatterns[AutorefsInlineProcessor.name].hook = None
382380
self.md.reset()
383381
_markdown_conversion_layer -= 1
384382

@@ -475,11 +473,11 @@ def _update_env(self, md: Markdown, *, config: Any | None = None) -> None:
475473
# MkDocs adds its own (required) extension that's not part of the config. Propagate it.
476474
if "relpath" in md.treeprocessors:
477475
relpath = md.treeprocessors["relpath"]
478-
new_relpath = type(relpath)(relpath.file, relpath.files, relpath.config) # type: ignore[attr-defined,call-arg]
476+
new_relpath = type(relpath)(relpath.file, relpath.files, relpath.config)
479477
new_md.treeprocessors.register(new_relpath, "relpath", priority=0)
480478
elif "zrelpath" in md.treeprocessors:
481479
zrelpath = md.treeprocessors["zrelpath"]
482-
new_zrelpath = type(zrelpath)(new_md, zrelpath.path, zrelpath.use_directory_urls) # type: ignore[attr-defined,call-arg]
480+
new_zrelpath = type(zrelpath)(new_md, zrelpath.path, zrelpath.use_directory_urls)
483481
new_md.treeprocessors.register(new_zrelpath, "zrelpath", priority=0)
484482

485483
self._md = new_md
@@ -603,7 +601,7 @@ def _download_inventories(self) -> None:
603601
for handler_name, conf in self._handlers_config.items():
604602
handler = self.get_handler(handler_name)
605603

606-
if handler.get_inventory_urls.__func__ is BaseHandler.get_inventory_urls: # type: ignore[attr-defined]
604+
if handler.get_inventory_urls.__func__ is BaseHandler.get_inventory_urls:
607605
if inv_configs := conf.pop("import", ()):
608606
warn(
609607
"mkdocstrings v1 will stop handling 'import' in handlers configuration. "
@@ -645,7 +643,7 @@ def _yield_inventory_items(self) -> Iterator[tuple[str, str]]:
645643
for fut, (handler, url, conf) in reversed(self._inv_futures.items()):
646644
try:
647645
yield from handler.load_inventory(BytesIO(fut.result()), url, **conf)
648-
except Exception as error: # noqa: BLE001
646+
except Exception as error: # noqa: BLE001,PERF203
649647
_logger.error("Couldn't load inventory %s through handler '%s': %s", url, handler.name, error) # noqa: TRY400
650648
self._inv_futures = {}
651649

src/mkdocstrings/_internal/handlers/rendering.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def __init__(self, md: Markdown):
8484
self._css_class = config.pop("css_class", "highlight")
8585
super().__init__(**{name: opt for name, opt in config.items() if name in self._highlight_config_keys})
8686

87-
def highlight(
87+
def highlight( # ty: ignore[invalid-method-override]
8888
self,
8989
src: str,
9090
language: str | None = None,
@@ -113,7 +113,7 @@ def highlight(
113113
src = textwrap.dedent(src)
114114

115115
kwargs.setdefault("css_class", self._css_class)
116-
old_linenums = self.linenums # type: ignore[has-type]
116+
old_linenums = self.linenums
117117
if linenums is not None:
118118
self.linenums = linenums
119119
try:
@@ -240,7 +240,7 @@ def __init__(self, md: Markdown, headings: list[Element]):
240240

241241
def run(self, root: Element) -> None:
242242
"""Record all heading elements encountered in the document."""
243-
permalink_class = self.md.treeprocessors["toc"].permalink_class # type: ignore[attr-defined]
243+
permalink_class = self.md.treeprocessors["toc"].permalink_class
244244
for el in root.iter():
245245
if self.regex.fullmatch(el.tag):
246246
el = copy.copy(el) # noqa: PLW2901

src/mkdocstrings/_internal/loggers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def log(self, level: int, msg: object, *args: object, **kwargs: object) -> None:
8282
if (key := (self, str(msg))) in self._logged:
8383
return
8484
self._logged.add(key)
85-
super().log(level, msg, *args, **kwargs) # type: ignore[arg-type]
85+
super().log(level, msg, *args, **kwargs) # ty: ignore[invalid-argument-type]
8686

8787

8888
class TemplateLogger:

src/mkdocstrings/_internal/plugin.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def on_config(self, config: MkDocsConfig) -> MkDocsConfig | None:
140140
handlers = Handlers(
141141
default=self.config.default_handler,
142142
handlers_config=self.config.handlers,
143-
theme=config.theme.name or os.path.dirname(config.theme.dirs[0]),
143+
theme=config.theme.name or os.path.dirname(config.theme.dirs[0]), # noqa: PTH120
144144
custom_templates=self.config.custom_templates,
145145
mdx=config.markdown_extensions,
146146
mdx_config=config.mdx_configs,
@@ -156,7 +156,7 @@ def on_config(self, config: MkDocsConfig) -> MkDocsConfig | None:
156156
autorefs: AutorefsPlugin
157157
try:
158158
# If autorefs plugin is explicitly enabled, just use it.
159-
autorefs = config.plugins["autorefs"] # type: ignore[assignment]
159+
autorefs = config.plugins["autorefs"] # ty: ignore[invalid-assignment]
160160
_logger.debug("Picked up existing autorefs instance %r", autorefs)
161161
except KeyError:
162162
# Otherwise, add a limited instance of it that acts only on what's added through `register_anchor`.
@@ -167,7 +167,7 @@ def on_config(self, config: MkDocsConfig) -> MkDocsConfig | None:
167167
_logger.debug("Added a subdued autorefs instance %r", autorefs)
168168

169169
mkdocstrings_extension = MkdocstringsExtension(handlers, autorefs)
170-
config.markdown_extensions.append(mkdocstrings_extension) # type: ignore[arg-type]
170+
config.markdown_extensions.append(mkdocstrings_extension) # ty: ignore[invalid-argument-type]
171171

172172
config.extra_css.insert(0, self.css_filename) # So that it has lower priority than user files.
173173

@@ -199,22 +199,22 @@ def plugin_enabled(self) -> bool:
199199
@event_priority(50) # Early, before autorefs' starts applying cross-refs and collecting backlinks.
200200
def _on_env_load_inventories(self, env: Environment, config: MkDocsConfig, *args: Any, **kwargs: Any) -> None: # noqa: ARG002
201201
if self.plugin_enabled and self._handlers:
202-
register = config.plugins["autorefs"].register_url # type: ignore[attr-defined]
202+
register = config.plugins["autorefs"].register_url # ty: ignore[possibly-missing-attribute]
203203
for identifier, url in self._handlers._yield_inventory_items():
204204
register(identifier, url)
205205

206206
@event_priority(-20) # Late, not important.
207207
def _on_env_add_css(self, env: Environment, config: MkDocsConfig, *args: Any, **kwargs: Any) -> None: # noqa: ARG002
208208
if self.plugin_enabled and self._handlers:
209209
css_content = "\n".join(handler.extra_css for handler in self.handlers.seen_handlers)
210-
write_file(css_content.encode("utf-8"), os.path.join(config.site_dir, self.css_filename))
210+
write_file(css_content.encode("utf-8"), os.path.join(config.site_dir, self.css_filename)) # noqa: PTH118
211211

212212
@event_priority(-20) # Late, not important.
213213
def _on_env_write_inventory(self, env: Environment, config: MkDocsConfig, *args: Any, **kwargs: Any) -> None: # noqa: ARG002
214214
if self.plugin_enabled and self._handlers and self.inventory_enabled:
215215
_logger.debug("Creating inventory file objects.inv")
216216
inv_contents = self.handlers.inventory.format_sphinx()
217-
write_file(inv_contents, os.path.join(config.site_dir, "objects.inv"))
217+
write_file(inv_contents, os.path.join(config.site_dir, "objects.inv")) # noqa: PTH118
218218

219219
@event_priority(-100) # Last, after autorefs has finished applying cross-refs and collecting backlinks.
220220
def _on_env_apply_backlinks(self, env: Environment, /, *, config: MkDocsConfig, files: Files) -> Environment: # noqa: ARG002
@@ -226,12 +226,12 @@ def repl(match: Match) -> str:
226226

227227
# The handler doesn't implement backlinks,
228228
# return early to avoid computing them.
229-
if handler.render_backlinks.__func__ is BaseHandler.render_backlinks: # type: ignore[attr-defined]
229+
if handler.render_backlinks.__func__ is BaseHandler.render_backlinks:
230230
return ""
231231

232232
identifier = match.group(1)
233233
aliases = handler.get_aliases(identifier)
234-
backlinks = self._autorefs.get_backlinks(identifier, *aliases, from_url=file.page.url) # type: ignore[union-attr]
234+
backlinks = self._autorefs.get_backlinks(identifier, *aliases, from_url=file.page.url)
235235

236236
# No backlinks, avoid calling the handler's method.
237237
if not backlinks:
@@ -240,7 +240,7 @@ def repl(match: Match) -> str:
240240
if "locale" in signature(handler.render_backlinks).parameters:
241241
render_backlinks = partial(handler.render_backlinks, locale=self.handlers._locale)
242242
else:
243-
render_backlinks = handler.render_backlinks # type: ignore[assignment]
243+
render_backlinks = handler.render_backlinks
244244

245245
return render_backlinks(backlinks)
246246

tests/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def fixture_mkdocs_conf(request: pytest.FixtureRequest, tmp_path: Path) -> Itera
2323
"""Yield a MkDocs configuration object."""
2424
conf = MkDocsConfig()
2525
while hasattr(request, "_parent_request") and hasattr(request._parent_request, "_parent_request"):
26-
request = request._parent_request
26+
request = request._parent_request # ty: ignore[invalid-assignment]
2727

2828
conf_dict = {
2929
"site_name": "foo",
@@ -33,7 +33,7 @@ def fixture_mkdocs_conf(request: pytest.FixtureRequest, tmp_path: Path) -> Itera
3333
**getattr(request, "param", {}),
3434
}
3535
# Re-create it manually as a workaround for https://github.com/mkdocs/mkdocs/issues/2289
36-
mdx_configs: dict[str, Any] = dict(ChainMap(*conf_dict.get("markdown_extensions", [])))
36+
mdx_configs: dict[str, Any] = dict(ChainMap(*conf_dict.get("markdown_extensions", []))) # ty: ignore[invalid-argument-type]
3737

3838
conf.load_dict(conf_dict)
3939
assert conf.validate() == ([], [])

0 commit comments

Comments
 (0)