Coverage for src/_griffe/docstrings/models.py: 95.03%

155 statements  

« prev     ^ index     » next       coverage.py v7.6.2, created at 2024-10-12 01:34 +0200

1# This module contains the models for storing docstrings structured data. 

2 

3from __future__ import annotations 

4 

5from typing import TYPE_CHECKING 

6 

7from _griffe.enumerations import DocstringSectionKind 

8 

9if TYPE_CHECKING: 

10 from typing import Any, Literal 

11 

12 from _griffe.expressions import Expr 

13 

14 

15# Elements ----------------------------------------------- 

16class DocstringElement: 

17 """This base class represents annotated, nameless elements.""" 

18 

19 def __init__(self, *, description: str, annotation: str | Expr | None = None) -> None: 

20 """Initialize the element. 

21 

22 Parameters: 

23 annotation: The element annotation, if any. 

24 description: The element description. 

25 """ 

26 self.description: str = description 

27 """The element description.""" 

28 self.annotation: str | Expr | None = annotation 

29 """The element annotation.""" 

30 

31 def as_dict(self, **kwargs: Any) -> dict[str, Any]: # noqa: ARG002 

32 """Return this element's data as a dictionary. 

33 

34 Parameters: 

35 **kwargs: Additional serialization options. 

36 

37 Returns: 

38 A dictionary. 

39 """ 

40 return { 

41 "annotation": self.annotation, 

42 "description": self.description, 

43 } 

44 

45 

46class DocstringNamedElement(DocstringElement): 

47 """This base class represents annotated, named elements.""" 

48 

49 def __init__( 

50 self, 

51 name: str, 

52 *, 

53 description: str, 

54 annotation: str | Expr | None = None, 

55 value: str | None = None, 

56 ) -> None: 

57 """Initialize the element. 

58 

59 Parameters: 

60 name: The element name. 

61 description: The element description. 

62 annotation: The element annotation, if any. 

63 value: The element value, as a string. 

64 """ 

65 super().__init__(description=description, annotation=annotation) 

66 self.name: str = name 

67 """The element name.""" 

68 self.value: str | None = value 

69 """The element value, if any""" 

70 

71 def as_dict(self, **kwargs: Any) -> dict[str, Any]: 

72 """Return this element's data as a dictionary. 

73 

74 Parameters: 

75 **kwargs: Additional serialization options. 

76 

77 Returns: 

78 A dictionary. 

79 """ 

80 base = {"name": self.name, **super().as_dict(**kwargs)} 

81 if self.value is not None: 

82 base["value"] = self.value 

83 return base 

84 

85 

86class DocstringAdmonition(DocstringElement): 

87 """This class represents an admonition.""" 

88 

89 @property 

90 def kind(self) -> str | Expr | None: 

91 """The kind of this admonition.""" 

92 return self.annotation 

93 

94 @kind.setter 

95 def kind(self, value: str | Expr) -> None: 

96 self.annotation = value 

97 

98 @property 

99 def contents(self) -> str: 

100 """The contents of this admonition.""" 

101 return self.description 

102 

103 @contents.setter 

104 def contents(self, value: str) -> None: 

105 self.description = value 

106 

107 

108class DocstringDeprecated(DocstringElement): 

109 """This class represents a documented deprecated item.""" 

110 

111 @property 

112 def version(self) -> str: 

113 """The version of this deprecation.""" 

114 return self.annotation # type: ignore[return-value] 

115 

116 @version.setter 

117 def version(self, value: str) -> None: 

118 self.annotation = value 

119 

120 

121class DocstringRaise(DocstringElement): 

122 """This class represents a documented raise value.""" 

123 

124 

125class DocstringWarn(DocstringElement): 

126 """This class represents a documented warn value.""" 

127 

128 

129class DocstringReturn(DocstringNamedElement): 

130 """This class represents a documented return value.""" 

131 

132 

133class DocstringYield(DocstringNamedElement): 

134 """This class represents a documented yield value.""" 

135 

136 

137class DocstringReceive(DocstringNamedElement): 

138 """This class represents a documented receive value.""" 

139 

140 

141class DocstringParameter(DocstringNamedElement): 

142 """This class represent a documented function parameter.""" 

143 

144 @property 

145 def default(self) -> str | None: 

146 """The default value of this parameter.""" 

147 return self.value 

148 

149 @default.setter 

150 def default(self, value: str) -> None: 

151 self.value = value 

152 

153 

154class DocstringAttribute(DocstringNamedElement): 

155 """This class represents a documented module/class attribute.""" 

156 

157 

158class DocstringFunction(DocstringNamedElement): 

159 """This class represents a documented function.""" 

160 

161 @property 

