Skip to content

Commit

Permalink
feat: Implement trim_doctest_flags for Google and Numpy
Browse files Browse the repository at this point in the history
  • Loading branch information
thatlittleboy authored and pawamoy committed Feb 23, 2022
1 parent ce3eb6b commit 8057153
Show file tree
Hide file tree
Showing 4 changed files with 289 additions and 27 deletions.
81 changes: 69 additions & 12 deletions src/griffe/docstrings/google.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@

_RE_ADMONITION: Pattern = re.compile(r"^(?P<type>[\w][\s\w-]*):(\s+(?P<title>[^\s].*))?$", re.I)
_RE_NAME_ANNOTATION_DESCRIPTION: Pattern = re.compile(r"^(?:(?P<name>\w+)?\s*(?:\((?P<type>.+)\))?:\s*)?(?P<desc>.*)$")
_RE_DOCTEST_BLANKLINE: Pattern = re.compile(r"^\s*<BLANKLINE>\s*$")
_RE_DOCTEST_FLAGS: Pattern = re.compile(r"(\s*#\s*doctest:.+)$")


def _read_block_items(docstring: Docstring, offset: int) -> ItemsBlock: # noqa: WPS231
Expand Down Expand Up @@ -191,7 +193,11 @@ def _read_parameters(docstring: Docstring, offset: int) -> tuple[list[DocstringP
return parameters, new_offset


def _read_parameters_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_parameters_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
parameters, new_offset = _read_parameters(docstring, offset)

if parameters:
Expand All @@ -201,7 +207,11 @@ def _read_parameters_section(docstring: Docstring, offset: int) -> tuple[Docstri
return None, new_offset


def _read_other_parameters_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_other_parameters_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
parameters, new_offset = _read_parameters(docstring, offset)

if parameters:
Expand All @@ -211,7 +221,11 @@ def _read_other_parameters_section(docstring: Docstring, offset: int) -> tuple[D
return None, new_offset


def _read_attributes_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]: # noqa: WPS231
def _read_attributes_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
attributes = []
block, new_offset = _read_block_items(docstring, offset)

Expand Down Expand Up @@ -246,7 +260,11 @@ def _read_attributes_section(docstring: Docstring, offset: int) -> tuple[Docstri
return None, new_offset


def _read_raises_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_raises_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
exceptions = []
block, new_offset = _read_block_items(docstring, offset)

Expand All @@ -269,7 +287,11 @@ def _read_raises_section(docstring: Docstring, offset: int) -> tuple[DocstringSe
return None, new_offset


def _read_warns_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_warns_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
warns = []
block, new_offset = _read_block_items(docstring, offset)

Expand All @@ -289,7 +311,11 @@ def _read_warns_section(docstring: Docstring, offset: int) -> tuple[DocstringSec
return None, new_offset


def _read_returns_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]: # noqa: WPS231
def _read_returns_section( # noqa: WPS231
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
returns = []
block, new_offset = _read_block_items(docstring, offset)

Expand Down Expand Up @@ -326,7 +352,11 @@ def _read_returns_section(docstring: Docstring, offset: int) -> tuple[DocstringS
return None, new_offset


def _read_yields_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]: # noqa: WPS231
def _read_yields_section( # noqa: WPS231
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
yields = []
block, new_offset = _read_block_items(docstring, offset)

Expand Down Expand Up @@ -364,7 +394,11 @@ def _read_yields_section(docstring: Docstring, offset: int) -> tuple[DocstringSe
return None, new_offset


def _read_receives_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]: # noqa: WPS231
def _read_receives_section( # noqa: WPS231
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
receives = []
block, new_offset = _read_block_items(docstring, offset)

Expand Down Expand Up @@ -402,7 +436,12 @@ def _read_receives_section(docstring: Docstring, offset: int) -> tuple[Docstring
return None, new_offset


def _read_examples_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]: # noqa: WPS231
def _read_examples_section( # noqa: WPS231
docstring: Docstring,
offset: int,
trim_doctest_flags: bool = True,
**options: Any,
) -> tuple[DocstringSection | None, int]:
text, new_offset = _read_block(docstring, offset)

sub_sections = []
Expand All @@ -422,6 +461,9 @@ def _read_examples_section(docstring: Docstring, offset: int) -> tuple[Docstring
current_text.append(line)

elif in_code_example:
if trim_doctest_flags:
line = _RE_DOCTEST_FLAGS.sub("", line)
line = _RE_DOCTEST_BLANKLINE.sub("", line)
current_example.append(line)

elif line.startswith("```"):
Expand All @@ -436,6 +478,9 @@ def _read_examples_section(docstring: Docstring, offset: int) -> tuple[Docstring
sub_sections.append((DocstringSectionKind.text, "\n".join(current_text).rstrip("\n")))
current_text = []
in_code_example = True

if trim_doctest_flags:
line = _RE_DOCTEST_FLAGS.sub("", line)
current_example.append(line)

else:
Expand All @@ -453,7 +498,11 @@ def _read_examples_section(docstring: Docstring, offset: int) -> tuple[Docstring
return None, new_offset


def _read_deprecated_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_deprecated_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
text, new_offset = _read_block(docstring, offset)

# early exit if there is no text in the yield section
Expand Down Expand Up @@ -498,6 +547,7 @@ def _is_empty_line(line) -> bool:
def parse( # noqa: WPS231
docstring: Docstring,
ignore_init_summary: bool = False,
trim_doctest_flags: bool = True,
**options: Any,
) -> list[DocstringSection]:
"""Parse a docstring.
Expand All @@ -508,6 +558,7 @@ def parse( # noqa: WPS231
Parameters:
docstring: The docstring to parse.
ignore_init_summary: Whether to ignore the summary in `__init__` methods' docstrings.
trim_doctest_flags: Whether to remove doctest flags from Python example blocks.
**options: Additional parsing options.
Returns:
Expand All @@ -519,8 +570,14 @@ def parse( # noqa: WPS231
in_code_block = False
lines = docstring.lines

options = {
"ignore_init_summary": ignore_init_summary,
"trim_doctest_flags": trim_doctest_flags,
**options,
}

ignore_summary = (
ignore_init_summary # noqa: WPS222
options["ignore_init_summary"] # noqa: WPS222
and docstring.parent is not None
and docstring.parent.name == "__init__"
and docstring.parent.is_function
Expand Down Expand Up @@ -563,7 +620,7 @@ def parse( # noqa: WPS231
)
current_section = []
reader = _section_reader[_section_kind[admonition_type.lower()]]
section, offset = reader(docstring, offset + 1)
section, offset = reader(docstring, offset + 1, **options)
if section:
section.title = title
sections.append(section)
Expand Down
78 changes: 67 additions & 11 deletions src/griffe/docstrings/numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ def _read_block(docstring: Docstring, offset: int) -> tuple[str, int]:
""",
re.IGNORECASE | re.VERBOSE,
)
_RE_DOCTEST_BLANKLINE: Pattern = re.compile(r"^\s*<BLANKLINE>\s*$")
_RE_DOCTEST_FLAGS: Pattern = re.compile(r"(\s*#\s*doctest:.+)$")


def _read_parameters(docstring: Docstring, offset: int) -> tuple[list[DocstringParameter], int]: # noqa: WPS231
Expand Down Expand Up @@ -239,7 +241,11 @@ def _read_parameters(docstring: Docstring, offset: int) -> tuple[list[DocstringP
return parameters, index


def _read_parameters_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_parameters_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
parameters, index = _read_parameters(docstring, offset)

if parameters:
Expand All @@ -249,7 +255,11 @@ def _read_parameters_section(docstring: Docstring, offset: int) -> tuple[Docstri
return None, index


def _read_other_parameters_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_other_parameters_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
parameters, index = _read_parameters(docstring, offset)

if parameters:
Expand All @@ -259,7 +269,11 @@ def _read_other_parameters_section(docstring: Docstring, offset: int) -> tuple[D
return None, index


def _read_deprecated_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_deprecated_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
# deprecated
# SINCE_VERSION
# TEXT?
Expand All @@ -278,7 +292,11 @@ def _read_deprecated_section(docstring: Docstring, offset: int) -> tuple[Docstri
return DocstringSection(DocstringSectionKind.deprecated, (version, text)), index


def _read_returns_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_returns_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
# returns
# (NAME : )?TYPE
# TEXT?
Expand All @@ -301,7 +319,11 @@ def _read_returns_section(docstring: Docstring, offset: int) -> tuple[DocstringS
return DocstringSection(DocstringSectionKind.returns, returns), index


def _read_yields_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_yields_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
# yields
# (NAME : )?TYPE
# TEXT?
Expand All @@ -324,7 +346,11 @@ def _read_yields_section(docstring: Docstring, offset: int) -> tuple[DocstringSe
return DocstringSection(DocstringSectionKind.yields, yields), index


def _read_receives_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_receives_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
# receives
# (NAME : )?TYPE
# TEXT?
Expand All @@ -347,7 +373,11 @@ def _read_receives_section(docstring: Docstring, offset: int) -> tuple[Docstring
return DocstringSection(DocstringSectionKind.receives, receives), index


def _read_raises_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_raises_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
# raises
# EXCEPTION
# TEXT?
Expand All @@ -365,7 +395,11 @@ def _read_raises_section(docstring: Docstring, offset: int) -> tuple[DocstringSe
return DocstringSection(DocstringSectionKind.raises, raises), index


def _read_warns_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_warns_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
# warns
# WARNING
# TEXT?
Expand All @@ -383,7 +417,11 @@ def _read_warns_section(docstring: Docstring, offset: int) -> tuple[DocstringSec
return DocstringSection(DocstringSectionKind.warns, warns), index


def _read_attributes_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]:
def _read_attributes_section(
docstring: Docstring,
offset: int,
**options: Any,
) -> tuple[DocstringSection | None, int]:
# attributes (for classes)
# NAME( : TYPE)?
# TEXT?
Expand All @@ -407,7 +445,12 @@ def _read_attributes_section(docstring: Docstring, offset: int) -> tuple[Docstri
return DocstringSection(DocstringSectionKind.attributes, attributes), index


def _read_examples_section(docstring: Docstring, offset: int) -> tuple[DocstringSection | None, int]: # noqa: WPS231
def _read_examples_section( # noqa: WPS231
docstring: Docstring,
offset: int,
trim_doctest_flags: bool = True,
**options: Any,
) -> tuple[DocstringSection | None, int]:
text, index = _read_block(docstring, offset)

sub_sections = []
Expand All @@ -427,6 +470,9 @@ def _read_examples_section(docstring: Docstring, offset: int) -> tuple[Docstring
current_text.append(line)

elif in_code_example:
if trim_doctest_flags:
line = _RE_DOCTEST_FLAGS.sub("", line)
line = _RE_DOCTEST_BLANKLINE.sub("", line)
current_example.append(line)

elif line.startswith("```"):
Expand All @@ -441,6 +487,9 @@ def _read_examples_section(docstring: Docstring, offset: int) -> tuple[Docstring
sub_sections.append((DocstringSectionKind.text, "\n".join(current_text).rstrip("\n")))
current_text = []
in_code_example = True

if trim_doctest_flags:
line = _RE_DOCTEST_FLAGS.sub("", line)
current_example.append(line)

else:
Expand Down Expand Up @@ -474,6 +523,7 @@ def _read_examples_section(docstring: Docstring, offset: int) -> tuple[Docstring

def parse( # noqa: WPS231
docstring: Docstring,
trim_doctest_flags: bool = True,
**options: Any,
) -> list[DocstringSection]:
"""Parse a docstring.
Expand All @@ -483,6 +533,7 @@ def parse( # noqa: WPS231
Parameters:
docstring: The docstring to parse.
trim_doctest_flags: Whether to remove doctest flags from Python example blocks.
**options: Additional parsing options.
Returns:
Expand All @@ -493,6 +544,11 @@ def parse( # noqa: WPS231

in_code_block = False

options = {
"trim_doctest_flags": trim_doctest_flags,
**options,
}

lines = docstring.lines
index = 0

Expand All @@ -512,7 +568,7 @@ def parse( # noqa: WPS231
)
current_section = []
reader = _section_reader[_section_kind[line_lower]]
section, index = reader(docstring, index + 2)
section, index = reader(docstring, index + 2, **options)
if section:
sections.append(section)

Expand Down
Loading

0 comments on commit 8057153

Please sign in to comment.