Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
339 changes: 129 additions & 210 deletions docs/writing/documentation.rst
Original file line number Diff line number Diff line change
@@ -1,247 +1,166 @@
Documenting Your Code
=====================

With readability of the code being a main focus for Python developers, proper
commenting is naturally important. Some best practice apply to code comments
and project documents, depending on the scope of the project.

Project documents
-----------------

A README file at the root directory give general information to the users and
the maintainers. It should be raw text or written in some very easy to read
markup, such as reStructuredText and Markdown. It should contain a few lines
explaining the purpose of the project or the library (without assuming the user
knows anything about the project), the url of the main source for the software,
and some basic credit information. This file is the main entry point for
readers of the code.

An INSTALL file is less often necessary with python, except if the dependencies
are complex or unusual, or if some C modules need to be compiled before use.
The installation instructions are often reduced to one command, such as ``pip
install module`` or ``python setup.py install`` and added to the README file.

A LICENSE file should always be present and specify the license under which the
Documentation
=============

Readability is a primary focus for Python developers, in both project
and code documentation. Following some simple best practices can save
both you and others a lot of time.

Project Documentation
---------------------

A ``README`` file at the root directory should give general
information to the users and the maintainers. It should be raw text or
written in some very easy to read markup, such as
:ref:`reStructuredText-ref` and Markdown. It should contain a few
lines explaining the purpose of the project or the library (without
assuming the user knows anything about the project), the url of the
main source for the software, and some basic credit information. This
file is the main entry point for readers of the code.

An ``INSTALL`` file is less necessary with python. The installation
instructions are often reduced to one command, such as ``pip install
module`` or ``python setup.py install`` and added to the ``README``
file.

A ``LICENSE`` file should *always* be present and specify the license under which the
software is made available to the public.

A TODO file or a TODO section in README should list the planned modifications
of the code.
A ``TODO`` file or a ``TODO`` section in ``README`` should list the
planned development for the code.

A CHANGELOG file or section in README should compile a short overview of the
changes in the code base for the latest versions.
A ``CHANGELOG`` file or section in ``README`` should compile a short
overview of the changes in the code base for the latest versions.

Documentation
-------------

As the project or library reaches a certain level of complexity, it may require
a fuller documentation, which can be of different flavors:

The introduction may show a very short overview of what can be done with the
product, using one or two extremely simplified use cases.

The tutorials will show in more details some main use cases. The reader will
follow a step-by-step procedure to set-up a working prototype.
Project Publication
-------------------

The API reference, which is often generated automatically from the code, will
list all publicly available interfaces, their parameters and their return
values, with an explanation of their use.
Depending on the project, your documentation might include some or all
of the following components:

Some documents intended for developers might give guidance about code
convention and general design decision of the project.
- A *introduction* should show a very short overview of what can be
done with the product, using one or two extremely simplified use
cases. This is the thirty-second pitch for your project.

Comments
--------
- A *tutorial* should show some primary use cases in more detail. The reader will
follow a step-by-step procedure to set-up a working prototype.

