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 epydoc section. Another blank line separates the epydoc section 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.

   @param longStrings: an iterable object which returns zero or more strings
   @param maxLength: the length to which each element from longStrings should be truncated
   @type maxLength: int
   @return: Elements from longStrings in the same order but possibly truncated
   @rtype: list
   @todo: Add more epydoc attributes!

   >>> 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.

Use the available epydoc fields where they are applicable. Some of the useful common field are:

@param <param name>: Describe the parameter

@type <param name>: Data type of the parameter

@return: Describe the return value

@rtype: Data type of the return value

@permission: Zope permission that the method requires

@todo: Todo for this method

The full list of available fields are listed here:

http://epydoc.sourceforge.net/manual-fields.html

NOTE: Within the description section of the docstring, you may use the string "DEPRECATED" on its on line to denote the method as deprecated.