xref: /aosp_15_r20/external/autotest/docs/coding-style.md (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Coding style for autotest in ChromeOS / Android / Brillo
2These rules elaborate on, but rarely deviate from PEP-8.  When in doubt, go
3with PEP-8.
4
5
6## Language
7 * Use Python where possible
8 * Prefer writing more Python to a smaller amount of shell script in host
9   commands.  In practice, the Python tends to be easier to maintain.
10 * Some tests use C/C++ in test dependencies, and this is also ok.
11
12
13## Indentation & whitespace
14
15Format your code for an 80 character wide screen.
16
17Indentation is 4 spaces, as opposed to hard tabs (which it used to be).
18This is the Python standard.
19
20For hanging indentation, use 8 spaces plus all args should be on the new line.
21
22```
23
24     # Either of the following hanging indentation is considered acceptable.
25YES: return 'class: %s, host: %s, args = %s' % (
26             self.__class__.__name__, self.hostname, self.args)
27
28YES: return 'class: %s, host: %s, args = %s' % (
29             self.__class__.__name__,
30             self.hostname,
31             self.args)
32
33     # Do not use 4 spaces for hanging indentation
34NO:  return 'class: %s, host: %s, args = %s' % (
35         self.__class__.__name__, self.hostname, self.args)
36
37     # Do put all args on new line
38NO:  return 'class: %s, host: %s, args = %s' % (self.__class__.__name__,
39             self.hostname, self.args)
40```
41
42Don't leave trailing whitespace, or put whitespace on blank lines.
43
44
45## Variable names and UpPeR cAsE
46 * Use descriptive variable names where possible
47 * Use `variable_names_like_this`
48 * Use `method_and_function_names_like_this`
49 * Use `UpperCamelCase` for class names
50
51
52## Importing modules
53
54The order of imports should be as follows:
55
56 * Standard python modules
57 * Non-standard python modules
58 * Autotest modules
59
60Within one of these three sections, all module imports using the from
61keyword should appear after regular imports.
62Each module should be imported on its own line.
63Do not use Wildcard imports (`from x import *`) if possible.
64
65Import modules, not classes.  For example:
66
67```
68from common_lib import error
69
70def foo():
71    raise error.AutoservError(...)
72```
73
74and not:
75
76```
77from common_lib.error import AutoservError
78```
79
80For example:
81
82```
83import os
84import pickle
85import random
86import re
87import select
88import shutil
89import signal
90import subprocess
91
92import common   # Magic autotest_lib module and sys.path setup code.
93import MySQLdb  # After common so that we check our site-packages first.
94
95from common_lib import error
96```
97
98### Automatically reorder imports
99
100To sort the imports on a list of files:
101
102`isort -o common -t common -sl FILENAMES`
103
104Or all the files in the current commit:
105
106`isort -o common -t common -sl $(git diff --name-only HEAD^ HEAD)`
107
108Or all the unstaged files:
109
110`isort -o common -t common -sl $(git diff --name-only)`
111
112## Testing None
113
114Use `is None` rather than `== None` and `is not None` rather than `!= None`.
115This way you'll never run into a case where someone's `__eq__` or `__ne__`
116method does the wrong thing.
117
118
119## Comments
120
121Generally, you want your comments to tell WHAT your code does, not HOW.
122We can figure out how from the code itself (or if not, your code needs fixing).
123
124Try to describle the intent of a function and what it does in a triple-quoted
125(multiline) string just after the def line. We've tried to do that in most
126places, though undoubtedly we're not perfect. A high level overview is
127incredibly helpful in understanding code.
128
129
130## Hardcoded String Formatting
131
132Strings should use only single quotes for hardcoded strings in the code.
133Double quotes are acceptable when single quote is used as part of the string.
134Multiline strings should not use '\' but wrap the string using parentheseses.
135
136```
137REALLY_LONG_STRING = ('This is supposed to be a really long string that is '
138                      'over 80 characters and does not use a slash to '
139                      'continue.')
140```
141
142## Docstrings
143
144Docstrings are important to keep our code self documenting. While it's not
145necessary to overdo documentation, we ask you to be sensible and document any
146nontrivial function. When creating docstrings, please add a newline at the
147beginning of your triple quoted string and another newline at the end of it. If
148the docstring has multiple lines, please include a short summary line followed
149by a blank line before continuing with the rest of the description. Please
150capitalize and punctuate accordingly the sentences. If the description has
151multiple lines, put two levels of indentation before proceeding with text. An
152example docstring:
153
154```python
155def foo(param1, param2):
156    """
157    Summary line.
158
159    Long description of method foo.
160
161    @param param1: A Spam object that has methods bar() and baz()
162            which raise SpamError if something goes awry.
163    @type param1: Spam
164
165    @return: a list of integers describing changes in a source tree
166    @rtype: list
167
168    @raise SpamError: when some stated condition occurs.
169
170    """
171```
172
173The tags that you can put inside your docstring are tags recognized by systems
174like epydoc. Not all places need all tags defined, so choose them wisely while
175writing code. Generally always list any parameters, the return value (if there
176is one), and exceptions that can be raised.
177
178|   Tag    | Description
179|----------|-------------------------------------------------------------------
180| @author  | Code author
181| @cvar    | Class variable (defined on `self.__class__.`)
182| @ivar    | Instance variable for a class (defined on `self.`)
183| @param   | Parameter description
184| @raise   | Exception type the function can throw, and the conditions for it
185| @return  | Return value description
186| @rtype   | The type the method returns
187| @see     | Reference to other parts of the codebase
188| @type    | The type of a given parameter or variable
189| @warning | Call attention to potential problems with the code
190| @version | Version string
191
192For additional information and fields, refer to the epydoc manual:
193http://epydoc.sourceforge.net/manual-fields.html
194
195## Simple code
196
197Keep it simple; this is not the right place to show how smart you are. We
198have plenty of system failures to deal with without having to spend ages
199figuring out your code, thanks ;-) Readbility, readability, readability.
200Strongly prefer readability and simplicity over compactness.
201
202"Debugging is twice as hard as writing the code in the first place. Therefore,
203if you write the code as cleverly as possible, you are, by definition, not
204smart enough to debug it."  Brian Kernighan
205
206
207## Function length
208
209Please keep functions short, under 30 lines or so if possible. Even though
210you are amazingly clever, and can cope with it, the rest of us are busy and
211stupid, so be nice and help us out. To quote the Linux Kernel coding style:
212
213Functions should be short and sweet, and do just one thing.  They should
214fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24,
215as we all know), and do one thing and do that well.
216
217
218## Exceptions
219
220When raising exceptions, the preferred syntax for it is:
221
222```
223raise FooException('Exception Message')
224```
225
226Please don't raise string exceptions, as they're deprecated and will be removed
227from future versions of python. If you're in doubt about what type of exception
228you will raise, please look at http://docs.python.org/lib/module-exceptions.html
229and client/common\_lib/error.py, the former is a list of python built in
230exceptions and the later is a list of autotest/autoserv internal exceptions. Of
231course, if you really need to, you can extend the exception definitions on
232client/common\_lib/error.py.
233
234
235## Submitting patches
236
237Submit changes through the ChromeOS gerrit instance.  This process is
238documented on
239[chromium.org](http://dev.chromium.org/developers/contributing-code).
240