From 34c165e497e80ea563ac0619c602ad6ab8bd4742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Luis=20Cano=20Rodr=C3=ADguez?= Date: Mon, 15 Nov 2021 12:46:03 +0100 Subject: [PATCH 1/5] Add clarification on other languages --- doc/tutorial/describing-code.rst | 49 ++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/doc/tutorial/describing-code.rst b/doc/tutorial/describing-code.rst index bfeca0455..f080b095c 100644 --- a/doc/tutorial/describing-code.rst +++ b/doc/tutorial/describing-code.rst @@ -14,8 +14,11 @@ section apply for the other domains as well. .. _tutorial-describing-objects: +Python +------ + Documenting Python objects --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ Sphinx offers several roles and directives to document Python objects, all grouped together in :ref:`the Python domain `. For example, @@ -68,7 +71,7 @@ Notice several things: ``.. function::`` directly. Cross-referencing Python objects --------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ By default, most of these directives generate entities that can be cross-referenced from any part of the documentation by using @@ -123,7 +126,7 @@ And finally, this is how the result would look: Beautiful, isn't it? Including doctests in your documentation ----------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Since you are now describing code from a Python library, it will become useful to keep both the documentation and the code as synchronized as possible. @@ -229,3 +232,43 @@ And finally, ``make test`` reports success! For big projects though, this manual approach can become a bit tedious. In the next section, you will see :doc:`how to automate the process `. + +Other languages (C, C++, others) +-------------------------------- + +Documenting and cross-referencing objects +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sphinx also supports documenting and cross-referencing objects written in +other programming languages. There are four extra built-in domains: +C, C++, JavaScript, and reStructuredText, and third party extensions may +define domains for more languages, such as +`.NET `, +`Fortran `_, +or `Julia `_. + +For example, to document a C++ type definition, you would use the built-in +:rst:dir:`cpp:type` directive, as follows: + +.. code-block:: rst + + .. cpp:type:: std::vector CustomList + + A typedef-like declaration of a type. + +Which would give the following result: + +.. cpp:type:: std::vector CustomList + + A typedef-like declaration of a type. + +All such directives then generate generate references that can be +cross-referenced by using the corresponding role. For example, to reference +the previous type definition, you can use the :rst:role:`cpp:type` role +as follows: + +.. code-block:: rst + + Cross reference to :cpp:type:`CustomList`. + +Which would produce a hyperlink to the previous definition: :cpp:type:`CustomList`. From d7d82a88ad2cf84b76b8e3256c9dfd59369b6de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Luis=20Cano=20Rodr=C3=ADguez?= Date: Mon, 15 Nov 2021 14:29:17 +0100 Subject: [PATCH 2/5] Typo Co-authored-by: Manuel Kaufmann --- doc/tutorial/describing-code.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial/describing-code.rst b/doc/tutorial/describing-code.rst index f080b095c..88e1f8702 100644 --- a/doc/tutorial/describing-code.rst +++ b/doc/tutorial/describing-code.rst @@ -262,7 +262,7 @@ Which would give the following result: A typedef-like declaration of a type. -All such directives then generate generate references that can be +All such directives then generate references that can be cross-referenced by using the corresponding role. For example, to reference the previous type definition, you can use the :rst:role:`cpp:type` role as follows: From eceb6b8f4b26e20246662ce916dc4143376b664d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Luis=20Cano=20Rodr=C3=ADguez?= Date: Mon, 15 Nov 2021 14:30:07 +0100 Subject: [PATCH 3/5] Remove reference to unmaintained extension --- doc/tutorial/describing-code.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/tutorial/describing-code.rst b/doc/tutorial/describing-code.rst index 88e1f8702..bf8ab1c1f 100644 --- a/doc/tutorial/describing-code.rst +++ b/doc/tutorial/describing-code.rst @@ -243,8 +243,7 @@ Sphinx also supports documenting and cross-referencing objects written in other programming languages. There are four extra built-in domains: C, C++, JavaScript, and reStructuredText, and third party extensions may define domains for more languages, such as -`.NET `, -`Fortran `_, +`Fortran `_ or `Julia `_. For example, to document a C++ type definition, you would use the built-in From 79f6d404135389b0e7a74675daf480dc890ae6a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Luis=20Cano=20Rodr=C3=ADguez?= Date: Thu, 18 Nov 2021 23:04:30 +0100 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Jakob Lykke Andersen --- doc/tutorial/describing-code.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/tutorial/describing-code.rst b/doc/tutorial/describing-code.rst index bf8ab1c1f..0b88f5bd9 100644 --- a/doc/tutorial/describing-code.rst +++ b/doc/tutorial/describing-code.rst @@ -240,11 +240,13 @@ Documenting and cross-referencing objects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sphinx also supports documenting and cross-referencing objects written in -other programming languages. There are four extra built-in domains: -C, C++, JavaScript, and reStructuredText, and third party extensions may +other programming languages. There are four additional built-in domains: +C, C++, JavaScript, and reStructuredText. Third-party extensions may define domains for more languages, such as -`Fortran `_ -or `Julia `_. + +- `Fortran `_, +- `Julia `_, or +- `PHP `_. For example, to document a C++ type definition, you would use the built-in :rst:dir:`cpp:type` directive, as follows: From fb92547b911cdbe2c766e513cc179a017dcc6705 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 21 Nov 2021 11:25:48 +0900 Subject: [PATCH 5/5] Fix #9866: autodoc: doccoment for the imported class was ignored Autodoc tried to scan doccomment on the module where the class defined. But it failed to get it if the class is imported from other module. This analyzes the target module to obtain the doccomment. --- CHANGES | 1 + sphinx/ext/autodoc/__init__.py | 12 ++++++++++-- tests/roots/test-ext-autodoc/target/classes.py | 3 +++ tests/test_ext_autodoc.py | 5 ++++- tests/test_ext_autodoc_autoclass.py | 12 ++++++++++++ 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 497aa719c..762fab5b8 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,7 @@ Features added Bugs fixed ---------- +* #9866: autodoc: doccoment for the imported class was ignored * #9857: Generated RFC links use outdated base url Testing diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 2cdf224cb..62f1fb1b3 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -1743,14 +1743,22 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: def get_variable_comment(self) -> Optional[List[str]]: try: key = ('', '.'.join(self.objpath)) - analyzer = ModuleAnalyzer.for_module(self.get_real_modname()) + if self.doc_as_attr: + analyzer = ModuleAnalyzer.for_module(self.modname) + else: + analyzer = ModuleAnalyzer.for_module(self.get_real_modname()) analyzer.analyze() - return list(self.analyzer.attr_docs.get(key, [])) + return list(analyzer.attr_docs.get(key, [])) except PycodeError: return None def add_content(self, more_content: Optional[StringList], no_docstring: bool = False ) -> None: + if self.doc_as_attr and self.modname != self.get_real_modname(): + # override analyzer to obtain doccomment around its definition. + self.analyzer = ModuleAnalyzer.for_module(self.modname) + self.analyzer.analyze() + if self.doc_as_attr and not self.get_variable_comment(): try: more_content = StringList([_('alias of %s') % restify(self.object)], source='') diff --git a/tests/roots/test-ext-autodoc/target/classes.py b/tests/roots/test-ext-autodoc/target/classes.py index d18128584..5ba0294fb 100644 --- a/tests/roots/test-ext-autodoc/target/classes.py +++ b/tests/roots/test-ext-autodoc/target/classes.py @@ -37,3 +37,6 @@ Alias = Foo #: docstring OtherAlias = Bar + +#: docstring +IntAlias = int diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py index 8f14392b2..c853fbb03 100644 --- a/tests/test_ext_autodoc.py +++ b/tests/test_ext_autodoc.py @@ -1870,12 +1870,15 @@ def test_autodoc_GenericAlias(app): ' .. py:attribute:: Class.T', ' :module: target.genericalias', '', + ' A list of int', + '', ' alias of :py:class:`~typing.List`\\ [:py:class:`int`]', '', '.. py:attribute:: T', ' :module: target.genericalias', '', - ' alias of :py:class:`~typing.List`\\ [:py:class:`int`]', + ' A list of int', + '', ] else: assert list(actual) == [ diff --git a/tests/test_ext_autodoc_autoclass.py b/tests/test_ext_autodoc_autoclass.py index 9c730f425..6f4e21060 100644 --- a/tests/test_ext_autodoc_autoclass.py +++ b/tests/test_ext_autodoc_autoclass.py @@ -407,6 +407,18 @@ def test_class_alias_having_doccomment(app): ] +def test_class_alias_for_imported_object_having_doccomment(app): + actual = do_autodoc(app, 'class', 'target.classes.IntAlias') + assert list(actual) == [ + '', + '.. py:attribute:: IntAlias', + ' :module: target.classes', + '', + ' docstring', + '', + ] + + @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_coroutine(app): options = {"members": None}