Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
pawamoy committed Dec 26, 2024
1 parent 341046b commit 15413c3
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 10 deletions.
53 changes: 47 additions & 6 deletions src/_griffe/docstrings/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,43 @@

from __future__ import annotations

from typing import TYPE_CHECKING
from textwrap import indent
from typing import TYPE_CHECKING, Any, Literal

from _griffe.enumerations import DocstringSectionKind

if TYPE_CHECKING:
from typing import Any, Literal

from _griffe.expressions import Expr


DocstringStyle = Literal["google", "numpy", "sphinx", "auto"]
"""The supported docstring styles (literal values of the Parser enumeration)."""


# Elements -----------------------------------------------
class DocstringElement:
"""This base class represents annotated, nameless elements."""

def __init__(self, *, description: str, annotation: str | Expr | None = None) -> None:
def __init__(self, *, description: str, annotation: str | Expr | None = None, hardcoded: bool = True) -> None:
"""Initialize the element.
Parameters:
annotation: The element annotation, if any.
description: The element description.
annotation: The element annotation, if any.
hardcoded: Whether the annotation was hardcoded into the docstring.
"""
self.description: str = description
"""The element description."""
self.annotation: str | Expr | None = annotation
"""The element annotation."""
self.hardcoded: bool = hardcoded
"""Whether the annotation was hardcoded into the docstring.
It could have been obtained via other means (e.g. type hints).
This helps to determine whether the annotation should be included
when re-rendering a docstring section.
"""

def as_dict(self, **kwargs: Any) -> dict[str, Any]: # noqa: ARG002
"""Return this element's data as a dictionary.
Expand All @@ -53,6 +65,7 @@ def __init__(
description: str,
annotation: str | Expr | None = None,
value: str | None = None,
hardcoded: bool = True,
) -> None:
"""Initialize the element.
Expand All @@ -61,8 +74,9 @@ def __init__(
description: The element description.
annotation: The element annotation, if any.
value: The element value, as a string.
hardcoded: Whether the annotation was hardcoded into the docstring.
"""
super().__init__(description=description, annotation=annotation)
super().__init__(description=description, annotation=annotation, hardcoded=hardcoded)
self.name: str = name
"""The element name."""
self.value: str | None = value
Expand Down Expand Up @@ -217,6 +231,12 @@ def as_dict(self, **kwargs: Any) -> dict[str, Any]:
base["title"] = self.title
return base

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


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

def render(self, style: DocstringStyle) -> str:
"""Render the section as a string."""
return self.value


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

def render(self, style: DocstringStyle) -> str:
"""Render the section as a string."""
return {
"google": self.render_google,
"numpy": self.render_numpy,
"sphinx": self.render_sphinx,
}.get(style, super().render)()

def render_google(self) -> str:
"""Render the section in Google style."""
lines = ["Parameters:"]
for param in self.value:
annotation = f" ({param.annotation})" if param.annotation and param.hardcoded else ""
lines.append(f" {param.name}{annotation}:")
lines.extend(indent(param.description, " " * 8).splitlines())
return "\n".join(lines)


class DocstringSectionOtherParameters(DocstringSectionParameters):
"""This class represents an other parameters section."""
Expand Down
5 changes: 1 addition & 4 deletions src/_griffe/docstrings/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import TYPE_CHECKING, Any, Callable, Literal

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


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

Expand Down

0 comments on commit 15413c3

Please sign in to comment.