Skip to content

Coding Style Guide

Vasileios Karakasis edited this page Feb 16, 2018 · 12 revisions

ReFrame follows the PEP8 coding style with some exceptions. These exceptions are mostly based on our perception of some aesthetic aspects of the code.

In short, we ignore the following PEP8 error codes:

  • E129: visually indented line with same indent as next logical line
  • E221: multiple spaces before operator
  • E226: missing whitespace around arithmetic operator
  • E241: whitespace after :
  • E272: multiple spaces before keyword

A rationale for these exceptions follows.

Line continuation

We prefer the Pythonic implicit line continuation inside parentheses or brackets. This happens naturally for lists, tuples, sets and dictionaries, but for expressions or lengthy assingments you must use parentheses explicitly instead of the \ line continuation character:

# OK
if (a_long_var > 0 and
    b_long_var == 3):
    do_sth()

# not OK
if a_long_var > 0 and \
   b_long_var == 3:
    do_sth()

However, the above if statement might give the E129 formatting error, but we choose to ignore it, because we prefer to be consistent with our line continuation policy. After all, PEP8 leaves it free.

NOTE on commenting if blocks: A comment that explains a specific branch should go inside the branch, not before the if. If the comment explains generally what we check, it should go outside.

Formatting dictionaries

When formatting dictionaries, we follow the PEP8 convention in general, with the exception that we allow multiple spaces after : in order to align the values. This forces us to ignore E241.

# OK -- PEP8
multiline_dict = {
    'foo': 1,
    'foobar': 2
}

# OK
multiline_dict = {
    'foo':    1,
    'foobar': 2
}

# not OK
multiline_dict = {
    'foo'    : 1,
    'foobar' : 2
}

# not OK
multiline_dict = {
    'foo'   : 1,
    'foobar': 2
}

Formatting operators

In multiline conditionals we always split the line after the operator. For aesthetics reasons we allow alignment of the binary operators as follows:

# OK
if (a_long_var > 0  and
    b_long_var == 3 and
    smaller != 5):
    do_sth()

However, if the two lines have very different lengths, it's better not to align. Similar rules apply to assignments in successive lines:

# OK
a_long   = 1
a_longer = 2

# OK, but maybe ugly
a_long      = 1
a_very_long = 2

For this reason, we ignore E221.

Finally, we allow the following type of aligning in successive assignemnts:

cflags   = my_cflags   or ''
cxxflags = my_cppflags or ''

The alignment of or here forces us to ignore E272 as well.

We are also a bit relaxed regarding the whitespace around arithmetic operators. We generally prefer the whitespace around every arithmetic operator, however, we accept removal of the whitespace in cases it makes the reading of an expression clearer (e.g., by creating visual groupings of the operands of operators with higher precedence):

# OK
n = 2*x + 1   # (1)

# OK, but not so readable as the previous one
n = 2 * x + 1 # (2)

# not OK
n = 2*x+1     # (3)

In order to accept syntax (1), we ignore also E226.

Formatting tools

  • pycodestyle
    • Usage: pycodestyle --ignore=E129,E221,E226,E241,E272 [FILE|DIR]
    • Produces a list non-compliances.
  • autopep8
    • Based on pycodestyle, auto-corrects the source file.
    • Usage: autopep8 -i --ignore=E129,E221,E226,E241,E272 [FILE]

NOTE: Although auto-formatting tools do a great job in homogenizing the code and correcting formatting mistakes, they cannot fully replace the developer's best judgement, especially when splitting long lines. Often they will split in not so meaningful places just to meet the formatting requirements. As a rule of thumb, try to conform to the style as you type.

Setting up your editor

  • Emacs:

    • Install the py-autopep8 package
    • Add the following lines in your .emacs file (format file on save):

(add-hook 'python-mode-hook 'py-autopep8-enable-on-save) (setq py-autopep8-options '("--ignore=E129,E221,E226,E241,E272"))

* Vim:
- `https://github.com/tell-k/vim-autopep8`
Clone this wiki locally