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