Coverage for tests/test_docstrings/helpers.py: 96.30%
23 statements
« prev ^ index » next coverage.py v7.6.2, created at 2024-10-12 01:34 +0200
« prev ^ index » next coverage.py v7.6.2, created at 2024-10-12 01:34 +0200
1"""This module contains helpers for testing docstring parsing."""
3from __future__ import annotations
5from typing import TYPE_CHECKING, Any, Protocol, Union
7from griffe import (
8 Attribute,
9 Class,
10 Docstring,
11 DocstringSection,
12 Function,
13 LogLevel,
14 Module,
15)
17if TYPE_CHECKING:
18 from collections.abc import Iterator
19 from types import ModuleType
22ParentType = Union[Module, Class, Function, Attribute, None]
23ParseResultType = tuple[list[DocstringSection], list[str]]
26class ParserType(Protocol): # noqa: D101
27 def __call__( # noqa: D102 27 ↛ exitline 27 didn't jump to the function exit
28 self,
29 docstring: str,
30 parent: ParentType | None = None,
31 **parser_opts: Any,
32 ) -> ParseResultType: ...
35def parser(parser_module: ModuleType) -> Iterator[ParserType]:
36 """Wrap a parser to help testing.
38 Parameters:
39 parser_module: The parser module containing a `parse` function.
41 Yields:
42 The wrapped function.
43 """
44 original_warn = parser_module.docstring_warning
46 def parse(docstring: str, parent: ParentType | None = None, **parser_opts: Any) -> ParseResultType:
47 """Parse a docstring.
49 Parameters:
50 docstring: The docstring to parse.
51 parent: The docstring's parent object.
52 **parser_opts: Additional options accepted by the parser.
54 Returns:
55 The parsed sections, and warnings.
56 """
57 docstring_object = Docstring(docstring, lineno=1, endlineno=None)
58 docstring_object.endlineno = len(docstring_object.lines) + 1
59 if parent is not None:
60 docstring_object.parent = parent
61 parent.docstring = docstring_object
62 warnings = []
63 parser_module.docstring_warning = ( # type: ignore[attr-defined]
64 lambda _docstring, _offset, message, log_level=LogLevel.warning: warnings.append(message)
65 )
66 func_name = f"parse_{parser_module.__name__.split('.')[-1]}"
67 func = getattr(parser_module, func_name)
68 sections = func(docstring_object, **parser_opts)
69 return sections, warnings
71 yield parse
73 parser_module.docstring_warning = original_warn # type: ignore[attr-defined]