Yes, you only need the type hints OR the annotations in the Args and Returns, not both.
References
According to the Google Python Style Guide: "The description should include required type(s) if the code does not contain a corresponding type annotation."
The Sphinx Docs also encourage this in their example code:
def function_with_pep484_type_annotations(param1: int, param2: str) -> bool:
"""Example function with PEP 484 type annotations.
Args:
param1: The first parameter.
param2: The second parameter.
Returns:
The return value. True for success, False otherwise.
"""
Answer from Kris Gesling on Stack Overflowpython - Type annotations with google style docstrings - Stack Overflow
coding style - What are the most common Python docstring formats? - Stack Overflow
My thoughts on docstrings, pdoc and Google style vs. Markdown
Confused by Google's docstring "Attributes" section.
Yes, you only need the type hints OR the annotations in the Args and Returns, not both.
References
According to the Google Python Style Guide: "The description should include required type(s) if the code does not contain a corresponding type annotation."
The Sphinx Docs also encourage this in their example code:
def function_with_pep484_type_annotations(param1: int, param2: str) -> bool:
"""Example function with PEP 484 type annotations.
Args:
param1: The first parameter.
param2: The second parameter.
Returns:
The return value. True for success, False otherwise.
"""
This is very much IMHO, but I don't think enumerating all the parameters in the docstring has a lot of value if you have decent names and type annotations.
def sum(a: int, b: int) -> int:
"""Returns the result of adding the inputs together."""
return a + b
is more than adequately clear IMO. In real life with this specific example I'd probably do:
def sum(a: int, b: int) -> int:
"""Does exactly what it says."""
return a + b
Since the parameters are two ints, the result is another int, and the name of the function is sum which is a perfectly ordinary English word that means "the thing you get when you add other things together", I don't think any further explanation is necessary (other than perhaps a confirmation that this isn't a trick).
Formats
Python docstrings can be written following several formats as the other posts showed. However the default Sphinx docstring format was not mentioned and is based on reStructuredText (reST). You can get some information about the main formats in this blog post.
Note that the reST is recommended by the PEP 287
There follows the main used formats for docstrings.
- Epytext
Historically a javadoc like style was prevalent, so it was taken as a base for Epydoc (with the called Epytext format) to generate documentation.
Example:
"""
This is a javadoc style.
@param param1: this is a first param
@param param2: this is a second param
@return: this is a description of what is returned
@raise keyError: raises an exception
"""
- reST
Nowadays, the probably more prevalent format is the reStructuredText (reST) format that is used by Sphinx to generate documentation. Note: it is used by default in JetBrains PyCharm (type triple quotes after defining a method and hit enter). It is also used by default as output format in Pyment.
Example:
"""
This is a reST style.
:param param1: this is a first param
:param param2: this is a second param
:returns: this is a description of what is returned
:raises keyError: raises an exception
"""
Google has their own format that is often used. It also can be interpreted by Sphinx (ie. using Napoleon plugin).
Example:
"""
This is an example of Google style.
Args:
param1: This is the first param.
param2: This is a second param.
Returns:
This is a description of what is returned.
Raises:
KeyError: Raises an exception.
"""
Even more examples
- Numpydoc
Note that Numpy recommend to follow their own numpydoc based on Google format and usable by Sphinx.
"""
My numpydoc description of a kind
of very exhautive numpydoc format docstring.
Parameters
----------
first : array_like
the 1st param name `first`
second :
the 2nd param
third : {'value', 'other'}, optional
the 3rd param, by default 'value'
Returns
-------
string
a value in a string
Raises
------
KeyError
when a key error
OtherError
when an other error
"""
Converting/Generating
It is possible to use a tool like Pyment to automatically generate docstrings to a Python project not yet documented, or to convert existing docstrings (can be mixing several formats) from a format to an other one.
Note: The examples are taken from the Pyment documentation
The Google style guide contains an excellent Python style guide. It includes conventions for readable docstring syntax that offers better guidance than PEP-257. For example:
def square_root(n):
"""Calculate the square root of a number.
Args:
n: the number to get the square root of.
Returns:
the square root of n.
Raises:
TypeError: if n is not a number.
ValueError: if n is negative.
"""
pass
I like to extend this to also include type information in the arguments, as described in this Sphinx documentation tutorial. For example:
def add_value(self, value):
"""Add a new value.
Args:
value (str): the value to add.
"""
pass
So, I wanted to add some API documentation to my project. Unfortunately, there are many competing standards/styles and many tools to generate HTML documentation.
Initially I chose pdoc, as it seems simple, does the job well and requires zero configuration. So far, so good. The problem is that is doesn't FULLY support ANY of the most popular docstring standards - ReStructuredText, Google, NumPy; instead, it uses its own style based on Markdown. I actually find it nice & clean, because:
-
you don't need to specify variable/attribute/arg types if you already have type hints in your code
-
you document instance/class variables right after they are declared (not in class docstring)
-
similarly, you document
_init__constructor right after it is declared, not in the class docstring
The problem is that - besides pdoc itself - no one really recognizes its Markdown standard. It's not supported by PyCharm, pyment, pymend, nor by other tools.
However! According to Sphinx/Napoleon Example Google Style Python Docstrings, it is totally possible to use the Google docstrings style in a similar way - i.e, the 3 bullet points above would still work!
So, I could simply use Google style (which is a recognized standard) in a way I would use pdoc's Markdown. The only thing to make sure is not to use the Attributes: and Methods: sections in class docstring, as it would appear as duplicate in generated HTML. I would still use sections Args: Returns: Yields: and Raises: in function docstrings, where applicable.
And my commandline to run pdoc would be:
pdoc modulename -o docs --docformat google --no-show-source
What do you guys think?
PS. One minor downside of placing docstrings after variable declarations is that they do NOT become __doc__, as they do in the case of modules, classes and functions. So, these comments would not be discoverable programmatically (or interactively via help()). But I guess it doesn't matter that much...
I just found out docstring conventions and Google's seems to be one people use and it looks pretty readable so I thought I'd add docstrings according to that.
However, I have no idea how Attributes: work.
First, I am using pycharm and have put the Google style in the Python Integrated Tools section, and it seems to work. I do get automatic docstring stub when I do """ """, though it does not seem to work for classes, just functions.
According to the Google styleguide section 3.8.4 you should use Attributes: section for public attributes. But it does not seem to do anything when it comes to showing the help.
If I take the sample class file in the styleguide, the Attributes: section doesn't show anywhere. Howering mouse over the SampleClass only shows the summary and the two rows after that and nothing more. Using the ctrl+Q shortcut to show the documentation shows the same thing. Screenshot here.
Same thing using the Google stylesheet example file from Sphinx. The Attributes: does not show up. Inline formatted or under the section. Screenshot here.
Is this a PyCharm issue or am I misunderstanding the idea behind the section?