Sphinx 7.4.7__py3-none-any.whl → 8.0.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 (234) hide show
  1. sphinx/__init__.py +2 -2
  2. sphinx/_cli/__init__.py +4 -4
  3. sphinx/application.py +2 -2
  4. sphinx/builders/__init__.py +2 -3
  5. sphinx/builders/_epub_base.py +33 -12
  6. sphinx/builders/changes.py +13 -5
  7. sphinx/builders/epub3.py +6 -2
  8. sphinx/builders/html/__init__.py +88 -58
  9. sphinx/builders/latex/__init__.py +38 -12
  10. sphinx/builders/latex/transforms.py +1 -1
  11. sphinx/builders/linkcheck.py +8 -49
  12. sphinx/builders/texinfo.py +12 -6
  13. sphinx/builders/text.py +7 -3
  14. sphinx/builders/xml.py +7 -3
  15. sphinx/cmd/quickstart.py +10 -20
  16. sphinx/config.py +13 -13
  17. sphinx/deprecation.py +8 -8
  18. sphinx/directives/other.py +2 -3
  19. sphinx/directives/patches.py +2 -2
  20. sphinx/domains/__init__.py +4 -2
  21. sphinx/domains/c/__init__.py +2 -2
  22. sphinx/domains/c/_ast.py +3 -2
  23. sphinx/domains/c/_parser.py +4 -3
  24. sphinx/domains/cpp/__init__.py +2 -2
  25. sphinx/domains/cpp/_ast.py +1 -2
  26. sphinx/domains/cpp/_parser.py +2 -2
  27. sphinx/domains/cpp/_symbol.py +2 -2
  28. sphinx/domains/math.py +1 -1
  29. sphinx/domains/python/_object.py +0 -1
  30. sphinx/domains/std/__init__.py +7 -8
  31. sphinx/environment/__init__.py +15 -32
  32. sphinx/environment/adapters/indexentries.py +4 -6
  33. sphinx/environment/adapters/toctree.py +4 -4
  34. sphinx/environment/collectors/title.py +1 -1
  35. sphinx/environment/collectors/toctree.py +1 -1
  36. sphinx/events.py +3 -1
  37. sphinx/ext/autodoc/__init__.py +17 -63
  38. sphinx/ext/autodoc/directive.py +7 -5
  39. sphinx/ext/autodoc/importer.py +2 -1
  40. sphinx/ext/autodoc/preserve_defaults.py +2 -2
  41. sphinx/ext/autosummary/__init__.py +7 -6
  42. sphinx/ext/autosummary/generate.py +5 -4
  43. sphinx/ext/doctest.py +5 -5
  44. sphinx/ext/graphviz.py +1 -1
  45. sphinx/ext/imgmath.py +1 -1
  46. sphinx/ext/inheritance_diagram.py +1 -1
  47. sphinx/ext/intersphinx/__init__.py +25 -5
  48. sphinx/ext/intersphinx/_cli.py +7 -6
  49. sphinx/ext/intersphinx/_load.py +240 -115
  50. sphinx/ext/intersphinx/_resolve.py +12 -11
  51. sphinx/ext/intersphinx/_shared.py +102 -9
  52. sphinx/ext/mathjax.py +1 -1
  53. sphinx/ext/napoleon/docstring.py +2 -2
  54. sphinx/ext/todo.py +2 -2
  55. sphinx/ext/viewcode.py +2 -1
  56. sphinx/highlighting.py +3 -3
  57. sphinx/io.py +2 -2
  58. sphinx/jinja2glue.py +13 -6
  59. sphinx/locale/__init__.py +4 -3
  60. sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
  61. sphinx/locale/ar/LC_MESSAGES/sphinx.po +2383 -2186
  62. sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
  63. sphinx/locale/bg/LC_MESSAGES/sphinx.po +2249 -2052
  64. sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
  65. sphinx/locale/bn/LC_MESSAGES/sphinx.po +2412 -2215
  66. sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
  67. sphinx/locale/ca/LC_MESSAGES/sphinx.po +3029 -2832
  68. sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
  69. sphinx/locale/cak/LC_MESSAGES/sphinx.po +2308 -2111
  70. sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
  71. sphinx/locale/cs/LC_MESSAGES/sphinx.po +2469 -2272
  72. sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
  73. sphinx/locale/cy/LC_MESSAGES/sphinx.po +2393 -2196
  74. sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
  75. sphinx/locale/da/LC_MESSAGES/sphinx.po +2532 -2335
  76. sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
  77. sphinx/locale/de/LC_MESSAGES/sphinx.po +2492 -2295
  78. sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
  79. sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +2250 -2053
  80. sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
  81. sphinx/locale/el/LC_MESSAGES/sphinx.po +2879 -2682
  82. sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
  83. sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +2250 -2053
  84. sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
  85. sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +2250 -2053
  86. sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
  87. sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +2989 -2792
  88. sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
  89. sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +2250 -2053
  90. sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
  91. sphinx/locale/eo/LC_MESSAGES/sphinx.po +2297 -2100
  92. sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
  93. sphinx/locale/es/LC_MESSAGES/sphinx.po +3017 -2820
  94. sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
  95. sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +2250 -2053
  96. sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
  97. sphinx/locale/et/LC_MESSAGES/sphinx.po +2748 -2551
  98. sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
  99. sphinx/locale/eu/LC_MESSAGES/sphinx.po +2459 -2262
  100. sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
  101. sphinx/locale/fa/LC_MESSAGES/sphinx.po +2957 -2760
  102. sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
  103. sphinx/locale/fi/LC_MESSAGES/sphinx.po +2321 -2124
  104. sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
  105. sphinx/locale/fr/LC_MESSAGES/sphinx.po +2977 -2780
  106. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
  107. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +2250 -2053
  108. sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
  109. sphinx/locale/gl/LC_MESSAGES/sphinx.po +2992 -2795
  110. sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
  111. sphinx/locale/he/LC_MESSAGES/sphinx.po +2375 -2178
  112. sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
  113. sphinx/locale/hi/LC_MESSAGES/sphinx.po +2937 -2740
  114. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
  115. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +2250 -2053
  116. sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
  117. sphinx/locale/hr/LC_MESSAGES/sphinx.po +2532 -2335
  118. sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
  119. sphinx/locale/hu/LC_MESSAGES/sphinx.po +2505 -2308
  120. sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
  121. sphinx/locale/id/LC_MESSAGES/sphinx.po +2925 -2728
  122. sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
  123. sphinx/locale/is/LC_MESSAGES/sphinx.po +2307 -2110
  124. sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
  125. sphinx/locale/it/LC_MESSAGES/sphinx.po +2514 -2317
  126. sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
  127. sphinx/locale/ja/LC_MESSAGES/sphinx.po +2970 -2773
  128. sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
  129. sphinx/locale/ka/LC_MESSAGES/sphinx.po +2868 -2671
  130. sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
  131. sphinx/locale/ko/LC_MESSAGES/sphinx.po +3016 -2819
  132. sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
  133. sphinx/locale/lt/LC_MESSAGES/sphinx.po +2476 -2279
  134. sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
  135. sphinx/locale/lv/LC_MESSAGES/sphinx.po +2477 -2280
  136. sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
  137. sphinx/locale/mk/LC_MESSAGES/sphinx.po +2292 -2095
  138. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
  139. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +2479 -2282
  140. sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
  141. sphinx/locale/ne/LC_MESSAGES/sphinx.po +2481 -2284
  142. sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
  143. sphinx/locale/nl/LC_MESSAGES/sphinx.po +2557 -2360
  144. sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
  145. sphinx/locale/pl/LC_MESSAGES/sphinx.po +2696 -2499
  146. sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
  147. sphinx/locale/pt/LC_MESSAGES/sphinx.po +2250 -2053
  148. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
  149. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +2979 -2782
  150. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
  151. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +2469 -2272
  152. sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
  153. sphinx/locale/ro/LC_MESSAGES/sphinx.po +2473 -2276
  154. sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
  155. sphinx/locale/ru/LC_MESSAGES/sphinx.po +2746 -2549
  156. sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
  157. sphinx/locale/si/LC_MESSAGES/sphinx.po +2331 -2134
  158. sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
  159. sphinx/locale/sk/LC_MESSAGES/sphinx.po +2966 -2769
  160. sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
  161. sphinx/locale/sl/LC_MESSAGES/sphinx.po +2404 -2207
  162. sphinx/locale/sphinx.pot +2262 -2065
  163. sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
  164. sphinx/locale/sq/LC_MESSAGES/sphinx.po +2972 -2775
  165. sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
  166. sphinx/locale/sr/LC_MESSAGES/sphinx.po +2440 -2243
  167. sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
  168. sphinx/locale/sv/LC_MESSAGES/sphinx.po +2483 -2286
  169. sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
  170. sphinx/locale/te/LC_MESSAGES/sphinx.po +2250 -2053
  171. sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
  172. sphinx/locale/tr/LC_MESSAGES/sphinx.po +2892 -2695
  173. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
  174. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +2400 -2203
  175. sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
  176. sphinx/locale/ur/LC_MESSAGES/sphinx.po +2250 -2053
  177. sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
  178. sphinx/locale/vi/LC_MESSAGES/sphinx.po +2422 -2225
  179. sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
  180. sphinx/locale/yue/LC_MESSAGES/sphinx.po +2250 -2053
  181. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
  182. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +2250 -2053
  183. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
  184. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +3028 -2831
  185. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
  186. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +2250 -2053
  187. sphinx/project.py +25 -20
  188. sphinx/pycode/ast.py +2 -2
  189. sphinx/pycode/parser.py +2 -2
  190. sphinx/pygments_styles.py +3 -3
  191. sphinx/registry.py +3 -8
  192. sphinx/search/__init__.py +1 -1
  193. sphinx/testing/path.py +2 -1
  194. sphinx/testing/util.py +1 -1
  195. sphinx/texinputs/Makefile.jinja +2 -1
  196. sphinx/texinputs_win/Makefile.jinja +2 -1
  197. sphinx/theming.py +3 -12
  198. sphinx/transforms/__init__.py +5 -5
  199. sphinx/transforms/references.py +1 -1
  200. sphinx/util/__init__.py +11 -35
  201. sphinx/util/_pathlib.py +31 -19
  202. sphinx/util/_timestamps.py +12 -0
  203. sphinx/util/cfamily.py +5 -5
  204. sphinx/util/console.py +4 -3
  205. sphinx/util/display.py +3 -3
  206. sphinx/util/docfields.py +1 -1
  207. sphinx/util/docutils.py +44 -10
  208. sphinx/util/fileutil.py +25 -20
  209. sphinx/util/i18n.py +9 -4
  210. sphinx/util/images.py +3 -2
  211. sphinx/util/inspect.py +28 -43
  212. sphinx/util/inventory.py +2 -2
  213. sphinx/util/matching.py +2 -2
  214. sphinx/util/math.py +1 -1
  215. sphinx/util/nodes.py +8 -8
  216. sphinx/util/osutil.py +36 -32
  217. sphinx/util/parallel.py +2 -2
  218. sphinx/util/requests.py +1 -1
  219. sphinx/util/template.py +3 -3
  220. sphinx/util/typing.py +36 -72
  221. sphinx/writers/html.py +1 -1
  222. sphinx/writers/html5.py +1 -1
  223. sphinx/writers/latex.py +4 -4
  224. sphinx/writers/manpage.py +2 -2
  225. sphinx/writers/texinfo.py +5 -5
  226. sphinx/writers/text.py +4 -4
  227. sphinx/writers/xml.py +2 -2
  228. {sphinx-7.4.7.dist-info → sphinx-8.0.0.dist-info}/METADATA +11 -10
  229. {sphinx-7.4.7.dist-info → sphinx-8.0.0.dist-info}/RECORD +232 -233
  230. sphinx/templates/quickstart/Makefile.jinja +0 -98
  231. sphinx/templates/quickstart/make.bat.jinja +0 -110
  232. {sphinx-7.4.7.dist-info → sphinx-8.0.0.dist-info}/LICENSE.rst +0 -0
  233. {sphinx-7.4.7.dist-info → sphinx-8.0.0.dist-info}/WHEEL +0 -0
  234. {sphinx-7.4.7.dist-info → sphinx-8.0.0.dist-info}/entry_points.txt +0 -0
