Skip to content
README.md 3.38 KiB
Newer Older
Andreas Klöckner's avatar
Andreas Klöckner committed
# Python

*   [PEP8](https://pep8.org) applies.
*   Functions methods that are not getters should start with a verb.
*   [`flake8`](http://flake8.pycqa.org/en/latest/) with [`pep8-naming`](https://pypi.org/project/pep8-naming/)
    should pass, with few exceptions.

    Use the configuration file for
    [pytools](https://gitlab.tiker.net/inducer/pytools/blob/master/setup.cfg)
    as a guide.

    When silencing warnings, be specific: `# noqa: F803` silences the specific
    warning on that line.

    Use an editor plugin to help with compliance.

*   Consider using [pylint](https://pylint.org), especially for new code. It
    finds many issues that `flake8` doesn't.

    Use this [config file](https://gitlab.tiker.net/inducer/ci-support/blob/master/.pylintrc-default)
    as a base.

*   For Py3-only code, use type annotations.

*   Think of compatibility/extensibility of functions. Realize that positional
    arguments are harder to extend/change after the fact than keyword
    arguments, which are comparatively easy to add/change. Specifically,
    document which parameters are keyword-only. For Py3-only code, add the `*`
Andreas Klöckner's avatar
Andreas Klöckner committed
    entry to explicitly denote that.

## Docstrings

*   Processed using [Sphinx](http://www.sphinx-doc.org/en/master/contents.html).
Andreas Klöckner's avatar
Andreas Klöckner committed
*   Follows [ReStructuredText with sphinx conventions](http://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html)
    (aka ReST).
*   Start with some descriptive text, if needed--specifically if there
    are concepts to explain.

*   Use `:arg name:` and `:returns:` name to describe parameters and return values.

*   Use `*name*` to refer to argument names or special values like *None*.
Andreas Klöckner's avatar
Andreas Klöckner committed

*   Enclose verbatim in-line source code in two backticks:

    ```rst
    Use ``x-y`` to compute the difference.
    ```

*   If a function is called `widget_as_json()`, don't feel the need to add a
    docstring saying just "returns the widget as JSON."

*   Be generous with ReST links, especially across projects. Add Intersphinx
    URLs to `doc/conf.py` if needed.

*   Use `.. autoclass/function/method` directives as shown below to generate
    as much as possible of the documentation from docstrings.

Sample docstring:

```python
__doc__ = """
Widget-related functionality

.. autoclass:: Widget
.. autofunction:: widget_as_json
"""

class Widget(object):
Andreas Klöckner's avatar
Andreas Klöckner committed
    .. attribute:: owner

        A :class:`Widget` object or *None*.

    .. automethod:: disown
    """

    def disown(self, brutally=False):
        """
        :arg brutally: if *True*, use violence.
        """
        pass

def widget_as_json(widget, recursive=True):
    """Returns output compliant with the schema at :ref:`json-schema`.
    Use ``widget[property]`` to access properties.

    :arg widget: :class:`mymodule.Widget`
Andreas Klöckner's avatar
Andreas Klöckner committed
        Second line is indented.
Andreas Klöckner's avatar
Andreas Klöckner committed
    :returns: a :class:`dict` containing a JSON representation of *widget*.
Andreas Klöckner's avatar
Andreas Klöckner committed
        Second and following line indented here, too.
Andreas Klöckner's avatar
Andreas Klöckner committed

    .. versionadded:: 2018.1

    .. versionchanged:: 2018.2

        Added the *recursive* argument.
    """
```

## Commit Messages

* Always have a commit message that describes what the commit does.
* Try to keep each commit limited to a single topic.
* When making small changes, try to keep commits self-contained, in the sense
  the code should be in a working state after each commit.
* Commit messages are like subject lines in emails stylistically. In particular,
  no periods at the end.