-
-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Implement handler and add templates
- Loading branch information
Showing
57 changed files
with
1,623 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ classifiers = [ | |
] | ||
dependencies = [ | ||
"griffe~=0.3", | ||
"-e ../griffe", | ||
] | ||
|
||
[project.urls] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
"""This module implements a handler for the Python language.""" | ||
|
||
import posixpath | ||
from typing import Any, BinaryIO, Iterator, Optional, Tuple | ||
|
||
from mkdocstrings.handlers.base import BaseHandler | ||
from mkdocstrings.handlers.python.collector import PythonCollector | ||
from mkdocstrings.handlers.python.renderer import PythonRenderer | ||
from mkdocstrings.inventory import Inventory | ||
from mkdocstrings.loggers import get_logger | ||
|
||
log = get_logger(__name__) | ||
|
||
|
||
class PythonHandler(BaseHandler): | ||
"""The Python handler class. | ||
Attributes: | ||
domain: The cross-documentation domain/language for this handler. | ||
enable_inventory: Whether this handler is interested in enabling the creation | ||
of the `objects.inv` Sphinx inventory file. | ||
""" | ||
|
||
domain: str = "py" # to match Sphinx's default domain | ||
enable_inventory: bool = True | ||
|
||
@classmethod | ||
def load_inventory( | ||
cls, in_file: BinaryIO, url: str, base_url: Optional[str] = None, **kwargs | ||
) -> Iterator[Tuple[str, str]]: | ||
"""Yield items and their URLs from an inventory file streamed from `in_file`. | ||
This implements mkdocstrings' `load_inventory` "protocol" (see plugin.py). | ||
Arguments: | ||
in_file: The binary file-like object to read the inventory from. | ||
url: The URL that this file is being streamed from (used to guess `base_url`). | ||
base_url: The URL that this inventory's sub-paths are relative to. | ||
**kwargs: Ignore additional arguments passed from the config. | ||
Yields: | ||
Tuples of (item identifier, item URL). | ||
""" | ||
if base_url is None: | ||
base_url = posixpath.dirname(url) | ||
|
||
for item in Inventory.parse_sphinx(in_file, domain_filter=("py",)).values(): # noqa: WPS526 | ||
yield item.name, posixpath.join(base_url, item.uri) | ||
|
||
|
||
def get_handler( | ||
theme: str, # noqa: W0613 (unused argument config) | ||
custom_templates: Optional[str] = None, | ||
**config: Any, | ||
) -> PythonHandler: | ||
"""Simply return an instance of `PythonHandler`. | ||
Arguments: | ||
theme: The theme to use when rendering contents. | ||
custom_templates: Directory containing custom templates. | ||
config: Configuration passed to the handler. | ||
Returns: | ||
An instance of `PythonHandler`. | ||
""" | ||
return PythonHandler( | ||
collector=PythonCollector(), | ||
renderer=PythonRenderer("python", theme, custom_templates), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
"""This module implements a collector for the Python language. | ||
It collects data with [Griffe](https://github.com/pawamoy/griffe). | ||
""" | ||
|
||
from collections import ChainMap | ||
|
||
from griffe import logger as griffe_logger | ||
|
||
from mkdocstrings.handlers.base import BaseCollector, CollectionError, CollectorItem | ||
from mkdocstrings.loggers import get_logger | ||
|
||
griffe_logger.get_logger = get_logger # patch logger to blend in MkDocs logs | ||
from griffe.collections import LinesCollection, ModulesCollection # noqa: E402 | ||
from griffe.docstrings.parsers import Parser # noqa: E402 | ||
from griffe.extensions import load_extensions # noqa: E402 | ||
from griffe.loader import GriffeLoader # noqa: E402 | ||
|
||
logger = get_logger(__name__) | ||
|
||
|
||
class PythonCollector(BaseCollector): | ||
"""The class responsible for loading Jinja templates and rendering them. | ||
It defines some configuration options, implements the `render` method, | ||
and overrides the `update_env` method of the [`BaseRenderer` class][mkdocstrings.handlers.base.BaseRenderer]. | ||
""" | ||
|
||
default_config: dict = {"docstring_style": "google", "docstring_options": {}} | ||
"""The default selection options. | ||
Option | Type | Description | Default | ||
------ | ---- | ----------- | ------- | ||
**`docstring_style`** | `"google" | "numpy" | "rst" | None` | The docstring style to use. | `"google"` | ||
**`docstring_options`** | dict[str, Any] | The options for the docstring parser. | `{}` | ||
""" | ||
|
||
def __init__(self) -> None: | ||
"""Initialize the object.""" | ||
self._modules_collection: ModulesCollection = ModulesCollection() | ||
self._lines_collection: LinesCollection = LinesCollection() | ||
|
||
def collect(self, identifier: str, config: dict) -> CollectorItem: # noqa: WPS231 | ||
"""Collect the documentation tree given an identifier and selection options. | ||
Arguments: | ||
identifier: The dotted-path of a Python object available in the Python path. | ||
config: Selection options, used to alter the data collection done by `pytkdocs`. | ||
Raises: | ||
CollectionError: When there was a problem collecting the object documentation. | ||
Returns: | ||
The collected object-tree. | ||
""" | ||
final_config = ChainMap(config, self.default_config) | ||
|
||
module_name = identifier.split(".", 1)[0] | ||
if module_name not in self._modules_collection: | ||
loader = GriffeLoader( | ||
extensions=load_extensions(final_config.get("extensions", [])), | ||
docstring_parser=Parser(final_config["docstring_style"]), | ||
docstring_options=final_config["docstring_options"], | ||
modules_collection=self._modules_collection, | ||
lines_collection=self._lines_collection, | ||
) | ||
try: | ||
module = loader.load_module(module_name) | ||
except ModuleNotFoundError as error: | ||
raise CollectionError from error | ||
|
||
for _ in range(5): | ||
if loader.follow_aliases(module): | ||
break | ||
else: | ||
logger.warning("some aliases could not be resolved") | ||
|
||
try: | ||
return self._modules_collection[identifier] | ||
except KeyError as error: # noqa: WPS440 | ||
raise CollectionError from error |
Oops, something went wrong.