162 def signature(self) -> str | Expr | None: 

163 """The function signature.""" 

164 return self.annotation 

165 

166 

167class DocstringClass(DocstringNamedElement): 

168 """This class represents a documented class.""" 

169 

170 @property 

171 def signature(self) -> str | Expr | None: 

172 """The class signature.""" 

173 return self.annotation 

174 

175 

176class DocstringModule(DocstringNamedElement): 

177 """This class represents a documented module.""" 

178 

179 

180# Sections ----------------------------------------------- 

181class DocstringSection: 

182 """This class represents a docstring section.""" 

183 

184 kind: DocstringSectionKind 

185 """The section kind.""" 

186 

187 def __init__(self, title: str | None = None) -> None: 

188 """Initialize the section. 

189 

190 Parameters: 

191 title: An optional title. 

192 """ 

193 self.title: str | None = title 

194 """The section title.""" 

195 self.value: Any = None 

196 """The section value.""" 

197 

198 def __bool__(self) -> bool: 

199 """Whether this section has a true-ish value.""" 

200 return bool(self.value) 

201 

202 def as_dict(self, **kwargs: Any) -> dict[str, Any]: 

203 """Return this section's data as a dictionary. 

204 

205 Parameters: 

206 **kwargs: Additional serialization options. 

207 

208 Returns: 

209 A dictionary. 

210 """ 

211 if hasattr(self.value, "as_dict"): # noqa: SIM108 211 ↛ 212line 211 didn't jump to line 212 because the condition on line 211 was never true

212 serialized_value = self.value.as_dict(**kwargs) 

213 else: 

214 serialized_value = self.value 

215 base = {"kind": self.kind.value, "value": serialized_value} 

216 if self.title: 216 ↛ 217line 216 didn't jump to line 217 because the condition on line 216 was never true

217 base["title"] = self.title 

218 return base 

219 

220 

221class DocstringSectionText(DocstringSection): 

222 """This class represents a text section.""" 

223 

224 kind: DocstringSectionKind = DocstringSectionKind.text 

225 

226 def __init__(self, value: str, title: str | None = None) -> None: 

227 """Initialize the section. 

228 

229 Parameters: 

230 value: The section text. 

231 title: An optional title. 

232 """ 

233 super().__init__(title) 

234 self.value: str = value 

235 

236 

237class DocstringSectionParameters(DocstringSection): 

238 """This class represents a parameters section.""" 

239 

240 kind: DocstringSectionKind = DocstringSectionKind.parameters 

241 

242 def __init__(self, value: list[DocstringParameter], title: str | None = None) -> None: 

243 """Initialize the section. 

244 

245 Parameters: 

246 value: The section parameters. 

247 title: An optional title. 

248 """ 

249 super().__init__(title) 

250 self.value: list[DocstringParameter] = value 

251 

252 

253class DocstringSectionOtherParameters(DocstringSectionParameters): 

254 """This class represents an other parameters section.""" 

255 

256 kind: DocstringSectionKind = DocstringSectionKind.other_parameters 

257 

258 

259class DocstringSectionRaises(DocstringSection): 

260 """This class represents a raises section.""" 

261 

262 kind: DocstringSectionKind = DocstringSectionKind.raises 

263 

264 def __init__(self, value: list[DocstringRaise], title: str | None = None) -> None: 

265 """Initialize the section. 

266 

267 Parameters: 

268 value: The section exceptions. 

269 title: An optional title. 

270 """ 

271 super().__init__(title) 

272 self.value: list[DocstringRaise] = value 

273 

274 

275class DocstringSectionWarns(DocstringSection): 

276 """This class represents a warns section.""" 

277 

278 kind: DocstringSectionKind = DocstringSectionKind.warns 

279 

280 def __init__(self, value: list[DocstringWarn], title: str | None = None) -> None: 

281 """Initialize the section. 

282 

283 Parameters: 

284 value: The section warnings. 

285 title: An optional title. 

286 """ 

287 super().__init__(title) 

288 self.value: list[DocstringWarn] = value 

289 

290 

291class DocstringSectionReturns(DocstringSection): 

292 """This class represents a returns section.""" 

293 

294 kind: DocstringSectionKind = DocstringSectionKind.returns 

295 

296 def __init__(self, value: list[DocstringReturn], title: str | None = None) -> None: 

297 """Initialize the section. 

298 

299 Parameters: 

300 value: The section returned items. 

301 title: An optional title. 

302 """ 

303 super().__init__(title) 

304 self.value: list[DocstringReturn] = value 

305 

306 

307class DocstringSectionYields(DocstringSection): 

308 """This class represents a yields section.""" 

309 

310 kind: DocstringSectionKind = DocstringSectionKind.yields 

