Docstrings: Who Are They For?

What are Docstrings?

Programmers provide documentation strings (docstrings) for their code in order to explain their code. For example, docstrings in Python are written to follow programming language conventions and should be written for all functions, modules, classes, and methods.

Docstrings usually consist of a summary that explains what the section of code does as well as arguments, return expectations, and error expectancies. So, as long as a programmer follows the docstring conventions of the language they are working in, their code should be well-documented. From my experience, I don’t believe this to be the case!

For starters, docstrings are added to blocks of code to explain said blocks of code, but are not code in themselves. A programmer does not provide instructions for a computer in a docstring. Instead, a programmer provides instructions and information for the people who read and use the code. If this is the case, then why do many docstring conventions include pseudo-code?

Examples

To explain what I mean, take a look at the docstring below which uses reStructuredText Style Python Docstrings (docstring reformatted from Daily Challenge #169; lines 62-71):

"""Saves new_row as a generator.

:param rows: Contains rows from get_rows().
:param count: Index of row to be saved in new_row.
:yields: Row in matrix rotated 90 degrees.
"""

The above example has pseudo-code (:param, :yields:) that explains the various parts of a function. If the code within the docstring was for the computer to “read,” this docstring convention would be feasible to use. However, docstrings are for humans to read and therefore the above example is problematic as the pseudo-code prevents easy readability (which is what Python is all about; see line 7 of The Zen of Python).

A solution to the above example would be to use a docstring format which is based on human readability. For example, the following docstring uses the same information, but uses Google Style Python Docstrings:

"""Saves new_row as a generator.

   Args:
       rows (list): Contains rows from get_rows().
       count (int): Index of row to be saved in new_row.

   Yields:
       new_row: Row in matrix rotated 90 degrees.
"""

This example seems to be easier for a human to read as it more closely resembles the syntax found in modern English. Of course, the difference between the two conventions can be more easily distinguished with a more detailed example.

Below are two examples from Napoleon – Marching toward legible docstrings:

reStructuredText:

:param path: The path of the file to wrap
:type path: str
:param field_storage: The :class:`FileStorage` instance to wrap
:type field_storage: FileStorage
:param temporary: Whether or not to delete the file when the File
   instance is destructed
:type temporary: bool
:returns: A buffered writable file descriptor
:rtype: BufferedFileStorage

Google Style:

Args:
    path (str): The path of the file to wrap
    field_storage (FileStorage): The :class:`FileStorage` instance to wrap
    temporary (bool): Whether or not to delete the file when the File
       instance is destructed

Returns:
    BufferedFileStorage: A buffered writable file descriptor

Both of the above examples share the same information, but in different formats. Which format is easier for you to read?

Conclusion

From my experience, it is easier to read the Google Style docstring than the reStructuredText docstring. This is due to the lack of pseudo-code and the inclusion of spacing inherent in this type of convention.

To conclude, it is only logical for docstrings to be written in a format that eases human readability as docstrings are written for humans to read and not for computers to read.


Do you agree with the conclusion? What are some other docstring formats you can think of that focus on readability? Leave your comments below to join the discussion.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments