Skip to content

Commit 43de476

Browse files
authored
Merge branch 'master' into doc-doctest
2 parents 676ea3f + eb337fe commit 43de476

File tree

12 files changed

+80
-74
lines changed

12 files changed

+80
-74
lines changed

AUTHORS.rst

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Maintainers
88
* Chris Sewell <@chrisjsewell>
99
* François Freitag <@francoisfreitag>
1010
* Jakob Lykke Andersen <@jakobandersen>
11-
* Jean-François Burnol <@jfbu>
11+
* Jean-François B. <@jfbu>
1212
* Stephen Finucane <@stephenfin>
1313
* Takayuki Shimizukawa <@shimizukawa>
1414
* Takeshi Komiya <@tk0miya>
@@ -35,7 +35,6 @@ Contributors
3535
* Christopher Perkins -- autosummary integration
3636
* Dan MacKinlay -- metadata fixes
3737
* Daniel Bültmann -- todo extension
38-
* Daniel Neuhäuser -- JavaScript domain, Python 3 support (GSOC)
3938
* Daniel Pizetta -- inheritance diagram improvements
4039
* Dave Kuhlman -- original LaTeX writer
4140
* Doug Hellmann -- graphviz improvements
@@ -73,14 +72,12 @@ Contributors
7372
* Michael Wilson -- Intersphinx HTTP basic auth support
7473
* Nathan Damon -- bugfix in validation of static paths in html builders
7574
* Pauli Virtanen -- autodoc improvements, autosummary extension
76-
* A. Rafey Khan -- improved intersphinx typing
77-
* Rob Ruana -- napoleon extension
78-
* Robert Lehmann -- gettext builder (GSOC project)
75+
* \A. Rafey Khan -- improved intersphinx typing
7976
* Roland Meister -- epub builder
8077
* Sebastian Wiesner -- image handling, distutils support
8178
* Stefan Seefeld -- toctree improvements
8279
* Stefan van der Walt -- autosummary extension
83-
* T. Powers -- HTML output improvements
80+
* \T. Powers -- HTML output improvements
8481
* Taku Shimizu -- epub3 builder
8582
* Thomas Lamb -- linkcheck builder
8683
* Thomas Waldmann -- apidoc module fixes

doc/usage/extensions/autosummary.rst

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -61,63 +61,67 @@ The :mod:`sphinx.ext.autosummary` extension does this in two parts:
6161
:event:`autodoc-process-docstring` and :event:`autodoc-process-signature`
6262
hooks as :mod:`~sphinx.ext.autodoc`.
6363

64-
**Options**
64+
.. rubric:: Options
6565

