stouputils.applications.automatic_docs.docstring module#

Docstring normalization applied before Sphinx parses the output of autodoc.

reStructuredText only recognizes a doctest block when it starts a new block, which means a blank line must separate it from the prose introducing it. A docstring written without that blank line gets folded into the preceding paragraph, so the >>> lines render as plain text (smart quotes included) instead of a highlighted code block. fix_doctest_blocks() inserts the missing blank lines and connect_docstring_fixes() wires it to the autodoc-process-docstring event, so the fix applies to every documented object at once.

VERBATIM_DIRECTIVES: frozenset[str] = frozenset({'code', 'code-block', 'doctest', 'literalinclude', 'math', 'parsed-literal', 'raw', 'sourcecode', 'testcleanup', 'testcode', 'testsetup'})[source]#

Directives whose body is taken verbatim, so >>> lines inside them must be left untouched.

DIRECTIVE_PATTERN: Pattern[str] = re.compile('^\\.\\.[ \\t]+([\\w-]+)::')[source]#

Matches the opening line of a reStructuredText directive, capturing its name.

fix_doctest_blocks(lines: list[str]) list[str][source]#

Insert the blank line reStructuredText needs before a doctest block that follows prose.

Lines inside a verbatim region (a literal block introduced by :: or a directive from VERBATIM_DIRECTIVES) are copied as-is, since their >>> already renders correctly and an extra blank line would truncate the block.

Parameters:

lines (list[str]) – Docstring lines, without trailing newlines

Returns:

The same lines with a blank line before every doctest block that lacked one

Return type:

list[str]

Examples

>>> fix_doctest_blocks(["Building resource locations", ">>> 1 + 1", "2"])
['Building resource locations', '', '>>> 1 + 1', '2']
>>> fix_doctest_blocks(["Already fine", "", ">>> 1 + 1", "2"])
['Already fine', '', '>>> 1 + 1', '2']
>>> fix_doctest_blocks([">>> a = 1", ">>> a", "1"])
['>>> a = 1', '>>> a', '1']
>>> fix_doctest_blocks(["Intro:", "", ">>> 1", "1", ">>> 2", "2"])
['Intro:', '', '>>> 1', '1', '>>> 2', '2']
>>> fix_doctest_blocks([".. code-block:: python", "", "    Header", "    >>> 1 + 1"])
['.. code-block:: python', '', '    Header', '    >>> 1 + 1']
>>> fix_doctest_blocks(["Sample::", "", "    Header", "    >>> 1 + 1"])
['Sample::', '', '    Header', '    >>> 1 + 1']
process_docstring(
app: Any,
what: str,
name: str,
obj: Any,
options: Any,
lines: list[str],
) None[source]#

Handler for the autodoc-process-docstring event, editing lines in place as Sphinx requires.

Parameters:
  • app (Any) – The Sphinx application, unused

  • what (str) – The type of the documented object, unused

  • name (str) – The fully qualified name of the documented object, unused

  • obj (Any) – The documented object itself, unused

  • options (Any) – The autodoc directive options, unused

  • lines (list[str]) – Docstring lines, modified in place

Examples

>>> lines = ["Intro", ">>> 1 + 1", "2"]
>>> process_docstring(None, "class", "Demo", None, None, lines)
>>> lines
['Intro', '', '>>> 1 + 1', '2']
connect_docstring_fixes(app: Any) None[source]#

Register the docstring fixes on a Sphinx application.

Connected with a low priority so it runs after napoleon has expanded the Google style sections into reStructuredText, which is what actually gets parsed.

Parameters:

app (Any) – The Sphinx application to connect the handler to