Sphinx 7.4.6__py3-none-any.whl → 8.0.0rc1__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 (115) hide show
  1. sphinx/__init__.py +2 -2
  2. sphinx/_cli/__init__.py +4 -4
  3. sphinx/application.py +7 -7
  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 +90 -59
  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 +12 -12
  17. sphinx/deprecation.py +8 -8
  18. sphinx/directives/__init__.py +14 -9
  19. sphinx/directives/other.py +2 -3
  20. sphinx/directives/patches.py +2 -2
  21. sphinx/domains/__init__.py +4 -2
  22. sphinx/domains/c/__init__.py +2 -2
  23. sphinx/domains/c/_ast.py +3 -2
  24. sphinx/domains/c/_parser.py +4 -3
  25. sphinx/domains/cpp/__init__.py +2 -2
  26. sphinx/domains/cpp/_ast.py +1 -2
  27. sphinx/domains/cpp/_parser.py +2 -2
  28. sphinx/domains/cpp/_symbol.py +2 -2
  29. sphinx/domains/javascript.py +1 -1
  30. sphinx/domains/math.py +1 -1
  31. sphinx/domains/python/__init__.py +1 -1
  32. sphinx/domains/python/_annotations.py +23 -1
  33. sphinx/domains/python/_object.py +0 -1
  34. sphinx/domains/std/__init__.py +7 -8
  35. sphinx/environment/__init__.py +14 -32
  36. sphinx/environment/adapters/indexentries.py +4 -6
  37. sphinx/environment/adapters/toctree.py +4 -4
  38. sphinx/environment/collectors/title.py +1 -1
  39. sphinx/environment/collectors/toctree.py +1 -1
  40. sphinx/events.py +3 -1
  41. sphinx/ext/autodoc/__init__.py +25 -67
  42. sphinx/ext/autodoc/directive.py +7 -5
  43. sphinx/ext/autodoc/importer.py +2 -1
  44. sphinx/ext/autodoc/preserve_defaults.py +2 -2
  45. sphinx/ext/autosummary/__init__.py +15 -7
  46. sphinx/ext/autosummary/generate.py +5 -4
  47. sphinx/ext/doctest.py +5 -5
  48. sphinx/ext/graphviz.py +1 -1
  49. sphinx/ext/imgmath.py +1 -1
  50. sphinx/ext/inheritance_diagram.py +1 -1
  51. sphinx/ext/intersphinx/__init__.py +25 -5
  52. sphinx/ext/intersphinx/_cli.py +7 -6
  53. sphinx/ext/intersphinx/_load.py +240 -115
  54. sphinx/ext/intersphinx/_resolve.py +12 -11
  55. sphinx/ext/intersphinx/_shared.py +102 -9
  56. sphinx/ext/mathjax.py +1 -1
  57. sphinx/ext/napoleon/docstring.py +2 -2
  58. sphinx/ext/todo.py +2 -2
  59. sphinx/ext/viewcode.py +2 -1
  60. sphinx/highlighting.py +3 -3
  61. sphinx/io.py +2 -2
  62. sphinx/jinja2glue.py +13 -6
  63. sphinx/locale/__init__.py +4 -3
  64. sphinx/locale/ta/LC_MESSAGES/sphinx.js +54 -54
  65. sphinx/locale/ta/LC_MESSAGES/sphinx.mo +0 -0
  66. sphinx/locale/ta/LC_MESSAGES/sphinx.po +1578 -1843
  67. sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +496 -704
  68. sphinx/project.py +23 -19
  69. sphinx/pycode/ast.py +2 -2
  70. sphinx/pycode/parser.py +2 -2
  71. sphinx/pygments_styles.py +3 -3
  72. sphinx/registry.py +3 -8
  73. sphinx/search/__init__.py +1 -1
  74. sphinx/testing/path.py +2 -1
  75. sphinx/testing/util.py +1 -1
  76. sphinx/texinputs/Makefile.jinja +2 -1
  77. sphinx/texinputs_win/Makefile.jinja +2 -1
  78. sphinx/theming.py +3 -12
  79. sphinx/transforms/__init__.py +5 -5
  80. sphinx/transforms/references.py +1 -1
  81. sphinx/util/__init__.py +11 -35
  82. sphinx/util/_timestamps.py +12 -0
  83. sphinx/util/cfamily.py +5 -5
  84. sphinx/util/console.py +4 -3
  85. sphinx/util/display.py +3 -3
  86. sphinx/util/docfields.py +1 -1
  87. sphinx/util/docutils.py +44 -10
  88. sphinx/util/fileutil.py +41 -9
  89. sphinx/util/i18n.py +9 -4
  90. sphinx/util/images.py +3 -2
  91. sphinx/util/inspect.py +29 -44
  92. sphinx/util/inventory.py +2 -2
  93. sphinx/util/matching.py +2 -2
  94. sphinx/util/math.py +1 -1
  95. sphinx/util/nodes.py +8 -8
  96. sphinx/util/osutil.py +46 -23
  97. sphinx/util/parallel.py +2 -2
  98. sphinx/util/requests.py +1 -1
  99. sphinx/util/template.py +3 -3
  100. sphinx/util/typing.py +67 -70
  101. sphinx/writers/html.py +1 -1
  102. sphinx/writers/html5.py +1 -1
  103. sphinx/writers/latex.py +4 -4
  104. sphinx/writers/manpage.py +2 -2
  105. sphinx/writers/texinfo.py +5 -5
  106. sphinx/writers/text.py +4 -4
  107. sphinx/writers/xml.py +2 -2
  108. {sphinx-7.4.6.dist-info → sphinx-8.0.0rc1.dist-info}/METADATA +10 -9
  109. {sphinx-7.4.6.dist-info → sphinx-8.0.0rc1.dist-info}/RECORD +112 -114
  110. sphinx/templates/quickstart/Makefile.jinja +0 -98
  111. sphinx/templates/quickstart/make.bat.jinja +0 -110
  112. sphinx/util/_pathlib.py +0 -120
  113. {sphinx-7.4.6.dist-info → sphinx-8.0.0rc1.dist-info}/LICENSE.rst +0 -0
  114. {sphinx-7.4.6.dist-info → sphinx-8.0.0rc1.dist-info}/WHEEL +0 -0
  115. {sphinx-7.4.6.dist-info → sphinx-8.0.0rc1.dist-info}/entry_points.txt +0 -0
