autodoc: add support for `python_display_short_literal` (#12003)

Co-authored-by: James Addison <55152140+jayaddison@users.noreply.github.com>
Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com>
This commit is contained in:
Bénédikt Tran
2025-02-02 23:50:41 +01:00
committed by GitHub
parent 50fb4a9dbb
commit 1b83e55809
8 changed files with 218 additions and 103 deletions

View File

@@ -6,19 +6,20 @@ from typing import Literal, TypeVar
class MyEnum(Enum):
a = 1
b = 2
T = TypeVar('T', bound=Literal[1234])
T = TypeVar('T', bound=Literal[1234, 'abcd'])
"""docstring"""
U = TypeVar('U', bound=Literal[MyEnum.a])
U = TypeVar('U', bound=Literal[MyEnum.a, MyEnum.b])
"""docstring"""
def bar(x: Literal[1234]):
def bar(x: Literal[1234, 'abcd']):
"""docstring"""
def foo(x: Literal[MyEnum.a]):
def foo(x: Literal[MyEnum.a, MyEnum.b]):
"""docstring"""

View File

@@ -3119,30 +3119,32 @@ def test_canonical(app):
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def bounded_typevar_rst(name, bound):
return [
'',
f'.. py:class:: {name}',
' :module: target.literal',
'',
' docstring',
'',
f' alias of TypeVar({name!r}, bound={bound})',
'',
]
def function_rst(name, sig):
return [
'',
f'.. py:function:: {name}({sig})',
' :module: target.literal',
'',
' docstring',
'',
]
@pytest.mark.sphinx('html', testroot='ext-autodoc', freshenv=True)
def test_literal_render(app):
def bounded_typevar_rst(name, bound):
return [
'',
f'.. py:class:: {name}',
' :module: target.literal',
'',
' docstring',
'',
f' alias of TypeVar({name!r}, bound={bound})',
'',
]
def function_rst(name, sig):
return [
'',
f'.. py:function:: {name}({sig})',
' :module: target.literal',
'',
' docstring',
'',
]
# autodoc_typehints_format can take 'short' or 'fully-qualified' values
# and this will be interpreted as 'smart' or 'fully-qualified-except-typing' by restify()
# and 'smart' or 'fully-qualified' by stringify_annotation().
@@ -3157,12 +3159,15 @@ def test_literal_render(app):
'',
'.. py:module:: target.literal',
'',
*bounded_typevar_rst('T', r'\ :py:obj:`~typing.Literal`\ [1234]'),
*bounded_typevar_rst('T', r"\ :py:obj:`~typing.Literal`\ [1234, 'abcd']"),
*bounded_typevar_rst(
'U', r'\ :py:obj:`~typing.Literal`\ [:py:attr:`~target.literal.MyEnum.a`]'
'U',
r'\ :py:obj:`~typing.Literal`\ ['
r':py:attr:`~target.literal.MyEnum.a`, '
r':py:attr:`~target.literal.MyEnum.b`]',
),
*function_rst('bar', 'x: ~typing.Literal[1234]'),
*function_rst('foo', 'x: ~typing.Literal[MyEnum.a]'),
*function_rst('bar', "x: ~typing.Literal[1234, 'abcd']"),
*function_rst('foo', 'x: ~typing.Literal[MyEnum.a, MyEnum.b]'),
]
# restify() assumes that 'fully-qualified' is 'fully-qualified-except-typing'
@@ -3173,12 +3178,66 @@ def test_literal_render(app):
'',
'.. py:module:: target.literal',
'',
*bounded_typevar_rst('T', r'\ :py:obj:`~typing.Literal`\ [1234]'),
*bounded_typevar_rst('T', r"\ :py:obj:`~typing.Literal`\ [1234, 'abcd']"),
*bounded_typevar_rst(
'U', r'\ :py:obj:`~typing.Literal`\ [:py:attr:`target.literal.MyEnum.a`]'
'U',
r'\ :py:obj:`~typing.Literal`\ ['
r':py:attr:`target.literal.MyEnum.a`, '
r':py:attr:`target.literal.MyEnum.b`]',
),
*function_rst('bar', 'x: typing.Literal[1234]'),
*function_rst('foo', 'x: typing.Literal[target.literal.MyEnum.a]'),
*function_rst('bar', "x: typing.Literal[1234, 'abcd']"),
*function_rst(
'foo',
'x: typing.Literal[target.literal.MyEnum.a, target.literal.MyEnum.b]',
),
]
@pytest.mark.sphinx(
'html',
testroot='ext-autodoc',
freshenv=True,
confoverrides={'python_display_short_literal_types': True},
)
def test_literal_render_pep604(app):
options = {
'members': None,
'exclude-members': 'MyEnum',
}
app.config.autodoc_typehints_format = 'short'
actual = do_autodoc(app, 'module', 'target.literal', options)
assert list(actual) == [
'',
'.. py:module:: target.literal',
'',
*bounded_typevar_rst('T', r"\ :py:obj:`~typing.Literal`\ [1234, 'abcd']"),
*bounded_typevar_rst(
'U',
r'\ :py:obj:`~typing.Literal`\ ['
r':py:attr:`~target.literal.MyEnum.a`, '
r':py:attr:`~target.literal.MyEnum.b`]',
),
*function_rst('bar', "x: 1234 | 'abcd'"),
*function_rst('foo', 'x: MyEnum.a | MyEnum.b'),
]
# restify() assumes that 'fully-qualified' is 'fully-qualified-except-typing'
# because it is more likely that a user wants to suppress 'typing.*'
app.config.autodoc_typehints_format = 'fully-qualified'
actual = do_autodoc(app, 'module', 'target.literal', options)
assert list(actual) == [
'',
'.. py:module:: target.literal',
'',
*bounded_typevar_rst('T', r"\ :py:obj:`~typing.Literal`\ [1234, 'abcd']"),
*bounded_typevar_rst(
'U',
r'\ :py:obj:`~typing.Literal`\ ['
r':py:attr:`target.literal.MyEnum.a`, '
r':py:attr:`target.literal.MyEnum.b`]',
),
*function_rst('bar', "x: 1234 | 'abcd'"),
*function_rst('foo', 'x: target.literal.MyEnum.a | target.literal.MyEnum.b'),
]