Style Guidelines

Python Code

  • Generally follow Python’s PEP 8 style guidelines. We run the pep8 command to verify this during unittest runs.

  • Break up logical blocks of related code with a newline. Specifically add a blank newline after conditional or looping blocks.

  • Don’t comment what is obvious. Instead prefer meaningful names of functions and variables:

    # Get the functions signal annotations <-- this comment is unnecessary
    return_type, arg_types = get_signal_annotations(func)
    
  • Use comments to explain non-obvious blocks and conditionals, magic, workarounds (with bug references), or generally complex pieces of code. Good examples:

    # If a property was defined with a decorator, it may already have
    # a name; if it was defined with an assignment (prop = Property(...))
    # we set the property's name to the member name
    if not prop.name:
        prop.name = name
    
    # Python causes MRO's to be calculated starting with the lowest
    # base class and working towards the descendant, storing the result
    # in __mro__ at each point. Therefore at this point we know that
    # we already have our base class MRO's available to us, there is
    # no need for us to (re)calculate them.
    if hasattr(base, '__mro__'):
        bases_of_subclasses += [list(base.__mro__)]
    

Python Doc Strings

  • Doc strings should generally follow PEP 257 unless noted here.

  • Use reStructuredText (reST) annotations.

  • Use three double quotes for doc strings (""").

  • Use a brief description on the same line as the triple quote.

  • Include function parameter documentation (including types, returns, and raises) between the brief description and the full description. Use a newline with indentation for the parameters descriptions.

    def spam(amount):
        """Creates a Spam object with the given amount.
    
        :param int amount:
            The amount of spam.
        :returns:
            A new Spam instance with the given amount set.
        :rtype: Spam
        :raises ValueError:
            If amount is not a numeric type.
    
        More complete description.
        """
    
  • For class documentation, use the classes doc string for an explanation of what the class is used for and how it works, including Python examples. Include __init__ argument documentation after the brief description in the classes doc string. The class __init__ should generally be the first method defined in a class putting it as close as possible (location wise) to the class documentation.

    class Bacon(CookedFood):
        """Bacon is a breakfast food.
    
        :param CookingType cooking_type:
            Enum for the type of cooking to use.
        :param float cooking_time:
            Amount of time used to cook the Bacon in minutes.
    
        Use Bacon in combination with other breakfast foods for
        a complete breakfast. For example, combine Bacon with
        other items in a list to make a breakfast:
    
        .. code-block:: python
    
            breakfast = [Bacon(), Spam(), Spam(), Eggs()]
    
        """
        def __init__(self, cooking_type=CookingType.BAKE, cooking_time=15.0):
            super(Bacon, self).__init__(cooking_type, cooking_time)