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

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) 

14 

15from debputy.manifest_parser.declarative_parser import ParserGenerator 

16from debputy.manifest_parser.tagging_types import DebputyParsedContent 

17from debputy.plugin.api.spec import ParserDocumentation 

18 

19_DEBPUTY_DOC_PARSER_GENERATOR = ParserGenerator() 

20 

21 

22class AttributeRefDoc(DebputyParsedContent): 

23 attr: NotRequired[Union[str, List[str]]] 

24 description: str 

25 

26 

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] 

35 

36 

37class PMRData(ParserRefDocumentation): 

38 rule_reference: str 

39 documentation: NotRequired[ParserRefDocumentation] 

40 

41 

42class DebputyDocReferenceData(DebputyParsedContent): 

43 pluggable_manifest_rules: NotRequired[List[PMRData]] 

44 

45 

46DEBPUTY_DOC_REFERENCE_DATA_PARSER = _DEBPUTY_DOC_PARSER_GENERATOR.generate_parser( 

47 DebputyDocReferenceData 

48) 

49 

50 

51D = TypeVar("D") 

52 

53 

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 

67 

68 return r 

69 

70 

71@dataclasses.dataclass(slots=True, frozen=True) 

72class DebputyParsedDoc: 

73 pluggable_manifest_rules: Mapping[str, ParserDocumentation] 

74 

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 ) 

87 

88 

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__