Coverage for src/debputy/plugin/api/doc_parsing.py: 96%
43 statements
« prev ^ index » next coverage.py v7.6.0, created at 2025-01-27 13:59 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2025-01-27 13:59 +0000
1import dataclasses
2from typing import (
3 List,
4 NotRequired,
5 Union,
6 Type,
7 Any,
8 Mapping,
9 Self,
10 Tuple,
11 Iterable,
12 TypeVar,
13)
15from debputy.manifest_parser.declarative_parser import ParserGenerator
16from debputy.manifest_parser.tagging_types import DebputyParsedContent
17from debputy.plugin.api.spec import ParserDocumentation
19_DEBPUTY_DOC_PARSER_GENERATOR = ParserGenerator()
22class AttributeRefDoc(DebputyParsedContent):
23 attr: NotRequired[Union[str, List[str]]]
24 description: str
27class ParserRefDocumentation(DebputyParsedContent):
28 title: str
29 description: NotRequired[str]
30 attributes: NotRequired[List[AttributeRefDoc]]
31 undocumented_attributes: NotRequired[List[str]]
32 non_mapping_description: NotRequired[str]
33 ref_doc_url: NotRequired[str]
34 synopsis: NotRequired[str]
37class PMRData(ParserRefDocumentation):
38 rule_reference: str
39 documentation: NotRequired[ParserRefDocumentation]
42class DebputyDocReferenceData(DebputyParsedContent):
43 pluggable_manifest_rules: NotRequired[List[PMRData]]
46DEBPUTY_DOC_REFERENCE_DATA_PARSER = _DEBPUTY_DOC_PARSER_GENERATOR.generate_parser(
47 DebputyDocReferenceData
48)
51D = TypeVar("D")
54def _unique(
55 topic: str, key_attr_name: str, kd: Iterable[Tuple[str, D]]
56) -> Mapping[str, D]:
57 seen = set()
58 r = {}
59 for k, d in kd:
60 if k in seen: 60 ↛ 61line 60 didn't jump to line 61 because the condition on line 60 was never true
61 raise ValueError(
62 f"The multiple instances of the {key_attr_name} attribute in {topic}"
63 f' had the value: "{k}". The value must be unique'
64 )
65 seen.add(k)
66 r[k] = d
68 return r
71@dataclasses.dataclass(slots=True, frozen=True)
72class DebputyParsedDoc:
73 pluggable_manifest_rules: Mapping[str, ParserDocumentation]
75 @classmethod
76 def from_ref_data(cls, docs: DebputyDocReferenceData) -> Self:
77 return cls(
78 pluggable_manifest_rules=_unique(
79 "pluggable-manifest-rules",
80 "rule-reference",
81 (
82 (d["rule_reference"], ParserDocumentation.from_ref_doc(d))
83 for d in docs.get("pluggable_manifest_rules", [])
84 ),
85 )
86 )
89def parser_type_name(v: Union[str, Type[Any]]) -> str:
90 if isinstance(v, str):
91 return v if v != "<ROOT>" else ""
92 return v.__name__