66-
* If you want the :rst:dir:`autosummary` table to also serve as a
67-
:rst:dir:`toctree` entry, use the ``toctree`` option, for example::
66+
.. rst:directive:option:: toctree: optional directory name
67+
68+
If you want the :rst:dir:`autosummary` table to also serve as a
69+
:rst:dir:`toctree` entry, use the ``toctree`` option, for example::
6870
6971
.. autosummary::
7072
:toctree: DIRNAME
7173
7274
sphinx.environment.BuildEnvironment
7375
sphinx.util.relative_uri
7476
75-
The ``toctree`` option also signals to the :program:`sphinx-autogen` script
76-
that stub pages should be generated for the entries listed in this
77-
directive. The option accepts a directory name as an argument;
78-
:program:`sphinx-autogen` will by default place its output in this
79-
directory. If no argument is given, output is placed in the same directory
80-
as the file that contains the directive.
77+
The ``toctree`` option also signals to the :program:`sphinx-autogen` script
78+
that stub pages should be generated for the entries listed in this
79+
directive. The option accepts a directory name as an argument;
80+
:program:`sphinx-autogen` will by default place its output in this
81+
directory. If no argument is given, output is placed in the same directory
82+
as the file that contains the directive.
8183
82-
You can also use ``caption`` option to give a caption to the toctree.
84+
.. versionadded:: 0.6
8385
84-
.. versionadded:: 3.1
86+
.. rst:directive:option:: caption: caption of ToC
8587
86-
caption option added.
88+
Add a caption to the toctree.
8789
88-
* If you don't want the :rst:dir:`autosummary` to show function signatures in
89-
the listing, include the ``nosignatures`` option::
90+
.. versionadded:: 3.1
9091
91-
.. autosummary::
92-
:nosignatures:
92+
.. rst:directive:option:: nosignatures
9393
94-
sphinx.environment.BuildEnvironment
95-
sphinx.util.relative_uri
94+
Do not show function signatures in the summary.
9695
97-
* You can specify a custom template with the ``template`` option.
98-
For example, ::
96+
.. versionadded:: 0.6
97+
98+
.. rst:directive:option:: template: filename
99+
100+
Specify a custom template for rendering the summary.
101+
For example, ::
99102
100103
.. autosummary::
101104
:template: mytemplate.rst
102105
103106
sphinx.environment.BuildEnvironment
104107
105-
would use the template :file:`mytemplate.rst` in your
106-
:confval:`templates_path` to generate the pages for all entries
107-
listed. See `Customizing templates`_ below.
108+
would use the template :file:`mytemplate.rst` in your
109+
:confval:`templates_path` to generate the pages for all entries
110+
listed. See `Customizing templates`_ below.
111+
112+
.. versionadded:: 1.0
108113
109-
.. versionadded:: 1.0
114+
.. rst:directive:option:: recursive
110115
111-
* You can specify the ``recursive`` option to generate documents for
112-
modules and sub-packages recursively. It defaults to disabled.
113-
For example, ::
116+
Generate documents for modules and sub-packages recursively.
117+
For example, ::
114118
115119
.. autosummary::
116120
:recursive:
117121
118122
sphinx.environment.BuildEnvironment
119123
120-
.. versionadded:: 3.1
124+
.. versionadded:: 3.1
121125
122126
123127
:program:`sphinx-autogen` -- generate autodoc stub pages

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ lint = [
9191
"types-Pygments==2.18.0.20240506",
9292
"types-requests==2.32.0.20241016", # align with requests
9393
"types-urllib3==1.26.25.14",
94-
"pyright==1.1.387",
94+
"pyright==1.1.388",
9595
"pytest>=6.0",
9696
]
9797
test = [

sphinx/ext/viewcode.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from sphinx.application import Sphinx
3030
from sphinx.builders import Builder
3131
from sphinx.environment import BuildEnvironment
32+
from sphinx.util._pathlib import _StrPath
3233
from sphinx.util.typing import ExtensionMetadata
3334

3435
logger = logging.getLogger(__name__)
@@ -207,7 +208,7 @@ def remove_viewcode_anchors(self) -> None:
207208
node.parent.remove(node)
208209

209210

210-
def get_module_filename(app: Sphinx, modname: str) -> str | None:
211+
def get_module_filename(app: Sphinx, modname: str) -> _StrPath | None:
211212
"""Get module filename for *modname*."""
212213
source_info = app.emit_firstresult('viewcode-find-source', modname)
213214
if source_info:

sphinx/pycode/__init__.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
from __future__ import annotations
44

5-
import os
6-
import os.path
75
import tokenize
86
from importlib import import_module
97
from typing import TYPE_CHECKING, Any, Literal
@@ -13,6 +11,7 @@
1311
from sphinx.util._pathlib import _StrPath
1412

1513
if TYPE_CHECKING:
14+
import os
1615
from inspect import Signature
1716

1817

@@ -28,7 +27,7 @@ class ModuleAnalyzer:
2827
cache: dict[tuple[Literal['file', 'module'], str | _StrPath], Any] = {}
2928

3029
@staticmethod
31-
def get_module_source(modname: str) -> tuple[str | None, str | None]:
30+
def get_module_source(modname: str) -> tuple[_StrPath | None, str | None]:
3231
"""Try to find the source code for a module.
3332
3433
Returns ('filename', 'source'). One of it can be None if
@@ -39,14 +38,15 @@ def get_module_source(modname: str) -> tuple[str | None, str | None]:
3938
except Exception as err:
4039
raise PycodeError('error importing %r' % modname, err) from err
4140
loader = getattr(mod, '__loader__', None)
42-
filename = getattr(mod, '__file__', None)
41+
filename: str | None = getattr(mod, '__file__', None)
4342
if loader and getattr(loader, 'get_source', None):
4443
# prefer Native loader, as it respects #coding directive
4544
try:
4645
source = loader.get_source(modname)
4746
if source:
47+
mod_path = None if filename is None else _StrPath(filename)
4848
# no exception and not None - it must be module source
49-
return filename, source
49+
return mod_path, source
5050
except ImportError:
5151
pass # Try other "source-mining" methods
5252
if filename is None and loader and getattr(loader, 'get_filename', None):
@@ -60,24 +60,28 @@ def get_module_source(modname: str) -> tuple[str | None, str | None]:
6060
if filename is None:
6161
# all methods for getting filename failed, so raise...
6262
raise PycodeError('no source found for module %r' % modname)
63-
filename = os.path.normpath(os.path.abspath(filename))
64-
if filename.lower().endswith(('.pyo', '.pyc')):
65-
filename = filename[:-1]
66-
if not os.path.isfile(filename) and os.path.isfile(filename + 'w'):
67-
filename += 'w'
68-
elif not filename.lower().endswith(('.py', '.pyw')):
69-
raise PycodeError('source is not a .py file: %r' % filename)
70-
71-
if not os.path.isfile(filename):
72-
raise PycodeError('source file is not present: %r' % filename)
73-
return filename, None
63+
mod_path = _StrPath(filename).resolve()
64+
if mod_path.suffix in {'.pyo', '.pyc'}:
65+
mod_path_pyw = mod_path.with_suffix('.pyw')
66+
if not mod_path.is_file() and mod_path_pyw.is_file():
67+
mod_path = mod_path_pyw
68+
else:
69+
mod_path = mod_path.with_suffix('.py')
70+
elif mod_path.suffix not in {'.py', '.pyw'}:
71+
msg = f'source is not a .py file: {mod_path!r}'
72+
raise PycodeError(msg)
73+
74+
if not mod_path.is_file():
75+
msg = f'source file is not present: {mod_path!r}'
76+
raise PycodeError(msg)
77+
return mod_path, None
7478

7579
@classmethod
7680
def for_string(
7781
cls: type[ModuleAnalyzer],
7882
string: str,
7983
modname: str,
80-
srcname: str = '<string>',
84+
srcname: str | os.PathLike[str] = '<string>',
8185
) -> ModuleAnalyzer:
8286
return cls(string, modname, srcname)
8387

sphinx/texinputs/sphinxlatexadmonitions.sty

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
% sphinxlatexshadowbox.sty, and handles both "with icon" and "without
3333
% icon" situations).
3434
%
35-
% The sphinxlightbox environment is kept for backward compatiblity, for user
35+
% The sphinxlightbox environment is kept for backward compatibility, for user
3636
% custom code which used it via custom definitions done in preamble or via
3737
% raw latex directive.
3838
% MEMO: here is for example how sphinxnote was formerly defined:

sphinx/transforms/i18n.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from __future__ import annotations
44

55
import contextlib
6-
import os.path
76
from re import DOTALL, match
87
from textwrap import indent
98
from typing import TYPE_CHECKING, Any, TypeVar
@@ -394,10 +393,8 @@ def apply(self, **kwargs: Any) -> None:
394393
textdomain = docname_to_domain(self.env.docname, self.config.gettext_compact)
395394

396395
# fetch translations
397-
dirs = [
398-
os.path.join(self.env.srcdir, directory)
399-
for directory in self.config.locale_dirs
400-
]
396+
srcdir = self.env.srcdir
397+
dirs = [srcdir / directory for directory in self.config.locale_dirs]
401398
catalog, has_catalog = init_locale(dirs, self.config.language, textdomain)
402399
if not has_catalog:
403400
return

sphinx/util/_pathlib.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Instances of _StrPath should not be constructed except in Sphinx itself.
44
Consumers of Sphinx APIs should prefer using ``pathlib.Path`` objects
55
where possible. _StrPath objects can be treated as equivalent to ``Path``,
6-
save that ``_StrPath.replace`` is overriden with ``str.replace``.
6+
save that ``_StrPath.replace`` is overridden with ``str.replace``.
77
88
To continue treating path-like objects as strings, use ``os.fspath``,
99
or explicit string coercion.

sphinx/util/logging.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
import logging.handlers
77
from collections import defaultdict
88
from contextlib import contextmanager, nullcontext
9+
from os.path import abspath
910
from typing import IO, TYPE_CHECKING, Any
1011

1112
from docutils import nodes
1213
from docutils.utils import get_source_line
1314

1415
from sphinx.errors import SphinxWarning
1516
from sphinx.util.console import colorize
16-
from sphinx.util.osutil import abspath
1717

1818
if TYPE_CHECKING:
1919
from collections.abc import Iterator, Sequence, Set

sphinx/writers/latex.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66

77
from __future__ import annotations
88

9-
import os.path
109
import re
1110
from collections import defaultdict
1211
from collections.abc import Iterable
12+
from pathlib import Path
1313
from typing import TYPE_CHECKING, Any, ClassVar, cast
1414

1515
from docutils import nodes, writers
@@ -583,18 +583,19 @@ def generate(
583583
def render(self, template_name: str, variables: dict[str, Any]) -> str:
584584
renderer = LaTeXRenderer(latex_engine=self.config.latex_engine)
585585
for template_dir in self.config.templates_path:
586-
template = os.path.join(self.builder.confdir, template_dir, template_name)
587-
if os.path.exists(template):
588-
return renderer.render(template, variables)
589-
elif template.endswith('.jinja'):
590-
legacy_template = template.removesuffix('.jinja') + '_t'
591-
if os.path.exists(legacy_template):
586+
template = self.builder.confdir / template_dir / template_name
587+
if template.exists():
588+
return renderer.render(str(template), variables)
589+
elif template.suffix == '.jinja':
590+
legacy_template_name = template.name.removesuffix('.jinja') + '_t'
591+
legacy_template = template.with_name(legacy_template_name)
592+
if legacy_template.exists():
592593
logger.warning(
593594
__('template %s not found; loading from legacy %s instead'),
594595
template_name,
595596
legacy_template,
596597
)
597-
return renderer.render(legacy_template, variables)
598+
return renderer.render(str(legacy_template), variables)
598599

599600
return renderer.render(template_name, variables)
600601

@@ -1648,7 +1649,9 @@ def visit_image(self, node: Element) -> None:
16481649
options = ''
16491650
if include_graphics_options:
16501651
options = '[%s]' % ','.join(include_graphics_options)
1651-
base, ext = os.path.splitext(uri)
1652+
img_path = Path(uri)
1653+
base = img_path.with_suffix('')
1654+
ext = img_path.suffix
16521655

16531656
if self.in_title and base:
16541657
# Lowercase tokens forcely because some fncychap themes capitalize
@@ -1657,8 +1660,8 @@ def visit_image(self, node: Element) -> None:
16571660
else:
16581661
cmd = rf'\sphinxincludegraphics{options}{{{{{base}}}{ext}}}'
16591662
# escape filepath for includegraphics, https://tex.stackexchange.com/a/202714/41112
1660-
if '#' in base:
1661-
cmd = r'{\catcode`\#=12' + cmd + '}'
1663+
if '#' in str(base):
1664+
cmd = rf'{{\catcode`\#=12{cmd}}}'
16621665
self.body.append(cmd)
16631666
self.body.extend(post)
16641667

0 commit comments

Comments
 (0)