@@ -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:
@@ -2008,7 +1962,8 @@ class UninitializedGlobalVariableMixin(DataDocumenterMixinBase):
2008
1962
  with mock(self.config.autodoc_mock_imports):
2009
1963
  parent = import_module(self.modname, self.config.autodoc_warningiserror)
2010
1964
  annotations = get_type_hints(parent, None,
2011
- self.config.autodoc_type_aliases)
1965
+ self.config.autodoc_type_aliases,
1966
+ include_extras=True)
2012
1967
  if self.objpath[-1] in annotations:
2013
1968
  self.object = UNINITIALIZED_ATTR
2014
1969
  self.parent = parent
@@ -2097,7 +2052,8 @@ class DataDocumenter(GenericAliasMixin,
2097
2052
  if self.config.autodoc_typehints != 'none':
2098
2053
  # obtain annotation for this data
2099
2054
  annotations = get_type_hints(self.parent, None,
2100
- self.config.autodoc_type_aliases)
2055
+ self.config.autodoc_type_aliases,
2056
+ include_extras=True)
2101
2057
  if self.objpath[-1] in annotations:
2102
2058
  if self.config.autodoc_typehints_format == "short":
2103
2059
  objrepr = stringify_annotation(annotations.get(self.objpath[-1]),
@@ -2322,7 +2278,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
2322
2278
  if len(sig.parameters) == 1:
2323
2279
  return None
2324
2280
 
2325
- def dummy(): # NoQA: ANN202
2281
+ def dummy(): # type: ignore[no-untyped-def] # NoQA: ANN202
2326
2282
  pass
2327
2283
 
2328
2284
  params = list(sig.parameters.values())
@@ -2541,7 +2497,8 @@ class UninitializedInstanceAttributeMixin(DataDocumenterMixinBase):
2541
2497
 
2542
2498
  def is_uninitialized_instance_attribute(self, parent: Any) -> bool:
2543
2499
  """Check the subject is an annotation only attribute."""
2544
- annotations = get_type_hints(parent, None, self.config.autodoc_type_aliases)
2500
+ annotations = get_type_hints(parent, None, self.config.autodoc_type_aliases,
2501
+ include_extras=True)
2545
2502
  return self.objpath[-1] in annotations
2546
2503
 
2547
2504
  def import_object(self, raiseerror: bool = False) -> bool:
@@ -2673,7 +2630,8 @@ class AttributeDocumenter(GenericAliasMixin, SlotsMixin, # type: ignore[misc]
2673
2630
  if self.config.autodoc_typehints != 'none':
2674
2631
  # obtain type annotation for this attribute
2675
2632
  annotations = get_type_hints(self.parent, None,
2676
- self.config.autodoc_type_aliases)
2633
+ self.config.autodoc_type_aliases,
2634
+ include_extras=True)
2677
2635
  if self.objpath[-1] in annotations:
2678
2636
  if self.config.autodoc_typehints_format == "short":
2679
2637
  objrepr = stringify_annotation(annotations.get(self.objpath[-1]),
@@ -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. '
@@ -765,7 +766,14 @@ class AutoLink(SphinxRole):
765
766
  try:
766
767
  # try to import object by name
767
768
  prefixes = get_import_prefixes_from_env(self.env)
768
- import_by_name(pending_xref['reftarget'], prefixes)
769
+ name = pending_xref['reftarget']
770
+ prefixes = [
771
+ prefix
772
+ for prefix in prefixes
773
+ if prefix is None
774
+ or not (name.startswith(f'{prefix}.') or name == prefix)
775
+ ]
776
+ import_by_name(name, prefixes)
769
777
  except ImportExceptionGroup:
770
778
  literal = cast(nodes.literal, pending_xref[0])
771
779
  objects[0] = nodes.emphasis(self.rawtext, literal.astext(),
@@ -794,7 +802,7 @@ def process_generate_options(app: Sphinx) -> None:
794
802
 
795
803
  if genfiles is True:
796
804
  env = app.builder.env
797
- 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
798
806
  if os.path.isfile(env.doc2path(x))]
799
807
  elif genfiles is False:
800
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
 
sphinx/ext/doctest.py CHANGED
@@ -11,7 +11,7 @@ import sys
11
11
  import time
12
12
  from io import StringIO
13
13
  from os import path
14
- from typing import TYPE_CHECKING, Any, Callable, ClassVar
14
+ from typing import TYPE_CHECKING, Any, ClassVar
15
15
 
16
16
  from docutils import nodes
17
17
  from docutils.parsers.rst import directives
@@ -27,7 +27,7 @@ from sphinx.util.docutils import SphinxDirective
27
27
  from sphinx.util.osutil import relpath
28
28
 
29
29
  if TYPE_CHECKING:
30
- from collections.abc import Iterable, Sequence
30
+ from collections.abc import Callable, Iterable, Sequence
31
31
 
32
32
  from docutils.nodes import Element, Node, TextElement
33
33
 
@@ -373,7 +373,7 @@ Doctest summary
373
373
  try:
374
374
  filename = relpath(node.source, self.env.srcdir).rsplit(':docstring of ', maxsplit=1)[0] # type: ignore[arg-type] # noqa: E501
375
375
  except Exception:
376
- filename = self.env.doc2path(docname, False)
376
+ filename = str(self.env.doc2path(docname, False))
377
377
  return filename
378
378
 
379
379
  @staticmethod
@@ -420,12 +420,12 @@ Doctest summary
420
420
 
421
421
  if self.config.doctest_test_doctest_blocks:
422
422
  def condition(node: Node) -> bool:
423
- return (isinstance(node, (nodes.literal_block, nodes.comment)) and
423
+ return (isinstance(node, nodes.literal_block | nodes.comment) and
424
424
  'testnodetype' in node) or \
425
425
  isinstance(node, nodes.doctest_block)
426
426
  else:
427
427
  def condition(node: Node) -> bool:
428
- return isinstance(node, (nodes.literal_block, nodes.comment)) \
428
+ return isinstance(node, nodes.literal_block | nodes.comment) \
429
429
  and 'testnodetype' in node
430
430
  for node in doctree.findall(condition):
431
431
  if self.skipped(node): # type: ignore[arg-type]
sphinx/ext/graphviz.py CHANGED
@@ -32,7 +32,7 @@ if TYPE_CHECKING:
32
32
  from sphinx.application import Sphinx
33
33
  from sphinx.config import Config
34
34
  from sphinx.util.typing import ExtensionMetadata, OptionSpec
35
- from sphinx.writers.html import HTML5Translator
35
+ from sphinx.writers.html5 import HTML5Translator
36
36
  from sphinx.writers.latex import LaTeXTranslator
37
37
  from sphinx.writers.manpage import ManualPageTranslator
38
38
  from sphinx.writers.texinfo import TexinfoTranslator
sphinx/ext/imgmath.py CHANGED
@@ -36,7 +36,7 @@ if TYPE_CHECKING:
36
36
  from sphinx.builders import Builder
37
37
  from sphinx.config import Config
38
38
  from sphinx.util.typing import ExtensionMetadata
39
- from sphinx.writers.html import HTML5Translator
39
+ from sphinx.writers.html5 import HTML5Translator
40
40
 
41
41
  logger = logging.getLogger(__name__)
42
42
 
@@ -59,7 +59,7 @@ if TYPE_CHECKING:
59
59
  from sphinx.application import Sphinx
60
60
  from sphinx.environment import BuildEnvironment
61
61
  from sphinx.util.typing import ExtensionMetadata, OptionSpec
62
- from sphinx.writers.html import HTML5Translator
62
+ from sphinx.writers.html5 import HTML5Translator
63
63
  from sphinx.writers.latex import LaTeXTranslator
64
64
  from sphinx.writers.texinfo import TexinfoTranslator
65
65
 
@@ -21,9 +21,8 @@ from __future__ import annotations
21
21
  __all__ = (
22
22
  'InventoryAdapter',
23
23
  'fetch_inventory',
24
- 'fetch_inventory_group',
25
24
  'load_mappings',
26
- 'normalize_intersphinx_mapping',
25
+ 'validate_intersphinx_mapping',
27
26
  'IntersphinxRoleResolver',
28
27
  'inventory_exists',
29
28
  'install_dispatcher',
@@ -42,9 +41,8 @@ import sphinx
42
41
  from sphinx.ext.intersphinx._cli import inspect_main
43
42
  from sphinx.ext.intersphinx._load import (
44
43
  fetch_inventory,
45
- fetch_inventory_group,
46
44
  load_mappings,
47
- normalize_intersphinx_mapping,
45
+ validate_intersphinx_mapping,
48
46
  )
49
47
  from sphinx.ext.intersphinx._resolve import (
50
48
  IntersphinxDispatcher,
@@ -69,7 +67,7 @@ def setup(app: Sphinx) -> ExtensionMetadata:
69
67
  app.add_config_value('intersphinx_cache_limit', 5, '')
70
68
  app.add_config_value('intersphinx_timeout', None, '')
71
69
  app.add_config_value('intersphinx_disabled_reftypes', ['std:doc'], 'env')
72
- app.connect('config-inited', normalize_intersphinx_mapping, priority=800)
70
+ app.connect('config-inited', validate_intersphinx_mapping, priority=800)
73
71
  app.connect('builder-inited', load_mappings)
74
72
  app.connect('source-read', install_dispatcher)
75
73
  app.connect('missing-reference', missing_reference)
@@ -79,3 +77,25 @@ def setup(app: Sphinx) -> ExtensionMetadata:
79
77
  'env_version': 1,
80
78
  'parallel_read_safe': True,
81
79
  }
80
+
81
+
82
+ # deprecated name -> (object to return, canonical path or empty string, removal version)
83
+ _DEPRECATED_OBJECTS: dict[str, tuple[object, str, tuple[int, int]]] = {
84
+ 'normalize_intersphinx_mapping': (
85
+ validate_intersphinx_mapping,
86
+ 'sphinx.ext.intersphinx.validate_intersphinx_mapping',
87
+ (10, 0),
88
+ ),
89
+ }
90
+
91
+
92
+ def __getattr__(name: str) -> object:
93
+ if name not in _DEPRECATED_OBJECTS:
94
+ msg = f'module {__name__!r} has no attribute {name!r}'
95
+ raise AttributeError(msg)
96
+
97
+ from sphinx.deprecation import _deprecation_warning
98
+
99
+ deprecated_object, canonical_name, remove = _DEPRECATED_OBJECTS[name]
100
+ _deprecation_warning(__name__, name, canonical_name, remove=remove)
101
+ return deprecated_object
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import sys
6
6
 
7
- from sphinx.ext.intersphinx._load import fetch_inventory
7
+ from sphinx.ext.intersphinx._load import _fetch_inventory
8
8
 
9
9
 
10
10
  def inspect_main(argv: list[str], /) -> int:
@@ -21,13 +21,14 @@ def inspect_main(argv: list[str], /) -> int:
21
21
  tls_cacerts: str | dict[str, str] | None = None
22
22
  user_agent: str = ''
23
23
 
24
- class MockApp:
25
- srcdir = ''
26
- config = MockConfig()
27
-
28
24
  try:
29
25
  filename = argv[0]
30
- inv_data = fetch_inventory(MockApp(), '', filename) # type: ignore[arg-type]
26
+ inv_data = _fetch_inventory(
27
+ target_uri='',
28
+ inv_location=filename,
29
+ config=MockConfig(), # type: ignore[arg-type]
30
+ srcdir='' # type: ignore[arg-type]
31
+ )
31
32
  for key in sorted(inv_data or {}):
32
33
  print(key)
33
34
  inv_entries = sorted(inv_data[key].items())