Introduction

You should follow this guide for all python source code that is created as part of the Chromium OS project i.e. src/platform/*. You may not like some bits of it, but you still need to follow it. In doing so, you ensure that others can work with your code.

This guide may be ignored if you are working on code that is part of an open source project that already conforms to a different style i.e. generally Python code in src/third_party. Autotest is a great example of this--see the other notable python style guides below.

Official Style Guide

The Google Python Style guide is the official python style guide for Chromium OS original code. Note that we deviate from that guide in two ways (in order to match the internal Google Python Style guide):

Other notable python style guides

The CODING STYLE file for autotest - When working on autotest code (or any autotest tests), you should ignore the Chromium OS style guidelines (AKA this page) and use the autotest ones.

Describing arguments in docstrings

PEP-257 says that "The docstring for a function or method should summarize its behavior and document its arguments, return value(s), side effects, exceptions raised, and restrictions. However, it doesn't specify any details of what this should look like.

Said another way, this is completely OK: from subprocess import Popen, PIPE

NOTE: Although not required, we still may want to encourage people to only import packages and modules.

Relative imports are forbidden (PEP-8 only "highly discourages" them). Where absolutely needed, the from __future__ import absolute_import syntax should be used (see PEP-328).

Do not use import *. Always be explicit about what you are importing. Using import * is useful for interactive python but shouldn't be used in checked in code.

The shebang line

All files that are meant to be executed should start with the line:

#!/usr/bin/python2

If your system doesn't support that, it is sufficiently unusual for us to not worry about compatibility with it. Most likely it will break in other fun ways.

Note that files that are not meant to be executed should not contain a shebang line.

String formatting

The Google style guide says that the '{}'.format() style is permitted. That is true, but in CrOS we much more often/always use % instead. You should stick to using % in CrOS code to match existing codebases.

Also keep in mind that for logging type functions, we don't format in place. Instead, we pass them as args to the function.

logging.info('name: %s; score: %d', name, n)

TODOs

It is OK to leave TODOs in code. Why? Encouraging people to at least document parts of code that need to be thought out more (or that are confusing) is better than leaving this code undocumented. See also the Google style guide here.

All TODOs should be formatted like:

TODO(username): Revisit this code when the frob feature is done.

...where username is your chromium.org username. If you don't have a chromium.org username, please use an email address.

Please do not use other forms of TODO (like TBD, FIXME, XXX, etc). This makes TODOs much harder for someone to find in the code.

pylint

Python code written for Chromium OS should be "pylint clean".

Pylint is a utility that analyzes python code to look for bugs and for style violations. We run it in Chromium OS because:

It can catch bugs at "compile time" that otherwise wouldn't show up until runtime. This can include typos and also places where you forgot to import the required module.

It helps to ensure that everyone is following the style guidelines.

Pylint is notoriously picky and sometimes warns about things that are really OK. Because of this, we:

Disable certain warnings in the Chromium OS pylintrc.

Don't consider it an problem to locally disable warnings parts of code. NOTE: There should be a high bar for disabling warnings. Specifically, you should first think about whether there's a way to rewrite the code to avoid the warning before disabling it.

You can use cros lint so that we can be sure everyone is on the same version. This should work outside and inside the chroot.

Other Considerations

Unit tests

All python modules should have a corresponding unit test module called <original name>_unittest.py in the same directory. We use a few related modules (they're available in the chroot as well):

Main Modules

All main modules require a main method. Use if __name__ == 'main': main(sys.argv[1:]) to invoke (not on one line of course).

If your main func wants argv[0], you should use sys.argv[0] directly. If you're trying to print an error message, then usually you want to use argparse (see below) and the parser.error() helper instead.

Main modules should have a symlink without an extension that point to the .py file. All actual code should be in .py files.