311 

312 def __init__(self, value: list[DocstringYield], title: str | None = None) -> None: 

313 """Initialize the section. 

314 

315 Parameters: 

316 value: The section yielded items. 

317 title: An optional title. 

318 """ 

319 super().__init__(title) 

320 self.value: list[DocstringYield] = value 

321 

322 

323class DocstringSectionReceives(DocstringSection): 

324 """This class represents a receives section.""" 

325 

326 kind: DocstringSectionKind = DocstringSectionKind.receives 

327 

328 def __init__(self, value: list[DocstringReceive], title: str | None = None) -> None: 

329 """Initialize the section. 

330 

331 Parameters: 

332 value: The section received items. 

333 title: An optional title. 

334 """ 

335 super().__init__(title) 

336 self.value: list[DocstringReceive] = value 

337 

338 

339class DocstringSectionExamples(DocstringSection): 

340 """This class represents an examples section.""" 

341 

342 kind: DocstringSectionKind = DocstringSectionKind.examples 

343 

344 def __init__( 

345 self, 

346 value: list[tuple[Literal[DocstringSectionKind.text, DocstringSectionKind.examples], str]], 

347 title: str | None = None, 

348 ) -> None: 

349 """Initialize the section. 

350 

351 Parameters: 

352 value: The section examples. 

353 title: An optional title. 

354 """ 

355 super().__init__(title) 

356 self.value: list[tuple[Literal[DocstringSectionKind.text, DocstringSectionKind.examples], str]] = value 

357 

358 

359class DocstringSectionAttributes(DocstringSection): 

360 """This class represents an attributes section.""" 

361 

362 kind: DocstringSectionKind = DocstringSectionKind.attributes 

363 

364 def __init__(self, value: list[DocstringAttribute], title: str | None = None) -> None: 

365 """Initialize the section. 

366 

367 Parameters: 

368 value: The section attributes. 

369 title: An optional title. 

370 """ 

371 super().__init__(title) 

372 self.value: list[DocstringAttribute] = value 

373 

374 

375class DocstringSectionFunctions(DocstringSection): 

376 """This class represents a functions/methods section.""" 

377 

378 kind: DocstringSectionKind = DocstringSectionKind.functions 

379 

380 def __init__(self, value: list[DocstringFunction], title: str | None = None) -> None: 

381 """Initialize the section. 

382 

383 Parameters: 

384 value: The section functions. 

385 title: An optional title. 

386 """ 

387 super().__init__(title) 

388 self.value: list[DocstringFunction] = value 

389 

390 

391class DocstringSectionClasses(DocstringSection): 

392 """This class represents a classes section.""" 

393 

394 kind: DocstringSectionKind = DocstringSectionKind.classes 

395 

396 def __init__(self, value: list[DocstringClass], title: str | None = None) -> None: 

397 """Initialize the section. 

398 

399 Parameters: 

400 value: The section classes. 

401 title: An optional title. 

402 """ 

403 super().__init__(title) 

404 self.value: list[DocstringClass] = value 

405 

406 

407class DocstringSectionModules(DocstringSection): 

408 """This class represents a modules section.""" 

409 

410 kind: DocstringSectionKind = DocstringSectionKind.modules 

411 

412 def __init__(self, value: list[DocstringModule], title: str | None = None) -> None: 

413 """Initialize the section. 

414 

415 Parameters: 

416 value: The section modules. 

417 title: An optional title. 

418 """ 

419 super().__init__(title) 

420 self.value: list[DocstringModule] = value 

421 

422 

423class DocstringSectionDeprecated(DocstringSection): 

424 """This class represents a deprecated section.""" 

425 

426 kind: DocstringSectionKind = DocstringSectionKind.deprecated 

427 

428 def __init__(self, version: str, text: str, title: str | None = None) -> None: 

429 """Initialize the section. 

430 

431 Parameters: 

432 version: The deprecation version. 

433 text: The deprecation text. 

434 title: An optional title. 

435 """ 

436 super().__init__(title) 

437 self.value: DocstringDeprecated = DocstringDeprecated(annotation=version, description=text) 

438 

439 

440class DocstringSectionAdmonition(DocstringSection): 

441 """This class represents an admonition section.""" 

442 

443 kind: DocstringSectionKind = DocstringSectionKind.admonition 

444 

445 def __init__(self, kind: str, text: str, title: str | None = None) -> None: 

446 """Initialize the section. 

447 

448 Parameters: 

449 kind: The admonition kind. 

450 text: The admonition text. 

451 title: An optional title. 

452 """ 

453 super().__init__(title) 

454 self.value: DocstringAdmonition = DocstringAdmonition(annotation=kind, description=text)