Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
07746bc
updates CHANGES
picnixz Feb 24, 2024
31877b0
fix :confval:`python_display_short_literal_types`
picnixz Feb 24, 2024
92eb945
add tests
picnixz Feb 24, 2024
dbd4628
Fix lint.
picnixz Feb 24, 2024
bf84060
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Feb 29, 2024
4d73d55
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Mar 2, 2024
bd17e8c
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Mar 23, 2024
93f822a
Update CHANGES.rst
picnixz Mar 23, 2024
dc61297
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Mar 23, 2024
5ab3b87
Update __init__.py
picnixz Mar 23, 2024
5cc3657
Update inspect.py
picnixz Mar 23, 2024
032bf8c
Update sphinx/util/typing.py
picnixz Mar 23, 2024
67f1219
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Mar 23, 2024
987af4c
Merge remote-tracking branch 'upstream/master' into fix/11995-python-…
picnixz Mar 27, 2024
8c6f1ed
revert some format
picnixz Mar 27, 2024
ae4145e
revert some format
picnixz Mar 27, 2024
2089d29
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Mar 27, 2024
1228326
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Mar 28, 2024
6b8fad3
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Apr 1, 2024
70a70ca
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Apr 4, 2024
13cf2c0
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Apr 4, 2024
c035957
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Apr 4, 2024
28d4733
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Apr 5, 2024
eebfdd4
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Apr 12, 2024
92b129b
Merge remote-tracking branch 'upstream/master' into fix/11995-python-…
picnixz Apr 24, 2024
deed23c
fixup!
picnixz Apr 24, 2024
00632e5
revert some mistake
picnixz Apr 24, 2024
d72aefc
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Apr 24, 2024
cb1c317
fixup
picnixz Apr 24, 2024
0b6f61a
fixup
picnixz Apr 24, 2024
f91b1c4
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Apr 25, 2024
c4731c7
cleanup
picnixz Apr 25, 2024
9e0bdc0
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz Apr 27, 2024
f134286
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz May 1, 2024
7dcbe64
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz May 21, 2024
d7f0508
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz May 22, 2024
d0bde20
Merge branch 'master' into fix/11995-python-display-short-literal
picnixz May 28, 2024
ad1c4a5
Merge remote-tracking branch 'upstream/master' into fix/11995-python-…
picnixz Jul 20, 2024
520363f
update CHANGES & fixup
picnixz Jul 20, 2024
81d928f
Merge branch 'master' into fix/11995-python-display-short-literal
AA-Turner Feb 2, 2025
327011f
post-merge
AA-Turner Feb 2, 2025
04bc826
Drop _Mode
AA-Turner Feb 2, 2025
bb6a019
Remove all RenderMode enum changes
AA-Turner Feb 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ Bugs fixed
* #10786: improve the error message when a file to be copied (e.g., an asset)
is removed during Sphinx execution.
Patch by Bénédikt Tran.
* #11995: autodoc: add support for :confval:`python_display_short_literal_types`.
Patch by Bénédikt Tran.