sphinx/domains/math.py CHANGED
@@ -74,7 +74,7 @@ class MathDomain(Domain):
74
74
  def process_doc(self, env: BuildEnvironment, docname: str,
75
75
  document: nodes.document) -> None:
76
76
  def math_node(node: Node) -> bool:
77
- return isinstance(node, (nodes.math, nodes.math_block))
77
+ return isinstance(node, nodes.math | nodes.math_block)
78
78
 
79
79
  self.data['has_equations'][docname] = any(document.findall(math_node))
80
80
 
@@ -25,7 +25,6 @@ from sphinx.util.nodes import (
25
25
  )
26
26
 
27
27
  if TYPE_CHECKING:
28
-
29
28
  from docutils.nodes import Node
30
29
  from docutils.parsers.rst.states import Inliner
31
30
 
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import re
6
6
  from copy import copy
7
- from typing import TYPE_CHECKING, Any, Callable, ClassVar, Final, cast
7
+ from typing import TYPE_CHECKING, Any, ClassVar, Final, cast
8
8
 
9
9
  from docutils import nodes
10
10
  from docutils.nodes import Element, Node, system_message
@@ -23,7 +23,7 @@ from sphinx.util.nodes import clean_astext, make_id, make_refnode
23
23
  from sphinx.util.parsing import nested_parse_to_nodes
