I have a Python application. I am using Sphinx with the autodoc extension to generate docs for it. In documenting function arguments, I see two main options:
def makeBaby(mommy, daddy):
"""Execute the miracle of life.
Args:
mommy: description of mommy
daddy: description of daddy
"""
def makeBaby(mommy, daddy):
"""Execute the miracle of life.
:param mommy: description of mommy
:param daddy: description of daddy
"""
Note that option 2 cannot be nested under a header like "Args", as in option 1, without breaking the rendered output. Option 2 has much better rendered output than option 1, but makes the actual docstrings much less readable. Why should param
need to be written a trillion times? Option 1 (from Google's Python style guide) provides much better docstrings, but the rendered output is poor. Does there exist a standard for function docstrings that produces both a clean raw docstring and good rendered output?
The Sphinx docstring formatA pair of :param: and :type: directive options must be used for each parameter we wish to document. The :raises: option is used to describe any errors that are raised by the code, while the :return: and :rtype: options are used to describe any values returned by our code.
Docstrings must be defined with three double-quotes. No blank lines should be left before or after the docstring. The text starts in the next line after the opening quotes. The closing quotes have their own line (meaning that they are not at the end of the last sentence).
Best practicesAll modules, classes, methods, and functions, including the __init__ constructor in packages should have docstrings. Descriptions are capitalized and have end-of-sentence punctuation. Always use """Triple double quotes.""" around docstrings. Docstrings are not followed by a blank line.
You can use the numpy docstrings format and numpydoc to have clear readable docstrings, plus a nice sphinx output.
Install numpydoc:
pip install numpydoc
Add 'numpydoc'
to your conf.py in extensions.
extensions = ['sphinx.ext.autodoc',
'numpydoc']
Then your docstrings would follow the numpy format. You can read more about the layout in the docs. For your example:
def makeBaby(mommy, daddy):
"""Execute the miracle of life.
Parameters
----------
mommy : description of mommy
daddy : description of daddy
Returns
-------
baby : mommy + daddy
"""
return mommy + daddy
And in sphinx:
I'm not sure I understand what you mean by
Note that option 2 cannot be nested under a header like "Args"
But actually Option 2 is the standard. It provides everything you need to document your functions/methods etc and, what most importantly, it's syntax is the part of the Sphinx documenting tool and it will be rendered correctly and similarly by any compliant parser. For example, consider how we can document this big class method with Option 2 (this is a copy'n'paste from a rst file but you can easily adapt it to paste in a docstring):
.. py:method:: create(**fields)
:module: redmine.managers.ResourceManager
:noindex:
Creates new issue resource with given fields and saves it to the Redmine.
:param project_id: (required). Id or identifier of issue's project.
:type project_id: integer or string
:param string subject: (required). Issue subject.
:param integer tracker_id: (optional). Issue tracker id.
:param string description: (optional). Issue description.
:param integer status_id: (optional). Issue status id.
:param integer priority_id: (optional). Issue priority id.
:param integer category_id: (optional). Issue category id.
:param integer fixed_version_id: (optional). Issue version id.
:param boolean is_private: (optional). Whether issue is private.
:param integer assigned_to_id: (optional). Issue will be assigned to this user id.
:param watcher_user_ids: (optional). User ids who will be watching this issue.
:type watcher_user_ids: list or tuple
:param integer parent_issue_id: (optional). Parent issue id.
:param start_date: (optional). Issue start date.
:type start_date: string or date object
:param due_date: (optional). Issue end date.
:type due_date: string or date object
:param integer estimated_hours: (optional). Issue estimated hours.
:param integer done_ratio: (optional). Issue done ratio.
:param list custom_fields: (optional). Custom fields in the form of [{'id': 1, 'value': 'foo'}].
:param uploads:
.. raw:: html
(optional). Uploads in the form of [{'': ''}, ...], accepted keys are:
- path (required). Absolute path to the file that should be uploaded.
- filename (optional). Name of the file after upload.
- description (optional). Description of the file.
- content_type (optional). Content type of the file.
:type uploads: list or tuple
:return: Issue resource object
Which will be rendered as:
I hope you can agree that it produces very similar and readable results in both raw and rendered form.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With