1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
"""The main parsing routine."""
import inspect
import typing as T
from docstring_parser import epydoc, google, numpydoc, rest
from docstring_parser.attrdoc import add_attribute_docstrings
from docstring_parser.common import (
Docstring,
DocstringStyle,
ParseError,
RenderingStyle,
)
_STYLE_MAP = {
DocstringStyle.REST: rest,
DocstringStyle.GOOGLE: google,
DocstringStyle.NUMPYDOC: numpydoc,
DocstringStyle.EPYDOC: epydoc,
}
def parse(text: str, style: DocstringStyle = DocstringStyle.AUTO) -> Docstring:
"""Parse the docstring into its components.
:param text: docstring text to parse
:param style: docstring style
:returns: parsed docstring representation
"""
if style != DocstringStyle.AUTO:
return _STYLE_MAP[style].parse(text)
exc: T.Optional[Exception] = None
rets = []
for module in _STYLE_MAP.values():
try:
ret = module.parse(text)
except ParseError as ex:
exc = ex
else:
rets.append(ret)
if not rets:
raise exc
return sorted(rets, key=lambda d: len(d.meta), reverse=True)[0]
def parse_from_object(
obj: T.Any,
style: DocstringStyle = DocstringStyle.AUTO,
) -> Docstring:
"""Parse the object's docstring(s) into its components.
The object can be anything that has a ``__doc__`` attribute. In contrast to
the ``parse`` function, ``parse_from_object`` is able to parse attribute
docstrings which are defined in the source code instead of ``__doc__``.
Currently only attribute docstrings defined at class and module levels are
supported. Attribute docstrings defined in ``__init__`` methods are not
supported.
When given a class, only the attribute docstrings of that class are parsed,
not its inherited classes. This is a design decision. Separate calls to
this function should be performed to get attribute docstrings of parent
classes.
:param obj: object from which to parse the docstring(s)
:param style: docstring style
:returns: parsed docstring representation
"""
docstring = parse(obj.__doc__, style=style)
if inspect.isclass(obj) or inspect.ismodule(obj):
add_attribute_docstrings(obj, docstring)
return docstring
def compose(
docstring: Docstring,
style: DocstringStyle = DocstringStyle.AUTO,
rendering_style: RenderingStyle = RenderingStyle.COMPACT,
indent: str = " ",
) -> str:
"""Render a parsed docstring into docstring text.
:param docstring: parsed docstring representation
:param style: docstring style to render
:param indent: the characters used as indentation in the docstring string
:returns: docstring text
"""
module = _STYLE_MAP[
docstring.style if style == DocstringStyle.AUTO else style
]
return module.compose(
docstring, rendering_style=rendering_style, indent=indent
)
|