Since docstrings are free-form, it really depends on what you use to parse code to generate API documentation.
I would recommend getting familiar with the Sphinx markup, since it is widely used and is becoming the de-facto standard for documenting Python projects, in part because of the excellent readthedocs.org service. To paraphrase an example from the Sphinx documentation as a Python snippet:
def send_message(sender, recipient, message_body, priority=1) -> int:
"""
Send a message to a recipient.
:param str sender: The person sending the message
:param str recipient: The recipient of the message
:param str message_body: The body of the message
:param priority: The priority of the message, can be a number 1-5
:type priority: integer or None
:return: the message id
:rtype: int
:raises ValueError: if the message_body exceeds 160 characters
:raises TypeError: if the message_body is not a basestring
"""
This markup supports cross-referencing between documents and more. Note that the Sphinx documentation uses (e.g.) :py:attr: whereas you can just use :attr: when documenting from the source code.
Naturally, there are other tools to document APIs. There's the more classic Doxygen which uses \param commands but those are not specifically designed to document Python code like Sphinx is.
Note that there is a similar question with a similar answer in here...
Answer from anarcat on Stack OverflowSince docstrings are free-form, it really depends on what you use to parse code to generate API documentation.
I would recommend getting familiar with the Sphinx markup, since it is widely used and is becoming the de-facto standard for documenting Python projects, in part because of the excellent readthedocs.org service. To paraphrase an example from the Sphinx documentation as a Python snippet:
def send_message(sender, recipient, message_body, priority=1) -> int:
"""
Send a message to a recipient.
:param str sender: The person sending the message
:param str recipient: The recipient of the message
:param str message_body: The body of the message
:param priority: The priority of the message, can be a number 1-5
:type priority: integer or None
:return: the message id
:rtype: int
:raises ValueError: if the message_body exceeds 160 characters
:raises TypeError: if the message_body is not a basestring
"""
This markup supports cross-referencing between documents and more. Note that the Sphinx documentation uses (e.g.) :py:attr: whereas you can just use :attr: when documenting from the source code.
Naturally, there are other tools to document APIs. There's the more classic Doxygen which uses \param commands but those are not specifically designed to document Python code like Sphinx is.
Note that there is a similar question with a similar answer in here...
Based on my experience, the numpy docstring conventions (PEP257 superset) are the most widely-spread followed conventions that are also supported by tools, such as Sphinx.
One example:
Parameters
----------
x : type
Description of parameter `x`.
Hi, can you please give me your feedback about the way I am writing Python docstring ?Mine looks usually like this: https://imgur.com/a/V6QJLJpand in full text (as I cannot insert the image directly):
def getItemsByFolder(folderId):"""Get all Items from database that belong to a particular folder.
Args:folderId (str): A valid folder Id that is present in the Items databaseReturns:list: A list containing folders folder Items represented as dictionaries"""
-
Is there a possibility to avoid this empty line above 'Args' ? (with a special character for example)I do not like it because it takes a lot of screen real-estate for nothing it makes functions hard to read.
-
Is 'Args' or 'Parameters' the correct keyword ?
Writing good documentation is an art unto itself. Repeating yourself (e.g., repeating the variable name without underscores) is valueless; e.g., ++i; // increment i. If you're just repeating variable names without underscores, then you're not adding to anyone's understanding of the code.
I think it's always important to document what exceptions your methods throw. Return values aren't always as obvious as the original programmer thinks they are, so that's usually useful to document as well. (Again, if your method is get_foo(), saying "returns a foo" doesn't add anything.)
One thing to point out about that mypy example, the authors are using type hints which replaces a lot of what would be included in a docstring:
def warn(self, msg: str, context: Context, file: Optional[str] = None,
origin: Optional[Context] = None)
Just from this, I know exactly what this method expects. Without it:
def warn(self, msg, context, file = None, origin = None)
I know a lot less.
I can not give you a definite answer, since such documentation also is sort of work and as such should be done, if useful. Generally speaking, only useful functionality should be exposed to the user and the application should be easy to use and understand.
Arguments Even obvious things can be exported for fast lookup. This is usually helpful for long and tedious methods. Optional parameters can be easily integrated by default parameters.
Return values With python it can be a pain to look up return values by inspecting objects (without source code), so when the source code is not at hand this should be done.
Side effects This is a quite vague term, but at least thread-safety support should be annotated in mixed applications cases (or explicitely). Default however is not thread-safe.
Exceptions Enforcing programmer/user input should be definitely documented, since this will cause crashing behavior.
In a small project, and as such internal project, for given knowledge and (hopefully) code, it does not make too much sense to comment everything. Concentrate on data structures and use cases for functions.