Sphinx 7.1.1__py3-none-any.whl → 7.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of Sphinx might be problematic. Click here for more details.

Files changed (313) hide show
  1. sphinx/__init__.py +6 -6
  2. sphinx/__main__.py +3 -1
  3. sphinx/addnodes.py +35 -22
  4. sphinx/application.py +40 -38
  5. sphinx/builders/__init__.py +16 -12
  6. sphinx/builders/_epub_base.py +15 -11
  7. sphinx/builders/changes.py +6 -4
  8. sphinx/builders/dirhtml.py +4 -2
  9. sphinx/builders/dummy.py +6 -4
  10. sphinx/builders/epub3.py +16 -8
  11. sphinx/builders/gettext.py +40 -43
  12. sphinx/builders/html/__init__.py +166 -196
  13. sphinx/builders/html/_assets.py +116 -0
  14. sphinx/builders/html/transforms.py +4 -2
  15. sphinx/builders/latex/__init__.py +12 -7
  16. sphinx/builders/latex/theming.py +5 -2
  17. sphinx/builders/latex/transforms.py +6 -3
  18. sphinx/builders/linkcheck.py +21 -13
  19. sphinx/builders/manpage.py +6 -4
  20. sphinx/builders/singlehtml.py +16 -9
  21. sphinx/builders/texinfo.py +11 -6
  22. sphinx/builders/text.py +8 -3
  23. sphinx/builders/xml.py +9 -4
  24. sphinx/cmd/build.py +27 -14
  25. sphinx/cmd/make_mode.py +13 -4
  26. sphinx/cmd/quickstart.py +13 -4
  27. sphinx/config.py +17 -14
  28. sphinx/deprecation.py +4 -2
  29. sphinx/directives/__init__.py +44 -12
  30. sphinx/directives/code.py +5 -4
  31. sphinx/directives/other.py +92 -44
  32. sphinx/directives/patches.py +1 -1
  33. sphinx/domains/__init__.py +11 -8
  34. sphinx/domains/c.py +67 -57
  35. sphinx/domains/changeset.py +3 -2
  36. sphinx/domains/citation.py +2 -1
  37. sphinx/domains/cpp.py +136 -93
  38. sphinx/domains/index.py +9 -5
  39. sphinx/domains/javascript.py +32 -19
  40. sphinx/domains/math.py +5 -3
  41. sphinx/domains/python.py +69 -57
  42. sphinx/domains/rst.py +20 -11
  43. sphinx/domains/std.py +21 -15
  44. sphinx/environment/__init__.py +97 -65
  45. sphinx/environment/adapters/indexentries.py +13 -10
  46. sphinx/environment/adapters/toctree.py +485 -308
  47. sphinx/environment/collectors/__init__.py +3 -4
  48. sphinx/environment/collectors/asset.py +10 -4
  49. sphinx/environment/collectors/dependencies.py +7 -4
  50. sphinx/environment/collectors/metadata.py +7 -5
  51. sphinx/environment/collectors/title.py +5 -3
  52. sphinx/environment/collectors/toctree.py +13 -8
  53. sphinx/errors.py +1 -1
  54. sphinx/events.py +5 -5
  55. sphinx/ext/apidoc.py +49 -27
  56. sphinx/ext/autodoc/__init__.py +179 -161
  57. sphinx/ext/autodoc/directive.py +10 -6
  58. sphinx/ext/autodoc/importer.py +22 -13
  59. sphinx/ext/autodoc/mock.py +4 -1
  60. sphinx/ext/autodoc/preserve_defaults.py +80 -12
  61. sphinx/ext/autodoc/type_comment.py +14 -10
  62. sphinx/ext/autodoc/typehints.py +7 -3
  63. sphinx/ext/autosectionlabel.py +6 -3
  64. sphinx/ext/autosummary/__init__.py +21 -15
  65. sphinx/ext/autosummary/generate.py +176 -126
  66. sphinx/ext/coverage.py +93 -8
  67. sphinx/ext/doctest.py +28 -17
  68. sphinx/ext/duration.py +19 -17
  69. sphinx/ext/extlinks.py +11 -6
  70. sphinx/ext/githubpages.py +8 -7
  71. sphinx/ext/graphviz.py +61 -17
  72. sphinx/ext/ifconfig.py +7 -4
  73. sphinx/ext/imgconverter.py +4 -2
  74. sphinx/ext/imgmath.py +29 -23
  75. sphinx/ext/inheritance_diagram.py +41 -27
  76. sphinx/ext/intersphinx.py +45 -38
  77. sphinx/ext/linkcode.py +8 -5
  78. sphinx/ext/mathjax.py +13 -9
  79. sphinx/ext/napoleon/__init__.py +3 -3
  80. sphinx/ext/napoleon/docstring.py +40 -31
  81. sphinx/ext/todo.py +10 -7
  82. sphinx/ext/viewcode.py +46 -25
  83. sphinx/extension.py +1 -1
  84. sphinx/highlighting.py +20 -12
  85. sphinx/io.py +5 -4
  86. sphinx/jinja2glue.py +24 -19
  87. sphinx/locale/__init__.py +8 -2
  88. sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
  89. sphinx/locale/ar/LC_MESSAGES/sphinx.po +756 -740
  90. sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
  91. sphinx/locale/bg/LC_MESSAGES/sphinx.po +754 -738
  92. sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
  93. sphinx/locale/bn/LC_MESSAGES/sphinx.po +755 -739
  94. sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
  95. sphinx/locale/ca/LC_MESSAGES/sphinx.po +768 -752
  96. sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
  97. sphinx/locale/cak/LC_MESSAGES/sphinx.po +754 -738
  98. sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
  99. sphinx/locale/cs/LC_MESSAGES/sphinx.po +758 -742
  100. sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
  101. sphinx/locale/cy/LC_MESSAGES/sphinx.po +759 -743
  102. sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
  103. sphinx/locale/da/LC_MESSAGES/sphinx.po +760 -744
  104. sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
  105. sphinx/locale/de/LC_MESSAGES/sphinx.po +759 -743
  106. sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
  107. sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +754 -738
  108. sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
  109. sphinx/locale/el/LC_MESSAGES/sphinx.po +763 -747
  110. sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
  111. sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +754 -738
  112. sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
  113. sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +754 -738
  114. sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
  115. sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +768 -752
  116. sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
  117. sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +754 -738
  118. sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
  119. sphinx/locale/eo/LC_MESSAGES/sphinx.po +754 -738
  120. sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
  121. sphinx/locale/es/LC_MESSAGES/sphinx.po +767 -751
  122. sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
  123. sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +754 -738
  124. sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
  125. sphinx/locale/et/LC_MESSAGES/sphinx.po +762 -746
  126. sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
  127. sphinx/locale/eu/LC_MESSAGES/sphinx.po +755 -739
  128. sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
  129. sphinx/locale/fa/LC_MESSAGES/sphinx.po +766 -750
  130. sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
  131. sphinx/locale/fi/LC_MESSAGES/sphinx.po +754 -738
  132. sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
  133. sphinx/locale/fr/LC_MESSAGES/sphinx.po +768 -752
  134. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
  135. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +754 -738
  136. sphinx/locale/gl/LC_MESSAGES/sphinx.js +60 -0
  137. sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
  138. sphinx/locale/gl/LC_MESSAGES/sphinx.po +3695 -0
  139. sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
  140. sphinx/locale/he/LC_MESSAGES/sphinx.po +755 -739
  141. sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
  142. sphinx/locale/hi/LC_MESSAGES/sphinx.po +763 -747
  143. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
  144. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +754 -738
  145. sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
  146. sphinx/locale/hr/LC_MESSAGES/sphinx.po +760 -744
  147. sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
  148. sphinx/locale/hu/LC_MESSAGES/sphinx.po +759 -743
  149. sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
  150. sphinx/locale/id/LC_MESSAGES/sphinx.po +765 -749
  151. sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
  152. sphinx/locale/is/LC_MESSAGES/sphinx.po +760 -744
  153. sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
  154. sphinx/locale/it/LC_MESSAGES/sphinx.po +760 -744
  155. sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
  156. sphinx/locale/ja/LC_MESSAGES/sphinx.po +767 -751
  157. sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
  158. sphinx/locale/ka/LC_MESSAGES/sphinx.po +759 -743
  159. sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
  160. sphinx/locale/ko/LC_MESSAGES/sphinx.po +767 -751
  161. sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
  162. sphinx/locale/lt/LC_MESSAGES/sphinx.po +755 -739
  163. sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
  164. sphinx/locale/lv/LC_MESSAGES/sphinx.po +755 -739
  165. sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
  166. sphinx/locale/mk/LC_MESSAGES/sphinx.po +754 -738
  167. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
  168. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +755 -739
  169. sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
  170. sphinx/locale/ne/LC_MESSAGES/sphinx.po +755 -739
  171. sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
  172. sphinx/locale/nl/LC_MESSAGES/sphinx.po +760 -744
  173. sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
  174. sphinx/locale/pl/LC_MESSAGES/sphinx.po +762 -745
  175. sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
  176. sphinx/locale/pt/LC_MESSAGES/sphinx.po +754 -738
  177. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
  178. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +768 -752
  179. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
  180. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +755 -739
  181. sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
  182. sphinx/locale/ro/LC_MESSAGES/sphinx.po +759 -743
  183. sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
  184. sphinx/locale/ru/LC_MESSAGES/sphinx.po +760 -744
  185. sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
  186. sphinx/locale/si/LC_MESSAGES/sphinx.po +754 -738
  187. sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
  188. sphinx/locale/sk/LC_MESSAGES/sphinx.po +765 -749
  189. sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
  190. sphinx/locale/sl/LC_MESSAGES/sphinx.po +755 -739
  191. sphinx/locale/sphinx.pot +748 -740
  192. sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
  193. sphinx/locale/sq/LC_MESSAGES/sphinx.po +768 -752
  194. sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
  195. sphinx/locale/sr/LC_MESSAGES/sphinx.po +754 -738
  196. sphinx/locale/sr@latin/LC_MESSAGES/sphinx.mo +0 -0
  197. sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po +754 -738
  198. sphinx/locale/sr_RS/LC_MESSAGES/sphinx.mo +0 -0
  199. sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po +754 -738
  200. sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
  201. sphinx/locale/sv/LC_MESSAGES/sphinx.po +755 -739
  202. sphinx/locale/ta/LC_MESSAGES/sphinx.mo +0 -0
  203. sphinx/locale/ta/LC_MESSAGES/sphinx.po +754 -738
  204. sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
  205. sphinx/locale/te/LC_MESSAGES/sphinx.po +754 -738
  206. sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
  207. sphinx/locale/tr/LC_MESSAGES/sphinx.po +763 -747
  208. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
  209. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +760 -749
  210. sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
  211. sphinx/locale/ur/LC_MESSAGES/sphinx.po +759 -748
  212. sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
  213. sphinx/locale/vi/LC_MESSAGES/sphinx.po +754 -738
  214. sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
  215. sphinx/locale/yue/LC_MESSAGES/sphinx.po +754 -738
  216. sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo +0 -0
  217. sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +768 -752
  218. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
  219. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +754 -738
  220. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
  221. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +767 -751
  222. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
  223. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +754 -738
  224. sphinx/parsers.py +5 -4
  225. sphinx/project.py +52 -34
  226. sphinx/pycode/__init__.py +2 -1
  227. sphinx/pycode/ast.py +7 -13
  228. sphinx/pycode/parser.py +42 -38
  229. sphinx/registry.py +35 -29
  230. sphinx/roles.py +9 -4
  231. sphinx/search/__init__.py +5 -17
  232. sphinx/search/da.py +1 -1
  233. sphinx/search/de.py +1 -1
  234. sphinx/search/en.py +1 -1
  235. sphinx/search/es.py +1 -1
  236. sphinx/search/fi.py +1 -1
  237. sphinx/search/fr.py +1 -1
  238. sphinx/search/hu.py +1 -1
  239. sphinx/search/it.py +1 -1
  240. sphinx/search/ja.py +1 -1
  241. sphinx/search/nl.py +1 -1
  242. sphinx/search/no.py +1 -1
  243. sphinx/search/pt.py +1 -1
  244. sphinx/search/ro.py +1 -1
  245. sphinx/search/ru.py +1 -1
  246. sphinx/search/sv.py +1 -1
  247. sphinx/search/tr.py +1 -1
  248. sphinx/search/zh.py +1 -1
  249. sphinx/testing/fixtures.py +23 -30
  250. sphinx/testing/path.py +9 -0
  251. sphinx/testing/restructuredtext.py +13 -5
  252. sphinx/testing/util.py +20 -63
  253. sphinx/texinputs/sphinxlatexobjects.sty +15 -15
  254. sphinx/themes/agogo/static/agogo.css_t +10 -4
  255. sphinx/themes/basic/layout.html +1 -1
  256. sphinx/themes/basic/static/basic.css_t +4 -0
  257. sphinx/themes/basic/static/documentation_options.js_t +1 -2
  258. sphinx/themes/basic/static/searchtools.js +17 -9
  259. sphinx/themes/basic/static/sphinx_highlight.js +13 -3
  260. sphinx/themes/bizstyle/static/bizstyle.css_t +4 -0
  261. sphinx/themes/classic/theme.conf +1 -1
  262. sphinx/themes/epub/static/epub.css_t +6 -1
  263. sphinx/themes/haiku/theme.conf +1 -1
  264. sphinx/themes/nature/static/nature.css_t +4 -0
  265. sphinx/themes/nonav/static/nonav.css_t +6 -1
  266. sphinx/themes/pyramid/static/pyramid.css_t +4 -0
  267. sphinx/themes/scrolls/static/scrolls.css_t +4 -0
  268. sphinx/themes/scrolls/theme.conf +1 -1
  269. sphinx/themes/sphinxdoc/static/sphinxdoc.css_t +4 -0
  270. sphinx/theming.py +9 -7
  271. sphinx/transforms/__init__.py +79 -3
  272. sphinx/transforms/compact_bullet_list.py +6 -3
  273. sphinx/transforms/i18n.py +26 -10
  274. sphinx/transforms/post_transforms/__init__.py +21 -8
  275. sphinx/transforms/post_transforms/code.py +6 -3
  276. sphinx/transforms/post_transforms/images.py +13 -9
  277. sphinx/util/__init__.py +21 -92
  278. sphinx/util/cfamily.py +7 -4
  279. sphinx/util/display.py +3 -2
  280. sphinx/util/docfields.py +7 -6
  281. sphinx/util/docstrings.py +1 -1
  282. sphinx/util/docutils.py +41 -31
  283. sphinx/util/fileutil.py +9 -6
  284. sphinx/util/i18n.py +21 -18
  285. sphinx/util/images.py +2 -1
  286. sphinx/util/index_entries.py +27 -0
  287. sphinx/util/inspect.py +83 -67
  288. sphinx/util/inventory.py +4 -2
  289. sphinx/util/logging.py +9 -6
  290. sphinx/util/matching.py +5 -2
  291. sphinx/util/math.py +6 -3
  292. sphinx/util/nodes.py +70 -31
  293. sphinx/util/osutil.py +22 -40
  294. sphinx/util/parallel.py +4 -1
  295. sphinx/util/rst.py +7 -3
  296. sphinx/util/tags.py +11 -4
  297. sphinx/util/template.py +17 -14
  298. sphinx/util/typing.py +61 -20
  299. sphinx/versioning.py +6 -4
  300. sphinx/writers/html.py +1 -1
  301. sphinx/writers/html5.py +32 -24
  302. sphinx/writers/latex.py +67 -53
  303. sphinx/writers/manpage.py +9 -5
  304. sphinx/writers/texinfo.py +11 -9
  305. sphinx/writers/text.py +14 -9
  306. sphinx/writers/xml.py +3 -2
  307. {sphinx-7.1.1.dist-info → sphinx-7.2.0.dist-info}/METADATA +7 -5
  308. sphinx-7.2.0.dist-info/RECORD +568 -0
  309. sphinx/testing/comparer.py +0 -97
  310. sphinx-7.1.1.dist-info/RECORD +0 -564
  311. {sphinx-7.1.1.dist-info → sphinx-7.2.0.dist-info}/LICENSE +0 -0
  312. {sphinx-7.1.1.dist-info → sphinx-7.2.0.dist-info}/WHEEL +0 -0
  313. {sphinx-7.1.1.dist-info → sphinx-7.2.0.dist-info}/entry_points.txt +0 -0
