8000 ci: Quality · diviyank/python@1a131d7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1a131d7

Browse files
committed
ci: Quality
1 parent 2860bb6 commit 1a131d7

File tree

8 files changed

+105
-71
lines changed

8 files changed

+105
-71
lines changed

src/mkdocstrings_handlers/python/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from mkdocstrings_handlers.python.handler import get_handler
44

5-
__all__ = ["get_handler"] # noqa: WPS410
5+
__all__ = ["get_handler"]
66

77
# TODO: CSS classes everywhere in templates
88
# TODO: name normalization (filenames, Jinja2 variables, HTML tags, CSS classes)

src/mkdocstrings_handlers/python/handler.py

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,33 @@
1010
import sys
1111
from collections import ChainMap
1212
from contextlib import suppress
13-
from typing import Any, BinaryIO, Iterator, Mapping, Optional, Tuple
13+
from typing import TYPE_CHECKING, Any, BinaryIO, Iterator, Mapping
1414

1515
from griffe.agents.extensions import load_extensions
1616
from griffe.collections import LinesCollection, ModulesCollection
1717
from griffe.docstrings.parsers import Parser
1818
from griffe.exceptions import AliasResolutionError
1919
from griffe.loader import GriffeLoader
2020
from griffe.logger import patch_loggers
21-
from markdown import Markdown
2221
from mkdocstrings.extension import PluginError
2322
from mkdocstrings.handlers.base import BaseHandler, CollectionError, CollectorItem
2423
from mkdocstrings.inventory import Inventory
2524
from mkdocstrings.loggers import get_logger
2625

2726
from mkdocstrings_handlers.python import rendering
2827

28+
if TYPE_CHECKING:
29+
from markdown import Markdown
30+
31+
2932
if sys.version_info >= (3, 11):
3033
from contextlib import chdir
3134
else:
3235
# TODO: remove once support for Python 3.10 is dropped
3336
from contextlib import contextmanager
3437

35-
@contextmanager # noqa: WPS440
36-
def chdir(path: str): # noqa: D103,WPS440
38+
@contextmanager
39+
def chdir(path: str) -> Iterator[None]: # noqa: D103
3740
old_wd = os.getcwd()
3841
os.chdir(path)
3942
try:
@@ -162,10 +165,14 @@ class PythonHandler(BaseHandler):
162165
163166
The modules must be listed as an array of strings. Default: `None`.
164167
165-
""" # noqa: E501
168+
"""
166169

167170
def __init__(
168-
self, *args: Any, config_file_path: str | None = None, paths: list[str] | None = None, **kwargs: Any
171+
self,
172+
*args: Any,
173+
config_file_path: str | None = None,
174+
paths: list[str] | None = None,
175+
**kwargs: Any,
169176
) -> None:
170177
"""Initialize the handler.
171178
@@ -186,9 +193,8 @@ def __init__(
186193
paths.append(os.path.dirname(config_file_path))
187194
search_paths = [path for path in sys.path if path] # eliminate empty path
188195
for path in reversed(paths):
189-
if not os.path.isabs(path):
190-
if config_file_path:
191-
path = os.path.abspath(os.path.join(os.path.dirname(config_file_path), path))
196+
if not os.path.isabs(path) and config_file_path:
197+
path = os.path.abspath(os.path.join(os.path.dirname(config_file_path), path)) # noqa: PLW2901
192198
if path not in search_paths:
193199
search_paths.insert(0, path)
194200
self._paths = search_paths
@@ -200,10 +206,10 @@ def load_inventory(
200206
cls,
201207
in_file: BinaryIO,
202208
url: str,
203-
base_url: Optional[str] = None,
209+
base_url: str | None = None,
204210
domains: list[str] | None = None,
205-
**kwargs: Any,
206-
) -> Iterator[Tuple[str, str]]:
211+
**kwargs: Any, # noqa: ARG003
212+
) -> Iterator[tuple[str, str]]:
207213
"""Yield items and their URLs from an inventory file streamed from `in_file`.
208214
209215
This implements mkdocstrings' `load_inventory` "protocol" (see [`mkdocstrings.plugin`][mkdocstrings.plugin]).
@@ -222,10 +228,10 @@ def load_inventory(
222228
if base_url is None:
223229
base_url = posixpath.dirname(url)
224230

225-
for item in Inventory.parse_sphinx(in_file, domain_filter=domains).values(): # noqa: WPS526
231+
for item in Inventory.parse_sphinx(in_file, domain_filter=domains).values():
226232
yield item.name, posixpath.join(base_url, item.uri)
227233

228-
def collect(self, identifier: str, config: Mapping[str, Any]) -> CollectorItem: # noqa: D102,WPS231
234+
def collect(self, identifier: str, config: Mapping[str, Any]) -> CollectorItem: # noqa: D102
229235
module_name = identifier.split(".", 1)[0]
230236
unknown_module = module_name not in self._modules_collection
231237
if config.get("fallback", False) and unknown_module:
@@ -247,23 +253,24 @@ def collect(self, identifier: str, config: Mapping[str, Any]) -> CollectorItem:
247253
modules_collection=self._modules_collection,
248254
lines_collection=self._lines_collection,
249255
)
250-
try: # noqa: WPS229 we expect one type of exception, and want to fail on the first one
256+
try:
251257
for pre_loaded_module in final_config.get("preload_modules") or []:
252258
if pre_loaded_module not in self._modules_collection:
253259
loader.load_module(pre_loaded_module)
254260
loader.load_module(module_name)
255261
except ImportError as error:
256262
raise CollectionError(str(error)) from error
257263
unresolved, iterations = loader.resolve_aliases(
258-
implicit=False, external=final_config["load_external_modules"]
264+
implicit=False,
265+
external=final_config["load_external_modules"],
259266
)
260267
if unresolved:
261268
logger.debug(f"{len(unresolved)} aliases were still unresolved after {iterations} iterations")
262269
logger.debug(f"Unresolved aliases: {', '.join(sorted(unresolved))}")
263270

