From 0a570562c2c4d58288f62252bad6c8ccc6eb8682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 3 Feb 2022 19:57:53 +0100 Subject: [PATCH 1/6] docs: Update docs --- README.md | 29 ++++++--- docs/usage.md | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 3 + 3 files changed, 198 insertions(+), 9 deletions(-) create mode 100644 docs/usage.md diff --git a/README.md b/README.md index 099db3d0..38fbb568 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![gitpod](https://img.shields.io/badge/gitpod-workspace-blue.svg?style=flat)](https://gitpod.io/#https://github.com/mkdocstrings/python) [![gitter](https://badges.gitter.im/join%20chat.svg)](https://gitter.im/python/community) -A Python handler for mkdocstrings. +A Python handler for [mkdocstrings](https://github.com/mkdocstrings/mkdocstrings). ## Requirements @@ -34,13 +34,24 @@ pyenv global system 3.7.12 ## Installation -With `pip`: -```bash -pip install mkdocstrings-python -``` +You can install this handler as a *mkdocstrings* extra: -With [`pipx`](https://github.com/pipxproject/pipx): -```bash -python3.7 -m pip install --user pipx -pipx install mkdocstrings-python +```toml +# PEP 621 dependencies declaration +# adapt to your dependencies manager +[project] +dependencies = [ + "mkdocstrings[python]>=0.18", +] ``` + +You can also explicitely depend on the handler: + +```toml +# PEP 621 dependencies declaration +# adapt to your dependencies manager +[project] +dependencies = [ + "mkdocstrings-python", +] +``` \ No newline at end of file diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 00000000..fd9f203a --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,175 @@ +## Handler options + +!!! warning "This the documentation for the NEW, EXPERIMENTAL Python handler." + To read the documentation for the LEGACY handler, + go to the [legacy handler documentation](https://mkdocstrings.github.io/python-legacy). + +Like every handler, the Python handler accepts the common +[`selection`](#selection) and [`rendering`](#rendering) options, +both as **global** and **local** options. +The `selection` options gives you control over the selection of Python objects, +while the `rendering` options lets you change how the documentation is rendered. + +### Selection + +The following options are directly passed to the handler's collector. +See [Collector: Griffe](#collector-griffe) to learn more about Griffe. + +Option | Description +------ | ----------- +**`docstring_style`** | Type: `str`. Docstring style to parse: `google` (default), `numpy` or `sphinx`. +**`docstring_options`** | Type: `dict`. Options to pass to the docstring parser. See [Collector: Griffe](#collector-griffe). + +!!! example "Configuration example" + === "Global" + ```yaml + # mkdocs.yml + plugins: + - mkdocstrings: + handlers: + python: + selection: + docstring_style: google + ``` + + === "Local" + ```yaml + ::: my_package + selection: + docstring_style: sphinx + ``` + +### Rendering + +::: mkdocstrings_handlers.python.renderer.PythonRenderer.default_config + rendering: + show_root_toc_entry: false + +These options affect how the documentation is rendered. + +!!! example "Configuration example" + === "Global" + ```yaml + # mkdocs.yml + plugins: + - mkdocstrings: + handlers: + python: + rendering: + show_root_heading: yes + ``` + + === "Local" + ```md + ## `ClassA` + + ::: my_package.my_module.ClassA + rendering: + show_root_heading: no + heading_level: 3 + ``` + +## Collector: Griffe + +The tool used by the Python handler to collect documentation from Python source code +is [Griffe](https://mkdocstrings.github.io/griffe). Griffe can mean "signature" in french. + +### Supported docstrings styles + +Griffe supports the Google-style, Numpy-style and Sphinx-style docstring formats. +The style used by default is the Google-style. +You can configure what style you want to use with +the `docstring_style` and `docstring_options` [selection options](#selection), +both globally or per autodoc instruction. + +- Google: see [Napoleon's documentation](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html). +- Numpy: see [Numpydoc's documentation](https://numpydoc.readthedocs.io/en/latest/format.html). +- Sphinx: see [Sphinx's documentation](https://sphinx-rtd-tutorial.readthedocs.io/en/latest/docstrings.html). + +See the supported docstring sections on [Griffe's documentation](https://mkdocstrings.github.io/griffe/docstrings/). + +#### Google-style admonitions + +With Google-style docstrings, any section that is not recognized will be transformed into its admonition equivalent. +For example: + +=== "Docstring" + ```python + """ + Important: + It looks like a section, but it will be rendered as an admonition. + + Tip: You can even chose a title. + This admonition has a custom title! + """ + ``` + +=== "Result" + !!! important + It looks like a section, but it will be rendered as an admonition. + + !!! tip "You can even chose a title." + This admonition has a custom title! + +## Finding modules + +In order for Griffe to find your packages and modules, +you can take advantage of the usual Python loading mechanisms: + +- install your package in the current virtualenv: + ```bash + . venv/bin/activate + pip install -e . + ``` + + ```bash + poetry install + ``` + + ...etc. + +- or add your package(s) parent directory in the `PYTHONPATH`. + +(*The following instructions assume your Python package is in the `src` directory.*) + +In Bash and other shells, you can run your command like this +(note the prepended `PYTHONPATH=...`): + +```console +$ PYTHONPATH=src mkdocs serve +``` + +You can also export that variable, +but this is **not recommended** as it could affect other Python processes: + +```bash +export PYTHONPATH=src # Linux/Bash and similar +setx PYTHONPATH src # Windows, USE AT YOUR OWN RISKS +``` + +## Recommended style (Material) + +Here are some CSS rules for the +[*Material for MkDocs*](https://squidfunk.github.io/mkdocs-material/) theme: + +```css +/* Indentation. */ +div.doc-contents:not(.first) { + padding-left: 25px; + border-left: .05rem solid var(--md-default-fg-color--lightest); + margin-bottom: 80px; +} +``` + +## Recommended style (ReadTheDocs) + +Here are some CSS rules for the built-in *ReadTheDocs* theme: + +```css +/* Indentation. */ +div.doc-contents:not(.first) { + padding-left: 25px; + border-left: .05rem solid rgba(200, 200, 200, 0.2); + margin-bottom: 60px; +} +``` diff --git a/mkdocs.yml b/mkdocs.yml index 8aaa1c22..8277f640 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -8,6 +8,7 @@ site_dir: "site" nav: - Home: - Overview: index.md + - Usage: usage.md - Changelog: changelog.md - Credits: credits.md - License: license.md @@ -72,6 +73,8 @@ plugins: python: import: - https://mkdocstrings.github.io/objects.inv + rendering: + show_submodules: no watch: - src/mkdocstrings_handlers From 1303557928a27a3d9b063baee9d698458f471357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 3 Feb 2022 19:58:13 +0100 Subject: [PATCH 2/6] build: Depend on Griffe >= 0.11.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index faaa9c33..35edf7c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ - "griffe>=0.10", + "griffe>=0.11.1", ] [project.urls] From 6f9d9dd2c99bf0f40eb3c48c2240f008b2521d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 3 Feb 2022 19:58:25 +0100 Subject: [PATCH 3/6] ci: Fix coverage configuration --- config/coverage.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/coverage.ini b/config/coverage.ini index 421b9684..418d1bb9 100644 --- a/config/coverage.ini +++ b/config/coverage.ini @@ -2,7 +2,7 @@ branch = true parallel = true source = - src/mkdocstrings/handlers/ + src/mkdocstrings_handlers tests/ [coverage:paths] From b787e78e31652438039775850e55ea956c22e8d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 3 Feb 2022 19:58:38 +0100 Subject: [PATCH 4/6] refactor: Move handler into its own module --- src/mkdocstrings_handlers/python/__init__.py | 76 +------------------- src/mkdocstrings_handlers/python/handler.py | 75 +++++++++++++++++++ src/mkdocstrings_handlers/python/renderer.py | 2 +- 3 files changed, 79 insertions(+), 74 deletions(-) create mode 100644 src/mkdocstrings_handlers/python/handler.py diff --git a/src/mkdocstrings_handlers/python/__init__.py b/src/mkdocstrings_handlers/python/__init__.py index b61f4c5e..dcccb5b2 100644 --- a/src/mkdocstrings_handlers/python/__init__.py +++ b/src/mkdocstrings_handlers/python/__init__.py @@ -1,75 +1,5 @@ -"""This module implements a handler for the Python language.""" +"""This package implements a handler for the Python language.""" -import posixpath -from typing import Any, BinaryIO, Iterator, Optional, Tuple +from mkdocstrings_handlers.python.handler import get_handler -from griffe.logger import patch_loggers - -from mkdocstrings.handlers.base import BaseHandler -from mkdocstrings.inventory import Inventory -from mkdocstrings.loggers import get_logger -from mkdocstrings_handlers.python.collector import PythonCollector -from mkdocstrings_handlers.python.renderer import PythonRenderer - -patch_loggers(get_logger) - - -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: Any, - ) -> 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), - ) +__all__ = ["get_handler"] diff --git a/src/mkdocstrings_handlers/python/handler.py b/src/mkdocstrings_handlers/python/handler.py new file mode 100644 index 00000000..b61f4c5e --- /dev/null +++ b/src/mkdocstrings_handlers/python/handler.py @@ -0,0 +1,75 @@ +"""This module implements a handler for the Python language.""" + +import posixpath +from typing import Any, BinaryIO, Iterator, Optional, Tuple + +from griffe.logger import patch_loggers + +from mkdocstrings.handlers.base import BaseHandler +from mkdocstrings.inventory import Inventory +from mkdocstrings.loggers import get_logger +from mkdocstrings_handlers.python.collector import PythonCollector +from mkdocstrings_handlers.python.renderer import PythonRenderer + +patch_loggers(get_logger) + + +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: Any, + ) -> 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), + ) diff --git a/src/mkdocstrings_handlers/python/renderer.py b/src/mkdocstrings_handlers/python/renderer.py index 67dec2de..60beada7 100644 --- a/src/mkdocstrings_handlers/python/renderer.py +++ b/src/mkdocstrings_handlers/python/renderer.py @@ -57,7 +57,7 @@ class PythonRenderer(BaseRenderer): Attributes: fallback_theme: The theme to fallback to. default_config: The default rendering options, - see [`default_config`][mkdocstrings_handlers.python.PythonRenderer.default_config]. + see [`default_config`][mkdocstrings_handlers.python.renderer.PythonRenderer.default_config]. """ fallback_theme = "material" From f6dda1e5d7781df1e3e01aa5afcbc9b5802a49a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 3 Feb 2022 20:00:53 +0100 Subject: [PATCH 5/6] docs: Add missing section-index plugin --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index 8277f640..0137f07c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -68,6 +68,7 @@ plugins: - literate-nav: nav_file: SUMMARY.md - coverage +- section-index - mkdocstrings: handlers: python: From 88ffdaaa82d37f6f365abd42239250cd1ed527ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 3 Feb 2022 20:01:25 +0100 Subject: [PATCH 6/6] chore: Prepare release 0.5.1 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0a097d9..f483a025 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [0.5.1](https://github.com/mkdocstrings/python/releases/tag/0.5.1) - 2022-02-03 + +[Compare with 0.5.0](https://github.com/mkdocstrings/python/compare/0.5.0...0.5.1) + +### Dependencies +- Depend on Griffe >= 0.11.1 ([1303557](https://github.com/mkdocstrings/python/commit/1303557928a27a3d9b063baee9d698458f471357) by Timothée Mazzucotelli). + +### Code Refactoring +- Move handler into its own module ([b787e78](https://github.com/mkdocstrings/python/commit/b787e78e31652438039775850e55ea956c22e8d0) by Timothée Mazzucotelli). + + ## [0.5.0](https://github.com/mkdocstrings/python/releases/tag/0.5.0) - 2022-02-03 [Compare with 0.4.1](https://github.com/mkdocstrings/python/compare/0.4.1...0.5.0)