Skip to content

Commit 15413c3

Browse files
committed
wip
1 parent 341046b commit 15413c3

File tree

2 files changed

+48
-10
lines changed

2 files changed

+48
-10
lines changed

src/_griffe/docstrings/models.py

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,43 @@
22

33
from __future__ import annotations
44

5-
from typing import TYPE_CHECKING
5+
from textwrap import indent
6+
from typing import TYPE_CHECKING, Any, Literal
67

78
from _griffe.enumerations import DocstringSectionKind
89

910
if TYPE_CHECKING:
10-
from typing import Any, Literal
11-
1211
from _griffe.expressions import Expr
1312

1413

14+
DocstringStyle = Literal["google", "numpy", "sphinx", "auto"]
15+
"""The supported docstring styles (literal values of the Parser enumeration)."""
16+
17+
1518
# Elements -----------------------------------------------
1619
class DocstringElement:
1720
"""This base class represents annotated, nameless elements."""
1821

19-
def __init__(self, *, description: str, annotation: str | Expr | None = None) -> None:
22+
def __init__(self, *, description: str, annotation: str | Expr | None = None, hardcoded: bool = True) -> None:
2023
"""Initialize the element.
2124
2225
Parameters:
23-
annotation: The element annotation, if any.
2426
description: The element description.
27+
annotation: The element annotation, if any.
28+
hardcoded: Whether the annotation was hardcoded into the docstring.
2529
"""
2630
self.description: str = description
2731
"""The element description."""
2832
self.annotation: str | Expr | None = annotation
2933
"""The element annotation."""
34+
self.hardcoded: bool = hardcoded
35+
"""Whether the annotation was hardcoded into the docstring.
36+
37+
It could have been obtained via other means (e.g. type hints).
38+
39+
This helps to determine whether the annotation should be included
40+
when re-rendering a docstring section.
41+
"""
3042

3143
def as_dict(self, **kwargs: Any) -> dict[str, Any]: # noqa: ARG002
3244
"""Return this element's data as a dictionary.
@@ -53,6 +65,7 @@ def __init__(
5365
description: str,
5466
annotation: str | Expr | None = None,
5567
value: str | None = None,
68+
hardcoded: bool = True,
5669
) -> None:
5770
"""Initialize the element.
5871
@@ -61,8 +74,9 @@ def __init__(
6174
description: The element description.
6275
annotation: The element annotation, if any.
6376
value: The element value, as a string.
77+
hardcoded: Whether the annotation was hardcoded into the docstring.
6478
"""
65-
super().__init__(description=description, annotation=annotation)
79+
super().__init__(description=description, annotation=annotation, hardcoded=hardcoded)
6680
self.name: str = name
6781
"""The element name."""
6882
self.value: str | None = value
@@ -217,6 +231,12 @@ def as_dict(self, **kwargs: Any) -> dict[str, Any]:
217231
base["title"] = self.title
218232
return base
219233

234+
def render(self, style: DocstringStyle) -> str:
235+
"""Render the section as a string."""
236+
raise NotImplementedError(
237+
f"Rendering not implemented for sections '{self.__class__.__name__}' and style '{style}'"
238+
)
239+
220240

221241
class DocstringSectionText(DocstringSection):
222242
"""This class represents a text section."""
@@ -233,6 +253,10 @@ def __init__(self, value: str, title: str | None = None) -> None:
233253
super().__init__(title)
234254
self.value: str = value
235255

256+
def render(self, style: DocstringStyle) -> str:
257+
"""Render the section as a string."""
258+
return self.value
259+
236260

237261
class DocstringSectionParameters(DocstringSection):
238262
"""This class represents a parameters section."""
@@ -249,6 +273,23 @@ def __init__(self, value: list[DocstringParameter], title: str | None = None) ->
249273
super().__init__(title)
250274
self.value: list[DocstringParameter] = value
251275

276+
def render(self, style: DocstringStyle) -> str:
277+
"""Render the section as a string."""
278+
return {
279+
"google": self.render_google,
280+
"numpy": self.render_numpy,
281+
"sphinx": self.render_sphinx,
282+
}.get(style, super().render)()
283+
284+
def render_google(self) -> str:
285+
"""Render the section in Google style."""
286+
lines = ["Parameters:"]
287+
for param in self.value:
288+
annotation = f" ({param.annotation})" if param.annotation and param.hardcoded else ""
289+
lines.append(f" {param.name}{annotation}:")
290+
lines.extend(indent(param.description, " " * 8).splitlines())
291+
return "\n".join(lines)
292+
252293

253294
class DocstringSectionOtherParameters(DocstringSectionParameters):
254295
"""This class represents an other parameters section."""

src/_griffe/docstrings/parsers.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from typing import TYPE_CHECKING, Any, Callable, Literal
77

88
from _griffe.docstrings.google import parse_google
9-
from _griffe.docstrings.models import DocstringSection, DocstringSectionText
9+
from _griffe.docstrings.models import DocstringSection, DocstringSectionText, DocstringStyle
1010
from _griffe.docstrings.numpy import parse_numpy
1111
from _griffe.docstrings.sphinx import parse_sphinx
1212
from _griffe.enumerations import Parser
@@ -22,9 +22,6 @@
2222
# in plain markup docstrings too, even more often than Google sections.
2323
_default_style_order = [Parser.sphinx, Parser.google, Parser.numpy]
2424

25-
26-
DocstringStyle = Literal["google", "numpy", "sphinx", "auto"]
27-
"""The supported docstring styles (literal values of the Parser enumeration)."""
2825
DocstringDetectionMethod = Literal["heuristics", "max_sections"]
2926
"""The supported methods to infer docstring styles."""
3027

0 commit comments

Comments
 (0)