Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

autodoc: Only add 'alias of' line for aliases having no docstr (#12484) #12498

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ Features added
Bugs fixed
----------

* #12484: autodoc: Do not add an 'alias of ...' line using the :rst:dir:`autodata`
and :rst:dir:`autoattribute` directives for generic aliases having docstrings.

Testing
-------

Expand Down
8 changes: 6 additions & 2 deletions sphinx/ext/autodoc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2126,7 +2126,8 @@ def add_content(self, more_content: StringList | None) -> None:
if not more_content:
more_content = StringList()

self.update_content(more_content)
if not self.get_module_comment(self.objpath[-1]):
Copy link
Member

@picnixz picnixz Jul 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue with this path is that it entirely disallows a documenter to subclass update_content. An alternative is to provide a method, say should_update_content which returns a boolean determining whether the directive should update the content or not. By default, this would return not self.get_module_comment(self.objpath[-1]) and subclasses could decide what to do.

EDIT: if this is how the class directive proceeds, you can keep this logic.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is handled the same way in ClassDocumenter

if self.doc_as_attr and not self.get_variable_comment():

So shall we keep it this way for now?

self.update_content(more_content)
super().add_content(more_content)


Expand Down Expand Up @@ -2709,7 +2710,10 @@ def add_content(self, more_content: StringList | None) -> None:

if more_content is None:
more_content = StringList()
self.update_content(more_content)

if not self.get_attribute_comment(self.parent, self.objpath[-1]):
self.update_content(more_content)

super().add_content(more_content)


Expand Down
19 changes: 16 additions & 3 deletions tests/roots/test-ext-autodoc/target/genericalias.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,27 @@
from typing import Callable, List

#: A list of int
T = List[int]
T1 = List[int]
felixblanke marked this conversation as resolved.
Show resolved Hide resolved

T2 = List[int]
"""Another list of int."""

T3 = List[int] # a generic alias not having a doccomment

C = Callable[[int], None] # a generic alias not having a doccomment


class Class:
#: A list of int
T = List[int]
T1 = List[int]

T2 = List[int]
"""Another list of int."""

T3 = List[int]


#: A list of Class
L = List[Class]
L1 = List[Class]

L2 = List[Class] # a generic alias not having a doccomment
28 changes: 18 additions & 10 deletions tests/test_extensions/test_ext_autodoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2212,29 +2212,40 @@ def test_autodoc_GenericAlias(app):
' :module: target.genericalias',
'',
'',
' .. py:attribute:: Class.T',
' .. py:attribute:: Class.T1',
' :module: target.genericalias',
'',
' A list of int',
'',
'',
' .. py:attribute:: Class.T2',
' :module: target.genericalias',
'',
' Another list of int.',
'',
'',
' .. py:attribute:: Class.T3',
' :module: target.genericalias',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
'',
'',
'.. py:data:: L',
'.. py:data:: L1',
' :module: target.genericalias',
'',
' A list of Class',
'',
' alias of :py:class:`~typing.List`\\ '
'[:py:class:`~target.genericalias.Class`]',
'',
'',
'.. py:data:: T',
'.. py:data:: T1',
' :module: target.genericalias',
'',
' A list of int',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
'',
'.. py:data:: T2',
' :module: target.genericalias',
'',
' Another list of int.',
'',
]

Expand Down Expand Up @@ -2341,9 +2352,6 @@ def test_autodoc_Annotated(app):
'',
' Type alias for a validated string.',
'',
' alias of :py:class:`~typing.Annotated`\\ [:py:class:`str`, '
':py:class:`~target.annotated.FuncValidator`\\ (func=\\ :py:class:`~target.annotated.validate`)]',
'',
'',
".. py:function:: hello(name: ~typing.Annotated[str, 'attribute']) -> None",
' :module: target.annotated',
Expand Down
27 changes: 24 additions & 3 deletions tests/test_extensions/test_ext_autodoc_autoattribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,36 @@ def test_autoattribute_slots_variable_str(app):

@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoattribute_GenericAlias(app):
actual = do_autodoc(app, 'attribute', 'target.genericalias.Class.T')
actual = do_autodoc(app, 'attribute', 'target.genericalias.Class.T3')
assert list(actual) == [
'',
'.. py:attribute:: Class.T',
'.. py:attribute:: Class.T3',
' :module: target.genericalias',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
'',
]


@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoattribute_GenericAlias_having_doccomment(app):
actual = do_autodoc(app, 'attribute', 'target.genericalias.Class.T1')
assert list(actual) == [
'',
'.. py:attribute:: Class.T1',
' :module: target.genericalias',
'',
' A list of int',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
]

actual = do_autodoc(app, 'attribute', 'target.genericalias.Class.T2')
assert list(actual) == [
'',
'.. py:attribute:: Class.T2',
' :module: target.genericalias',
'',
' Another list of int.',
'',
]

Expand Down
26 changes: 23 additions & 3 deletions tests/test_extensions/test_ext_autodoc_autodata.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,35 @@ def test_autodata_type_comment(app):

@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodata_GenericAlias(app):
actual = do_autodoc(app, 'data', 'target.genericalias.T')
actual = do_autodoc(app, 'data', 'target.genericalias.T3')
assert list(actual) == [
'',
'.. py:data:: T',
'.. py:data:: T3',
' :module: target.genericalias',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
'',
]


@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodata_GenericAlias_having_doccomment(app):
actual = do_autodoc(app, 'data', 'target.genericalias.T1')
assert list(actual) == [
'',
'.. py:data:: T1',
' :module: target.genericalias',
'',
' A list of int',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`int`]',
]
actual = do_autodoc(app, 'data', 'target.genericalias.T2')
assert list(actual) == [
'',
'.. py:data:: T2',
' :module: target.genericalias',
'',
' Another list of int.',
'',
]

Expand Down
20 changes: 16 additions & 4 deletions tests/test_extensions/test_ext_autodoc_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1564,19 +1564,31 @@ def test_autodoc_typehints_format_fully_qualified_for_class_alias(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc',
confoverrides={'autodoc_typehints_format': "fully-qualified"})
def test_autodoc_typehints_format_fully_qualified_for_generic_alias(app):
actual = do_autodoc(app, 'data', 'target.genericalias.L')
actual = do_autodoc(app, 'data', 'target.genericalias.L2')
assert list(actual) == [
'',
'.. py:data:: L',
'.. py:data:: L2',
' :module: target.genericalias',
'',
' A list of Class',
'',
' alias of :py:class:`~typing.List`\\ [:py:class:`target.genericalias.Class`]',
'',
]


@pytest.mark.sphinx('html', testroot='ext-autodoc',
confoverrides={'autodoc_typehints_format': "fully-qualified"})
def test_autodoc_typehints_format_fully_qualified_for_generic_alias_having_doccomment(app):
actual = do_autodoc(app, 'data', 'target.genericalias.L1')
assert list(actual) == [
'',
'.. py:data:: L1',
' :module: target.genericalias',
'',
' A list of Class',
'',
]


@pytest.mark.sphinx('html', testroot='ext-autodoc',
confoverrides={'autodoc_typehints_format': "fully-qualified"})
def test_autodoc_typehints_format_fully_qualified_for_newtype_alias(app):
Expand Down