Skip to content

Commit 31728e9

Browse files
authored
Merge branch 'master' into workflow-simplification
2 parents bf90d18 + 4dbdf80 commit 31728e9

File tree

148 files changed

+27985
-5538
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

148 files changed

+27985
-5538
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,5 @@ tests/roots/test-pycode/cp_1251_coded.py working-tree-encoding=windows-1251
6565

6666
tests/js/fixtures/**/*.js generated
6767
sphinx/search/minified-js/*.js generated
68+
sphinx/search/_stopwords/ generated
6869
sphinx/themes/bizstyle/static/css3-mediaqueries.js generated

AUTHORS.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ Contributors
102102
* Slawek Figiel -- additional warning suppression
103103
* Stefan Seefeld -- toctree improvements
104104
* Stefan van der Walt -- autosummary extension
105+
* Steve Piercy -- documentation improvements
105106
* \T. Powers -- HTML output improvements
106107
* Taku Shimizu -- epub3 builder
107108
* Thomas Lamb -- linkcheck builder

CHANGES.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ Features added
1919
* #13439: linkcheck: Permit warning on every redirect with
2020
``linkcheck_allowed_redirects = {}``.
2121
Patch by Adam Turner.
22+
* #13497: Support C domain objects in the table of contents.
23+
* #13535: html search: Update to the latest version of Snowball (v3.0.1).
24+
Patch by Adam Turner.
25+
* #13704: autodoc: Detect :py:func:`typing_extensions.overload <typing.overload>`
26+
and :py:func:`~typing.final` decorators.
27+
Patch by Spencer Brown.
2228

2329
Bugs fixed
2430
----------

doc/extdev/markupapi.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,9 @@ The methods are used as follows:
173173
def run(self) -> list[Node]:
174174
container = docutils.nodes.Element()
175175
# either
176-
nested_parse_with_titles(self.state, self.result, container)
176+
nested_parse_with_titles(self.state, self.result, container, self.content_offset)
177177
# or
178-
self.state.nested_parse(self.result, 0, container)
178+
self.state.nested_parse(self.result, self.content_offset, container)
179179
parsed = container.children
180180
return parsed
181181

doc/internals/contributing.rst

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,15 @@ Updating generated files
337337
------------------------
338338

339339
* JavaScript stemming algorithms in :file:`sphinx/search/non-minified-js/*.js`
340-
are generated using `snowball <https://github.com/snowballstem/snowball>`_
341-
by cloning the repository, executing ``make dist_libstemmer_js`` and then
342-
unpacking the tarball which is generated in :file:`dist` directory.
340+
and stopword files in :file:`sphinx/search/_stopwords/`
341+
are generated from the `Snowball project`_
342+
by running :file:`utils/generate_snowball.py`.
343343

344344
Minified files in :file:`sphinx/search/minified-js/*.js` are generated from
345-
non-minified ones using :program:`uglifyjs` (installed via npm), with ``-m``
346-
option to enable mangling.
345+
non-minified ones using :program:`uglifyjs` (installed via npm).
346+
See :file:`sphinx/search/minified-js/README.rst`.
347+
348+
.. _Snowball project: https://snowballstem.org/
347349

348350
* The :file:`searchindex.js` files found in
349351
the :file:`tests/js/fixtures/*` directories

doc/latex.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ Keys that don't need to be overridden unless in special cases are:
500500
.. hint::
501501

502502
If the key value is set to
503-
:code-tex:`r'\\newcommand\sphinxbackoftitlepage{<Extra
503+
:code-tex:`r'\\newcommand\\sphinxbackoftitlepage{<Extra
504504
material>}\\sphinxmaketitle'`, then ``<Extra material>`` will be
505505
typeset on back of title page (``'manual'`` docclass only).
506506

@@ -1694,7 +1694,7 @@ Macros
16941694
.. hint::
16951695

16961696
If adding to preamble the loading of ``tocloft`` package, also add to
1697-
preamble :code-tex:`\\renewcommand\sphinxtableofcontentshook{}` else it
1697+
preamble :code-tex:`\\renewcommand\\sphinxtableofcontentshook{}` else it
16981698
will reset :code-tex:`\\l@section` and :code-tex:`\\l@subsection`
16991699
cancelling ``tocloft`` customization.
17001700

doc/man/sphinx-build.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,13 +272,13 @@ Options
272272
From Sphinx 8.1, :option:`!--keep-going` is always enabled.
273273
Previously, it was only applicable whilst using :option:`--fail-on-warning`,
274274
which by default exited :program:`sphinx-build` on the first warning.
275-
Using :option:`!--keep-going` runs :program:`!sphinx-build` to completion
275+
Using :option:`!--keep-going` runs :program:`sphinx-build` to completion
276276
and exits with exit status 1 if errors are encountered.
277277

278278
.. versionadded:: 1.8
279279
.. versionchanged:: 8.1
280280
:program:`sphinx-build` no longer exits on the first warning,
281-
meaning that in effect :option:`!--fail-on-warning` is always enabled.
281+
meaning that in effect :option:`!--keep-going` is always enabled.
282282
The option is retained for compatibility, but may be removed at some
283283
later date.
284284

doc/usage/configuration.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3668,7 +3668,7 @@ and which failures and redirects it ignores.
36683668
.. versionadded:: 4.1
36693669

36703670
.. versionchanged:: 8.3
3671-
Setting :confval:`!linkcheck_allowed_redirects` to the empty directory
3671+
Setting :confval:`!linkcheck_allowed_redirects` to an empty dictionary
36723672
may now be used to warn on all redirects encountered
36733673
by the *linkcheck* builder.
36743674

pyproject.toml

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -92,19 +92,19 @@ docs = [
9292
"sphinxcontrib-websupport",
9393
]
9494
lint = [
95-
"ruff==0.11.7",
95+
"ruff==0.11.10",
9696
"mypy==1.15.0",
9797
"sphinx-lint>=0.9",
9898
"types-colorama==0.4.15.20240311",
99-
"types-defusedxml==0.7.0.20240218",
100-
"types-docutils==0.21.0.20241128",
99+
"types-defusedxml==0.7.0.20250516",
100+
"types-docutils==0.21.0.20250514",
101101
"types-Pillow==10.2.0.20240822",
102-
"types-Pygments==2.19.0.20250305",
103-
"types-requests==2.32.0.20250328", # align with requests
102+
"types-Pygments==2.19.0.20250516",
103+
"types-requests==2.32.0.20250515", # align with requests
104104
"types-urllib3==1.26.25.14",
105105
"pyright==1.1.400",
106106
"pytest>=8.0",
107-
"pypi-attestations==0.0.25",
107+
"pypi-attestations==0.0.26",
108108
"betterproto==2.0.0b6",
109109
]
110110
test = [
@@ -135,13 +135,13 @@ docs = [
135135
"sphinxcontrib-websupport",
136136
]
137137
lint = [
138-
"ruff==0.11.7",
138+
"ruff==0.11.10",
139139
"sphinx-lint>=0.9",
140140
]
141141
package = [
142142
"betterproto==2.0.0b6", # resolution fails without betterproto
143143
"build",
144-
"pypi-attestations==0.0.25",
144+
"pypi-attestations==0.0.26",
145145
"twine>=6.1",
146146
]
147147
test = [
@@ -164,11 +164,11 @@ types = [
164164
type-stubs = [
165165
# align with versions used elsewhere
166166
"types-colorama==0.4.15.20240311",
167-
"types-defusedxml==0.7.0.20240218",
168-
"types-docutils==0.21.0.20241128",
167+
"types-defusedxml==0.7.0.20250516",
168+
"types-docutils==0.21.0.20250514",
169169
"types-Pillow==10.2.0.20240822",
170-
"types-Pygments==2.19.0.20250305",
171-
"types-requests==2.32.0.20250328",
170+
"types-Pygments==2.19.0.20250516",
171+
"types-requests==2.32.0.20250515",
172172
"types-urllib3==1.26.25.14",
173173
]
174174

@@ -283,14 +283,12 @@ module = [
283283
"tests.test_theming.test_templating",
284284
"tests.test_theming.test_theming",
285285
# tests/test_transforms
286-
"tests.test_transforms.test_transforms_move_module_targets",
287286
"tests.test_transforms.test_transforms_post_transforms_images",
288287
"tests.test_transforms.test_transforms_reorder_nodes",
289288
# tests/test_util
290289
"tests.test_util.test_util",
291290
"tests.test_util.test_util_display",
292291
"tests.test_util.test_util_docutils",
293-
"tests.test_util.test_util_images",
294292
"tests.test_util.test_util_inventory",
295293
# tests/test_writers
296294
"tests.test_writers.test_docutilsconf",
@@ -340,7 +338,6 @@ module = [
340338
# tests/test_transforms
341339
"tests.test_transforms.test_transforms_post_transforms",
342340
# tests/test_util
343-
"tests.test_util.test_util_fileutil",
344341
"tests.test_util.test_util_i18n",
345342
"tests.test_util.test_util_inspect",
346343
"tests.test_util.test_util_logging",

sphinx/domains/c/__init__.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
from docutils.nodes import Element, Node, TextElement, system_message
4141

42-
from sphinx.addnodes import pending_xref
42+
from sphinx.addnodes import desc_signature, pending_xref
4343
from sphinx.application import Sphinx
4444
from sphinx.builders import Builder
4545
from sphinx.domains.c._symbol import LookupKey
@@ -309,6 +309,32 @@ def after_content(self) -> None:
309309
self.env.current_document.c_parent_symbol = self.oldParentSymbol
310310
self.env.ref_context['c:parent_key'] = self.oldParentKey
311311

312+
def _object_hierarchy_parts(self, sig_node: desc_signature) -> tuple[str, ...]:
313+
last_symbol: Symbol = self.env.current_document.c_last_symbol
314+
return tuple(map(str, last_symbol.get_full_nested_name().names))
315+
316+
def _toc_entry_name(self, sig_node: desc_signature) -> str:
317+
if not sig_node.get('_toc_parts'):
318+
return ''
319+
320+
config = self.config
321+
objtype = sig_node.parent.get('objtype')
322+
if config.add_function_parentheses and (
323+
objtype in {'function', 'method'}
324+
or (objtype == 'macro' and '(' in sig_node.rawsource)
325+
):
326+
parens = '()'
327+
else:
328+
parens = ''
329+
*parents, name = sig_node['_toc_parts']
330+
if config.toc_object_entries_show_parents == 'domain':
331+
return '::'.join((name + parens,))
332+
if config.toc_object_entries_show_parents == 'hide':
333+
return name + parens
334+
if config.toc_object_entries_show_parents == 'all':
335+
return '::'.join([*parents, name + parens])
336+
return ''
337+
312338

313339
class CMemberObject(CObject):
314340
object_type = 'member'

sphinx/domains/javascript.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,9 @@ def handle_signature(self, sig: str, signode: desc_signature) -> tuple[str, str]
137137
_pseudo_parse_arglist(
138138
signode,
139139
arglist,
140-
multi_line_parameter_list,
141-
trailing_comma,
140+
multi_line_parameter_list=multi_line_parameter_list,
141+
trailing_comma=trailing_comma,
142+
env=self.env,
142143
)
143144
return fullname, prefix
144145

sphinx/domains/python/_annotations.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,15 +552,18 @@ def _keyword_only_separator() -> addnodes.desc_parameter:
552552
def _pseudo_parse_arglist(
553553
signode: desc_signature,
554554
arglist: str,
555+
*,
555556
multi_line_parameter_list: bool = False,
556557
trailing_comma: bool = True,
558+
env: BuildEnvironment,
557559
) -> None:
558560
"""'Parse' a list of arguments separated by commas.
559561
560562
Arguments can have "optional" annotations given by enclosing them in
561563
brackets. Currently, this will split at any comma, even if it's inside a
562564
string literal (e.g. default argument value).
563565
"""
566+
# TODO: decompose 'env' parameter into only the required bits
564567
paramlist = addnodes.desc_parameterlist()
565568
paramlist['multi_line_parameter_list'] = multi_line_parameter_list
566569
paramlist['multi_line_trailing_comma'] = trailing_comma
@@ -583,9 +586,30 @@ def _pseudo_parse_arglist(
583586
ends_open += 1
584587
argument = argument[:-1].strip()
585588
if argument:
586-
stack[-1] += addnodes.desc_parameter(
587-
'', '', addnodes.desc_sig_name(argument, argument)
588-
)
589+
param_with_annotation, _, default_value = argument.partition('=')
590+
param_name, _, annotation = param_with_annotation.partition(':')
591+
del param_with_annotation
592+
593+
node = addnodes.desc_parameter()
594+
node += addnodes.desc_sig_name('', param_name.strip())
595+
if annotation:
596+
children = _parse_annotation(annotation.strip(), env=env)
597+
node += addnodes.desc_sig_punctuation('', ':')
598+
node += addnodes.desc_sig_space()
599+
node += addnodes.desc_sig_name('', '', *children) # type: ignore[arg-type]
600+
if default_value:
601+
if annotation:
602+
node += addnodes.desc_sig_space()
603+
node += addnodes.desc_sig_operator('', '=')
604+
if annotation:
605+
node += addnodes.desc_sig_space()
606+
node += nodes.inline(
607+
'',
608+
default_value.strip(),
609+
classes=['default_value'],
610+
support_smartquotes=False,
611+
)
612+
stack[-1] += node
589613
while ends_open:
590614
stack.append(addnodes.desc_optional())
591615
stack[-2] += stack[-1]

sphinx/domains/python/_object.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,9 @@ def handle_signature(self, sig: str, signode: desc_signature) -> tuple[str, str]
363363
_pseudo_parse_arglist(
364364
signode,
365365
arglist,
366-
multi_line_parameter_list,
367-
trailing_comma,
366+
multi_line_parameter_list=multi_line_parameter_list,
367+
trailing_comma=trailing_comma,
368+
env=self.env,
368369
)
369370
except (NotImplementedError, ValueError) as exc:
370371
# duplicated parameter names raise ValueError and not a SyntaxError
@@ -374,8 +375,9 @@ def handle_signature(self, sig: str, signode: desc_signature) -> tuple[str, str]
374375
_pseudo_parse_arglist(
375376
signode,
376377
arglist,
377-
multi_line_parameter_list,
378-
trailing_comma,
378+
multi_line_parameter_list=multi_line_parameter_list,
379+
trailing_comma=trailing_comma,
380+
env=self.env,
379381
)
380382
else:
381383
if self.needs_arglist():

sphinx/pycode/parser.py

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,9 @@ def __init__(self, buffers: list[str], encoding: str) -> None:
247247
self.deforders: dict[str, int] = {}
248248
self.finals: list[str] = []
249249
self.overloads: dict[str, list[Signature]] = {}
250-
self.typing: str | None = None
251-
self.typing_final: str | None = None
252-
self.typing_overload: str | None = None
250+
self.typing_mods: set[str] = set()
251+
self.typing_final_names: set[str] = set()
252+
self.typing_overload_names: set[str] = set()
253253
super().__init__()
254254

255255
def get_qualname_for(self, name: str) -> list[str] | None:
@@ -295,11 +295,8 @@ def add_variable_annotation(self, name: str, annotation: ast.AST) -> None:
295295
self.annotations[basename, name] = ast_unparse(annotation)
296296

297297
def is_final(self, decorators: list[ast.expr]) -> bool:
298-
final = []
299-
if self.typing:
300-
final.append('%s.final' % self.typing)
301-
if self.typing_final:
302-
final.append(self.typing_final)
298+
final = {f'{modname}.final' for modname in self.typing_mods}
299+
final |= self.typing_final_names
303300

304301
for decorator in decorators:
305302
try:
@@ -311,11 +308,8 @@ def is_final(self, decorators: list[ast.expr]) -> bool:
311308
return False
312309

313310
def is_overload(self, decorators: list[ast.expr]) -> bool:
314-
overload = []
315-
if self.typing:
316-
overload.append('%s.overload' % self.typing)
317-
if self.typing_overload:
318-
overload.append(self.typing_overload)
311+
overload = {f'{modname}.overload' for modname in self.typing_mods}
312+
overload |= self.typing_overload_names
319313

320314
for decorator in decorators:
321315
try:
@@ -348,22 +342,24 @@ def visit_Import(self, node: ast.Import) -> None:
348342
for name in node.names:
349343
self.add_entry(name.asname or name.name)
350344

351-
if name.name == 'typing':
352-
self.typing = name.asname or name.name
353-
elif name.name == 'typing.final':
354-
self.typing_final = name.asname or name.name
355-
elif name.name == 'typing.overload':
356-
self.typing_overload = name.asname or name.name
345+
if name.name in {'typing', 'typing_extensions'}:
346+
self.typing_mods.add(name.asname or name.name)
347+
elif name.name in {'typing.final', 'typing_extensions.final'}:
348+
self.typing_final_names.add(name.asname or name.name)
349+
elif name.name in {'typing.overload', 'typing_extensions.overload'}:
350+
self.typing_overload_names.add(name.asname or name.name)
357351

358352
def visit_ImportFrom(self, node: ast.ImportFrom) -> None:
359353
"""Handles Import node and record the order of definitions."""
360354
for name in node.names:
361355
self.add_entry(name.asname or name.name)
362356

363-
if node.module == 'typing' and name.name == 'final':
364-
self.typing_final = name.asname or name.name
365-
elif node.module == 'typing' and name.name == 'overload':
366-
self.typing_overload = name.asname or name.name
357+
if node.module not in {'typing', 'typing_extensions'}:
358+
continue
359+
if name.name == 'final':
360+
self.typing_final_names.add(name.asname or name.name)
361+
elif name.name == 'overload':
362+
self.typing_overload_names.add(name.asname or name.name)
367363

368364
def visit_Assign(self, node: ast.Assign) -> None:
369365
"""Handles Assign node and pick up a variable comment."""

0 commit comments

Comments
 (0)