264271
try:
265272
doc_object = self._modules_collection[identifier]
266-
except KeyError as error: # noqa: WPS440
273+
except KeyError as error:
267274
raise CollectionError(f"{identifier} could not be found") from error
268275

269276
if not unknown_module:
@@ -287,9 +294,11 @@ def render(self, data: CollectorItem, config: Mapping[str, Any]) -> str: # noqa
287294
heading_level = final_config["heading_level"]
288295
try:
289296
final_config["members_order"] = rendering.Order(final_config["members_order"])
290-
except ValueError:
297+
except ValueError as error:
291298
choices = "', '".join(item.value for item in rendering.Order)
292-
raise PluginError(f"Unknown members_order '{final_config['members_order']}', choose between '{choices}'.")
299+
raise PluginError(
300+
f"Unknown members_order '{final_config['members_order']}', choose between '{choices}'.",
301+
) from error
293302

294303
if final_config["filters"]:
295304
final_config["filters"] = [
@@ -320,11 +329,11 @@ def get_anchors(self, data: CollectorItem) -> list[str]: # noqa: D102 (ignore m
320329

321330

322331
def get_handler(
323-
theme: str, # noqa: W0613 (unused argument config)
324-
custom_templates: Optional[str] = None,
332+
theme: str,
333+
custom_templates: str | None = None,
325334
config_file_path: str | None = None,
326335
paths: list[str] | None = None,
327-
**config: Any,
336+
**config: Any, # noqa: ARG001
328337
) -> PythonHandler:
329338
"""Simply return an instance of `PythonHandler`.
330339

src/mkdocstrings_handlers/python/rendering.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
import re
77
import sys
88
from functools import lru_cache
9-
from typing import Any, Pattern, Sequence
9+
from typing import TYPE_CHECKING, Any, Callable, Match, Pattern, Sequence
1010

11-
from griffe.dataclasses import Alias, Object
1211
from markupsafe import Markup
13-
from mkdocstrings.handlers.base import CollectorItem
1412
from mkdocstrings.loggers import get_logger
1513

14+
if TYPE_CHECKING:
15+
from griffe.dataclasses import Alias, Object
16+
from mkdocstrings.handlers.base import CollectorItem
17+
1618
logger = get_logger(__name__)
1719

1820

@@ -102,7 +104,7 @@ def do_order_members(
102104
return sorted(members, key=order_map[order])
103105

104106

105-
def do_crossref(path: str, brief: bool = True) -> Markup:
107+
def do_crossref(path: str, *, brief: bool = True) -> Markup:
106108
"""Filter to create cross-references.
107109
108110
Parameters:
@@ -118,7 +120,7 @@ def do_crossref(path: str, brief: bool = True) -> Markup:
118120
return Markup("<span data-autorefs-optional-hover={full_path}>{path}</span>").format(full_path=full_path, path=path)
119121

120122

121-
def do_multi_crossref(text: str, code: bool = True) -> Markup:
123+
def do_multi_crossref(text: str, *, code: bool = True) -> Markup:
122124
"""Filter to create cross-references.
123125
124126
Parameters:
@@ -131,8 +133,8 @@ def do_multi_crossref(text: str, code: bool = True) -> Markup:
131133
group_number = 0
132134
variables = {}
133135

134-
def repl(match): # noqa: WPS430
135-
nonlocal group_number # noqa: WPS420
136+
def repl(match: Match) -> str:
137+
nonlocal group_number
136138
group_number += 1
137139
path = match.group()
138140
path_var = f"path{group_number}"
@@ -145,15 +147,15 @@ def repl(match): # noqa: WPS430
145147
return Markup(text).format(**variables)
146148

147149

148-
def _keep_object(name, filters):
150+
def _keep_object(name: str, filters: Sequence[tuple[Pattern, bool]]) -> bool:
149151
keep = None
150152
rules = set()
151153
for regex, exclude in filters:
152154
rules.add(exclude)
153155
if regex.search(name):
154156
keep = not exclude
155157
if keep is None:
156-
if rules == {False}: # noqa: WPS531
158+
if rules == {False}:
157159
# only included stuff, no match = reject
158160
return False
159161
# only excluded stuff, or included and excluded stuff, no match = keep
@@ -163,7 +165,8 @@ def _keep_object(name, filters):
163165

164166
def do_filter_objects(
165167
objects_dictionary: dict[str, Object | Alias],
166-
filters: list[tuple[bool, Pattern]] | None = None,
168+
*,
169+
filters: Sequence[tuple[Pattern, bool]] | None = None,
167170
members_list: list[str] | None = None,
168171
keep_no_docstrings: bool = True,
169172
) -> list[Object | Alias]:
@@ -195,14 +198,14 @@ def do_filter_objects(
195198

196199

197200
@lru_cache(maxsize=1)
198-
def _get_black_formatter():
201+
def _get_black_formatter() -> Callable[[str, int], str]:
199202
try:
200203
from black import Mode, format_str
201204
except ModuleNotFoundError:
202205
logger.warning("Formatting signatures requires Black to be installed.")
203206
return lambda text, _: text
204207

205-
def formatter(code, line_length): # noqa: WPS430
208+
def formatter(code: str, line_length: int) -> str:
206209
mode = Mode(line_length=line_length)
207210
return format_str(code, mode=mode)
208211

src/mkdocstrings_handlers/python/templates/material/_base/children.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
{% set extra_level = 0 %}
2020
{% endif %}
2121

22-
{% with attributes = obj.attributes|filter_objects(config.filters, members_list, config.show_if_no_docstring) %}
22+
{% with attributes = obj.attributes|filter_objects(filters=config.filters, members_list=members_list, keep_no_docstrings=config.show_if_no_docstring) %}
2323
{% if attributes %}
2424
{% if config.show_category_heading %}
2525
{% filter heading(heading_level, id=html_id ~ "-attributes") %}Attributes{% endfilter %}
@@ -34,7 +34,7 @@
3434
{% endif %}
3535
{% endwith %}
3636

37-
{% with classes = obj.classes|filter_objects(config.filters, members_list, config.show_if_no_docstring) %}
37+
{% with classes = obj.classes|filter_objects(filters=config.filters, members_list=members_list, keep_no_docstrings=config.show_if_no_docstring) %}
3838
{% if classes %}
3939
{% if config.show_category_heading %}
4040
{% filter heading(heading_level, id=html_id ~ "-classes") %}Classes{% endfilter %}
@@ -49,7 +49,7 @@
4949
{% endif %}
5050
{% endwith %}
5151

52-
{% with functions = obj.functions|filter_objects(config.filters, members_list, config.show_if_no_docstring) %}
52+
{% with functions = obj.functions|filter_objects(filters=config.filters, members_list=members_list, keep_no_docstrings=config.show_if_no_docstring) %}
5353
{% if functions %}
5454
{% if config.show_category_heading %}
5555
{% filter heading(heading_level, id=html_id ~ "-functions") %}Functions{% endfilter %}
@@ -67,7 +67,7 @@
6767
{% endwith %}
6868

6969
{% if config.show_submodules %}
70-
{% with modules = obj.modules|filter_objects(config.filters, members_list, config.show_if_no_docstring) %}
70+
{% with modules = obj.modules|filter_objects(filters=config.filters, members_list=members_list, keep_no_docstrings=config.show_if_no_docstring) %}
7171
{% if modules %}
7272
{% if config.show_category_heading %}
7373
{% filter heading(heading_level, id=html_id ~ "-modules") %}Modules{% endfilter %}
@@ -88,7 +88,7 @@
8888
{% else %}
8989

9090
{% for child in obj.members|
91-
filter_objects(config.filters, members_list, config.show_if_no_docstring)|
91+
filter_objects(filters=config.filters, members_list=members_list, keep_no_docstrings=config.show_if_no_docstring)|
9292
order_members(config.members_order, members_list) %}
9393

9494
{% if not (obj.kind.value == "class" and child.name == "__init__" and config.merge_init_into_class) %}

tests/conftest.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,23 @@
33
from __future__ import annotations
44

55
from collections import ChainMap
6+
from typing import TYPE_CHECKING, Any, Iterator
67

78
import pytest
89
from markdown.core import Markdown
910
from mkdocs import config
1011
from mkdocs.config.defaults import get_schema
1112

13+
if TYPE_CHECKING:
14+
from pathlib import Path
15+
16+
from mkdocstrings.plugin import MkdocstringsPlugin
17+
18+
from mkdocstrings_handlers.python.handler import PythonHandler
19+
1220

1321
@pytest.fixture(name="mkdocs_conf")
14-
def fixture_mkdocs_conf(request, tmp_path):
22+
def fixture_mkdocs_conf(request: pytest.FixtureRequest, tmp_path: Path) -> Iterator[config.Config]:
1523
"""Yield a MkDocs configuration object.
1624
1725
Parameters:
@@ -21,9 +29,9 @@ def fixture_mkdocs_conf(request, tmp_path):
2129
Yields:
2230
MkDocs config.
2331
"""
24-
conf = config.Config(schema=get_schema())
25-
while hasattr(request, "_parent_request") and hasattr(request._parent_request, "_parent_request"): # noqa: WPS437
26-
request = request._parent_request # noqa: WPS437
32+
conf = config.Config(schema=get_schema()) # type: ignore[call-arg]
33+
while hasattr(request, "_parent_request") and hasattr(request._parent_request, "_parent_request"):
34+
request = request._parent_request
2735

2836
conf_dict = {
2937
"site_name": "foo",
@@ -33,7 +41,7 @@ def fixture_mkdocs_conf(request, tmp_path):
3341
**getattr(request, "param", {}),
3442
}
3543
# Re-create it manually as a workaround for https://github.com/mkdocs/mkdocs/issues/2289
36-
mdx_configs = dict(ChainMap(*conf_dict.get("markdown_extensions", [])))
44+
mdx_configs: dict[str, Any] = dict(ChainMap(*conf_dict.get("markdown_extensions", []))) # type: ignore[arg-type]
3745

3846
conf.load_dict(conf_dict)
3947
assert conf.validate() == ([], [])
@@ -48,7 +56,7 @@ def fixture_mkdocs_conf(request, tmp_path):
4856

4957

5058
@pytest.fixture(name="plugin")
51-
def fixture_plugin(mkdocs_conf):
59+
def fixture_plugin(mkdocs_conf: config.Config) -> MkdocstringsPlugin:
5260
"""Return a plugin instance.
5361
5462
Parameters:
@@ -57,26 +65,24 @@ def fixture_plugin(mkdocs_conf):
5765
Returns:
5866
mkdocstrings plugin instance.
5967
"""
60-
plugin = mkdocs_conf["plugins"]["mkdocstrings"]
61-
plugin.md = Markdown(extensions=mkdocs_conf["markdown_extensions"], extension_configs=mkdocs_conf["mdx_configs"])
62-
return plugin
68+
return mkdocs_conf["plugins"]["mkdocstrings"]
6369

6470

6571
@pytest.fixture(name="ext_markdown")
66-
def fixture_ext_markdown(plugin):
72+
def fixture_ext_markdown(mkdocs_conf: config.Config) -> Markdown:
6773
"""Return a Markdown instance with MkdocstringsExtension.
6874
6975
Parameters:
70-
plugin: Pytest fixture: [tests.conftest.fixture_plugin][].
76+
mkdocs_conf: Pytest fixture: [tests.conftest.fixture_mkdocs_conf][].
7177
7278
Returns:
7379
A Markdown instance.
7480
"""
75-
return plugin.md
81+
return Markdown(extensions=mkdocs_conf["markdown_extensions"], extension_configs=mkdocs_conf["mdx_configs"])
7682

7783

7884
@pytest.fixture(name="handler")
79-
def fixture_handler(plugin):
85+
def fixture_handler(plugin: MkdocstringsPlugin, ext_markdown: Markdown) -> PythonHandler:
8086
"""Return a handler instance.
8187
8288
Parameters:
@@ -86,5 +92,5 @@ def fixture_handler(plugin):
8692
A handler instance.
8793
"""
8894
handler = plugin.handlers.get_handler("python")
89-
handler._update_env(plugin.md, plugin.handlers._config) # noqa: WPS437
90-
return handler
95+
handler._update_env(ext_markdown, plugin.handlers._config)
96+
return handler # type: ignore[return-value]

0 commit comments

Comments
 (0)
0