Testing
-------
Expand Down
97 changes: 49 additions & 48 deletions sphinx/ext/autodoc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from sphinx.util.typing import (
ExtensionMetadata,
OptionSpec,
RenderMode,
get_type_hints,
restify,
stringify_annotation,
Expand Down Expand Up @@ -70,6 +71,20 @@
special_member_re = re.compile(r'^__\S+__$')


def _get_render_mode(
config: Config, default: RenderMode = RenderMode.fully_qualified_except_typing,
) -> RenderMode:
if config.autodoc_typehints_format == "short":
mode = RenderMode.smart
else:
mode = default

if config.python_display_short_literal_types:
mode |= RenderMode.short_literal

return mode


def identity(x: Any) -> Any:
return x

Expand Down Expand Up @@ -503,8 +518,8 @@ def format_signature(self, **kwargs: Any) -> str:
retann = self.retann
else:
# try to introspect the signature
retann = None
try:
retann = None
args = self._call_format_args(**kwargs)
if args:
matched = re.match(r'^(\(.*\))\s+->\s+(.*)$', args)
Expand Down Expand Up @@ -1318,6 +1333,8 @@ def format_args(self, **kwargs: Any) -> str:
kwargs.setdefault('show_annotation', False)
if self.config.autodoc_typehints_format == "short":
kwargs.setdefault('unqualified_typehints', True)
if self.config.python_display_short_literal_types:
kwargs.setdefault('short_literal_types', True)

try:
self.env.app.emit('autodoc-before-process-signature', self.object, False)
Expand Down Expand Up @@ -1348,6 +1365,8 @@ def add_directive_header(self, sig: str) -> None:
def format_signature(self, **kwargs: Any) -> str:
if self.config.autodoc_typehints_format == "short":
kwargs.setdefault('unqualified_typehints', True)
if self.config.python_display_short_literal_types:
kwargs.setdefault('short_literal_types', True)

sigs = []
if (self.analyzer and
Expand Down Expand Up @@ -1610,6 +1629,8 @@ def format_args(self, **kwargs: Any) -> str:
kwargs.setdefault('show_annotation', False)
if self.config.autodoc_typehints_format == "short":
kwargs.setdefault('unqualified_typehints', True)
if self.config.python_display_short_literal_types:
kwargs.setdefault('short_literal_types', True)

try:
self._signature_class, _signature_method_name, sig = self._get_signature()
Expand Down Expand Up @@ -1648,6 +1669,8 @@ def format_signature(self, **kwargs: Any) -> str:

if self.config.autodoc_typehints_format == "short":
kwargs.setdefault('unqualified_typehints', True)
if self.config.python_display_short_literal_types:
kwargs.setdefault('short_literal_types', True)

sig = super().format_signature()
sigs = []
Expand Down Expand Up @@ -1735,10 +1758,8 @@ def add_directive_header(self, sig: str) -> None:
self.env.events.emit('autodoc-process-bases',
self.fullname, self.object, self.options, bases)

if self.config.autodoc_typehints_format == "short":
base_classes = [restify(cls, "smart") for cls in bases]
else:
base_classes = [restify(cls) for cls in bases]
mode = _get_render_mode(self.config)
base_classes = [restify(cls, mode) for cls in bases]

sourcename = self.get_sourcename()
self.add_line('', sourcename)
Expand Down Expand Up @@ -1849,25 +1870,19 @@ def get_variable_comment(self) -> list[str] | None:
return None

def add_content(self, more_content: StringList | None) -> None:
mode = _get_render_mode(self.config)

if inspect.isNewType(self.object):
if self.config.autodoc_typehints_format == "short":
supertype = restify(self.object.__supertype__, "smart")
else:
supertype = restify(self.object.__supertype__)
supertype = restify(self.object.__supertype__, mode)

more_content = StringList([_('alias of %s') % supertype, ''], source='')
if isinstance(self.object, TypeVar):
attrs = [repr(self.object.__name__)]
for constraint in self.object.__constraints__:
if self.config.autodoc_typehints_format == "short":
attrs.append(stringify_annotation(constraint, "smart"))
else:
attrs.append(stringify_annotation(constraint))
attrs = [
repr(self.object.__name__),
*(stringify_annotation(c, mode) for c in self.object.__constraints__),
]
if self.object.__bound__:
if self.config.autodoc_typehints_format == "short":
bound = restify(self.object.__bound__, "smart")
else:
bound = restify(self.object.__bound__)
bound = restify(self.object.__bound__, mode)
attrs.append(r"bound=\ " + bound)
if self.object.__covariant__:
attrs.append("covariant=True")
Expand All @@ -1888,10 +1903,7 @@ def add_content(self, more_content: StringList | None) -> None:

if self.doc_as_attr and not self.get_variable_comment():
try:
if self.config.autodoc_typehints_format == "short":
alias = restify(self.object, "smart")
else:
alias = restify(self.object)
alias = restify(self.object, mode)
more_content = StringList([_('alias of %s') % alias], source='')
except AttributeError:
pass # Invalid class object is passed.
Expand Down Expand Up @@ -1982,11 +1994,8 @@ def should_suppress_directive_header(self) -> bool:

def update_content(self, more_content: StringList) -> None:
if inspect.isgenericalias(self.object):
if self.config.autodoc_typehints_format == "short":
alias = restify(self.object, "smart")
else:
alias = restify(self.object)

mode = _get_render_mode(self.config)
alias = restify(self.object, mode)
more_content.append(_('alias of %s') % alias, '')
more_content.append('', '')

Expand Down Expand Up @@ -2099,12 +2108,8 @@ def add_directive_header(self, sig: str) -> None:
annotations = get_type_hints(self.parent, None,
self.config.autodoc_type_aliases)
if self.objpath[-1] in annotations:
if self.config.autodoc_typehints_format == "short":
objrepr = stringify_annotation(annotations.get(self.objpath[-1]),
"smart")
else:
objrepr = stringify_annotation(annotations.get(self.objpath[-1]),
"fully-qualified-except-typing")
mode = _get_render_mode(self.config)
objrepr = stringify_annotation(annotations.get(self.objpath[-1]), mode)
self.add_line(' :type: ' + objrepr, sourcename)

try:
Expand Down Expand Up @@ -2194,6 +2199,8 @@ def format_args(self, **kwargs: Any) -> str:
kwargs.setdefault('show_annotation', False)
if self.config.autodoc_typehints_format == "short":
kwargs.setdefault('unqualified_typehints', True)
if self.config.python_display_short_literal_types:
kwargs.setdefault('short_literal_types', True)

try:
if self.object == object.__init__ and self.parent != object: # NoQA: E721
Expand Down Expand Up @@ -2247,6 +2254,8 @@ def document_members(self, all_members: bool = False) -> None:
def format_signature(self, **kwargs: Any) -> str:
if self.config.autodoc_typehints_format == "short":
kwargs.setdefault('unqualified_typehints', True)
if self.config.python_display_short_literal_types:
kwargs.setdefault('short_literal_types', True)

sigs = []
if (self.analyzer and
Expand Down Expand Up @@ -2675,12 +2684,8 @@ def add_directive_header(self, sig: str) -> None:
annotations = get_type_hints(self.parent, None,
self.config.autodoc_type_aliases)
if self.objpath[-1] in annotations:
if self.config.autodoc_typehints_format == "short":
objrepr = stringify_annotation(annotations.get(self.objpath[-1]),
"smart")
else:
objrepr = stringify_annotation(annotations.get(self.objpath[-1]),
"fully-qualified-except-typing")
mode = _get_render_mode(self.config)
objrepr = stringify_annotation(annotations.get(self.objpath[-1]), mode)
self.add_line(' :type: ' + objrepr, sourcename)

try:
Expand Down Expand Up @@ -2716,11 +2721,11 @@ def get_doc(self) -> list[list[str]] | None:
if comment:
return [comment]

orig = self.config.autodoc_inherit_docstrings
try:
# Disable `autodoc_inherit_docstring` temporarily to avoid to obtain
# a docstring from the value which descriptor returns unexpectedly.
# ref: https://github.com/sphinx-doc/sphinx/issues/7805
orig = self.config.autodoc_inherit_docstrings
self.config.autodoc_inherit_docstrings = False # type: ignore[attr-defined]
return super().get_doc()
finally:
Expand Down Expand Up @@ -2811,14 +2816,10 @@ def add_directive_header(self, sig: str) -> None:
return

try:
signature = inspect.signature(func,
type_aliases=self.config.autodoc_type_aliases)
signature = inspect.signature(func, type_aliases=self.config.autodoc_type_aliases)
if signature.return_annotation is not Parameter.empty:
if self.config.autodoc_typehints_format == "short":
objrepr = stringify_annotation(signature.return_annotation, "smart")
else:
objrepr = stringify_annotation(signature.return_annotation,
"fully-qualified-except-typing")
mode = _get_render_mode(self.config)
objrepr = stringify_annotation(signature.return_annotation, mode)
self.add_line(' :type: ' + objrepr, sourcename)
except TypeError as exc:
logger.warning(__("Failed to get a function signature for %s: %s"),
Expand Down
9 changes: 6 additions & 3 deletions sphinx/ext/autodoc/typehints.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import sphinx
from sphinx import addnodes
from sphinx.util import inspect
from sphinx.util.typing import ExtensionMetadata, stringify_annotation
from sphinx.util.typing import ExtensionMetadata, RenderMode, stringify_annotation

if TYPE_CHECKING:
from docutils.nodes import Element
Expand All @@ -24,9 +24,12 @@ def record_typehints(app: Sphinx, objtype: str, name: str, obj: Any,
options: Options, args: str, retann: str) -> None:
"""Record type hints to env object."""
if app.config.autodoc_typehints_format == 'short':
mode = 'smart'
mode = RenderMode.smart
else:
mode = 'fully-qualified'
mode = RenderMode.fully_qualified

if app.config.python_display_short_literal_types:
mode |= RenderMode.short_literal

try:
if callable(obj):
Expand Down
8 changes: 5 additions & 3 deletions sphinx/ext/napoleon/docstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from sphinx.locale import _, __
from sphinx.util import logging
from sphinx.util.typing import get_type_hints, stringify_annotation
from sphinx.util.typing import RenderMode, get_type_hints, stringify_annotation

if TYPE_CHECKING:
from collections.abc import Iterator
Expand Down Expand Up @@ -880,8 +880,10 @@ def _lookup_annotation(self, _name: str) -> str:
) or {})
self._annotations = get_type_hints(self._obj, None, localns)
if _name in self._annotations:
return stringify_annotation(self._annotations[_name],
'fully-qualified-except-typing')
mode = RenderMode.fully_qualified_except_typing
if getattr(self._config, 'python_display_short_literal_types', None):
mode |= RenderMode.short_literal
return stringify_annotation(self._annotations[_name], mode)
# No annotation found
return ""

Expand Down
23 changes: 15 additions & 8 deletions sphinx/util/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

from sphinx.pycode.ast import unparse as ast_unparse
from sphinx.util import logging
from sphinx.util.typing import ForwardRef, stringify_annotation
from sphinx.util.typing import ForwardRef, RenderMode, stringify_annotation

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -649,20 +649,28 @@ def evaluate(
return sig.replace(parameters=parameters, return_annotation=return_annotation)


def stringify_signature(sig: inspect.Signature, show_annotation: bool = True,
show_return_annotation: bool = True,
unqualified_typehints: bool = False) -> str:
def stringify_signature(
sig: inspect.Signature,
show_annotation: bool = True,
show_return_annotation: bool = True,
unqualified_typehints: bool = False,
short_literal_types: bool = False,
) -> str:
"""Stringify a Signature object.

:param show_annotation: If enabled, show annotations on the signature
:param show_return_annotation: If enabled, show annotation of the return value
:param unqualified_typehints: If enabled, show annotations as unqualified
(ex. io.StringIO -> StringIO)
:param short_literal_types: If enabled, use short literal types.
"""
if unqualified_typehints:
mode = 'smart'
mode = RenderMode.smart
else:
mode = 'fully-qualified'
mode = RenderMode.fully_qualified

if short_literal_types:
mode |= RenderMode.short_literal

args = []
last_kind = None
Expand Down Expand Up @@ -703,8 +711,7 @@ def stringify_signature(sig: inspect.Signature, show_annotation: bool = True,

concatenated_args = ', '.join(args)
if (sig.return_annotation is Parameter.empty or
show_annotation is False or
show_return_annotation is False):
show_annotation is False or show_return_annotation is False):
return f'({concatenated_args})'
else:
annotation = stringify_annotation(sig.return_annotation, mode)
Expand Down
Loading