Skip to content

Commit

Permalink
docs: Add how-to set objects' docstring styles
Browse files Browse the repository at this point in the history
  • Loading branch information
pawamoy committed Jan 16, 2025
1 parent a22237a commit 1081fd5
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 0 deletions.
8 changes: 8 additions & 0 deletions docs/guide/users.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,12 @@ These how-tos will show you how to achieve specific things with Griffe.

[:octicons-arrow-right-24: See how to selectively inspect objects](users/how-to/selectively-inspect.md)

- :material-select:{ .lg .middle } **Set objects' docstring style**

---

Sometimes the wrong docstring styles are attached to objects. You can fix this with a few different methods.

[:octicons-arrow-right-24: See how to set the correct docstring styles on objects](users/how-to/set-docstring-styles.md)

</div>
132 changes: 132 additions & 0 deletions docs/guide/users/how-to/set-docstring-styles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Setting the right docstring style for every docstring

Griffe attaches the specified docstring style and parsing options to each object in the tree of the package(s) you load. If your package(s) use several docstring styles, some of these objects will have the wrong style attached to them. This is problematic because other Griffe extensions rely on this attached style to parse docstrings and modify them. We plan to alleviate this limitation in the future (see [issue-340](https://github.com/mkdocstrings/griffe/issues/340)), but the most robust thing you can do is to make sure each object has the *right style* attached, as easly as possible, so that other extensions can work without issue.

There are currently two ways to make sure objects have the right docstring style attached as early as possible:

1. Use the [`auto` docstring style](https://mkdocstrings.github.io/griffe/reference/docstrings/#auto-style) (currently only available to sponsors). Griffe will use regular expressions to infer the docstring style used. 100% accuracy is impossible to achieve, so it's possible that you get incorrect styles for some objects.
2. Write and use a custom Griffe extension.

This how-to provides a few extension-based solutions to correctly set docstring styles in your packages. **Just make sure to enable these extensions in first position.**

## Markup comment

Depending on the markup you use in docstrings, you can add a comment that tells Griffe which docstring style to use.

=== "Markdown"

```python
def function():
"""Summary.

Body.

<!-- style: google -->
"""
```

=== "reStructuredText"

```python
def function():
"""Summary.

Body.

.. style: google
"""
```

Your Griffe extension can then use regular expressions to search for such comments. For example with Markdown (HTML) comments:

```python
import re
import griffe


class ApplyDocstringStyle(griffe.Extension):
def __init__(self, regex: str = "<!-- style: (google|numpy|sphinx) -->") -> None:
self.regex = re.compile(regex)

def on_instance(self, *, obj: griffe.Object, **kwargs) -> None:
if obj.docstring:
if match := self.regex.search(obj.docstring.value):
obj.docstring.parser = match.group(1)
```

## Python comment

You could also decide to add a trailing comment to your docstrings to indicate which style to use.

```python
def function():
"""Summary.
Body.
""" # style: google
```

Your extension can then pick up this comment to assign the right style:

```python
import re
import griffe


class ApplyDocstringStyle(griffe.Extension):
def __init__(self, regex: str = ".*# style: (google|numpy|sphinx)$") -> None:
self.regex = re.compile(regex)

def on_instance(self, *, obj: griffe.Object, **kwargs) -> None:
if obj.docstring:
if match := self.regex.search(obj.docstring.source):
obj.docstring.parser = match.group(1)
```

## Explicit configuration

Finally, you could decide to map a list of objects to the docstring style they should use. Your extension can either accept options, or it could hard-code that list:

```python
import griffe
from fnmatch import fnmatch

class ApplyDocstringStyle(griffe.Extension):
def __init__(self, config: dict[str, str]):
self.instances = {}
self.globs = {}
for key, value in config.items():
if "*" in key:
self.globs[key] = value
else:
self.instances[key] = value

def on_instance(self, *, obj: griffe.Object, **kwargs) -> None:
if obj.path in self.instances:
if obj.docstring:
obj.docsring.parser = self.instances[obj.path]
else:
for pattern, style in self.globs:
if fnmatch(obj.path, pattern):
if obj.docstring:
obj.docstring.parser = style
```

Example configuration in MkDocs:

```yaml
plugins:
- mkdocstrings:
handlers:
python:
options:
extensions:
- your_griffe_extension.py:
config:
path.to.obj1: google
path.to.obj2: numpy
path.to.obj3.*: sphinx
path.to.obj4*: google
```
The benefit of this last solution is that it works for code you don't have control over. An alternative solution is to use the [griffe-autodocstringstyle extension](https://mkdocstrings.github.io/griffe/extensions/official/autodocstringstyle/) (sponsors only), which automatically assigns the `auto` style to all objects coming from sources found in a virtual environment.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ nav:
- Parse docstrings: guide/users/how-to/parse-docstrings.md
- Support custom decorators: guide/users/how-to/support-decorators.md
- Selectively inspect objects: guide/users/how-to/selectively-inspect.md
- Set objects' docstring style: guide/users/how-to/set-docstring-styles.md
- Contributor guide:
- guide/contributors.md
- Environment setup: guide/contributors/setup.md
Expand Down

0 comments on commit 1081fd5

Please sign in to comment.