Comments are written directly inside the code, either using the hash sign (#)
or a docstring_.

.. _docstring: docstrings_
- An *API reference* is typically generated from the code (see
:ref:`docstrings <docstring-ref>`). It will list all publicly available interfaces,
parameters, and return values.

Finding the correct balance between undocumented code and verbose and useless
comment boilerplates is difficult, and is the subject of heated discussion
among developers.
- *Developer documentation* is intended for potential contributors. This can
include code convention and general design strategy of the project.

The following guidelines seem to be most commonly agreed upon:

**Wrong or outdated comments are worse than no comments at all.** Following the
saying that it is better, on a boat, to know that we do not know were we are
than to wrongly believe we know where we are, wrong or outdated comments can be
misleading for the maintainers, slow down considerably bug hunting or
refactoring, and then, when discovered wrong, they will throw suspicion on all
other comments in the code, regardless of their individual correctness.

**There's no need to comment perfect code...** An hypothetical perfectly readable
code, with a crystal clear logic stream, expressive variable and function
names, orthogonal segmentation passing exactly between the flesh and the bones,
and no implicit assumptions of any kind, would not require any comment at all.
When striving for coding excellence, it is useful to see any existing comment,
or any feeling of a need for a comment, as the sign that the code do not
express clearly enough its intent and can be improved.

**.. but no code is perfect.** Perfect code is a chimera, it exists only in
our dreams. In real life, a code base is full of trade offs, and comments are
often needed in the most difficult parts. Moreover, any special case, any
obscure hack, any monkey patch and any ugly workaround MUST be signaled and
explained by a proper comment. This should be enforced by the law!

**TODOs** are special comments that a developer write as a reminder for later
use. It is said that its original intent was that someone might, one day,
search for the string "TODO" in the code base and actually roll their sleeves
and start *to do the TODOs*. There is no available record that it ever
happened. However, TODOs comment are still very useful, because they mark the
current limits of the code, and it is not unlikely that, when required to add a
new behavior to the actual code, looking at the TODOs will show where to start.

**Do not use triple-quote strings to comment code.** A common operation when
modifying code is to comment out some lines or even a full function or class
definition. This can be done by adding triple-quotes around the code block to
be skipped, but this is not a good practice, because line-oriented command-line
tools such as ``grep`` will not be aware that the commented code is inactive.
It is better to add hashes at the proper indentation level for every commented
line. Good editors allow to do this with few keystrokes (ctrl-v on Vim).

**Bad**

.. code-block:: python

def tricky_function():
'''
Commented out because its breaks something.
if foo:
do_bar()
'''
return baz

def tricky_function():
# Commented out because its breaks something.
#if foo:
#do_bar()
return baz


def tricky_function():
# Commented out because its breaks something.
# if foo:
# do_bar()
return baz

**Good**

.. code-block:: python

def tricky_function():
# Commented out because its breaks something.
#if foo:
# do_bar()
return baz

Note that comment text is properly written and separated from the hash by a
space. Commented code is not separated from the hash by an additional space;
this helps when uncommented the code.

The Basics
::::::::::


Code Comments
-------------

Information regarding code comments is taken from PEP 008 (http://www.python.org/dev/peps/pep-0008/).
Block comment styling should be used when commenting out multiple lines of code.: ::

Block comments generally apply to some (or all) code that follows them,
and are indented to the same level as that code. Each line of a block
comment starts with a # and a single space (unless it is indented text
inside the comment).
Paragraphs inside a block comment are separated by a line containing a
single #.

In-line comments are used for individual lines and should be used sparingly.: ::

An inline comment is a comment on the same line as a statement. Inline
comments should be separated by at least two spaces from the statement.
They should start with a # and a single space.
Inline comments are unnecessary and in fact distracting if they state
the obvious. Don't do this:
x = x + 1 # Increment x
But sometimes, this is useful: ::
x = x + 1 # Compensate for border

Docstrings
-----------
.. _sphinx-ref:

PEP 257 is the primary reference for docstrings. (http://www.python.org/dev/peps/pep-0257/)
Sphinx
~~~~~~

There are two types of docstrings, one-line and multi-line. Their names
should be fairly self explanatory.
One-line docstrings: ::
Sphinx_ is far and away the most popular python documentation
tool. **Use it.** It converts :ref:`restructuredtext-ref` markup language
into a range of output formats including HTML, LaTeX (for printable
PDF versions), manual pages, and plain text.

def kos_root():
"""Return the pathname of the KOS root directory."""
global _kos_root
if _kos_root: return _kos_root
...
There is also **great**, **free** hosting for your Sphinx_ docs:
`Read The Docs`_. Use it. You can configure it with commit hooks to
your source repository so that rebuilding your documentation will
happen automatically.

Multi-line docstrings: ::
.. note::

def complex(real=0.0, imag=0.0):
"""Form a complex number.
Sphinx is famous for its API generation, but it also works well
for general project documentation. This Guide is built with
Sphinx_ and is hosted on `Read The Docs`_

Keyword arguments:
real -- the real part (default 0.0)
imag -- the imaginary part (default 0.0)
.. _Sphinx: http://sphinx.pocoo.org
.. _Read The Docs: http://readthedocs.org

"""
if imag == 0.0 and real == 0.0: return complex_zero
...
.. _restructuredtext-ref:

reStructuredText
~~~~~~~~~~~~~~~~

.. _sphinx-ref:
Most Python documentation is written with reStructuredText_. It's like
Markdown with all the optional extensions built in.

The `reStructuredText Primer`_ and the `reStructuredText Quick
Reference`_ should help you familiarize yourself with its syntax.

Sphinx
------
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
.. _reStructuredText Primer: http://sphinx.pocoo.org/rest.html
.. _reStructuredText Quick Reference: http://docutils.sourceforge.net/docs/user/rst/quickref.html

Sphinx_ is a tool which converts documentation in the :ref:`restructuredtext-ref`
markup language into a range of output formats including HTML, LaTeX (for
printable PDF versions), manual pages and plain text.

There is also a great free hosting for your Sphinx_ docs: `Read The Docs`_
Code Documentation Advice
-------------------------

.. note:: This Guide is built with Sphinx_ and hosted on `Read The Docs`_
Comments clarify code and begin with a hash (``#``).

.. _Sphinx: http://sphinx.pocoo.org
.. _Read The Docs: http://readthedocs.org
.. _docstring-ref:

.. _restructuredtext-ref:
In Python, *docstrings* describe modules, classes, and functions: ::

def square_and_rooter(x):
"""Returns the square root of self times self."""
...

reStructuredText
----------------
In general, follow the `comment section of PEP 0008`_ (the "Python Style Guide").

Most Python documentation is written with reStructuredText_. The
`reStructuredText Primer <http://sphinx.pocoo.org/rest.html>`_ and the
`reStructuredText Quick Reference <http://docutils.sourceforge.net/docs/user/rst/quickref.html>`_
should help you familiarize yourself with its syntax.
.. _comment section of PEP 0008: http://www.python.org/dev/peps/pep-0008/#comments

Commenting Sections of Code
~~~~~~~~~~~~~~~~~~~~~~~~~~~

*Do not use triple-quote strings to comment code*. This is not a good
practice, because line-oriented command-line tools such as grep will
not be aware that the commented code is inactive. It is better to add
hashes at the proper indentation level for every commented line. Your
editor probably has the ability to do this easily, and it is worth
learning the comment/uncomment toggle. (*e.g.* ctrl-v on Vim)

Docstrings and Magic
~~~~~~~~~~~~~~~~~~~~

Some tools use docstrings to embed more-than-documentation behavior,
such as unit test logic. Those can be nice, but you won't ever go
wrong with vanilla "here's what this does."

Docstrings versus Block comments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

These aren't interchangeable. For a function or class, the leading
comment block is a programmer's note. The docstring describes the
operation of the function or class: ::

# This function slows down program execution for some reason.
def square_and_rooter(x):
"""Returns the square root of self times self."""
...

.. seealso:: Further reading on docstrings: `PEP 0257`_

.. _PEP 0257: http://www.python.org/dev/peps/pep-0257/

.. _reStructuredText: http://docutils.sourceforge.net/rst.html

Other Tools
:::::::::::
-----------

You might see these in the wild. Use :ref:`sphinx-ref`.

Pycco_
Pycco is a "literate-programming-style documentation generator"
and is a port of the node.js Docco_. It makes code into a
side-by-side HTML code and documentation.

.. _Pycco: http://fitzgen.github.com/pycco
.. _Docco: http://jashkenas.github.com/docco

Epydoc
------
`Epydoc <http://epydoc.sourceforge.net/>`_ generates API documentation based on docstrings.
Epydoc is able to parse docstrings marked up with :ref:`reStructuredText-ref`,
`Javadoc <http://www.oracle.com/technetwork/java/javase/documentation/index-jsp-135444.html#javadocdocuments>`_,
`epytext <http://epydoc.sourceforge.net/manual-epytext.html>`_ or plaintext.
It supports various output formats, most notable HTML, PDF or LaTeX documents.
Ronn_
Ronn builds unix manuals. It converts human readable textfiles to roff for terminal display, and also to HTML for the web.

The development of Epydoc is discontinued. You should use :ref:`sphinx-ref` instead.
.. _Ronn: https://github.com/rtomayko/ronn

pycco / docco / shocco
----------------------
Epydoc_
Epydoc is discontinued. Use :ref:`sphinx-ref` instead.

Ronn
----
.. _Epydoc: http://epydoc.sourceforge.net