diff options
author | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2020-06-06 20:20:21 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-06 20:20:21 +0300 |
commit | 7fa47e4b1b184ddab8827651548cedd62415fbcb (patch) | |
tree | 5e04d6e2f363ef42e11b67785e2258a3d5cc6ffa | |
parent | bf89b1d101fd51fb5c7b76a9af016ddbd68ce2d6 (diff) | |
parent | 8bd5f8b214b25242487948931f8e9b9d1bcf9f98 (diff) |
Merge pull request #7788 from tk0miya/7722_support_typevar
autodoc: Support TypeVar (refs: #7722)
-rw-r--r-- | CHANGES | 1 | ||||
-rw-r--r-- | sphinx/ext/autodoc/__init__.py | 45 | ||||
-rw-r--r-- | tests/roots/test-ext-autodoc/target/typevar.py | 15 | ||||
-rw-r--r-- | tests/test_ext_autodoc.py | 40 |
4 files changed, 100 insertions, 1 deletions
@@ -52,6 +52,7 @@ Features added * #2106: autodoc: Support multiple signatures on docstring * #4422: autodoc: Support GenericAlias in Python 3.7 or above * #3610: autodoc: Support overloaded functions +* #7722: autodoc: Support TypeVar * #7466: autosummary: headings in generated documents are not translated * #7490: autosummary: Add ``:caption:`` option to autosummary directive to set a caption to the toctree diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 31301e01e..09db26948 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -16,7 +16,7 @@ import warnings from inspect import Parameter, Signature from types import ModuleType from typing import ( - Any, Callable, Dict, Iterator, List, Optional, Sequence, Set, Tuple, Type, Union + Any, Callable, Dict, Iterator, List, Optional, Sequence, Set, Tuple, Type, TypeVar, Union ) from docutils.statemachine import StringList @@ -1644,6 +1644,48 @@ class GenericAliasDocumenter(DataDocumenter): super().add_content(content) +class TypeVarDocumenter(DataDocumenter): + """ + Specialized Documenter subclass for TypeVars. + """ + + objtype = 'typevar' + directivetype = 'data' + priority = DataDocumenter.priority + 1 + + @classmethod + def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any + ) -> bool: + return isinstance(member, TypeVar) and isattr # type: ignore + + def add_directive_header(self, sig: str) -> None: + self.options.annotation = SUPPRESS # type: ignore + super().add_directive_header(sig) + + def get_doc(self, encoding: str = None, ignore: int = None) -> List[List[str]]: + if ignore is not None: + warnings.warn("The 'ignore' argument to autodoc.%s.get_doc() is deprecated." + % self.__class__.__name__, + RemovedInSphinx50Warning, stacklevel=2) + + if self.object.__doc__ != TypeVar.__doc__: + return super().get_doc() + else: + return [] + + def add_content(self, more_content: Any, no_docstring: bool = False) -> None: + attrs = [repr(self.object.__name__)] + for constraint in self.object.__constraints__: + attrs.append(stringify_typehint(constraint)) + if self.object.__covariant__: + attrs.append("covariant=True") + if self.object.__contravariant__: + attrs.append("contravariant=True") + + content = StringList([_('alias of TypeVar(%s)') % ", ".join(attrs)], source='') + super().add_content(content) + + class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: ignore """ Specialized Documenter subclass for methods (normal, static and class). @@ -2017,6 +2059,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_autodocumenter(DataDocumenter) app.add_autodocumenter(DataDeclarationDocumenter) app.add_autodocumenter(GenericAliasDocumenter) + app.add_autodocumenter(TypeVarDocumenter) app.add_autodocumenter(FunctionDocumenter) app.add_autodocumenter(DecoratorDocumenter) app.add_autodocumenter(MethodDocumenter) diff --git a/tests/roots/test-ext-autodoc/target/typevar.py b/tests/roots/test-ext-autodoc/target/typevar.py new file mode 100644 index 000000000..9c6b0eab0 --- /dev/null +++ b/tests/roots/test-ext-autodoc/target/typevar.py @@ -0,0 +1,15 @@ +from typing import TypeVar + +#: T1 +T1 = TypeVar("T1") + +T2 = TypeVar("T2") # A TypeVar not having doc comment + +#: T3 +T3 = TypeVar("T3", int, str) + +#: T4 +T4 = TypeVar("T4", covariant=True) + +#: T5 +T5 = TypeVar("T5", contravariant=True) diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py index e80e8b357..e4ec4a815 100644 --- a/tests/test_ext_autodoc.py +++ b/tests/test_ext_autodoc.py @@ -1618,6 +1618,46 @@ def test_autodoc_GenericAlias(app): ] +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_autodoc_TypeVar(app): + options = {"members": None, + "undoc-members": None} + actual = do_autodoc(app, 'module', 'target.typevar', options) + assert list(actual) == [ + '', + '.. py:module:: target.typevar', + '', + '', + '.. py:data:: T1', + ' :module: target.typevar', + '', + ' T1', + '', + " alias of TypeVar('T1')", + '', + '.. py:data:: T3', + ' :module: target.typevar', + '', + ' T3', + '', + " alias of TypeVar('T3', int, str)", + '', + '.. py:data:: T4', + ' :module: target.typevar', + '', + ' T4', + '', + " alias of TypeVar('T4', covariant=True)", + '', + '.. py:data:: T5', + ' :module: target.typevar', + '', + ' T5', + '', + " alias of TypeVar('T5', contravariant=True)", + ] + + @pytest.mark.skipif(sys.version_info < (3, 9), reason='py39+ is required.') @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_Annotated(app): |