24
24
 
25
25
  if TYPE_CHECKING:
26
- from collections.abc import Iterable, Iterator
26
+ from collections.abc import Callable, Iterable, Iterator
27
27
 
28
28
  from sphinx.application import Sphinx
29
29
  from sphinx.builders import Builder
@@ -402,7 +402,7 @@ class Glossary(SphinxDirective):
402
402
  in_comment = False
403
403
  was_empty = True
404
404
  messages: list[Node] = []
405
- for line, (source, lineno) in zip(self.content, self.content.items):
405
+ for line, (source, lineno) in zip(self.content, self.content.items, strict=True):
406
406
  # empty line -> add to last definition
407
407
  if not line:
408
408
  if in_definition and entries:
@@ -814,13 +814,12 @@ class StandardDomain(Domain):
814
814
  if not sectname:
815
815
  continue
816
816
  else:
817
- if (isinstance(node, (nodes.definition_list,
818
- nodes.field_list)) and
817
+ if (isinstance(node, nodes.definition_list | nodes.field_list) and
819
818
  node.children):
820
819
  node = cast(nodes.Element, node.children[0])
821
- if isinstance(node, (nodes.field, nodes.definition_list_item)):
820
+ if isinstance(node, nodes.field | nodes.definition_list_item):
822
821
  node = cast(nodes.Element, node.children[0])
823
- if isinstance(node, (nodes.term, nodes.field_name)):
822
+ if isinstance(node, nodes.term | nodes.field_name):
824
823
  sectname = clean_astext(node)
825
824
  else:
826
825
  toctree = next(node.findall(addnodes.toctree), None)
@@ -1114,7 +1113,7 @@ class StandardDomain(Domain):
1114
1113
  return title_getter(elem)
1115
1114
  else:
1116
1115
  for subnode in elem:
1117
- if isinstance(subnode, (nodes.caption, nodes.title)):
1116
+ if isinstance(subnode, nodes.caption | nodes.title):
1118
1117
  return clean_astext(subnode)
1119
1118
 
1120
1119
  return None
@@ -5,11 +5,10 @@ from __future__ import annotations
5
5
  import functools
6
6
  import os
7
7
  import pickle
8
- import time
9
8
  from collections import defaultdict
10
9
  from copy import copy
11
10
  from os import path
12
- from typing import TYPE_CHECKING, Any, Callable, NoReturn
11
+ from typing import TYPE_CHECKING, Any, NoReturn
13
12
 
14
13
  from sphinx import addnodes
15
14
  from sphinx.environment.adapters import toctree as toctree_adapters
@@ -17,13 +16,14 @@ from sphinx.errors import BuildEnvironmentError, DocumentError, ExtensionError,
17
16
  from sphinx.locale import __
18
17
  from sphinx.transforms import SphinxTransformer
19
18
  from sphinx.util import DownloadFiles, FilenameUniqDict, logging
19
+ from sphinx.util._timestamps import _format_rfc3339_microseconds
20
20
  from sphinx.util.docutils import LoggingReporter
21
21
  from sphinx.util.i18n import CatalogRepository, docname_to_domain
22
22
  from sphinx.util.nodes import is_translatable
23
- from sphinx.util.osutil import canon_path, os_path
23
+ from sphinx.util.osutil import _last_modified_time, canon_path, os_path
24
24
 
25
25
  if TYPE_CHECKING:
26
- from collections.abc import Iterator
26
+ from collections.abc import Callable, Iterator
27
27
  from pathlib import Path
28
28
 
29
29
  from docutils import nodes
@@ -36,6 +36,7 @@ if TYPE_CHECKING:
36
36
  from sphinx.domains import Domain
37
37
  from sphinx.events import EventManager
38
38
  from sphinx.project import Project
39
+ from sphinx.util._pathlib import _StrPath
39
40
 
40
41
  logger = logging.getLogger(__name__)
41
42
 
@@ -59,7 +60,7 @@ default_settings: dict[str, Any] = {
59
60
 
60
61
  # This is increased every time an environment attribute is added
61
62
  # or changed to properly invalidate pickle files.
62
- ENV_VERSION = 62
63
+ ENV_VERSION = 63
63
64
 
64
65
  # config status
65
66
  CONFIG_UNSET = -1
@@ -124,7 +125,7 @@ if TYPE_CHECKING:
124
125
  def __getitem__(self, key: Literal["todo"]) -> TodoDomain: ... # NoQA: E704
125
126
  @overload
126
127
  def __getitem__(self, key: str) -> Domain: ... # NoQA: E704
127
- def __getitem__(self, key): raise NotImplementedError # NoQA: E704
128
+ def __getitem__(self, _key: str) -> Domain: raise NotImplementedError # NoQA: E704
128
129
  def __setitem__( # NoQA: E301,E704
129
130
  self, key: str, value: Domain,
130
131
  ) -> NoReturn: raise NotImplementedError
@@ -413,13 +414,13 @@ class BuildEnvironment:
413
414
  """
414
415
  return self.project.path2doc(filename)
415
416
 
416
- def doc2path(self, docname: str, base: bool = True) -> str:
417
+ def doc2path(self, docname: str, base: bool = True) -> _StrPath:
417
418
  """Return the filename for the document name.
418
419
 
419
420
  If *base* is True, return absolute path under self.srcdir.
420
421
  If *base* is False, return relative path to self.srcdir.
421
422
  """
422
- return self.project.doc2path(docname, base)
423
+ return self.project.doc2path(docname, absolute=base)
423
424
 
424
425
  def relfn2path(self, filename: str, docname: str | None = None) -> tuple[str, str]:
425
426
  """Return paths to a file referenced from a document, relative to
@@ -508,7 +509,8 @@ class BuildEnvironment:
508
509
  if newmtime > mtime:
509
510
  logger.debug('[build target] outdated %r: %s -> %s',
510
511
  docname,
511
- _format_modified_time(mtime), _format_modified_time(newmtime))
512
+ _format_rfc3339_microseconds(mtime),
513
+ _format_rfc3339_microseconds(newmtime))
512
514
  changed.add(docname)
513
515
  continue
514
516
  # finally, check the mtime of dependencies
@@ -528,7 +530,8 @@ class BuildEnvironment:
528
530
  logger.debug(
529
531
  '[build target] outdated %r from dependency %r: %s -> %s',
530
532
  docname, deppath,
531
- _format_modified_time(mtime), _format_modified_time(depmtime),
533
+ _format_rfc3339_microseconds(mtime),
534
+ _format_rfc3339_microseconds(depmtime),
532
535
  )
533
536
  changed.add(docname)
534
537
  break
@@ -628,7 +631,7 @@ class BuildEnvironment:
628
631
 
629
632
  doctree = pickle.loads(serialised)
630
633
  doctree.settings.env = self
631
- doctree.reporter = LoggingReporter(self.doc2path(docname))
634
+ doctree.reporter = LoggingReporter(str(self.doc2path(docname)))
632
635
  return doctree
633
636
 
634
637
  @functools.cached_property
@@ -650,7 +653,7 @@ class BuildEnvironment:
650
653
  try:
651
654
  doctree = self._write_doc_doctree_cache.pop(docname)
652
655
  doctree.settings.env = self
653
- doctree.reporter = LoggingReporter(self.doc2path(docname))
656
+ doctree.reporter = LoggingReporter(str(self.doc2path(docname)))
654
657
  except KeyError:
655
658
  doctree = self.get_doctree(docname)
656
659
 
@@ -756,26 +759,6 @@ class BuildEnvironment:
756
759
  self.events.emit('env-check-consistency', self)
757
760
 
758
761
 
759
- def _last_modified_time(filename: str | os.PathLike[str]) -> int:
760
- """Return the last modified time of ``filename``.
761
-
762
- The time is returned as integer microseconds.
763
- The lowest common denominator of modern file-systems seems to be
764
- microsecond-level precision.
765
-
766
- We prefer to err on the side of re-rendering a file,
767
- so we round up to the nearest microsecond.
768
- """
769
- # upside-down floor division to get the ceiling
770
- return -(os.stat(filename).st_mtime_ns // -1_000)
771
-
772
-
773
- def _format_modified_time(timestamp: int) -> str:
774
- """Return an RFC 3339 formatted string representing the given timestamp."""
775
- seconds, fraction = divmod(timestamp, 10**6)
776
- return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(seconds)) + f'.{fraction // 1_000}'
777
-
778
-
779
762
  def _traverse_toctree(
780
763
  traversed: set[str],
781
764
  parent: str | None,
@@ -13,16 +13,14 @@ from sphinx.util import logging
13
13
  from sphinx.util.index_entries import _split_into
14
14
 
15
15
  if TYPE_CHECKING:
16
- from typing import Literal, Optional, Union
17
-
18
- from typing_extensions import TypeAlias
16
+ from typing import Literal, TypeAlias
19
17
 
20
18
  from sphinx.builders import Builder
21
19
  from sphinx.environment import BuildEnvironment
22
20
 
23
- _IndexEntryTarget: TypeAlias = tuple[Optional[str], Union[str, Literal[False]]]
21
+ _IndexEntryTarget: TypeAlias = tuple[str | None, str | Literal[False]]
24
22
  _IndexEntryTargets: TypeAlias = list[_IndexEntryTarget]
25
- _IndexEntryCategoryKey: TypeAlias = Optional[str]
23
+ _IndexEntryCategoryKey: TypeAlias = str | None
26
24
  _IndexEntrySubItems: TypeAlias = dict[
27
25
  str,
28
26
  tuple[_IndexEntryTargets, _IndexEntryCategoryKey],
@@ -32,7 +30,7 @@ if TYPE_CHECKING:
32
30
  _IndexEntrySubItems,
33
31
  _IndexEntryCategoryKey,
34
32
  ]
35
- _IndexEntryMap = dict[str, _IndexEntry]
33
+ _IndexEntryMap: TypeAlias = dict[str, _IndexEntry]
36
34
  _Index: TypeAlias = list[
37
35
  tuple[
38
36
  str,
@@ -319,7 +319,7 @@ def _toctree_entry(
319
319
  ref, location=toctreenode, type='toc', subtype='no_title')
320
320
  except KeyError:
321
321
  # this is raised if the included file does not exist
322
- ref_path = env.doc2path(ref, False)
322
+ ref_path = str(env.doc2path(ref, False))
323
323
  if excluded(ref_path):
324
324
  message = __('toctree contains reference to excluded document %r')
325
325
  elif not included(ref_path):
@@ -404,7 +404,7 @@ def _toctree_standard_entry(
404
404
  def _toctree_add_classes(node: Element, depth: int, docname: str) -> None:
405
405
  """Add 'toctree-l%d' and 'current' classes to the toctree."""
406
406
  for subnode in node.children:
407
- if isinstance(subnode, (addnodes.compact_paragraph, nodes.list_item)):
407
+ if isinstance(subnode, addnodes.compact_paragraph | nodes.list_item):
408
408
  # for <p> and <li>, indicate the depth level and recurse
409
409
  subnode['classes'].append(f'toctree-l{depth - 1}')
410
410
  _toctree_add_classes(subnode, depth, docname)
@@ -442,7 +442,7 @@ def _toctree_copy(node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tag
442
442
 
443
443
  copy = node.copy()
444
444
  for subnode in node.children:
445
- if isinstance(subnode, (addnodes.compact_paragraph, nodes.list_item)):
445
+ if isinstance(subnode, addnodes.compact_paragraph | nodes.list_item):
446
446
  # for <p> and <li>, just recurse
447
447
  copy.append(_toctree_copy(subnode, depth, maxdepth, collapse, tags))
448
448
  elif isinstance(subnode, nodes.bullet_list):
@@ -462,7 +462,7 @@ def _toctree_copy(node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tag
462
462
  copy.append(_toctree_copy(
463
463
  child, depth, maxdepth, collapse, tags, # type: ignore[type-var]
464
464
  ))
465
- elif isinstance(subnode, (nodes.reference, nodes.title)):
465
+ elif isinstance(subnode, nodes.reference | nodes.title):
466
466
  # deep copy references and captions
467
467
  sub_node_copy = subnode.copy()
468
468
  sub_node_copy.children = [child.deepcopy() for child in subnode.children]
@@ -43,7 +43,7 @@ class TitleCollector(EnvironmentCollector):
43
43
  for node in doctree.findall(nodes.section):
44
44
  visitor = SphinxContentsFilter(doctree)
45
45
  node[0].walkabout(visitor)
46
- titlenode += visitor.get_entry_text()
46
+ titlenode += visitor.get_entry_text() # type: ignore[no-untyped-call]
47
47
  break
48
48
  else:
49
49
  # document has no title
@@ -78,7 +78,7 @@ class TocTreeCollector(EnvironmentCollector):
78
78
  # and unnecessary stuff
79
79
  visitor = SphinxContentsFilter(doctree)
80
80
  title.walkabout(visitor)
81
- nodetext = visitor.get_entry_text()
81
+ nodetext = visitor.get_entry_text() # type: ignore[no-untyped-call]
82
82
  anchorname = _make_anchor_name(sectionnode['ids'], numentries)
83
83
  # make these nodes:
84
84
  # list_item -> compact_paragraph -> reference
sphinx/events.py CHANGED
@@ -8,7 +8,7 @@ from __future__ import annotations
8
8
  import contextlib
9
9
  from collections import defaultdict
10
10
  from operator import attrgetter
11
- from typing import TYPE_CHECKING, Any, Callable, NamedTuple
11
+ from typing import TYPE_CHECKING, Any, NamedTuple
12
12
 
13
13
  from sphinx.errors import ExtensionError, SphinxError
14
14
  from sphinx.locale import __
@@ -16,6 +16,8 @@ from sphinx.util import logging
16
16
  from sphinx.util.inspect import safe_getattr
17
17
 
18
18
  if TYPE_CHECKING:
19
+ from collections.abc import Callable
20
+
19
21
  from sphinx.application import Sphinx
20
22
 
21
23
 
@@ -10,20 +10,18 @@ from __future__ import annotations
10
10
  import functools
11
11
  import operator
12
12
  import re
13
- import sys
14
- import warnings
15
13
  from inspect import Parameter, Signature
16
- from typing import TYPE_CHECKING, Any, Callable, ClassVar, TypeVar
14
+ from typing import TYPE_CHECKING, Any, ClassVar, NewType, TypeVar
17
15
 
18
16
  from docutils.statemachine import StringList
19
17
 
20
18
  import sphinx
21
19
  from sphinx.config import ENUM, Config
22
- from sphinx.deprecation import RemovedInSphinx80Warning
20
+ from sphinx.errors import PycodeError
23
21
  from sphinx.ext.autodoc.importer import get_class_members, import_module, import_object
24
22
  from sphinx.ext.autodoc.mock import ismock, mock, undecorate
25
23
  from sphinx.locale import _, __
26
- from sphinx.pycode import ModuleAnalyzer, PycodeError
24
+ from sphinx.pycode import ModuleAnalyzer
27
25
  from sphinx.util import inspect, logging
28
26
  from sphinx.util.docstrings import prepare_docstring, separate_metadata
29
27
  from sphinx.util.inspect import (
@@ -42,7 +40,7 @@ from sphinx.util.typing import (
42
40
  )
43
41
 
44
42
  if TYPE_CHECKING:
45
- from collections.abc import Iterator, Sequence
43
+ from collections.abc import Callable, Iterator, Sequence
46
44
  from types import ModuleType
47
45
 
48
46
  from sphinx.application import Sphinx
@@ -267,13 +265,6 @@ class ObjectMember:
267
265
 
268
266
  This is used for the result of `Documenter.get_module_members()` to
269
267
  represent each member of the object.
270
-
271
- .. Note::
272
-
273
- An instance of this class behaves as a tuple of (name, object)
274
- for compatibility to old Sphinx. The behavior will be dropped
275
- in the future. Therefore extensions should not use the tuple
276
- interface.
277
268
  """
278
269
 
279
270
  def __init__(self, name: str, obj: Any, *, docstring: str | None = None,
@@ -284,12 +275,6 @@ class ObjectMember:
284
275
  self.skipped = skipped
285
276
  self.class_ = class_
286
277
 
287
- def __getitem__(self, index: int) -> Any:
288
- warnings.warn('The tuple interface of ObjectMember is deprecated. '
289
- 'Use (obj.__name__, obj.object) instead.',
290
- RemovedInSphinx80Warning, stacklevel=2)
291
- return (self.__name__, self.object)[index]
292
-
293
278
 
294
279
  class Documenter:
295
280
  """
@@ -627,7 +612,7 @@ class Documenter:
627
612
 
628
613
  # add additional content (e.g. from document), if present
629
614
  if more_content:
630
- for line, src in zip(more_content.data, more_content.items):
615
+ for line, src in zip(more_content.data, more_content.items, strict=True):
631
616
  self.add_line(line, src[0], src[1])
632
617
 
633
618
  def get_object_members(self, want_all: bool) -> tuple[bool, list[ObjectMember]]:
@@ -684,21 +669,8 @@ class Documenter:
684
669
 
685
670
  # process members and determine which to skip
686
671
  for obj in members:
687
- try:
688
- membername = obj.__name__
689
- member = obj.object
690
- except AttributeError:
691
- if isinstance(obj, ObjectMember):
692
- raise
693
- # To be removed, retained for compatibility.
694
- # See https://github.com/sphinx-doc/sphinx/issues/11631
695
- membername, member = obj
696
- warnings.warn(
697
- 'Returning tuples of (name, object) as '
698
- 'the second return value from get_object_members() is deprecated. '
699
- 'Return ObjectMember(name, object) instances instead.',
700
- RemovedInSphinx80Warning, stacklevel=2,
701
- )
672
+ membername = obj.__name__
673
+ member = obj.object
702
674
 
703
675
  # if isattr is True, the member is documented as an attribute
704
676
  isattr = member is INSTANCEATTR or (namespace, membername) in attr_docs
@@ -1003,7 +975,7 @@ class ModuleDocumenter(Documenter):
1003
975
  super().add_content(None)
1004
976
  self.indent = old_indent
1005
977
  if more_content:
1006
- for line, src in zip(more_content.data, more_content.items):
978
+ for line, src in zip(more_content.data, more_content.items, strict=True):
1007
979
  self.add_line(line, src[0], src[1])
1008
980
 
1009
981
  @classmethod
@@ -1410,7 +1382,7 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
1410
1382
  if len(sig.parameters) == 0:
1411
1383
  return None
1412
1384
 
1413
- def dummy(): # NoQA: ANN202
1385
+ def dummy(): # type: ignore[no-untyped-def] # NoQA: ANN202
1414
1386
  pass
1415
1387
 
1416
1388
  params = list(sig.parameters.values())
@@ -1478,7 +1450,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1478
1450
 
1479
1451
  # Must be higher than FunctionDocumenter, ClassDocumenter, and
1480
1452
  # AttributeDocumenter as NewType can be an attribute and is a class
1481
- # after Python 3.10. Before 3.10 it is a kind of function object
1453
+ # after Python 3.10.
1482
1454
  priority = 15
1483
1455
 
1484
1456
  _signature_class: Any = None
@@ -1504,7 +1476,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1504
1476
  cls: type[Documenter], member: Any, membername: str, isattr: bool, parent: Any,
1505
1477
  ) -> bool:
1506
1478
  return isinstance(member, type) or (
1507
- isattr and (inspect.isNewType(member) or isinstance(member, TypeVar)))
1479
+ isattr and isinstance(member, NewType | TypeVar))
1508
1480
 
1509
1481
  def import_object(self, raiseerror: bool = False) -> bool:
1510
1482
  ret = super().import_object(raiseerror)
@@ -1515,7 +1487,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1515
1487
  self.doc_as_attr = (self.objpath[-1] != self.object.__name__)
1516
1488
  else:
1517
1489
  self.doc_as_attr = True
1518
- if inspect.isNewType(self.object) or isinstance(self.object, TypeVar):
1490
+ if isinstance(self.object, NewType | TypeVar):
1519
1491
  modname = getattr(self.object, '__module__', self.modname)
1520
1492
  if modname != self.modname and self.modname.startswith(modname):
1521
1493
  bases = self.modname[len(modname):].strip('.').split('.')
@@ -1524,7 +1496,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1524
1496
  return ret
1525
1497
 
1526
1498
  def _get_signature(self) -> tuple[Any | None, str | None, Signature | None]:
1527
- if inspect.isNewType(self.object) or isinstance(self.object, TypeVar):
1499
+ if isinstance(self.object, NewType | TypeVar):
1528
1500
  # Suppress signature
1529
1501
  return None, None, None
1530
1502
 
@@ -1709,14 +1681,14 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1709
1681
  self.directivetype = 'attribute'
1710
1682
  super().add_directive_header(sig)
1711
1683
 
1712
- if inspect.isNewType(self.object) or isinstance(self.object, TypeVar):
1684
+ if isinstance(self.object, NewType | TypeVar):
1713
1685
  return
1714
1686
 
1715
1687
  if self.analyzer and '.'.join(self.objpath) in self.analyzer.finals:
1716
1688
  self.add_line(' :final:', sourcename)
1717
1689
 
1718
1690
  canonical_fullname = self.get_canonical_fullname()
1719
- if (not self.doc_as_attr and not inspect.isNewType(self.object)
1691
+ if (not self.doc_as_attr and not isinstance(self.object, NewType)
1720
1692
  and canonical_fullname and self.fullname != canonical_fullname):
1721
1693
  self.add_line(' :canonical: %s' % canonical_fullname, sourcename)
1722
1694
 
@@ -1768,24 +1740,6 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1768
1740
  if isinstance(self.object, TypeVar):
1769
1741
  if self.object.__doc__ == TypeVar.__doc__:
1770
1742
  return []
1771
- if sys.version_info[:2] < (3, 10):
1772
- if inspect.isNewType(self.object) or isinstance(self.object, TypeVar):
1773
- parts = self.modname.strip('.').split('.')
1774
- orig_objpath = self.objpath
1775
- for i in range(len(parts)):
1776
- new_modname = '.'.join(parts[:len(parts) - i])
1777
- new_objpath = parts[len(parts) - i:] + orig_objpath
1778
- try:
1779
- analyzer = ModuleAnalyzer.for_module(new_modname)
1780
- analyzer.analyze()
1781
- key = ('', new_objpath[-1])
1782
- comment = list(analyzer.attr_docs.get(key, []))
1783
- if comment:
1784
- self.objpath = new_objpath
1785
- self.modname = new_modname
1786
- return [comment]
1787
- except PycodeError:
1788
- pass
1789
1743
  if self.doc_as_attr:
1790
1744
  # Don't show the docstring of the class when it is an alias.
1791
1745
  if self.get_variable_comment():
@@ -1849,7 +1803,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1849
1803
  return None
1850
1804
 
1851
1805
  def add_content(self, more_content: StringList | None) -> None:
1852
- if inspect.isNewType(self.object):
1806
+ if isinstance(self.object, NewType):
1853
1807
  if self.config.autodoc_typehints_format == "short":
1854
1808
  supertype = restify(self.object.__supertype__, "smart")
1855
1809
  else:
@@ -2324,7 +2278,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
2324
2278
  if len(sig.parameters) == 1:
2325
2279
  return None
2326
2280
 
2327
- def dummy(): # NoQA: ANN202
2281
+ def dummy(): # type: ignore[no-untyped-def] # NoQA: ANN202
2328
2282
  pass
2329
2283
 
2330
2284
  params = list(sig.parameters.values())
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Any, Callable
3
+ from collections.abc import Callable
4
+ from typing import TYPE_CHECKING, Any
4
5
 
5
6
  from docutils import nodes
6
7
  from docutils.statemachine import StringList
@@ -31,14 +32,14 @@ AUTODOC_EXTENDABLE_OPTIONS = ['members', 'private-members', 'special-members',
31
32
  'exclude-members']
32
33
 
33
34
 
34
- class DummyOptionSpec(dict):
35
+ class DummyOptionSpec(dict[str, Callable[[str], str]]):
35
36
  """An option_spec allows any options."""
36
37
 
37
38
  def __bool__(self) -> bool:
38
39
  """Behaves like some options are defined."""
39
40
  return True
40
41
 
41
- def __getitem__(self, key: str) -> Callable[[str], str]:
42
+ def __getitem__(self, _key: str) -> Callable[[str], str]:
42
43
  return lambda x: x
43
44
 
44
45
 
@@ -56,8 +57,9 @@ class DocumenterBridge:
56
57
  self.state = state
57
58
 
58
59
 
59
- def process_documenter_options(documenter: type[Documenter], config: Config, options: dict,
60
- ) -> Options:
60
+ def process_documenter_options(
61
+ documenter: type[Documenter], config: Config, options: dict[str, str],
62
+ ) -> Options:
61
63
  """Recognize options of Documenter from user input."""
62
64
  default_options = config.autodoc_default_options
63
65
  for name in AUTODOC_DEFAULT_OPTIONS:
@@ -11,8 +11,9 @@ import typing
11
11
  from enum import Enum
12
12
  from typing import TYPE_CHECKING, NamedTuple
13
13
 
14
+ from sphinx.errors import PycodeError
14
15
  from sphinx.ext.autodoc.mock import ismock, undecorate
15
- from sphinx.pycode import ModuleAnalyzer, PycodeError
16
+ from sphinx.pycode import ModuleAnalyzer
16
17
  from sphinx.util import logging
17
18
  from sphinx.util.inspect import (
18
19
  getannotations,
@@ -102,9 +102,9 @@ def _is_lambda(x: Any, /) -> bool:
102
102
 
103
103
 
104
104
  def _get_arguments_inner(x: Any, /) -> ast.arguments | None:
105
- if isinstance(x, (ast.AsyncFunctionDef, ast.FunctionDef, ast.Lambda)):
105
+ if isinstance(x, ast.AsyncFunctionDef | ast.FunctionDef | ast.Lambda):
106
106
  return x.args
107
- if isinstance(x, (ast.Assign, ast.AnnAssign)):
107
+ if isinstance(x, ast.Assign | ast.AnnAssign):
108
108
  return _get_arguments_inner(x.value)
109
109
  return None
110
110
 
@@ -69,13 +69,14 @@ import sphinx
69
69
  from sphinx import addnodes
70
70
  from sphinx.config import Config
71
71
  from sphinx.environment import BuildEnvironment
72
- from sphinx.ext.autodoc import INSTANCEATTR, Documenter
73
- from sphinx.ext.autodoc.directive import DocumenterBridge, Options
72
+ from sphinx.errors import PycodeError
73
+ from sphinx.ext.autodoc import INSTANCEATTR, Documenter, Options
74
+ from sphinx.ext.autodoc.directive import DocumenterBridge
74
75
  from sphinx.ext.autodoc.importer import import_module
75
76
  from sphinx.ext.autodoc.mock import mock
76
77
  from sphinx.locale import __
77
78
  from sphinx.project import Project
78
- from sphinx.pycode import ModuleAnalyzer, PycodeError
79
+ from sphinx.pycode import ModuleAnalyzer
79
80
  from sphinx.registry import SphinxComponentRegistry
80
81
  from sphinx.util import logging, rst
81
82
  from sphinx.util.docutils import (
@@ -97,7 +98,7 @@ if TYPE_CHECKING:
97
98
  from sphinx.application import Sphinx
98
99
  from sphinx.extension import Extension
99
100
  from sphinx.util.typing import ExtensionMetadata, OptionSpec
100
- from sphinx.writers.html import HTML5Translator
101
+ from sphinx.writers.html5 import HTML5Translator
101
102
 
102
103
  logger = logging.getLogger(__name__)
103
104
 
@@ -248,7 +249,7 @@ class Autosummary(SphinxDirective):
248
249
  docname = posixpath.join(tree_prefix, real_name)
249
250
  docname = posixpath.normpath(posixpath.join(dirname, docname))
250
251
  if docname not in self.env.found_docs:
251
- if excluded(self.env.doc2path(docname, False)):
252
+ if excluded(str(self.env.doc2path(docname, False))):
252
253
  msg = __('autosummary references excluded document %r. Ignored.')
253
254
  else:
254
255
  msg = __('autosummary: stub file not found %r. '
@@ -801,7 +802,7 @@ def process_generate_options(app: Sphinx) -> None:
801
802
 
802
803
  if genfiles is True:
803
804
  env = app.builder.env
804
- genfiles = [env.doc2path(x, base=False) for x in env.found_docs
805
+ genfiles = [str(env.doc2path(x, base=False)) for x in env.found_docs
805
806
  if os.path.isfile(env.doc2path(x))]
806
807
  elif genfiles is False:
807
808
  pass
@@ -34,6 +34,7 @@ import sphinx.locale
34
34
  from sphinx import __display_version__, package_dir
35
35
  from sphinx.builders import Builder
36
36
  from sphinx.config import Config
37
+ from sphinx.errors import PycodeError
37
38
  from sphinx.ext.autodoc.importer import import_module
38
39
  from sphinx.ext.autosummary import (
39
40
  ImportExceptionGroup,
@@ -42,7 +43,7 @@ from sphinx.ext.autosummary import (
42
43
  import_ivar_by_name,
43
44
  )
44
45
  from sphinx.locale import __
45
- from sphinx.pycode import ModuleAnalyzer, PycodeError
46
+ from sphinx.pycode import ModuleAnalyzer
46
47
  from sphinx.registry import SphinxComponentRegistry
47
48
  from sphinx.util import logging, rst
48
49
  from sphinx.util.inspect import getall, safe_getattr
@@ -145,7 +146,7 @@ class AutosummaryRenderer:
145
146
  # ``install_gettext_translations`` is injected by the ``jinja2.ext.i18n`` extension
146
147
  self.env.install_gettext_translations(app.translator) # type: ignore[attr-defined]
147
148
 
148
- def render(self, template_name: str, context: dict) -> str:
149
+ def render(self, template_name: str, context: dict[str, Any]) -> str:
149
150
  """Render a template file."""
150
151
  try:
151
152
  template = self.env.get_template(template_name)
@@ -282,7 +283,7 @@ def generate_autosummary_content(
282
283
  imported_members: bool,
283
284
  app: Any,
284
285
  recursive: bool,
285
- context: dict,
286
+ context: dict[str, Any],
286
287
  modname: str | None = None,
287
288
  qualname: str | None = None,
288
289
  ) -> str:
@@ -392,7 +393,7 @@ def _skip_member(app: Sphinx, obj: Any, name: str, objtype: str) -> bool:
392
393
 
393
394
 
394
395
  def _get_class_members(obj: Any) -> dict[str, Any]:
395
- members = sphinx.ext.autodoc.get_class_members(obj, None, safe_getattr)
396
+ members = sphinx.ext.autodoc.importer.get_class_members(obj, None, safe_getattr)
396
397
  return {name: member.object for name, member in members.items()}
397
398
 
398
399