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