@@ -9,25 +9,15 @@ from __future__ import annotations
9
9
 
10
10
  import re
11
11
  import sys
12
+ import warnings
12
13
  from inspect import Parameter, Signature
13
- from typing import (
14
- TYPE_CHECKING,
15
- Any,
16
- Callable,
17
- Iterator,
18
- List,
19
- Sequence,
20
- Tuple,
21
- TypeVar,
22
- Union,
23
- )
14
+ from typing import TYPE_CHECKING, Any, Callable, TypeVar
24
15
 
25
16
  from docutils.statemachine import StringList
26
17
 
27
18
  import sphinx
28
- from sphinx.application import Sphinx
29
19
  from sphinx.config import ENUM, Config
30
- from sphinx.environment import BuildEnvironment
20
+ from sphinx.deprecation import RemovedInSphinx80Warning
31
21
  from sphinx.ext.autodoc.importer import get_class_members, import_module, import_object
32
22
  from sphinx.ext.autodoc.mock import ismock, mock, undecorate
33
23
  from sphinx.locale import _, __
@@ -44,8 +34,11 @@ from sphinx.util.inspect import (
44
34
  from sphinx.util.typing import OptionSpec, get_type_hints, restify, stringify_annotation
45
35
 
46
36
  if TYPE_CHECKING:
37
+ from collections.abc import Iterator, Sequence
47
38
  from types import ModuleType
48
39
 
40
+ from sphinx.application import Sphinx
41
+ from sphinx.environment import BuildEnvironment
49
42
  from sphinx.ext.autodoc.directive import DocumenterBridge
50
43
 
51
44
  logger = logging.getLogger(__name__)
@@ -260,7 +253,7 @@ class Options(dict):
260
253
  return None
261
254
 
262
255
 
263
- class ObjectMember(tuple):
256
+ class ObjectMember:
264
257
  """A member of object.
265
258
 
266
259
  This is used for the result of `Documenter.get_module_members()` to
@@ -274,10 +267,7 @@ class ObjectMember(tuple):
274
267
  interface.
275
268
  """
276
269
 
277
- def __new__(cls, name: str, obj: Any, **kwargs: Any) -> Any:
278
- return super().__new__(cls, (name, obj)) # type: ignore
279
-
280
- def __init__(self, name: str, obj: Any, docstring: str | None = None,
270
+ def __init__(self, name: str, obj: Any, *, docstring: str | None = None,
281
271
  class_: Any = None, skipped: bool = False) -> None:
282
272
  self.__name__ = name
283
273
  self.object = obj
@@ -285,8 +275,11 @@ class ObjectMember(tuple):
285
275
  self.skipped = skipped
286
276
  self.class_ = class_
287
277
 
288
-
289
- ObjectMembers = Union[List[ObjectMember], List[Tuple[str, Any]]]
278
+ def __getitem__(self, index):
279
+ warnings.warn('The tuple interface of ObjectMember is deprecated. '
280
+ 'Use (obj.__name__, obj.object) instead.',
281
+ RemovedInSphinx80Warning, stacklevel=2)
282
+ return (self.__name__, self.object)[index]
290
283
 
291
284
 
292
285
  class Documenter:
@@ -317,6 +310,7 @@ class Documenter:
317
310
  titles_allowed = True
318
311
 
319
312
  option_spec: OptionSpec = {
313
+ 'no-index': bool_option,
320
314
  'noindex': bool_option,
321
315
  }
322
316
 
@@ -328,7 +322,8 @@ class Documenter:
328
322
  def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any,
329
323
  ) -> bool:
330
324
  """Called to see if a member can be documented by this Documenter."""
331
- raise NotImplementedError('must be implemented in subclasses')
325
+ msg = 'must be implemented in subclasses'
326
+ raise NotImplementedError(msg)
332
327
 
333
328
  def __init__(self, directive: DocumenterBridge, name: str, indent: str = '') -> None:
334
329
  self.directive = directive
@@ -339,21 +334,21 @@ class Documenter:
339
334
  self.indent = indent
340
335
  # the module and object path within the module, and the fully
341
336
  # qualified name (all set after resolve_name succeeds)
342
- self.modname: str = None
343
- self.module: ModuleType = None
344
- self.objpath: list[str] = None
345
- self.fullname: str = None
337
+ self.modname: str = ''
338
+ self.module: ModuleType | None = None
339
+ self.objpath: list[str] = []
340
+ self.fullname = ''
346
341
  # extra signature items (arguments and return annotation,
347
342
  # also set after resolve_name succeeds)
348
- self.args: str = None
349
- self.retann: str = None
343
+ self.args: str | None = None
344
+ self.retann: str = ''
350
345
  # the object to document (set after import_object succeeds)
351
346
  self.object: Any = None
352
- self.object_name: str = None
347
+ self.object_name = ''
353
348
  # the parent/owner of the object to document
354
349
  self.parent: Any = None
355
350
  # the module analyzer to get at attribute docs, or None
356
- self.analyzer: ModuleAnalyzer = None
351
+ self.analyzer: ModuleAnalyzer | None = None
357
352
 
358
353
  @property
359
354
  def documenters(self) -> dict[str, type[Documenter]]:
@@ -367,8 +362,8 @@ class Documenter:
367
362
  else:
368
363
  self.directive.result.append('', source, *lineno)
369
364
 
370
- def resolve_name(self, modname: str, parents: Any, path: str, base: Any,
371
- ) -> tuple[str, list[str]]:
365
+ def resolve_name(self, modname: str | None, parents: Any, path: str, base: str,
366
+ ) -> tuple[str | None, list[str]]:
372
367
  """Resolve the module and name of the object to document given by the
373
368
  arguments and the current module/class.
374
369
 
@@ -376,7 +371,8 @@ class Documenter:
376
371
  example, it would return ``('zipfile', ['ZipFile', 'open'])`` for the
377
372
  ``zipfile.ZipFile.open`` method.
378
373
  """
379
- raise NotImplementedError('must be implemented in subclasses')
374
+ msg = 'must be implemented in subclasses'
375
+ raise NotImplementedError(msg)
380
376
 
381
377
  def parse_name(self) -> bool:
382
378
  """Determine what module to import and what attribute to document.
@@ -389,6 +385,7 @@ class Documenter:
389
385
  # an autogenerated one
390
386
  try:
391
387
  matched = py_ext_sig_re.match(self.name)
388
+ assert matched is not None
392
389
  explicit_modname, path, base, tp_list, args, retann = matched.groups()
393
390
  except AttributeError:
394
391
  logger.warning(__('invalid signature for auto%s (%r)') % (self.objtype, self.name),
@@ -404,11 +401,12 @@ class Documenter:
404
401
  parents = []
405
402
 
406
403
  with mock(self.config.autodoc_mock_imports):
407
- self.modname, self.objpath = self.resolve_name(modname, parents, path, base)
404
+ modname, self.objpath = self.resolve_name(modname, parents, path, base)
408
405
 
409
- if not self.modname:
406
+ if not modname:
410
407
  return False
411
408
 
409
+ self.modname = modname
412
410
  self.args = args
413
411
  self.retann = retann
414
412
  self.fullname = ((self.modname or '') +
@@ -458,12 +456,12 @@ class Documenter:
458
456
  return False
459
457
  return True
460
458
 
461
- def format_args(self, **kwargs: Any) -> str | None:
459
+ def format_args(self, **kwargs: Any) -> str:
462
460
  """Format the argument signature of *self.object*.
463
461
 
464
462
  Should return None if the object does not have a signature.
465
463
  """
466
- pass
464
+ return ''
467
465
 
468
466
  def format_name(self) -> str:
469
467
  """Format the name of *self.object*.
@@ -476,7 +474,7 @@ class Documenter:
476
474
  # directives of course)
477
475
  return '.'.join(self.objpath) or self.modname
478
476
 
479
- def _call_format_args(self, **kwargs: Any) -> str | None:
477
+ def _call_format_args(self, **kwargs: Any) -> str:
480
478
  if kwargs:
481
479
  try:
482
480
  return self.format_args(**kwargs)
@@ -537,8 +535,8 @@ class Documenter:
537
535
  if i == 0:
538
536
  prefix = " " * len(prefix)
539
537
 
540
- if self.options.noindex:
541
- self.add_line(' :noindex:', sourcename)
538
+ if self.options.no_index or self.options.noindex:
539
+ self.add_line(' :no-index:', sourcename)
542
540
  if self.objpath:
543
541
  # Be explicit about the module, this is necessary since .. class::
544
542
  # etc. don't support a prepended module name
@@ -600,9 +598,9 @@ class Documenter:
600
598
  docstring = False
601
599
  # make a copy of docstring for attributes to avoid cache
602
600
  # the change of autodoc-process-docstring event.
603
- docstrings = [list(attr_docs[key])]
601
+ attribute_docstrings = [list(attr_docs[key])]
604
602
 
605
- for i, line in enumerate(self.process_doc(docstrings)):
603
+ for i, line in enumerate(self.process_doc(attribute_docstrings)):
606
604
  self.add_line(line, sourcename, i)
607
605
 
608
606
  # add content from docstrings
@@ -625,16 +623,17 @@ class Documenter:
625
623
  for line, src in zip(more_content.data, more_content.items):
626
624
  self.add_line(line, src[0], src[1])
627
625
 
628
- def get_object_members(self, want_all: bool) -> tuple[bool, ObjectMembers]:
626
+ def get_object_members(self, want_all: bool) -> tuple[bool, list[ObjectMember]]:
629
627
  """Return `(members_check_module, members)` where `members` is a
630
628
  list of `(membername, member)` pairs of the members of *self.object*.
631
629
 
632
630
  If *want_all* is True, return all members. Else, only return those
633
631
  members given by *self.options.members* (which may also be None).
634
632
  """
635
- raise NotImplementedError('must be implemented in subclasses')
633
+ msg = 'must be implemented in subclasses'
634
+ raise NotImplementedError(msg)
636
635
 
637
- def filter_members(self, members: ObjectMembers, want_all: bool,
636
+ def filter_members(self, members: list[ObjectMember], want_all: bool,
638
637
  ) -> list[tuple[str, Any, bool]]:
639
638
  """Filter the given member list.
640
639
 
@@ -679,7 +678,8 @@ class Documenter:
679
678
  # process members and determine which to skip
680
679
  for obj in members:
681
680
  try:
682
- membername, member = obj
681
+ membername = obj.__name__
682
+ member = obj.object
683
683
  # if isattr is True, the member is documented as an attribute
684
684
  isattr = member is INSTANCEATTR or (namespace, membername) in attr_docs
685
685
 
@@ -813,7 +813,7 @@ class Documenter:
813
813
  classes.sort(key=lambda cls: cls.priority)
814
814
  # give explicitly separated module name, so that members
815
815
  # of inner classes can be documented
816
- full_mname = self.modname + '::' + '.'.join(self.objpath + [mname])
816
+ full_mname = f'{self.modname}::' + '.'.join((*self.objpath, mname))
817
817
  documenter = classes[-1](self.directive, full_mname, self.indent)
818
818
  memberdocumenters.append((documenter, isattr))
819
819
 
@@ -898,8 +898,8 @@ class Documenter:
898
898
  # no source file -- e.g. for builtin and C modules
899
899
  self.analyzer = None
900
900
  # at least add the module.__file__ as a dependency
901
- if hasattr(self.module, '__file__') and self.module.__file__:
902
- self.directive.record_dependencies.add(self.module.__file__)
901
+ if module___file__ := getattr(self.module, '__file__', ''):
902
+ self.directive.record_dependencies.add(module___file__)
903
903
  else:
904
904
  self.directive.record_dependencies.add(self.analyzer.srcname)
905
905
 
@@ -960,13 +960,14 @@ class ModuleDocumenter(Documenter):
960
960
 
961
961
  option_spec: OptionSpec = {
962
962
  'members': members_option, 'undoc-members': bool_option,
963
- 'noindex': bool_option, 'inherited-members': inherited_members_option,
963
+ 'no-index': bool_option, 'inherited-members': inherited_members_option,
964
964
  'show-inheritance': bool_option, 'synopsis': identity,
965
965
  'platform': identity, 'deprecated': bool_option,
966
966
  'member-order': member_order_option, 'exclude-members': exclude_members_option,
967
967
  'private-members': members_option, 'special-members': members_option,
968
968
  'imported-members': bool_option, 'ignore-module-all': bool_option,
969
969
  'no-value': bool_option,
970
+ 'noindex': bool_option,
970
971
  }
971
972
 
972
973
  def __init__(self, *args: Any) -> None:
@@ -989,8 +990,8 @@ class ModuleDocumenter(Documenter):
989
990
  # don't document submodules automatically
990
991
  return False
991
992
 
992
- def resolve_name(self, modname: str, parents: Any, path: str, base: Any,
993
- ) -> tuple[str, list[str]]:
993
+ def resolve_name(self, modname: str | None, parents: Any, path: str, base: str,
994
+ ) -> tuple[str | None, list[str]]:
994
995
  if modname is not None:
995
996
  logger.warning(__('"::" in automodule name doesn\'t make sense'),
996
997
  type='autodoc')
@@ -1058,7 +1059,7 @@ class ModuleDocumenter(Documenter):
1058
1059
 
1059
1060
  return members
1060
1061
 
1061
- def get_object_members(self, want_all: bool) -> tuple[bool, ObjectMembers]:
1062
+ def get_object_members(self, want_all: bool) -> tuple[bool, list[ObjectMember]]:
1062
1063
  members = self.get_module_members()
1063
1064
  if want_all:
1064
1065
  if self.__all__ is None:
@@ -1087,16 +1088,21 @@ class ModuleDocumenter(Documenter):
1087
1088
  def sort_members(self, documenters: list[tuple[Documenter, bool]],
1088
1089
  order: str) -> list[tuple[Documenter, bool]]:
1089
1090
  if order == 'bysource' and self.__all__:
1091
+ assert self.__all__ is not None
1092
+ module_all = self.__all__
1093
+ module_all_set = set(module_all)
1094
+ module_all_len = len(module_all)
1095
+
1090
1096
  # Sort alphabetically first (for members not listed on the __all__)
1091
1097
  documenters.sort(key=lambda e: e[0].name)
1092
1098
 
1093
1099
  # Sort by __all__
1094
1100
  def keyfunc(entry: tuple[Documenter, bool]) -> int:
1095
1101
  name = entry[0].name.split('::')[1]
1096
- if self.__all__ and name in self.__all__:
1097
- return self.__all__.index(name)
1102
+ if name in module_all_set:
1103
+ return module_all.index(name)
1098
1104
  else:
1099
- return len(self.__all__)
1105
+ return module_all_len
1100
1106
  documenters.sort(key=keyfunc)
1101
1107
 
1102
1108
  return documenters
@@ -1109,19 +1115,21 @@ class ModuleLevelDocumenter(Documenter):
1109
1115
  Specialized Documenter subclass for objects on module level (functions,
1110
1116
  classes, data/constants).
1111
1117
  """
1112
- def resolve_name(self, modname: str, parents: Any, path: str, base: Any,
1113
- ) -> tuple[str, list[str]]:
1114
- if modname is None:
1115
- if path:
1116
- modname = path.rstrip('.')
1117
- else:
1118
- # if documenting a toplevel object without explicit module,
1119
- # it can be contained in another auto directive ...
1120
- modname = self.env.temp_data.get('autodoc:module')
1121
- # ... or in the scope of a module directive
1122
- if not modname:
1123
- modname = self.env.ref_context.get('py:module')
1124
- # ... else, it stays None, which means invalid
1118
+ def resolve_name(self, modname: str | None, parents: Any, path: str, base: str,
1119
+ ) -> tuple[str | None, list[str]]:
1120
+ if modname is not None:
1121
+ return modname, parents + [base]
1122
+ if path:
1123
+ modname = path.rstrip('.')
1124
+ return modname, parents + [base]
1125
+
1126
+ # if documenting a toplevel object without explicit module,
1127
+ # it can be contained in another auto directive ...
1128
+ modname = self.env.temp_data.get('autodoc:module')
1129
+ # ... or in the scope of a module directive
1130
+ if not modname:
1131
+ modname = self.env.ref_context.get('py:module')
1132
+ # ... else, it stays None, which means invalid
1125
1133
  return modname, parents + [base]
1126
1134
 
1127
1135
 
@@ -1130,31 +1138,33 @@ class ClassLevelDocumenter(Documenter):
1130
1138
  Specialized Documenter subclass for objects on class level (methods,
1131
1139
  attributes).
1132
1140
  """
1133
- def resolve_name(self, modname: str, parents: Any, path: str, base: Any,
1134
- ) -> tuple[str, list[str]]:
1135
- if modname is None:
1136
- if path:
1137
- mod_cls = path.rstrip('.')
1138
- else:
1139
- mod_cls = None
1140
- # if documenting a class-level object without path,
1141
- # there must be a current class, either from a parent
1142
- # auto directive ...
1143
- mod_cls = self.env.temp_data.get('autodoc:class')
1144
- # ... or from a class directive
1145
- if mod_cls is None:
1146
- mod_cls = self.env.ref_context.get('py:class')
1141
+ def resolve_name(self, modname: str | None, parents: Any, path: str, base: str,
1142
+ ) -> tuple[str | None, list[str]]:
1143
+ if modname is not None:
1144
+ return modname, parents + [base]
1145
+
1146
+ if path:
1147
+ mod_cls = path.rstrip('.')
1148
+ else:
1149
+ # if documenting a class-level object without path,
1150
+ # there must be a current class, either from a parent
1151
+ # auto directive ...
1152
+ mod_cls_ = self.env.temp_data.get('autodoc:class')
1153
+ # ... or from a class directive
1154
+ if mod_cls_ is None:
1155
+ mod_cls_ = self.env.ref_context.get('py:class')
1147
1156
  # ... if still None, there's no way to know
1148
- if mod_cls is None:
1157
+ if mod_cls_ is None:
1149
1158
  return None, []
1150
- modname, sep, cls = mod_cls.rpartition('.')
1151
- parents = [cls]
1152
- # if the module name is still missing, get it like above
1153
- if not modname:
1154
- modname = self.env.temp_data.get('autodoc:module')
1155
- if not modname:
1156
- modname = self.env.ref_context.get('py:module')
1157
- # ... else, it stays None, which means invalid
1159
+ mod_cls = mod_cls_
1160
+ modname, sep, cls = mod_cls.rpartition('.')
1161
+ parents = [cls]
1162
+ # if the module name is still missing, get it like above
1163
+ if not modname:
1164
+ modname = self.env.temp_data.get('autodoc:module')
1165
+ if not modname:
1166
+ modname = self.env.ref_context.get('py:module')
1167
+ # ... else, it stays None, which means invalid
1158
1168
  return modname, parents + [base]
1159
1169
 
1160
1170
 
@@ -1163,12 +1173,12 @@ class DocstringSignatureMixin:
1163
1173
  Mixin for FunctionDocumenter and MethodDocumenter to provide the
1164
1174
  feature of reading the signature from the docstring.
1165
1175
  """
1166
- _new_docstrings: list[list[str]] = None
1167
- _signatures: list[str] = None
1176
+ _new_docstrings: list[list[str]] | None = None
1177
+ _signatures: list[str] = []
1168
1178
 
1169
- def _find_signature(self) -> tuple[str | None, str | None]:
1179
+ def _find_signature(self) -> tuple[str | None, str | None] | None:
1170
1180
  # candidates of the object name
1171
- valid_names = [self.objpath[-1]] # type: ignore
1181
+ valid_names = [self.objpath[-1]] # type: ignore[attr-defined]
1172
1182
  if isinstance(self, ClassDocumenter):
1173
1183
  valid_names.append('__init__')
1174
1184
  if hasattr(self.object, '__mro__'):
@@ -1200,7 +1210,8 @@ class DocstringSignatureMixin:
1200
1210
  break
1201
1211
 
1202
1212
  # re-prepare docstring to ignore more leading indentation
1203
- tab_width = self.directive.state.document.settings.tab_width # type: ignore
1213
+ directive = self.directive # type: ignore[attr-defined]
1214
+ tab_width = directive.state.document.settings.tab_width
1204
1215
  self._new_docstrings[i] = prepare_docstring('\n'.join(doclines[j + 1:]),
1205
1216
  tab_width)
1206
1217
 
@@ -1211,25 +1222,27 @@ class DocstringSignatureMixin:
1211
1222
  # subsequent signatures
1212
1223
  self._signatures.append(f"({args}) -> {retann}")
1213
1224
 
1214
- if result:
1225
+ if result is not None:
1215
1226
  # finish the loop when signature found
1216
1227
  break
1217
1228
 
1218
1229
  return result
1219
1230
 
1220
- def get_doc(self) -> list[list[str]]:
1231
+ def get_doc(self) -> list[list[str]] | None:
1221
1232
  if self._new_docstrings is not None:
1222
1233
  return self._new_docstrings
1223
1234
  return super().get_doc() # type: ignore[misc]
1224
1235
 
1225
1236
  def format_signature(self, **kwargs: Any) -> str:
1226
- if self.args is None and self.config.autodoc_docstring_signature: # type: ignore
1237
+ self.args: str | None
1238
+ if (self.args is None
1239
+ and self.config.autodoc_docstring_signature): # type: ignore[attr-defined]
1227
1240
  # only act if a signature is not explicitly given already, and if
1228
1241
  # the feature is enabled
1229
1242
  result = self._find_signature()
1230
1243
  if result is not None:
1231
1244
  self.args, self.retann = result
1232
- sig = super().format_signature(**kwargs) # type: ignore
1245
+ sig = super().format_signature(**kwargs) # type: ignore[misc]
1233
1246
  if self._signatures:
1234
1247
  return "\n".join([sig] + self._signatures)
1235
1248
  else:
@@ -1257,7 +1270,7 @@ class DocstringStripSignatureMixin(DocstringSignatureMixin):
1257
1270
  return super().format_signature(**kwargs)
1258
1271
 
1259
1272
 
1260
- class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: ignore
1273
+ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: ignore[misc]
1261
1274
  """
1262
1275
  Specialized Documenter subclass for functions.
1263
1276
  """
@@ -1271,7 +1284,7 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
1271
1284
  return (inspect.isfunction(member) or inspect.isbuiltin(member) or
1272
1285
  (inspect.isroutine(member) and isinstance(parent, ModuleDocumenter)))
1273
1286
 
1274
- def format_args(self, **kwargs: Any) -> str | None:
1287
+ def format_args(self, **kwargs: Any) -> str:
1275
1288
  if self.config.autodoc_typehints in ('none', 'description'):
1276
1289
  kwargs.setdefault('show_annotation', False)
1277
1290
  if self.config.autodoc_typehints_format == "short":
@@ -1284,7 +1297,7 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
1284
1297
  except TypeError as exc:
1285
1298
  logger.warning(__("Failed to get a function signature for %s: %s"),
1286
1299
  self.fullname, exc)
1287
- return None
1300
+ return ''
1288
1301
  except ValueError:
1289
1302
  args = ''
1290
1303
 
@@ -1328,13 +1341,13 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
1328
1341
  if dispatchfunc:
1329
1342
  documenter = FunctionDocumenter(self.directive, '')
1330
1343
  documenter.object = dispatchfunc
1331
- documenter.objpath = [None]
1344
+ documenter.objpath = ['']
1332
1345
  sigs.append(documenter.format_signature())
1333
- if overloaded:
1346
+ if overloaded and self.analyzer is not None:
1334
1347
  actual = inspect.signature(self.object,
1335
1348
  type_aliases=self.config.autodoc_type_aliases)
1336
1349
  __globals__ = safe_getattr(self.object, '__globals__', {})
1337
- for overload in self.analyzer.overloads.get('.'.join(self.objpath)):
1350
+ for overload in self.analyzer.overloads['.'.join(self.objpath)]:
1338
1351
  overload = self.merge_default_value(actual, overload)
1339
1352
  overload = evaluate_signature(overload, __globals__,
1340
1353
  self.config.autodoc_type_aliases)
@@ -1375,7 +1388,8 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
1375
1388
  if params[0].annotation is Parameter.empty:
1376
1389
  params[0] = params[0].replace(annotation=typ)
1377
1390
  try:
1378
- dummy.__signature__ = sig.replace(parameters=params) # type: ignore
1391
+ dummy.__signature__ = sig.replace( # type: ignore[attr-defined]
1392
+ parameters=params)
1379
1393
  return dummy
1380
1394
  except (AttributeError, TypeError):
1381
1395
  # failed to update signature (ex. built-in or extension types)
@@ -1393,12 +1407,12 @@ class DecoratorDocumenter(FunctionDocumenter):
1393
1407
  # must be lower than FunctionDocumenter
1394
1408
  priority = -1
1395
1409
 
1396
- def format_args(self, **kwargs: Any) -> Any:
1410
+ def format_args(self, **kwargs: Any) -> str:
1397
1411
  args = super().format_args(**kwargs)
1398
1412
  if ',' in args:
1399
1413
  return args
1400
1414
  else:
1401
- return None
1415
+ return ''
1402
1416
 
1403
1417
 
1404
1418
  # Types which have confusing metaclass signatures it would be best not to show.
@@ -1415,7 +1429,7 @@ _CLASS_NEW_BLACKLIST = [
1415
1429
  ]
1416
1430
 
1417
1431
 
1418
- class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: ignore
1432
+ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: ignore[misc]
1419
1433
  """
1420
1434
  Specialized Documenter subclass for classes.
1421
1435
  """
@@ -1423,11 +1437,12 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1423
1437
  member_order = 20
1424
1438
  option_spec: OptionSpec = {
1425
1439
  'members': members_option, 'undoc-members': bool_option,
1426
- 'noindex': bool_option, 'inherited-members': inherited_members_option,
1440
+ 'no-index': bool_option, 'inherited-members': inherited_members_option,
1427
1441
  'show-inheritance': bool_option, 'member-order': member_order_option,
1428
1442
  'exclude-members': exclude_members_option,
1429
1443
  'private-members': members_option, 'special-members': members_option,
1430
1444
  'class-doc-from': class_doc_from_option,
1445
+ 'noindex': bool_option,
1431
1446
  }
1432
1447
 
1433
1448
  # Must be higher than FunctionDocumenter, ClassDocumenter, and
@@ -1436,7 +1451,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1436
1451
  priority = 15
1437
1452
 
1438
1453
  _signature_class: Any = None
1439
- _signature_method_name: str = None
1454
+ _signature_method_name: str = ''
1440
1455
 
1441
1456
  def __init__(self, *args: Any) -> None:
1442
1457
  super().__init__(*args)
@@ -1558,26 +1573,27 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1558
1573
  # with __init__ in C and no `__text_signature__`.
1559
1574
  return None, None, None
1560
1575
 
1561
- def format_args(self, **kwargs: Any) -> str | None:
1576
+ def format_args(self, **kwargs: Any) -> str:
1562
1577
  if self.config.autodoc_typehints in ('none', 'description'):
1563
1578
  kwargs.setdefault('show_annotation', False)
1564
1579
  if self.config.autodoc_typehints_format == "short":
1565
1580
  kwargs.setdefault('unqualified_typehints', True)
1566
1581
 
1567
1582
  try:
1568
- self._signature_class, self._signature_method_name, sig = self._get_signature()
1583
+ self._signature_class, _signature_method_name, sig = self._get_signature()
1569
1584
  except TypeError as exc:
1570
1585
  # __signature__ attribute contained junk
1571
1586
  logger.warning(__("Failed to get a constructor signature for %s: %s"),
1572
1587
  self.fullname, exc)
1573
- return None
1588
+ return ''
1589
+ self._signature_method_name = _signature_method_name or ''
1574
1590
 
1575
1591
  if sig is None:
1576
- return None
1592
+ return ''
1577
1593
 
1578
1594
  return stringify_signature(sig, show_return_annotation=False, **kwargs)
1579
1595
 
1580
- def _find_signature(self) -> tuple[str, str]:
1596
+ def _find_signature(self) -> tuple[str | None, str | None] | None:
1581
1597
  result = super()._find_signature()
1582
1598
  if result is not None:
1583
1599
  # Strip a return value from signature of constructor in docstring (first entry)
@@ -1696,12 +1712,12 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1696
1712
  self.add_line('', sourcename)
1697
1713
  self.add_line(' ' + _('Bases: %s') % ', '.join(base_classes), sourcename)
1698
1714
 
1699
- def get_object_members(self, want_all: bool) -> tuple[bool, ObjectMembers]:
1715
+ def get_object_members(self, want_all: bool) -> tuple[bool, list[ObjectMember]]:
1700
1716
  members = get_class_members(self.object, self.objpath, self.get_attr,
1701
1717
  self.config.autodoc_inherit_docstrings)
1702
1718
  if not want_all:
1703
1719
  if not self.options.members:
1704
- return False, [] # type: ignore
1720
+ return False, []
1705
1721
  # specific members given
1706
1722
  selected = []
1707
1723
  for name in self.options.members:
@@ -1740,8 +1756,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1740
1756
  pass
1741
1757
  if self.doc_as_attr:
1742
1758
  # Don't show the docstring of the class when it is an alias.
1743
- comment = self.get_variable_comment()
1744
- if comment:
1759
+ if self.get_variable_comment():
1745
1760
  return []
1746
1761
  else:
1747
1762
  return None
@@ -1891,12 +1906,12 @@ class ExceptionDocumenter(ClassDocumenter):
1891
1906
 
1892
1907
  class DataDocumenterMixinBase:
1893
1908
  # define types of instance variables
1894
- config: Config = None
1895
- env: BuildEnvironment = None
1896
- modname: str = None
1897
- parent: Any = None
1898
- object: Any = None
1899
- objpath: list[str] = None
1909
+ config: Config
1910
+ env: BuildEnvironment
1911
+ modname: str
1912
+ parent: Any
1913
+ object: Any
1914
+ objpath: list[str]
1900
1915
 
1901
1916
  def should_suppress_directive_header(self) -> bool:
1902
1917
  """Check directive header should be suppressed."""
@@ -1942,7 +1957,7 @@ class UninitializedGlobalVariableMixin(DataDocumenterMixinBase):
1942
1957
 
1943
1958
  def import_object(self, raiseerror: bool = False) -> bool:
1944
1959
  try:
1945
- return super().import_object(raiseerror=True) # type: ignore
1960
+ return super().import_object(raiseerror=True) # type: ignore[misc]
1946
1961
  except ImportError as exc:
1947
1962
  # annotation only instance variable (PEP-526)
1948
1963
  try:
@@ -1971,7 +1986,7 @@ class UninitializedGlobalVariableMixin(DataDocumenterMixinBase):
1971
1986
  if self.object is UNINITIALIZED_ATTR:
1972
1987
  return []
1973
1988
  else:
1974
- return super().get_doc() # type: ignore
1989
+ return super().get_doc() # type: ignore[misc]
1975
1990
 
1976
1991
 
1977
1992
  class DataDocumenter(GenericAliasMixin,
@@ -2016,7 +2031,7 @@ class DataDocumenter(GenericAliasMixin,
2016
2031
  if super().should_suppress_value_header():
2017
2032
  return True
2018
2033
  else:
2019
- doc = self.get_doc()
2034
+ doc = self.get_doc() or []
2020
2035
  docstring, metadata = separate_metadata('\n'.join(sum(doc, [])))
2021
2036
  if 'hide-value' in metadata:
2022
2037
  return True
@@ -2094,7 +2109,7 @@ class DataDocumenter(GenericAliasMixin,
2094
2109
  super().add_content(more_content)
2095
2110
 
2096
2111
 
2097
- class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: ignore
2112
+ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: ignore[misc]
2098
2113
  """
2099
2114
  Specialized Documenter subclass for methods (normal, static and class).
2100
2115
  """
@@ -2125,7 +2140,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
2125
2140
 
2126
2141
  return ret
2127
2142
 
2128
- def format_args(self, **kwargs: Any) -> str | None:
2143
+ def format_args(self, **kwargs: Any) -> str:
2129
2144
  if self.config.autodoc_typehints in ('none', 'description'):
2130
2145
  kwargs.setdefault('show_annotation', False)
2131
2146
  if self.config.autodoc_typehints_format == "short":
@@ -2151,7 +2166,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
2151
2166
  except TypeError as exc:
2152
2167
  logger.warning(__("Failed to get a method signature for %s: %s"),
2153
2168
  self.fullname, exc)
2154
- return None
2169
+ return ''
2155
2170
  except ValueError:
2156
2171
  args = ''
2157
2172
 
@@ -2206,9 +2221,9 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
2206
2221
  documenter = MethodDocumenter(self.directive, '')
2207
2222
  documenter.parent = self.parent
2208
2223
  documenter.object = dispatchmeth
2209
- documenter.objpath = [None]
2224
+ documenter.objpath = ['']
2210
2225
  sigs.append(documenter.format_signature())
2211
- if overloaded:
2226
+ if overloaded and self.analyzer is not None:
2212
2227
  if inspect.isstaticmethod(self.object, cls=self.parent, name=self.object_name):
2213
2228
  actual = inspect.signature(self.object, bound_method=False,
2214
2229
  type_aliases=self.config.autodoc_type_aliases)
@@ -2217,7 +2232,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
2217
2232
  type_aliases=self.config.autodoc_type_aliases)
2218
2233
 
2219
2234
  __globals__ = safe_getattr(self.object, '__globals__', {})
2220
- for overload in self.analyzer.overloads.get('.'.join(self.objpath)):
2235
+ for overload in self.analyzer.overloads['.'.join(self.objpath)]:
2221
2236
  overload = self.merge_default_value(actual, overload)
2222
2237
  overload = evaluate_signature(overload, __globals__,
2223
2238
  self.config.autodoc_type_aliases)
@@ -2262,7 +2277,8 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
2262
2277
  if params[1].annotation is Parameter.empty:
2263
2278
  params[1] = params[1].replace(annotation=typ)
2264
2279
  try:
2265
- dummy.__signature__ = sig.replace(parameters=params) # type: ignore
2280
+ dummy.__signature__ = sig.replace( # type: ignore[attr-defined]
2281
+ parameters=params)
2266
2282
  return dummy
2267
2283
  except (AttributeError, TypeError):
2268
2284
  # failed to update signature (ex. built-in or extension types)
@@ -2317,7 +2333,7 @@ class NonDataDescriptorMixin(DataDocumenterMixinBase):
2317
2333
  """
2318
2334
 
2319
2335
  def import_object(self, raiseerror: bool = False) -> bool:
2320
- ret = super().import_object(raiseerror) # type: ignore
2336
+ ret = super().import_object(raiseerror) # type: ignore[misc]
2321
2337
  if ret and not inspect.isattributedescriptor(self.object):
2322
2338
  self.non_data_descriptor = True
2323
2339
  else:
@@ -2335,7 +2351,7 @@ class NonDataDescriptorMixin(DataDocumenterMixinBase):
2335
2351
  # to display
2336
2352
  return None
2337
2353
  else:
2338
- return super().get_doc() # type: ignore
2354
+ return super().get_doc() # type: ignore[misc]
2339
2355
 
2340
2356
 
2341
2357
  class SlotsMixin(DataDocumenterMixinBase):
@@ -2346,13 +2362,15 @@ class SlotsMixin(DataDocumenterMixinBase):
2346
2362
  def isslotsattribute(self) -> bool:
2347
2363
  """Check the subject is an attribute in __slots__."""
2348
2364
  try:
2349
- __slots__ = inspect.getslots(self.parent)
2350
- return bool(__slots__) and self.objpath[-1] in __slots__
2365
+ if parent___slots__ := inspect.getslots(self.parent):
2366
+ return self.objpath[-1] in parent___slots__
2367
+ else:
2368
+ return False
2351
2369
  except (ValueError, TypeError):
2352
2370
  return False
2353
2371
 
2354
2372
  def import_object(self, raiseerror: bool = False) -> bool:
2355
- ret = super().import_object(raiseerror) # type: ignore
2373
+ ret = super().import_object(raiseerror) # type: ignore[misc]
2356
2374
  if self.isslotsattribute():
2357
2375
  self.object = SLOTSATTR
2358
2376
 
@@ -2367,9 +2385,9 @@ class SlotsMixin(DataDocumenterMixinBase):
2367
2385
  def get_doc(self) -> list[list[str]] | None:
2368
2386
  if self.object is SLOTSATTR:
2369
2387
  try:
2370
- __slots__ = inspect.getslots(self.parent)
2371
- if __slots__ and __slots__.get(self.objpath[-1]):
2372
- docstring = prepare_docstring(__slots__[self.objpath[-1]])
2388
+ parent___slots__ = inspect.getslots(self.parent)
2389
+ if parent___slots__ and parent___slots__.get(self.objpath[-1]):
2390
+ docstring = prepare_docstring(parent___slots__[self.objpath[-1]])
2373
2391
  return [docstring]
2374
2392
  else:
2375
2393
  return []
@@ -2378,7 +2396,7 @@ class SlotsMixin(DataDocumenterMixinBase):
2378
2396
  (self.parent.__qualname__, exc), type='autodoc')
2379
2397
  return []
2380
2398
  else:
2381
- return super().get_doc() # type: ignore
2399
+ return super().get_doc() # type: ignore[misc]
2382
2400
 
2383
2401
 
2384
2402
  class RuntimeInstanceAttributeMixin(DataDocumenterMixinBase):
@@ -2398,7 +2416,7 @@ class RuntimeInstanceAttributeMixin(DataDocumenterMixinBase):
2398
2416
  def is_runtime_instance_attribute(self, parent: Any) -> bool:
2399
2417
  """Check the subject is an attribute defined in __init__()."""
2400
2418
  # An instance variable defined in __init__().
2401
- if self.get_attribute_comment(parent, self.objpath[-1]): # type: ignore
2419
+ if self.get_attribute_comment(parent, self.objpath[-1]): # type: ignore[attr-defined]
2402
2420
  return True
2403
2421
  if self.is_runtime_instance_attribute_not_commented(parent):
2404
2422
  return True
@@ -2420,18 +2438,18 @@ class RuntimeInstanceAttributeMixin(DataDocumenterMixinBase):
2420
2438
  except (AttributeError, PycodeError):
2421
2439
  pass
2422
2440
 
2423
- return None
2441
+ return False
2424
2442
 
2425
2443
  def import_object(self, raiseerror: bool = False) -> bool:
2426
2444
  """Check the existence of runtime instance attribute after failing to import the
2427
2445
  attribute."""
2428
2446
  try:
2429
- return super().import_object(raiseerror=True) # type: ignore
2447
+ return super().import_object(raiseerror=True) # type: ignore[misc]
2430
2448
  except ImportError as exc:
2431
2449
  try:
2432
2450
  with mock(self.config.autodoc_mock_imports):
2433
2451
  ret = import_object(self.modname, self.objpath[:-1], 'class',
2434
- attrgetter=self.get_attr, # type: ignore
2452
+ attrgetter=self.get_attr, # type: ignore[attr-defined]
2435
2453
  warningiserror=self.config.autodoc_warningiserror)
2436
2454
  parent = ret[3]
2437
2455
  if self.is_runtime_instance_attribute(parent):
@@ -2456,7 +2474,7 @@ class RuntimeInstanceAttributeMixin(DataDocumenterMixinBase):
2456
2474
  self.is_runtime_instance_attribute_not_commented(self.parent)):
2457
2475
  return None
2458
2476
  else:
2459
- return super().get_doc() # type: ignore
2477
+ return super().get_doc() # type: ignore[misc]
2460
2478
 
2461
2479
 
2462
2480
  class UninitializedInstanceAttributeMixin(DataDocumenterMixinBase):
@@ -2479,11 +2497,11 @@ class UninitializedInstanceAttributeMixin(DataDocumenterMixinBase):
2479
2497
  """Check the exisitence of uninitialized instance attribute when failed to import
2480
2498
  the attribute."""
2481
2499
  try:
2482
- return super().import_object(raiseerror=True) # type: ignore
2500
+ return super().import_object(raiseerror=True) # type: ignore[misc]
2483
2501
  except ImportError as exc:
2484
2502
  try:
2485
2503
  ret = import_object(self.modname, self.objpath[:-1], 'class',
2486
- attrgetter=self.get_attr, # type: ignore
2504
+ attrgetter=self.get_attr, # type: ignore[attr-defined]
2487
2505
  warningiserror=self.config.autodoc_warningiserror)
2488
2506
  parent = ret[3]
2489
2507
  if self.is_uninitialized_instance_attribute(parent):
@@ -2506,11 +2524,10 @@ class UninitializedInstanceAttributeMixin(DataDocumenterMixinBase):
2506
2524
  def get_doc(self) -> list[list[str]] | None:
2507
2525
  if self.object is UNINITIALIZED_ATTR:
2508
2526
  return None
2509
- else:
2510
- return super().get_doc() # type: ignore
2527
+ return super().get_doc() # type: ignore[misc]
2511
2528
 
2512
2529
 
2513
- class AttributeDocumenter(GenericAliasMixin, SlotsMixin, # type: ignore
2530
+ class AttributeDocumenter(GenericAliasMixin, SlotsMixin, # type: ignore[misc]
2514
2531
  RuntimeInstanceAttributeMixin,
2515
2532
  UninitializedInstanceAttributeMixin, NonDataDescriptorMixin,
2516
2533
  DocstringStripSignatureMixin, ClassLevelDocumenter):
@@ -2651,10 +2668,10 @@ class AttributeDocumenter(GenericAliasMixin, SlotsMixin, # type: ignore
2651
2668
  # a docstring from the value which descriptor returns unexpectedly.
2652
2669
  # ref: https://github.com/sphinx-doc/sphinx/issues/7805
2653
2670
  orig = self.config.autodoc_inherit_docstrings
2654
- self.config.autodoc_inherit_docstrings = False # type: ignore
2671
+ self.config.autodoc_inherit_docstrings = False # type: ignore[attr-defined]
2655
2672
  return super().get_doc()
2656
2673
  finally:
2657
- self.config.autodoc_inherit_docstrings = orig # type: ignore
2674
+ self.config.autodoc_inherit_docstrings = orig # type: ignore[attr-defined]
2658
2675
 
2659
2676
  def add_content(self, more_content: StringList | None) -> None:
2660
2677
  # Disable analyzing attribute comment on Documenter.add_content() to control it on
@@ -2667,7 +2684,8 @@ class AttributeDocumenter(GenericAliasMixin, SlotsMixin, # type: ignore
2667
2684
  super().add_content(more_content)
2668
2685
 
2669
2686
 
2670
- class PropertyDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter): # type: ignore
2687
+ class PropertyDocumenter(DocstringStripSignatureMixin, # type: ignore[misc]
2688
+ ClassLevelDocumenter):
2671
2689
  """
2672
2690
  Specialized Documenter subclass for properties.
2673
2691
  """
@@ -2707,10 +2725,10 @@ class PropertyDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter): #
2707
2725
  self.isclassmethod = False
2708
2726
  return ret
2709
2727
 
2710
- def format_args(self, **kwargs: Any) -> str | None:
2728
+ def format_args(self, **kwargs: Any) -> str:
2711
2729
  func = self._get_property_getter()
2712
2730
  if func is None:
2713
- return None
2731
+ return ''
2714
2732
 
2715
2733
  # update the annotations of the property getter
2716
2734
  self.env.app.emit('autodoc-before-process-signature', func, False)