diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8a4c486e..d0a097d9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,21 @@ 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.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)
+
+### Features
+- Allow changing docstring style of an object ([39240c1](https://github.com/mkdocstrings/python/commit/39240c1497dced15c03f9046138f2829fc10e139) by Timothée Mazzucotelli).
+
+### Bug Fixes
+- Warn if Black is not installed when formatting signature ([b848277](https://github.com/mkdocstrings/python/commit/b84827789b2bf66a4b76ff63a514ec6ba98cae68) by Timothée Mazzucotelli).
+- Fix missing default for `docstring_section_style` option ([774988e](https://github.com/mkdocstrings/python/commit/774988ef06a9bf3446949da63611ad7bc5a712fc) by Timothée Mazzucotelli).
+
+### Code Refactoring
+- Change to new way of stripping paragraphs ([33d4594](https://github.com/mkdocstrings/python/commit/33d45945bf8ffce2435a6b3749795397fa7c3fc8) by Timothée Mazzucotelli).
+
+
## [0.4.1](https://github.com/mkdocstrings/python/releases/tag/0.4.1) - 2022-02-01
[Compare with 0.4.0](https://github.com/mkdocstrings/python/compare/0.4.0...0.4.1)
diff --git a/src/mkdocstrings_handlers/python/collector.py b/src/mkdocstrings_handlers/python/collector.py
index 98dfeaff..2a2823c3 100644
--- a/src/mkdocstrings_handlers/python/collector.py
+++ b/src/mkdocstrings_handlers/python/collector.py
@@ -28,8 +28,8 @@ class PythonCollector(BaseCollector):
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. | `{}`
+ **`docstring_style`** | `"google" | "numpy" | "sphinx" | None` | The docstring style to use. | `"google"`
+ **`docstring_options`** | `dict[str, Any]` | The options for the docstring parser. | `{}`
"""
def __init__(self) -> None:
@@ -51,13 +51,17 @@ def collect(self, identifier: str, config: dict) -> CollectorItem: # noqa: WPS2
The collected object-tree.
"""
final_config = ChainMap(config, self.default_config)
+ parser_name = final_config["docstring_style"]
+ parser_options = final_config["docstring_options"]
+ just_loaded = False
module_name = identifier.split(".", 1)[0]
if module_name not in self._modules_collection:
+ just_loaded = True
loader = GriffeLoader(
extensions=load_extensions(final_config.get("extensions", [])),
- docstring_parser=Parser(final_config["docstring_style"]),
- docstring_options=final_config["docstring_options"],
+ docstring_parser=Parser(parser_name),
+ docstring_options=parser_options,
modules_collection=self._modules_collection,
lines_collection=self._lines_collection,
)
@@ -71,6 +75,12 @@ def collect(self, identifier: str, config: dict) -> CollectorItem: # noqa: WPS2
logger.warning(f"{len(unresolved)} aliases were still unresolved after {iterations} iterations")
try:
- return self._modules_collection[identifier]
+ doc_object = self._modules_collection[identifier]
except KeyError as error: # noqa: WPS440
raise CollectionError(f"{identifier} could not be found") from error
+
+ if not just_loaded and doc_object.docstring is not None:
+ doc_object.docstring.parser = parser_name and Parser(parser_name)
+ doc_object.docstring.parser_options = parser_options
+
+ return doc_object
diff --git a/src/mkdocstrings_handlers/python/renderer.py b/src/mkdocstrings_handlers/python/renderer.py
index fcbf91e3..67dec2de 100644
--- a/src/mkdocstrings_handlers/python/renderer.py
+++ b/src/mkdocstrings_handlers/python/renderer.py
@@ -6,6 +6,7 @@
import re
import sys
from collections import ChainMap
+from functools import lru_cache
from typing import Any, Sequence
from griffe.dataclasses import Alias, Object
@@ -14,7 +15,9 @@
from mkdocstrings.extension import PluginError
from mkdocstrings.handlers.base import BaseRenderer, CollectorItem
+from mkdocstrings.loggers import get_logger
+logger = get_logger(__name__)
# TODO: CSS classes everywhere in templates
# TODO: name normalization (filenames, Jinja2 variables, HTML tags, CSS classes)
# TODO: Jinja2 blocks everywhere in templates
@@ -77,6 +80,7 @@ class PythonRenderer(BaseRenderer):
"group_by_category": True,
"heading_level": 2,
"members_order": Order.alphabetical.value,
+ "docstring_section_style": "table",
}
"""The default rendering options.
@@ -91,7 +95,7 @@ class PythonRenderer(BaseRenderer):
**`show_if_no_docstring`** | `bool` | Show the object heading even if it has no docstring or children with docstrings. | `False`
**`show_signature`** | `bool` | Show method and function signatures. | `True`
**`show_signature_annotations`** | `bool` | Show the type annotations in method and function signatures. | `False`
- **`separate_signature`** | `bool` | Whether to put the whole signature in a foldable code block below the heading. | `False`
+ **`separate_signature`** | `bool` | Whether to put the whole signature in a code block below the heading. | `False`
**`line_length`** | `int` | Maximum line length when formatting code. | `60`
**`show_source`** | `bool` | Show the source code of this object. | `True`
**`show_bases`** | `bool` | Show the base classes of a class. | `True`
@@ -99,6 +103,7 @@ class PythonRenderer(BaseRenderer):
**`group_by_category`** | `bool` | Group the object's children by categories: attributes, classes, functions, methods, and modules. | `True`
**`heading_level`** | `int` | The initial heading level to use. | `2`
**`members_order`** | `str` | The members ordering to use. Options: `alphabetical` - order by the members names, `source` - order members as they appear in the source file. | `alphabetical`
+ **`docstring_section_style`** | `str` | The style used to render docstring sections. Options: `table`, `list`, `spacy`. | `table`
""" # noqa: E501
def render(self, data: CollectorItem, config: dict) -> str: # noqa: D102 (ignore missing docstring)
@@ -143,15 +148,11 @@ def do_format_signature(self, signature: str, line_length: int) -> str:
Returns:
The same code, formatted.
"""
- from black import Mode, format_str
-
code = signature.strip()
if len(code) < line_length:
return code
- mode = Mode(line_length=line_length)
- formatted = format_str(f"def {code}: pass", mode=mode)
- # remove starting `def ` and trailing `: pass`
- return formatted[4:-5].strip()[:-1]
+ formatter = _get_black_formatter()
+ return formatter(code, line_length)
def do_order_members(self, members: Sequence[Object | Alias], order: Order) -> Sequence[Object | Alias]:
"""Order members given an ordering method.
@@ -207,3 +208,20 @@ def repl(match): # noqa: WPS430
if code:
text = f"{text}"
return Markup(text).format(**variables)
+
+
+@lru_cache(maxsize=1)
+def _get_black_formatter():
+ try:
+ from black import Mode, format_str
+ except ModuleNotFoundError:
+ logger.warning("Formatting signatures requires Black to be installed.")
+ return lambda text, _: text
+
+ def formatter(code, line_length): # noqa: WPS430
+ mode = Mode(line_length=line_length)
+ formatted = format_str(f"def {code}: pass", mode=mode)
+ # remove starting `def ` and trailing `: pass`
+ return formatted[4:-5].strip()[:-1]
+
+ return formatter
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html
index 13bac623..a8c08873 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html
@@ -1,5 +1,5 @@
{{ log.debug() }}
- {{ section.title|convert_markdown(heading_level, html_id)|strip_p }}
+ {{ section.title|convert_markdown(heading_level, html_id, strip_paragraph=True) }}
{{ section.value.contents|convert_markdown(heading_level, html_id) }}
\ No newline at end of file