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

New Sphinx tutorial, part III #9534

Merged
merged 27 commits into from Oct 9, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1a1e45f
Add cross reference to role definitions
astrojuanlu Aug 9, 2021
2c1fa83
Add tutorial section on documenting Python objects
astrojuanlu Aug 9, 2021
a5c6845
Add section on Python code preparation
astrojuanlu Aug 10, 2021
8334fd9
Add section on doctests
astrojuanlu Aug 10, 2021
8573c28
Add section on automatic documentation generation
astrojuanlu Aug 11, 2021
a606db0
Add section on autosummary
astrojuanlu Aug 12, 2021
c721d17
Style improvement
astrojuanlu Sep 6, 2021
722629b
Rephrase explanation on square brackets
astrojuanlu Sep 6, 2021
da93cfc
Reword primary domains
astrojuanlu Sep 6, 2021
d505635
Be more explicit on automatic xref generation
astrojuanlu Sep 6, 2021
878478e
Simplify doctest section
astrojuanlu Sep 6, 2021
70bc61f
Include explanation about doctests
astrojuanlu Sep 6, 2021
32f2f90
Simplify installation
astrojuanlu Sep 6, 2021
2755333
Add connections to the next sections
astrojuanlu Sep 6, 2021
53104ca
Add reference to tutorial TOC
astrojuanlu Sep 6, 2021
5daf336
Style improvements
astrojuanlu Sep 13, 2021
91a605c
Highlight only function docstring
astrojuanlu Sep 13, 2021
d7e525b
Insist that automatic is better
astrojuanlu Sep 13, 2021
9aa9d0e
Typo
astrojuanlu Sep 13, 2021
c2847c2
Improve text of some links
astrojuanlu Sep 13, 2021
87b8a0b
Remove square brackets
astrojuanlu Sep 13, 2021
1677f41
Point readers to info field lists instead
astrojuanlu Sep 13, 2021
ccc95ea
Amend explanation on the default-domain directive
astrojuanlu Sep 13, 2021
9a8d7ae
Use stable Sphinx version
astrojuanlu Sep 13, 2021
02119ab
Fix line width
astrojuanlu Sep 13, 2021
ae3eab2
Get function signature right since the beginning
astrojuanlu Sep 13, 2021
4920e4e
Explain that there are several domains
astrojuanlu Sep 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file added doc/_static/tutorial/lumache-autosummary.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/tutorial/lumache-py-function-full.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/tutorial/lumache-py-function.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
166 changes: 166 additions & 0 deletions doc/tutorial/automatic-doc-generation.rst
@@ -0,0 +1,166 @@
Automatic documentation generation from code
============================================

In the :ref:`previous section <tutorial-describing-objects>` of the tutorial
you manually documented a Python function in Sphinx. However, the description
was out of sync with the code itself, since the function signature was not
the same. Besides, it would be nice to reuse `Python
docstrings <https://www.python.org/dev/peps/pep-0257/#what-is-a-docstring>`_
in the documentation, rather than having to write the information in two
places.

Fortunately, :doc:`autodoc </usage/extensions/autodoc>` provides this
astrojuanlu marked this conversation as resolved.
Show resolved Hide resolved
functionality.

Reusing signatures and docstrings with autodoc
----------------------------------------------

To use autodoc, first add it to the list of enabled extensions:

.. code-block:: python
:caption: docs/source/conf.py
:emphasize-lines: 4

extensions = [
'sphinx.ext.duration',
'sphinx.ext.doctest',
tk0miya marked this conversation as resolved.
Show resolved Hide resolved
'sphinx.ext.autodoc',
]

Next, move the content of the ``.. py:function`` directive to the function
docstring in the original Python file and add an optional ``kind`` argument,
astrojuanlu marked this conversation as resolved.
Show resolved Hide resolved
as follows:

.. code-block:: python
:caption: lumache.py
:emphasize-lines: 1-9
astrojuanlu marked this conversation as resolved.
Show resolved Hide resolved

def get_random_ingredients(kind=None):
"""
Return a list of random ingredients as strings.

:param kind: Optional "kind" of ingredients.
:type kind: list[str] or None
:raise lumache.InvalidKindError: If the kind is invalid.
:return: The ingredients list.
:rtype: list[str]

"""
return ["shells", "gorgonzola", "parsley"]

Finally, replace the ``.. py:function`` directive from the Sphinx documentation
with :rst:dir:`autofunction`:

.. code-block:: rst
:caption: docs/source/usage.rst
:emphasize-lines: 3

you can use the ``lumache.get_random_ingredients()`` function:

.. autofunction:: lumache.get_random_ingredients

If you now build the HTML documentation, the output will be the same!
astrojuanlu marked this conversation as resolved.
Show resolved Hide resolved
Sphinx took the reStructuredText from the docstring and included it,
also generating proper cross-references.

You can also autogenerate documentation from other objects. For example, add
the code for the ``InvalidKindError`` exception:

.. code-block:: python
:caption: lumache.py

class InvalidKindError(Exception):
"""Raised if the kind is invalid."""
pass

And replace the ``.. py:exception`` directive with :rst:dir:`autoexception`
as follows:

.. code-block:: rst
:caption: docs/source/usage.rst
:emphasize-lines: 4

or ``"veggies"``. Otherwise, :py:func:`lumache.get_random_ingredients`
will raise an exception.

.. autoexception:: lumache.InvalidKindError

And again, after running ``make html``, the output will be the same as before.

Generating comprehensive API references
---------------------------------------

While using ``sphinx.ext.autodoc`` makes keeping the code and the documentation
in sync much easier, it still requires you to write an ``auto*`` directive
for every object you want to document. Sphinx provides yet another level of
automation: the :doc:`autosummary </usage/extensions/autosummary>` extension.

The :rst:dir:`autosummary` directive generates documents that contain all the
necessary ``autodoc`` directives. To use it, first enable the autosummary
extension:

.. code-block:: python
:caption: docs/source/conf.py
:emphasize-lines: 5

extensions = [
'sphinx.ext.duration',
'sphinx.ext.doctest',
tk0miya marked this conversation as resolved.
Show resolved Hide resolved
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
]

Next, create a new ``api.rst`` file with these contents:

.. code-block:: rst
:caption: docs/source/api.rst

API
===

.. autosummary::
:toctree: generated

lumache

Remember to include the new document in the root toctree:

.. code-block:: rst
:caption: docs/source/index.rst
:emphasize-lines: 7

Contents
--------

.. toctree::

usage
api

Finally, after you build the HTML documentation running ``make html``, it will
contain two new pages:

- ``api.html``, corresponding to ``docs/source/api.rst`` and containing a table
with the objects you included in the ``autosummary`` directive (in this case,
only one).
- ``generated/lumache.html``, corresponding to a newly created reST file
``generated/lumache.rst`` and containing a summary of members of the module,
in this case one function and one exception.

.. figure:: /_static/tutorial/lumache-autosummary.png
:width: 80%
:align: center
:alt: Summary page created by autosummary

Summary page created by autosummary

Each of the links in the summary page will take you to the places where you
originally used the correspoding ``autodoc`` directive, in this case in the
astrojuanlu marked this conversation as resolved.
Show resolved Hide resolved
``usage.rst`` document.

.. note::

The generated files are based on `Jinja2
templates <https://jinja2docs.readthedocs.io/>`_ that
:ref:`can be customized <autosummary-customizing-templates>`,
but that is out of scope for this tutorial.