2. Docstrings

Every method and function definition within a Zope product should include a docstring. The docstring is usually composed of two parts: the explanatory text and the doctest code. The explanation usually includes a description of all or most of the following aspects of the function:

  • The function's purpose

  • The context in which the function is usually called

  • What parameters it expects

  • What it returns

  • Any side effects of the function

This explanatory text should scale in size with the complexity and significance of the function.

The second part of the docstring is the doctest section. This is composed of zendmd commands and expected output from those commands. The commands are run as part of the testing process and output is compared to the output lines. This code serves two primary purposes. First it is a working example of how the function should be called and what it returns. Second it serves as a basic test to ensure the function is not horribly broken. This is not intended as a replacement for unit tests. Thorough testing of boundary cases and unusual situations still belongs in unit tests whereas the doctests are much simpler and more instructional in nature.

Docstrings begin on the line immediately following the function definition and are indented one level from the definition. The first and last lines of the docstring are three double quotes and a newline. One blank line separates the description from the doctest section. The code for the function begins on the line immediately following the docstring. Example:

def TruncateStrings(longStrings, maxLength):
    """
    Foo truncates all the strings in a list to a maximum length.  longStrings is any
    iterable object which returns zero or more strings.  maxLength is the length to
    which each element from longStrings should be truncated.  TruncateStrings returns a
    new list with the elements from longStrings in the same order but possibly
    truncated.

    >>> from Products.SomeModule import TruncateStrings
    >>> TruncateStrings(['abcd', 'efg', 'hi', ''], 3)
    ['abc', 'efg', 'hi', '']
    >>> TruncateStrings([], 5)
    []
    """
    return [s[:maxLength] for s in longStrings]

The easiest way to create the doctest portion is from within zendmd. Except for the indentation, the docstring should exactly match commands and output from a zendmd session.