Coverage for src/griffe/_internal/docstrings/models.py: 92.16%
192 statements
« prev ^ index » next coverage.py v7.10.2, created at 2025-08-11 13:44 +0200
« prev ^ index » next coverage.py v7.10.2, created at 2025-08-11 13:44 +0200
1# This module contains the models for storing docstrings structured data.
3from __future__ import annotations
5from typing import TYPE_CHECKING
7from griffe._internal.enumerations import DocstringSectionKind
8from griffe._internal.expressions import ExprTuple
10if TYPE_CHECKING:
11 from collections.abc import Sequence
12 from typing import Any, Literal
14 from griffe._internal.expressions import Expr
17# Elements -----------------------------------------------
18class DocstringElement:
19 """This base class represents annotated, nameless elements."""
21 def __init__(self, *, description: str, annotation: str | Expr | None = None) -> None:
22 """Initialize the element.
24 Parameters:
25 annotation: The element annotation, if any.
26 description: The element description.
27 """
28 self.description: str = description
29 """The element description."""
30 self.annotation: str | Expr | None = annotation
31 """The element annotation."""
33 def as_dict(self, **kwargs: Any) -> dict[str, Any]: # noqa: ARG002
34 """Return this element's data as a dictionary.
36 Parameters:
37 **kwargs: Additional serialization options.
39 Returns:
40 A dictionary.
41 """
42 return {
43 "annotation": self.annotation,
44 "description": self.description,
45 }
48class DocstringNamedElement(DocstringElement):
49 """This base class represents annotated, named elements."""
51 def __init__(
52 self,
53 name: str,
54 *,
55 description: str,
56 annotation: str | Expr | None = None,
57 value: str | Expr | None = None,
58 ) -> None:
59 """Initialize the element.
61 Parameters:
62 name: The element name.
63 description: The element description.
64 annotation: The element annotation, if any.
65 value: The element value, as a string.
66 """
67 super().__init__(description=description, annotation=annotation)
68 self.name: str = name
69 """The element name."""
70 self.value: str | Expr | None = value
71 """The element value, if any"""
73 def as_dict(self, **kwargs: Any) -> dict[str, Any]:
74 """Return this element's data as a dictionary.
76 Parameters:
77 **kwargs: Additional serialization options.
79 Returns:
80 A dictionary.
81 """
82 base = {"name": self.name, **super().as_dict(**kwargs)}
83 if self.value is not None:
84 base["value"] = self.value
85 return base
88class DocstringAdmonition(DocstringElement):
89 """This class represents an admonition."""
91 @property
92 def kind(self) -> str | Expr | None:
93 """The kind of this admonition."""
94 return self.annotation
96 @kind.setter
97 def kind(self, value: str | Expr) -> None:
98 self.annotation = value
100 @property
101 def contents(self) -> str:
102 """The contents of this admonition."""
103 return self.description
105 @contents.setter
106 def contents(self, value: str) -> None:
107 self.description = value
110class DocstringDeprecated(DocstringElement):
111 """This class represents a documented deprecated item."""
113 @property
114 def version(self) -> str:
115 """The version of this deprecation."""
116 return self.annotation # type: ignore[return-value]
118 @version.setter
119 def version(self, value: str) -> None:
120 self.annotation = value
123class DocstringRaise(DocstringElement):
124 """This class represents a documented raise value."""
127class DocstringWarn(DocstringElement):
128 """This class represents a documented warn value."""
131class DocstringReturn(DocstringNamedElement):
132 """This class represents a documented return value."""
135class DocstringYield(DocstringNamedElement):
136 """This class represents a documented yield value."""
139class DocstringReceive(DocstringNamedElement):
140 """This class represents a documented receive value."""
143class DocstringParameter(DocstringNamedElement):
144 """This class represent a documented function parameter."""
146 @property
147 def default(self) -> str | Expr | None:
148 """The default value of this parameter."""
149 return self.value
151 @default.setter
152 def default(self, value: str) -> None:
153 self.value = value
156class DocstringTypeParameter(DocstringNamedElement):
157 """This class represent a documented type parameter."""
159 @property
160 def default(self) -> str | Expr | None:
161 """The default value of this type parameter."""
162 return self.value
164 @default.setter
165 def default(self, value: str) -> None:
166 self.value = value
168 @property
169 def bound(self) -> str | Expr | None:
170 """The bound of this type parameter."""
171 if not isinstance(self.annotation, ExprTuple):
172 return self.annotation
173 return None
175 @bound.setter
176 def bound(self, bound: str | Expr | None) -> None:
177 self.annotation = bound
179 @property
180 def constraints(self) -> tuple[str | Expr, ...] | None:
181 """The constraints of this type parameter."""
182 if isinstance(self.annotation, ExprTuple):
183 return tuple(self.annotation.elements)
184 return None
186 @constraints.setter
187 def constraints(self, constraints: Sequence[str | Expr] | None) -> None:
188 if constraints is not None:
189 self.annotation = ExprTuple(constraints)
190 else:
191 self.annotation = None
194class DocstringAttribute(DocstringNamedElement):
195 """This class represents a documented module/class attribute."""
198class DocstringFunction(DocstringNamedElement):
199 """This class represents a documented function."""
201 @property
202 def signature(self) -> str | Expr | None:
203 """The function signature."""
204 return self.annotation
207class DocstringClass(DocstringNamedElement):
208 """This class represents a documented class."""
210 @property
211 def signature(self) -> str | Expr | None:
212 """The class signature."""
213 return self.annotation
216class DocstringTypeAlias(DocstringNamedElement):
217 """This class represents a documented type alias."""
220class DocstringModule(DocstringNamedElement):
221 """This class represents a documented module."""
224# Sections -----------------------------------------------
225class DocstringSection:
226 """This class represents a docstring section."""
228 kind: DocstringSectionKind
229 """The section kind."""
231 def __init__(self, title: str | None = None) -> None:
232 """Initialize the section.
234 Parameters:
235 title: An optional title.
236 """
237 self.title: str | None = title
238 """The section title."""
239 self.value: Any = None
240 """The section value."""
242 def __bool__(self) -> bool:
243 """Whether this section has a true-ish value."""
244 return bool(self.value)
246 def as_dict(self, **kwargs: Any) -> dict[str, Any]:
247 """Return this section's data as a dictionary.
249 Parameters:
250 **kwargs: Additional serialization options.
252 Returns:
253 A dictionary.
254 """
255 if hasattr(self.value, "as_dict"): # noqa: SIM108 255 ↛ 256line 255 didn't jump to line 256 because the condition on line 255 was never true
256 serialized_value = self.value.as_dict(**kwargs)
257 else:
258 serialized_value = self.value
259 base = {"kind": self.kind.value, "value": serialized_value}
260 if self.title: 260 ↛ 261line 260 didn't jump to line 261 because the condition on line 260 was never true
261 base["title"] = self.title
262 return base
265class DocstringSectionText(DocstringSection):
266 """This class represents a text section."""
268 kind: DocstringSectionKind = DocstringSectionKind.text
270 def __init__(self, value: str, title: str | None = None) -> None:
271 """Initialize the section.
273 Parameters:
274 value: The section text.
275 title: An optional title.
276 """
277 super().__init__(title)
278 self.value: str = value
281class DocstringSectionParameters(DocstringSection):
282 """This class represents a parameters section."""
284 kind: DocstringSectionKind = DocstringSectionKind.parameters
286 def __init__(self, value: list[DocstringParameter], title: str | None = None) -> None:
287 """Initialize the section.
289 Parameters:
290 value: The section parameters.
291 title: An optional title.
292 """
293 super().__init__(title)
294 self.value: list[DocstringParameter] = value
297class DocstringSectionOtherParameters(DocstringSectionParameters):
298 """This class represents an other parameters section."""
300 kind: DocstringSectionKind = DocstringSectionKind.other_parameters
303class DocstringSectionTypeParameters(DocstringSection):
304 """This class represents a type parameters section."""
306 kind: DocstringSectionKind = DocstringSectionKind.type_parameters
308 def __init__(self, value: list[DocstringTypeParameter], title: str | None = None) -> None:
309 """Initialize the section.
311 Parameters:
312 value: The section type parameters.
313 title: An optional title.
314 """
315 super().__init__(title)
316 self.value: list[DocstringTypeParameter] = value
319class DocstringSectionRaises(DocstringSection):
320 """This class represents a raises section."""
322 kind: DocstringSectionKind = DocstringSectionKind.raises
324 def __init__(self, value: list[DocstringRaise], title: str | None = None) -> None:
325 """Initialize the section.
327 Parameters:
328 value: The section exceptions.
329 title: An optional title.
330 """
331 super().__init__(title)
332 self.value: list[DocstringRaise] = value
335class DocstringSectionWarns(DocstringSection):
336 """This class represents a warns section."""
338 kind: DocstringSectionKind = DocstringSectionKind.warns
340 def __init__(self, value: list[DocstringWarn], title: str | None = None) -> None:
341 """Initialize the section.
343 Parameters:
344 value: The section warnings.
345 title: An optional title.
346 """
347 super().__init__(title)
348 self.value: list[DocstringWarn] = value
351class DocstringSectionReturns(DocstringSection):
352 """This class represents a returns section."""
354 kind: DocstringSectionKind = DocstringSectionKind.returns
356 def __init__(self, value: list[DocstringReturn], title: str | None = None) -> None:
357 """Initialize the section.
359 Parameters:
360 value: The section returned items.
361 title: An optional title.
362 """
363 super().__init__(title)
364 self.value: list[DocstringReturn] = value
367class DocstringSectionYields(DocstringSection):
368 """This class represents a yields section."""
370 kind: DocstringSectionKind = DocstringSectionKind.yields
372 def __init__(self, value: list[DocstringYield], title: str | None = None) -> None:
373 """Initialize the section.
375 Parameters:
376 value: The section yielded items.
377 title: An optional title.
378 """
379 super().__init__(title)
380 self.value: list[DocstringYield] = value
383class DocstringSectionReceives(DocstringSection):
384 """This class represents a receives section."""
386 kind: DocstringSectionKind = DocstringSectionKind.receives
388 def __init__(self, value: list[DocstringReceive], title: str | None = None) -> None:
389 """Initialize the section.
391 Parameters:
392 value: The section received items.
393 title: An optional title.
394 """
395 super().__init__(title)
396 self.value: list[DocstringReceive] = value
399class DocstringSectionExamples(DocstringSection):
400 """This class represents an examples section."""
402 kind: DocstringSectionKind = DocstringSectionKind.examples
404 def __init__(
405 self,
406 value: list[tuple[Literal[DocstringSectionKind.text, DocstringSectionKind.examples], str]],
407 title: str | None = None,
408 ) -> None:
409 """Initialize the section.
411 Parameters:
412 value: The section examples.
413 title: An optional title.
414 """
415 super().__init__(title)
416 self.value: list[tuple[Literal[DocstringSectionKind.text, DocstringSectionKind.examples], str]] = value
419class DocstringSectionAttributes(DocstringSection):
420 """This class represents an attributes section."""
422 kind: DocstringSectionKind = DocstringSectionKind.attributes
424 def __init__(self, value: list[DocstringAttribute], title: str | None = None) -> None:
425 """Initialize the section.
427 Parameters:
428 value: The section attributes.
429 title: An optional title.
430 """
431 super().__init__(title)
432 self.value: list[DocstringAttribute] = value
435class DocstringSectionFunctions(DocstringSection):
436 """This class represents a functions/methods section."""
438 kind: DocstringSectionKind = DocstringSectionKind.functions
440 def __init__(self, value: list[DocstringFunction], title: str | None = None) -> None:
441 """Initialize the section.
443 Parameters:
444 value: The section functions.
445 title: An optional title.
446 """
447 super().__init__(title)
448 self.value: list[DocstringFunction] = value
451class DocstringSectionClasses(DocstringSection):
452 """This class represents a classes section."""
454 kind: DocstringSectionKind = DocstringSectionKind.classes
456 def __init__(self, value: list[DocstringClass], title: str | None = None) -> None:
457 """Initialize the section.
459 Parameters:
460 value: The section classes.
461 title: An optional title.
462 """
463 super().__init__(title)
464 self.value: list[DocstringClass] = value
467class DocstringSectionTypeAliases(DocstringSection):
468 """This class represents a type aliases section."""
470 kind: DocstringSectionKind = DocstringSectionKind.type_aliases
472 def __init__(self, value: list[DocstringTypeAlias], title: str | None = None) -> None:
473 """Initialize the section.
475 Parameters:
476 value: The section classes.
477 title: An optional title.
478 """
479 super().__init__(title)
480 self.value: list[DocstringTypeAlias] = value
483class DocstringSectionModules(DocstringSection):
484 """This class represents a modules section."""
486 kind: DocstringSectionKind = DocstringSectionKind.modules
488 def __init__(self, value: list[DocstringModule], title: str | None = None) -> None:
489 """Initialize the section.
491 Parameters:
492 value: The section modules.
493 title: An optional title.
494 """
495 super().__init__(title)
496 self.value: list[DocstringModule] = value
499class DocstringSectionDeprecated(DocstringSection):
500 """This class represents a deprecated section."""
502 kind: DocstringSectionKind = DocstringSectionKind.deprecated
504 def __init__(self, version: str, text: str, title: str | None = None) -> None:
505 """Initialize the section.
507 Parameters:
508 version: The deprecation version.
509 text: The deprecation text.
510 title: An optional title.
511 """
512 super().__init__(title)
513 self.value: DocstringDeprecated = DocstringDeprecated(annotation=version, description=text)
516class DocstringSectionAdmonition(DocstringSection):
517 """This class represents an admonition section."""
519 kind: DocstringSectionKind = DocstringSectionKind.admonition
521 def __init__(self, kind: str, text: str, title: str | None = None) -> None:
522 """Initialize the section.
524 Parameters:
525 kind: The admonition kind.
526 text: The admonition text.
527 title: An optional title.
528 """
529 super().__init__(title)
530 self.value: DocstringAdmonition = DocstringAdmonition(annotation=kind, description=text)