aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGoogle Python team <noreply@google.com>2019-10-10 00:40:18 -0700
committerGregory P. Smith [Google LLC] <greg@krypto.org>2019-10-11 09:25:02 -0700
commit83a9e8d7ca3d47239cb0a7bf532de791e6df3ba6 (patch)
treefd3e530c4b23dad6d3e3c8c80e957d47057a9593
parenta940c9b4c79a0a14d4c95060cea3643c6d9bf90a (diff)
downloadgoogle-styleguide-83a9e8d7ca3d47239cb0a7bf532de791e6df3ba6.tar.gz
Project import generated by Copybara.
PiperOrigin-RevId: 273904189
-rw-r--r--pyguide.md1041
1 files changed, 772 insertions, 269 deletions
diff --git a/pyguide.md b/pyguide.md
index b2c7f2e..5d9938c 100644
--- a/pyguide.md
+++ b/pyguide.md
@@ -7,8 +7,10 @@ See README.md for details.
# Google Python Style Guide
+<a id="1-background"></a>
+
<a id="background"></a>
-## 1 Background
+## 1 Background
Python is the main dynamic language used at Google. This style guide is a list
of *dos and don'ts* for Python programs.
@@ -21,17 +23,24 @@ auto-formatter to avoid arguing over formatting.
<a id="s2-python-language-rules"></a>
+<a id="2-python-language-rules"></a>
+
<a id="python-language-rules"></a>
-## 2 Python Language Rules
+## 2 Python Language Rules
<a id="s2.1-lint"></a>
+<a id="21-lint"></a>
+
<a id="lint"></a>
-### 2.1 Lint
+### 2.1 Lint
Run `pylint` over your code.
<a id="s2.1.1-definition"></a>
-#### 2.1.1 Definition
+<a id="211-definition"></a>
+
+<a id="lint-definition"></a>
+#### 2.1.1 Definition
`pylint` is a tool for finding bugs and style problems in Python source
code. It finds problems that are typically caught by a compiler for less dynamic
@@ -40,18 +49,27 @@ warnings may be incorrect; however, spurious warnings should be fairly
infrequent.
<a id="s2.1.2-pros"></a>
-#### 2.1.2 Pros
+<a id="212-pros"></a>
+
+<a id="lint-pros"></a>
+#### 2.1.2 Pros
Catches easy-to-miss errors like typos, using-vars-before-assignment, etc.
<a id="s2.1.3-cons"></a>
-#### 2.1.3 Cons
+<a id="213-cons"></a>
+
+<a id="lint-cons"></a>
+#### 2.1.3 Cons
`pylint` isn't perfect. To take advantage of it, we'll need to sometimes: a)
Write around it b) Suppress its warnings or c) Improve it.
<a id="s2.1.4-decision"></a>
-#### 2.1.4 Decision
+<a id="214-decision"></a>
+
+<a id="lint-decision"></a>
+#### 2.1.4 Decision
Make sure you run `pylint` on your code.
@@ -103,32 +121,46 @@ encouraged. The first two break callers that pass arguments by name, while the
last does not enforce that the arguments are actually unused.
<a id="s2.2-imports"></a>
+<a id="22-imports"></a>
+
<a id="imports"></a>
-### 2.2 Imports
+### 2.2 Imports
Use `import` statements for packages and modules only, not for individual
classes or functions. Note that there is an explicit exemption for imports from
the [typing module](#typing-imports).
<a id="s2.2.1-definition"></a>
-#### 2.2.1 Definition
+<a id="221-definition"></a>
+
+<a id="imports-definition"></a>
+#### 2.2.1 Definition
Reusability mechanism for sharing code from one module to another.
<a id="s2.2.2-pros"></a>
-#### 2.2.2 Pros
+<a id="222-pros"></a>
+
+<a id="imports-pros"></a>
+#### 2.2.2 Pros
The namespace management convention is simple. The source of each identifier is
indicated in a consistent way; `x.Obj` says that object `Obj` is defined in
module `x`.
<a id="s2.2.3-cons"></a>
-#### 2.2.3 Cons
+<a id="223-cons"></a>
+
+<a id="imports-cons"></a>
+#### 2.2.3 Cons
Module names can still collide. Some module names are inconveniently long.
<a id="s2.2.4-decision"></a>
-#### 2.2.4 Decision
+<a id="224-decision"></a>
+
+<a id="imports-decision"></a>
+#### 2.2.4 Decision
* Use `import x` for importing packages and modules.
* Use `from x import y` where `x` is the package prefix and `y` is the module
@@ -150,28 +182,41 @@ Do not use relative names in imports. Even if the module is in the same package,
use the full package name. This helps prevent unintentionally importing a
package twice.
-Imports from the [typing module](#typing-imports) are exempt from this rule.
+Imports from the [typing module](#typing-imports) and the
+[six.moves module](https://six.readthedocs.io/#module-six.moves)
+are exempt from this rule.
<a id="s2.3-packages"></a>
+<a id="23-packages"></a>
+
<a id="packages"></a>
-### 2.3 Packages
+### 2.3 Packages
Import each module using the full pathname location of the module.
<a id="s2.3.1-pros"></a>
-#### 2.3.1 Pros
+<a id="231-pros"></a>
+
+<a id="packages-pros"></a>
+#### 2.3.1 Pros
Avoids conflicts in module names or incorrect imports due to the module search
path not being what the author expected. Makes it easier to find modules.
-<a id="S2.3.2-cons"></a>
-#### 2.3.2 Cons
+<a id="s2.3.2-cons"></a>
+<a id="232-cons"></a>
+
+<a id="packages-cons"></a>
+#### 2.3.2 Cons
Makes it harder to deploy code because you have to replicate the package
hierarchy. Not really a problem with modern deployment mechanisms.
<a id="s2.3.3-decision"></a>
-#### 2.3.3 Decision
+<a id="233-decision"></a>
+
+<a id="packages-decision"></a>
+#### 2.3.3 Decision
All new code should import each module by its full package name.
@@ -209,20 +254,29 @@ The directory the main binary is located in should not be assumed to be in
code should assume that `import jodie` refers to a third party or top level
package named `jodie`, not a local `jodie.py`.
+
<a id="s2.4-exceptions"></a>
+<a id="24-exceptions"></a>
+
<a id="exceptions"></a>
-### 2.4 Exceptions
+### 2.4 Exceptions
Exceptions are allowed but must be used carefully.
<a id="s2.4.1-definition"></a>
-#### 2.4.1 Definition
+<a id="241-definition"></a>
+
+<a id="exceptions-definition"></a>
+#### 2.4.1 Definition
Exceptions are a means of breaking out of the normal flow of control of a code
block to handle errors or other exceptional conditions.
<a id="s2.4.2-pros"></a>
-#### 2.4.2 Pros
+<a id="242-pros"></a>
+
+<a id="exceptions-pros"></a>
+#### 2.4.2 Pros
The control flow of normal operation code is not cluttered by error-handling
code. It also allows the control flow to skip multiple frames when a certain
@@ -230,13 +284,19 @@ condition occurs, e.g., returning from N nested functions in one step instead of
having to carry-through error codes.
<a id="s2.4.3-cons"></a>
-#### 2.4.3 Cons
+<a id="243-cons"></a>
+
+<a id="exceptions-cons"></a>
+#### 2.4.3 Cons
May cause the control flow to be confusing. Easy to miss error cases when making
library calls.
<a id="s2.4.4-decision"></a>
-#### 2.4.4 Decision
+<a id="244-decision"></a>
+
+<a id="exceptions-decision"></a>
+#### 2.4.4 Decision
Exceptions must follow certain conditions:
@@ -245,12 +305,13 @@ Exceptions must follow certain conditions:
message'`).
- Make use of built-in exception classes when it makes sense. For example,
- raise a `ValueError` if you were passed a negative number but were expecting
- a positive one. Do not use `assert` statements for validating argument
- values of a public API. `assert` is used to ensure internal correctness, not
- to enforce correct usage nor to indicate that some unexpected event
- occurred. If an exception is desired in the latter cases, use a raise
- statement. For example:
+ raise a `ValueError` to indicate a programming mistake like a violated
+ precondition (such as if you were passed a negative number but required a
+ positive one). Do not use `assert` statements for validating argument values
+ of a public API. `assert` is used to ensure internal correctness, not to
+ enforce correct usage nor to indicate that some unexpected event occurred.
+ If an exception is desired in the latter cases, use a raise statement. For
+ example:
```python
@@ -260,13 +321,17 @@ Exceptions must follow certain conditions:
Args:
minimum: A port value greater or equal to 1024.
- Raises:
- ValueError: If the minimum port specified is less than 1024.
- ConnectionError: If no available port is found.
+
Returns:
The new minimum port.
+
+ Raises:
+ ConnectionError: If no available port is found.
"""
if minimum < 1024:
+ # Note that this raising of ValueError is not mentioned in the doc
+ # string's "Raises:" section because it is not appropriate to
+ # guarantee this specific behavioral reaction to API misuse.
raise ValueError('Minimum port must be at least 1024, not %d.' % (minimum,))
port = self._find_next_open_port(minimum)
if not port:
@@ -282,6 +347,7 @@ Exceptions must follow certain conditions:
Args:
minimum: A port value greater or equal to 1024.
+
Returns:
The new minimum port.
"""
@@ -296,11 +362,17 @@ Exceptions must follow certain conditions:
`Error` and should not introduce stutter (`foo.FooError`).
- Never use catch-all `except:` statements, or catch `Exception` or
- `StandardError`, unless you are re-raising the exception or in the outermost
- block in your thread (and printing an error message). Python is very
- tolerant in this regard and `except:` will really catch everything including
- misspelled names, sys.exit() calls, Ctrl+C interrupts, unittest failures and
- all kinds of other exceptions that you simply don't want to catch.
+ `StandardError`, unless you are
+
+ - re-raising the exception, or
+ - creating an isolation point in the program where exceptions are not
+ propagated but are recorded and suppressed instead, such as protecting a
+ thread from crashing by guarding its outermost block.
+
+ Python is very tolerant in this regard and `except:` will really catch
+ everything including misspelled names, sys.exit() calls, Ctrl+C interrupts,
+ unittest failures and all kinds of other exceptions that you simply don't
+ want to catch.
- Minimize the amount of code in a `try`/`except` block. The larger the body
of the `try`, the more likely that an exception will be raised by a line of
@@ -322,29 +394,43 @@ Exceptions must follow certain conditions:
```
<a id="s2.5-global-variables"></a>
+<a id="25-global-variables"></a>
+
<a id="global-variables"></a>
-### 2.5 Global variables
+### 2.5 Global variables
Avoid global variables.
<a id="s2.5.1-definition"></a>
-#### 2.5.1 Definition
+<a id="251-definition"></a>
+
+<a id="global-variables-definition"></a>
+#### 2.5.1 Definition
Variables that are declared at the module level or as class attributes.
<a id="s2.5.2-pros"></a>
-#### 2.5.2 Pros
+<a id="252-pros"></a>
+
+<a id="global-variables-pros"></a>
+#### 2.5.2 Pros
Occasionally useful.
<a id="s2.5.3-cons"></a>
-#### 2.5.3 Cons
+<a id="253-cons"></a>
+
+<a id="global-variables-cons"></a>
+#### 2.5.3 Cons
Has the potential to change module behavior during the import, because
assignments to global variables are done when the module is first imported.
<a id="s2.5.4-decision"></a>
-#### 2.5.4 Decision
+<a id="254-decision"></a>
+
+<a id="global-variables-decision"></a>
+#### 2.5.4 Decision
Avoid global variables.
@@ -357,21 +443,29 @@ the module by prepending an `_` to the name. External access must be done
through public module-level functions. See [Naming](#s3.16-naming) below.
<a id="s2.6-nested"></a>
-<a id="nested"></a>
-### 2.6 Nested/Local/Inner Classes and Functions
+<a id="26-nested"></a>
+
+<a id="nested-classes-functions"></a>
+### 2.6 Nested/Local/Inner Classes and Functions
Nested local functions or classes are fine when used to close over a local
variable. Inner classes are fine.
<a id="s2.6.1-definition"></a>
-#### 2.6.1 Definition
+<a id="261-definition"></a>
+
+<a id="nested-classes-functions-definition"></a>
+#### 2.6.1 Definition
A class can be defined inside of a method, function, or class. A function can be
defined inside a method or function. Nested functions have read-only access to
variables defined in enclosing scopes.
<a id="s2.6.2-pros"></a>
-#### 2.6.2 Pros
+<a id="262-pros"></a>
+
+<a id="nested-classes-functions-pros"></a>
+#### 2.6.2 Pros
Allows definition of utility classes and functions that are only used inside of
a very limited scope. Very
@@ -379,48 +473,69 @@ a very limited scope. Very
Commonly used for implementing decorators.
<a id="s2.6.3-cons"></a>
-#### 2.6.3 Cons
+<a id="263-cons"></a>
+
+<a id="nested-classes-functions-cons"></a>
+#### 2.6.3 Cons
Instances of nested or local classes cannot be pickled. Nested functions and
classes cannot be directly tested. Nesting can make your outer function longer
and less readable.
<a id="s2.6.4-decision"></a>
-#### 2.6.4 Decision
+<a id="264-decision"></a>
+
+<a id="nested-classes-functions-decision"></a>
+#### 2.6.4 Decision
They are fine with some caveats. Avoid nested functions or classes except when
closing over a local value. Do not nest a function just to hide it from users
of a module. Instead, prefix its name with an \_ at the module level so that it
can still be accessed by tests.
-<a id="list-comprehensions"></a>
<a id="s2.7-list_comprehensions"></a>
+<a id="27-list_comprehensions"></a>
<a id="list_comprehensions"></a>
-### 2.7 Comprehensions & Generator Expressions
+<a id="list-comprehensions"></a>
+
+<a id="comprehensions"></a>
+### 2.7 Comprehensions & Generator Expressions
Okay to use for simple cases.
<a id="s2.7.1-definition"></a>
-#### 2.7.1 Definition
+<a id="271-definition"></a>
+
+<a id="comprehensions-definition"></a>
+#### 2.7.1 Definition
List, Dict, and Set comprehensions as well as generator expressions provide a
concise and efficient way to create container types and iterators without
resorting to the use of traditional loops, `map()`, `filter()`, or `lambda`.
<a id="s2.7.2-pros"></a>
-#### 2.7.2 Pros
+<a id="272-pros"></a>
+
+<a id="comprehensions-pros"></a>
+#### 2.7.2 Pros
Simple comprehensions can be clearer and simpler than other dict, list, or set
creation techniques. Generator expressions can be very efficient, since they
avoid the creation of a list entirely.
<a id="s2.7.3-cons"></a>
-#### 2.7.3 Cons
+<a id="273-cons"></a>
+
+<a id="comprehensions-cons"></a>
+#### 2.7.3 Cons
Complicated comprehensions or generator expressions can be hard to read.
<a id="s2.7.4-decision"></a>
-#### 2.7.4 Decision
+<a id="274-decision"></a>
+
+<a id="comprehensions-decision"></a>
+#### 2.7.4 Decision
Okay to use for simple cases. Each portion must fit on one line: mapping
expression, `for` clause, filter expression. Multiple `for` clauses or filter
@@ -478,33 +593,46 @@ No:
```
<a id="s2.8-default-iterators-and-operators"></a>
-<a id="default-iterators-and-operators"></a>
-### 2.8 Default Iterators and Operators
+
+<a id="default-iterators-operators"></a>
+### 2.8 Default Iterators and Operators
Use default iterators and operators for types that support them, like lists,
dictionaries, and files.
<a id="s2.8.1-definition"></a>
-#### 2.8.1 Definition
+<a id="281-definition"></a>
+
+<a id="default-iterators-operators-definition"></a>
+#### 2.8.1 Definition
Container types, like dictionaries and lists, define default iterators and
membership test operators ("in" and "not in").
<a id="s2.8.2-pros"></a>
-#### 2.8.2 Pros
+<a id="282-pros"></a>
+
+<a id="default-iterators-operators-pros"></a>
+#### 2.8.2 Pros
The default iterators and operators are simple and efficient. They express the
operation directly, without extra method calls. A function that uses default
operators is generic. It can be used with any type that supports the operation.
<a id="s2.8.3-cons"></a>
-#### 2.8.3 Cons
+<a id="283-cons"></a>
+
+<a id="default-iterators-operators-cons"></a>
+#### 2.8.3 Cons
You can't tell the type of objects by reading the method names (e.g. has\_key()
means a dictionary). This is also an advantage.
<a id="s2.8.4-decision"></a>
-#### 2.8.4 Decision
+<a id="284-decision"></a>
+
+<a id="default-iterators-operators-decision"></a>
+#### 2.8.4 Decision
Use default iterators and operators for types that support them, like lists,
dictionaries, and files. The built-in types define iterator methods, too. Prefer
@@ -529,63 +657,91 @@ No: for key in adict.keys(): ...
```
<a id="s2.9-generators"></a>
+<a id="29-generators"></a>
+
<a id="generators"></a>
-### 2.9 Generators
+### 2.9 Generators
Use generators as needed.
<a id="s2.9.1-definition"></a>
-#### 2.9.1 Definition
+<a id="291-definition"></a>
+
+<a id="generators-definition"></a>
+#### 2.9 Definition
A generator function returns an iterator that yields a value each time it
executes a yield statement. After it yields a value, the runtime state of the
generator function is suspended until the next value is needed.
<a id="s2.9.2-pros"></a>
-#### 2.9.2 Pros
+<a id="292-pros"></a>
+
+<a id="generators-pros"></a>
+#### 2.9.2 Pros
Simpler code, because the state of local variables and control flow are
preserved for each call. A generator uses less memory than a function that
creates an entire list of values at once.
<a id="s2.9.3-cons"></a>
-#### 2.9.3 Cons
+<a id="293-cons"></a>
+
+<a id="generators-cons"></a>
+#### 2.9.3 Cons
None.
<a id="s2.9.4-decision"></a>
-#### 2.9.4 Decision
+<a id="294-decision"></a>
+
+<a id="generators-decision"></a>
+#### 2.9.4 Decision
Fine. Use "Yields:" rather than "Returns:" in the docstring for generator
functions.
<a id="s2.10-lambda-functions"></a>
-<a id="lambda-functions"></a>
-### 2.10 Lambda Functions
+<a id="210-lambda-functions"></a>
+
+<a id="lambdas"></a>
+### 2.10 Lambda Functions
Okay for one-liners.
<a id="s2.10.1-definition"></a>
-#### 2.10.1 Definition
+<a id="2101-definition"></a>
+
+<a id="lambdas-definition"></a>
+#### 2.10.1 Definition
Lambdas define anonymous functions in an expression, as opposed to a statement.
They are often used to define callbacks or operators for higher-order functions
like `map()` and `filter()`.
<a id="s2.10.2-pros"></a>
-#### 2.10.2 Pros
+<a id="2102-pros"></a>
+
+<a id="lambdas-pros"></a>
+#### 2.10.2 Pros
Convenient.
<a id="s2.10.3-cons"></a>
-#### 2.10.3 Cons
+<a id="2103-cons"></a>
+
+<a id="lambdas-cons"></a>
+#### 2.10.3 Cons
Harder to read and debug than local functions. The lack of names means stack
traces are more difficult to understand. Expressiveness is limited because the
function may only contain an expression.
<a id="s2.10.4-decision"></a>
-#### 2.10.4 Decision
+<a id="2104-decision"></a>
+
+<a id="lambdas-decision"></a>
+#### 2.10.4 Decision
Okay to use them for one-liners. If the code inside the lambda function is
longer than 60-80 chars, it's probably better to define it as a regular [nested
@@ -596,43 +752,82 @@ module instead of lambda functions. For example, prefer `operator.mul` to
`lambda x, y: x * y`.
<a id="s2.11-conditional-expressions"></a>
+<a id="211-conditional-expressions"></a>
+
<a id="conditional-expressions"></a>
-### 2.11 Conditional Expressions
+### 2.11 Conditional Expressions
-Okay for one-liners.
+Okay for simple cases.
<a id="s2.11.1-definition"></a>
-#### 2.11.1 Definition
+<a id="2111-definition"></a>
+
+<a id="conditional-expressions-definition"></a>
+#### 2.11.1 Definition
Conditional expressions (sometimes called a “ternary operator”) are mechanisms
that provide a shorter syntax for if statements. For example:
`x = 1 if cond else 2`.
<a id="s2.11.2-pros"></a>
-#### 2.11.2 Pros
+<a id="2112-pros"></a>
+
+<a id="conditional-expressions-pros"></a>
+#### 2.11.2 Pros
Shorter and more convenient than an if statement.
<a id="s2.11.3-cons"></a>
-#### 2.11.3 Cons
+<a id="2113-cons"></a>
+
+<a id="conditional-expressions-cons"></a>
+#### 2.11.3 Cons
May be harder to read than an if statement. The condition may be difficult to
locate if the expression is long.
<a id="s2.11.4-decision"></a>
-#### 2.11.4 Decision
+<a id="2114-decision"></a>
-Okay to use for one-liners. In other cases prefer to use a complete if
-statement.
+<a id="conditional-expressions-decision"></a>
+#### 2.11.4 Decision
+
+Okay to use for simple cases. Each portion must fit on one line:
+true-expression, if-expression, else-expression. Use a complete if statement
+when things get more complicated.
+
+```python
+one_line = 'yes' if predicate(value) else 'no'
+slightly_split = ('yes' if predicate(value)
+ else 'no, nein, nyet')
+the_longest_ternary_style_that_can_be_done = (
+ 'yes, true, affirmative, confirmed, correct'
+ if predicate(value)
+ else 'no, false, negative, nay')
+```
+
+```python
+bad_line_breaking = ('yes' if predicate(value) else
+ 'no')
+portion_too_long = ('yes'
+ if some_long_module.some_long_predicate_function(
+ really_long_variable_name)
+ else 'no, false, negative, nay')
+```
<a id="s2.12-default-argument-values"></a>
-<a id="default-argument-values"></a>
-### 2.12 Default Argument Values
+<a id="212-default-argument-values"></a>
+
+<a id="default-arguments"></a>
+### 2.12 Default Argument Values
Okay in most cases.
<a id="s2.12.1-definition"></a>
-#### 2.12.1 Definition
+<a id="2121-definition"></a>
+
+<a id="default-arguments-definition"></a>
+#### 2.12.1 Definition
You can specify values for variables at the end of a function's parameter list,
e.g., `def foo(a, b=0):`. If `foo` is called with only one argument,
@@ -640,16 +835,22 @@ e.g., `def foo(a, b=0):`. If `foo` is called with only one argument,
second argument.
<a id="s2.12.2-pros"></a>
-#### 2.12.2 Pros
+<a id="2122-pros"></a>
+
+<a id="default-arguments-pros"></a>
+#### 2.12.2 Pros
-Often you have a function that uses lots of default values, but-rarely-you want
-to override the defaults. Default argument values provide an easy way to do
-this, without having to define lots of functions for the rare exceptions. Also,
-Python does not support overloaded methods/functions and default arguments are
-an easy way of "faking" the overloading behavior.
+Often you have a function that uses lots of default values, but on rare
+occasions you want to override the defaults. Default argument values provide an
+easy way to do this, without having to define lots of functions for the rare
+exceptions. As Python does not support overloaded methods/functions, default
+arguments are an easy way of "faking" the overloading behavior.
<a id="s2.12.3-cons"></a>
-#### 2.12.3 Cons
+<a id="2123-cons"></a>
+
+<a id="default-arguments-cons"></a>
+#### 2.12.3 Cons
Default arguments are evaluated once at module load time. This may cause
problems if the argument is a mutable object such as a list or a dictionary. If
@@ -657,7 +858,10 @@ the function modifies the object (e.g., by appending an item to a list), the
default value is modified.
<a id="s2.12.4-decision"></a>
-#### 2.12.4 Decision
+<a id="2124-decision"></a>
+
+<a id="default-arguments-decision"></a>
+#### 2.12.4 Decision
Okay to use with the following caveat:
@@ -685,20 +889,28 @@ No: def foo(a, b=FLAGS.my_thing): # sys.argv has not yet been parsed...
```
<a id="s2.13-properties"></a>
+<a id="213-properties"></a>
+
<a id="properties"></a>
-### 2.13 Properties
+### 2.13 Properties
Use properties for accessing or setting data where you would normally have used
simple, lightweight accessor or setter methods.
<a id="s2.13.1-definition"></a>
-#### 2.13.1 Definition
+<a id="2131-definition"></a>
+
+<a id="properties-definition"></a>
+#### 2.13.1 Definition
A way to wrap method calls for getting and setting an attribute as a standard
attribute access when the computation is lightweight.
<a id="s2.13.2-pros"></a>
-#### 2.13.2 Pros
+<a id="2132-pros"></a>
+
+<a id="properties-pros"></a>
+#### 2.13.2 Pros
Readability is increased by eliminating explicit get and set method calls for
simple attribute access. Allows calculations to be lazy. Considered the Pythonic
@@ -708,13 +920,19 @@ access is reasonable. This also allows accessor methods to be added in the
future without breaking the interface.
<a id="s2.13.3-cons"></a>
-#### 2.13.3 Cons
+<a id="2133-cons"></a>
+
+<a id="properties-cons"></a>
+#### 2.13.3 Cons
Must inherit from `object` in Python 2. Can hide side-effects much like operator
overloading. Can be confusing for subclasses.
<a id="s2.13.4-decision"></a>
-#### 2.13.4 Decision
+<a id="2134-decision"></a>
+
+<a id="properties-decision"></a>
+#### 2.13.4 Decision
Use properties in new code to access or set data where you would normally have
used simple, lightweight accessor or setter methods. Properties should be
@@ -749,7 +967,7 @@ Yes: import math
@property
def area(self):
- """Gets or sets the area of the square."""
+ """Area of the square."""
return self._get_area()
@area.setter
@@ -770,42 +988,53 @@ Yes: import math
```
<a id="s2.14-truefalse-evaluations"></a>
+<a id="214-truefalse-evaluations"></a>
+
<a id="truefalse-evaluations"></a>
-### 2.14 True/False evaluations
+### 2.14 True/False Evaluations
Use the "implicit" false if at all possible.
<a id="s2.14.1-definition"></a>
-#### 2.14.1 Definition
+<a id="2141-definition"></a>
+
+<a id="truefalse-evaluations-definition"></a>
+#### 2.14.1 Definition
Python evaluates certain values as `False` when in a boolean context. A quick
"rule of thumb" is that all "empty" values are considered false, so
`0, None, [], {}, ''` all evaluate as false in a boolean context.
<a id="s2.14.2-pros"></a>
-#### 2.14.2 Pros
+<a id="2142-pros"></a>
+
+<a id="truefalse-evaluations-pros"></a>
+#### 2.14.2 Pros
Conditions using Python booleans are easier to read and less error-prone. In
most cases, they're also faster.
<a id="s2.14.3-cons"></a>
-#### 2.14.3 Cons
+<a id="2143-cons"></a>
+
+<a id="truefalse-evaluations-cons"></a>
+#### 2.14.3 Cons
May look strange to C/C++ developers.
<a id="s2.14.4-decision"></a>
-#### 2.14.4 Decision
+<a id="2144-decision"></a>
-Use the "implicit" false if at all possible, e.g., `if foo:` rather than
-`if foo != []:`. There are a few caveats that you should keep in mind though:
+<a id="truefalse-evaluations-decision"></a>
+#### 2.14.4 Decision
-- Never use `==` or `!=` to compare singletons like `None`. Use `is` or
- `is not`.
+Use the "implicit" false if possible, e.g., `if foo:` rather than `if foo !=
+[]:`. There are a few caveats that you should keep in mind though:
-- Beware of writing `if x:` when you really mean `if x is not None:`-e.g.,
- when testing whether a variable or argument that defaults to `None` was set
- to some other value. The other value might be a value that's false in a
- boolean context!
+- Always use `if foo is None:` (or `is not None`) to check for a `None`
+ value-e.g., when testing whether a variable or argument that defaults to
+ `None` was set to some other value. The other value might be a value that's
+ false in a boolean context!
- Never compare a boolean variable to `False` using `==`. Use `if not x:`
instead. If you need to distinguish `False` from `None` then chain the
@@ -852,8 +1081,10 @@ Use the "implicit" false if at all possible, e.g., `if foo:` rather than
- Note that `'0'` (i.e., `0` as string) evaluates to true.
<a id="s2.15-deprecated-language-features"></a>
-<a id="deprecated-language-features"></a>
-### 2.15 Deprecated Language Features
+<a id="215-deprecated-language-features"></a>
+
+<a id="deprecated-features"></a>
+### 2.15 Deprecated Language Features
Use string methods instead of the `string` module where possible. Use function
call syntax instead of `apply`. Use list comprehensions and `for` loops instead
@@ -861,13 +1092,19 @@ of `filter` and `map` when the function argument would have been an inlined
lambda anyway. Use `for` loops instead of `reduce`.
<a id="s2.15.1-definition"></a>
-#### 2.15.1 Definition
+<a id="2151-definition"></a>
+
+<a id="deprecated-features-definition"></a>
+#### 2.15.1 Definition
Current versions of Python provide alternative constructs that people find
generally preferable.
<a id="s2.15.2-decision"></a>
-#### 2.15.2 Decision
+<a id="2152-decision"></a>
+
+<a id="deprecated-features-decision"></a>
+#### 2.15.2 Decision
We do not use any Python version which does not support these features, so there
is no reason not to use the new styles.
@@ -891,13 +1128,18 @@ No: words = string.split(foo, ':')
```
<a id="s2.16-lexical-scoping"></a>
+<a id="216-lexical-scoping"></a>
+
<a id="lexical-scoping"></a>
-### 2.16 Lexical Scoping
+### 2.16 Lexical Scoping
Okay to use.
<a id="s2.16.1-definition"></a>
-#### 2.16.1 Definition
+<a id="2161-definition"></a>
+
+<a id="lexical-scoping-definition"></a>
+#### 2.16.1 Definition
A nested Python function can refer to variables defined in enclosing functions,
but can not assign to them. Variable bindings are resolved using lexical
@@ -918,13 +1160,19 @@ def get_adder(summand1):
```
<a id="s2.16.2-pros"></a>
-#### 2.16.2 Pros
+<a id="2162-pros"></a>
+
+<a id="lexical-scoping-pros"></a>
+#### 2.16.2 Pros
Often results in clearer, more elegant code. Especially comforting to
experienced Lisp and Scheme (and Haskell and ML and ...) programmers.
<a id="s2.16.3-cons"></a>
-#### 2.16.3 Cons
+<a id="2163-cons"></a>
+
+<a id="lexical-scoping-cons"></a>
+#### 2.16.3 Cons
Can lead to confusing bugs. Such as this example based on
[PEP-0227](http://www.google.com/url?sa=D&q=http://www.python.org/dev/peps/pep-0227/):
@@ -946,19 +1194,28 @@ So `foo([1, 2, 3])` will print `1 2 3 3`, not `1 2 3
4`.
<a id="s2.16.4-decision"></a>
-#### 2.16.4 Decision
+<a id="2164-decision"></a>
+
+<a id="lexical-scoping-decision"></a>
+#### 2.16.4 Decision
Okay to use.
<a id="s2.17-function-and-method-decorators"></a>
+<a id="217-function-and-method-decorators"></a>
<a id="function-and-method-decorators"></a>
-### 2.17 Function and Method Decorators
+
+<a id="decorators"></a>
+### 2.17 Function and Method Decorators
Use decorators judiciously when there is a clear advantage. Avoid
`@staticmethod` and limit use of `@classmethod`.
<a id="s2.17.1-definition"></a>
-#### 2.17.1 Definition
+<a id="2171-definition"></a>
+
+<a id="decorators-definition"></a>
+#### 2.17.1 Definition
[Decorators for Functions and
Methods](https://docs.python.org/3/glossary.html#term-decorator)
@@ -985,13 +1242,19 @@ class C(object):
```
<a id="s2.17.2-pros"></a>
-#### 2.17.2 Pros
+<a id="2172-pros"></a>
+
+<a id="decorators-pros"></a>
+#### 2.17.2 Pros
Elegantly specifies some transformation on a method; the transformation might
eliminate some repetitive code, enforce invariants, etc.
<a id="s2.17.3-cons"></a>
-#### 2.17.3 Cons
+<a id="2173-cons"></a>
+
+<a id="decorators-cons"></a>
+#### 2.17.3 Cons
Decorators can perform arbitrary operations on a function's arguments or return
values, resulting in surprising implicit behavior. Additionally, decorators
@@ -999,7 +1262,10 @@ execute at import time. Failures in decorator code are pretty much impossible to
recover from.
<a id="s2.17.4-decision"></a>
-#### 2.17.4 Decision
+<a id="2174-decision"></a>
+
+<a id="decorators-decision"></a>
+#### 2.17.4 Decision
Use decorators judiciously when there is a clear advantage. Decorators should
follow the same import and naming guidelines as functions. Decorator pydoc
@@ -1022,8 +1288,10 @@ Use `@classmethod` only when writing a named constructor or a class-specific
routine that modifies necessary global state such as a process-wide cache.
<a id="s2.18-threading"></a>
+<a id="218-threading"></a>
+
<a id="threading"></a>
-### 2.18 Threading
+### 2.18 Threading
Do not rely on the atomicity of built-in types.
@@ -1039,13 +1307,18 @@ primitives. Learn about the proper use of condition variables so you can use
`threading.Condition` instead of using lower-level locks.
<a id="s2.19-power-features"></a>
+<a id="219-power-features"></a>
+
<a id="power-features"></a>
-### 2.19 Power Features
+### 2.19 Power Features
Avoid these features.
<a id="s2.19.1-definition"></a>
-#### 2.19.1 Definition
+<a id="2191-definition"></a>
+
+<a id="power-features-definition"></a>
+#### 2.19.1 Definition
Python is an extremely flexible language and gives you many fancy features such
as custom metaclasses, access to bytecode, on-the-fly compilation, dynamic
@@ -1053,12 +1326,18 @@ inheritance, object reparenting, import hacks, reflection (e.g. some uses of
`getattr()`), modification of system internals, etc.
<a id="s2.19.2-pros"></a>
-#### 2.19.2 Pros
+<a id="2192-pros"></a>
+
+<a id="power-features-pros"></a>
+#### 2.19.2 Pros
These are powerful language features. They can make your code more compact.
<a id="s2.19.3-cons"></a>
-#### 2.19.3 Cons
+<a id="2193-cons"></a>
+
+<a id="power-features-cons"></a>
+#### 2.19.3 Cons
It's very tempting to use these "cool" features when they're not absolutely
necessary. It's harder to read, understand, and debug code that's using unusual
@@ -1067,7 +1346,10 @@ but when revisiting the code, it tends to be more difficult than code that is
longer but is straightforward.
<a id="s2.19.4-decision"></a>
-#### 2.19.4 Decision
+<a id="2194-decision"></a>
+
+<a id="power-features-decision"></a>
+#### 2.19.4 Decision
Avoid these features in your code.
@@ -1076,15 +1358,20 @@ to use (for example, `abc.ABCMeta`, `collections.namedtuple`, `dataclasses`,
and `enum`).
<a id="s2.20-modern-python"></a>
+<a id="220-modern-python"></a>
+
<a id="modern-python"></a>
-### 2.20 Modern Python: Python 3 and from \_\_future\_\_ imports
+### 2.20 Modern Python: Python 3 and from \_\_future\_\_ imports
Python 3 is here! While not every project is ready to
use it yet, all code should be written to be 3 compatible (and tested under
3 when possible).
<a id="s2.20.1-definition"></a>
-#### 2.20.1 Definition
+<a id="2201-definition"></a>
+
+<a id="modern-python-definition"></a>
+#### 2.20.1 Definition
Python 3 is a significant change in the Python language. While existing code is
often written with 2.7 in mind, there are some simple things to do to make code
@@ -1092,20 +1379,29 @@ more explicit about its intentions and thus better prepared for use under Python
3 without modification.
<a id="s2.20.2-pros"></a>
-#### 2.20.2 Pros
+<a id="2202-pros"></a>
+
+<a id="modern-python-pros"></a>
+#### 2.20.2 Pros
Code written with Python 3 in mind is more explicit and easier to get running
under Python 3 once all of the dependencies of your project are ready.
<a id="s2.20.3-cons"></a>
-#### 2.20.3 Cons
+<a id="2203-cons"></a>
+
+<a id="modern-python-cons"></a>
+#### 2.20.3 Cons
Some people find the additional boilerplate to be ugly. It's unusual to add
imports to a module that doesn't actually require the features added by the
import.
<a id="s2.20.4-decision"></a>
-#### 2.20.4 Decision
+<a id="2204-decision"></a>
+
+<a id="modern-python-decision"></a>
+#### 2.20.4 Decision
##### from \_\_future\_\_ imports
@@ -1124,10 +1420,11 @@ imports](https://www.python.org/dev/peps/pep-0328/), [new `/` division
behavior](https://www.python.org/dev/peps/pep-0238/), and [the print
function](https://www.python.org/dev/peps/pep-3105/).
-Please don't omit or remove these imports, even if they're not currently used
-in the module. It is better to always have the future imports in all files
-so that they are not forgotten during later edits when someone starts using
-such a feature.
+
+Please don't omit or remove these imports, even if they're not currently used in
+the module, unless the code is Python 3 only. It is better to always have the
+future imports in all files so that they are not forgotten during later edits
+when someone starts using such a feature.
There are other `from __future__` import statements. Use them as you see fit. We
do not include `unicode_literals` in our recommendations as it is not a clear
@@ -1135,15 +1432,20 @@ win due to implicit default codec conversion consequences it introduces in many
places within Python 2.7. Most code is better off with explicit use of `b''` and
`u''` bytes and unicode string literals as necessary.
-##### The six, future, or past libraries.
+##### The six, future, or past libraries
When your project needs to actively support use under both Python 2 and 3, use
-of these libraries is encouraged as you see fit. They exist to make your code
-cleaner and life easier.
+the [six](https://pypi.org/project/six/),
+[future](https://pypi.org/project/future/), and
+[past](https://pypi.org/project/past/) libraries as you see fit. They exist to
+make your code cleaner and life easier.
<a name="s2.21-typed-code"></a>
+<a name="221-type-annotated-code"></a>
<a name="typed-code"></a>
-### 2.21 Type Annotated Code
+
+<a id="typed-code"></a>
+### 2.21 Type Annotated Code
You can annotate Python 3 code with type hints according to
[PEP-484](https://www.python.org/dev/peps/pep-0484/), and type-check the code at
@@ -1158,7 +1460,10 @@ modules.
<a id="s2.21.1-definition"></a>
-#### 2.21.1 Definition
+<a id="2211-definition"></a>
+
+<a id="typed-code-definition"></a>
+#### 2.21.1 Definition
Type annotations (or "type hints") are for function or method arguments and
return values:
@@ -1174,42 +1479,64 @@ a = SomeFunc() # type: SomeType
```
<a id="s2.21.2-pros"></a>
-#### 2.21.2 Pros
+<a id="2212-pros"></a>
+
+<a id="typed-code-pros"></a>
+#### 2.21.2 Pros
Type annotations improve the readability and maintainability of your code. The
type checker will convert many runtime errors to build-time errors, and reduce
your ability to use [Power Features](#power-features).
<a id="s2.21.3-cons"></a>
-#### 2.21.3 Cons
+<a id="2213-cons"></a>
+
+<a id="typed-code-cons"></a>
+#### 2.21.3 Cons
You will have to keep the type declarations up to date. You might see type errors that you think are valid code. Use of a [type checker](https://github.com/google/pytype)
may reduce your ability to use [Power Features](#power-features).
<a id="s2.21.4-decision"></a>
-#### 2.21.4 Decision
+<a id="2214-decision"></a>
-This highly depends on the complexity of your project. Give it a try.
+<a id="typed-code-decision"></a>
+#### 2.21.4 Decision
+You are strongly encouraged to enable Python type analysis when updating code.
+When adding or modifying public APIs, include type annotations and enable
+checking via pytype in the build system. As static analysis is relatively new to
+Python, we acknowledge that undesired side-effects (such as
+wrongly
+inferred types) may prevent adoption by some projects. In those situations,
+authors are encouraged to add a comment with a TODO or link to a bug describing
+the issue(s) currently preventing type annotation adoption in the BUILD file or
+in the code itself as appropriate.
<a id="s3-python-style-rules"></a>
+<a id="3-python-style-rules"></a>
+
<a id="python-style-rules"></a>
-## 3 Python Style Rules
+## 3 Python Style Rules
<a id="s3.1-semicolons"></a>
+<a id="31-semicolons"></a>
+
<a id="semicolons"></a>
-### 3.1 Semicolons
+### 3.1 Semicolons
Do not terminate your lines with semicolons, and do not use semicolons to put
two statements on the same line.
<a id="s3.2-line-length"></a>
+<a id="32-line-length"></a>
+
<a id="line-length"></a>
-### 3.2 Line length
+### 3.2 Line length
Maximum line length is *80 characters*.
-Exceptions:
+Explicit exceptions to the 80 character limit:
- Long import statements.
- URLs, pathnames, or long flags in comments.
@@ -1279,9 +1606,16 @@ Yes: with very_long_first_expression_function() as spam:
Make note of the indentation of the elements in the line continuation examples
above; see the [indentation](#s3.4-indentation) section for explanation.
+In all other cases where a line exceeds 80 characters, and the
+[yapf](https://github.com/google/yapf/)
+auto-formatter does not help bring the line below the limit, the line is allowed
+to exceed this maximum.
+
<a id="s3.3-parentheses"></a>
+<a id="33-parentheses"></a>
+
<a id="parentheses"></a>
-### 3.3 Parentheses
+### 3.3 Parentheses
Use parentheses sparingly.
@@ -1314,10 +1648,11 @@ No: if (x):
return (foo)
```
-
<a id="s3.4-indentation"></a>
+<a id="34-indentation"></a>
+
<a id="indentation"></a>
-### 3.4 Indentation
+### 3.4 Indentation
Indent your code blocks with *4 spaces*.
@@ -1378,9 +1713,11 @@ No: # Stuff on first line forbidden
```
<a id="s3.4.1-trailing_comma"></a>
+<a id="341-trailing_comma"></a>
<a id="trailing_comma"></a>
-### 3.4.1 Trailing commas in sequences of items?
+<a id="trailing-comma"></a>
+### 3.4.1 Trailing commas in sequences of items?
Trailing commas in sequences of items are recommended only when the closing
container token `]`, `)`, or `}` does not appear on the same line as the final
@@ -1408,8 +1745,10 @@ No: golomb4 = [
```
<a id="s3.5-blank-lines"></a>
+<a id="35-blank-lines"></a>
+
<a id="blank-lines"></a>
-### 3.5 Blank Lines
+### 3.5 Blank Lines
Two blank lines between top-level definitions, be they function or class
definitions. One blank line between method definitions and between the `class`
@@ -1417,8 +1756,10 @@ line and the first method. No blank line following a `def` line. Use single
blank lines as you judge appropriate within functions or methods.
<a id="s3.6-whitespace"></a>
+<a id="36-whitespace"></a>
+
<a id="whitespace"></a>
-### 3.6 Whitespace
+### 3.6 Whitespace
Follow standard typographic rules for the use of spaces around punctuation.
@@ -1467,6 +1808,8 @@ Yes: dict['key'] = list[index]
No: dict ['key'] = list [index]
```
+No trailing whitespace.
+
Surround binary operators with a single space on either side for assignment
(`=`), comparisons (`==, <, >, !=, <>, <=, >=, in, not in, is, is not`), and
Booleans (`and, or, not`). Use your better judgment for the insertion of spaces
@@ -1523,8 +1866,10 @@ No:
<a id="Python_Interpreter"></a>
<a id="s3.7-shebang-line"></a>
+<a id="37-shebang-line"></a>
+
<a id="shebang-line"></a>
-### 3.7 Shebang Line
+### 3.7 Shebang Line
Most `.py` files do not need to start with a `#!` line. Start the main file of a
program with
@@ -1536,15 +1881,20 @@ by Python when importing modules. It is only necessary on a file that will be
executed directly.
<a id="s3.8-comments"></a>
-<a id="comments"></a>
-### 3.8 Comments and Docstrings
+<a id="38-comments-and-docstrings"></a>
+
+<a id="documentation"></a>
+### 3.8 Comments and Docstrings
Be sure to use the right style for module, function, method docstrings and
inline comments.
<a id="s3.8.1-comments-in-doc-strings"></a>
+<a id="381-docstrings"></a>
<a id="comments-in-doc-strings"></a>
-#### 3.8.1 Docstrings
+
+<a id="docstrings"></a>
+#### 3.8.1 Docstrings
Python uses _docstrings_ to document code. A docstring is a string that is the
first statement in a package, module, class or function. These strings can be
@@ -1560,16 +1910,40 @@ the first quote of the first line. There are more formatting guidelines for
docstrings below.
<a id="s3.8.2-comments-in-modules"></a>
+<a id="382-modules"></a>
<a id="comments-in-modules"></a>
-#### 3.8.2 Modules
-Every file should contain license boilerplate. Choose the appropriate
-boilerplate for the license used by the project (for example, Apache 2.0, BSD,
-LGPL, GPL)
+<a id="module-docs"></a>
+#### 3.8.2 Modules
+
+Every file should contain license boilerplate.
+Choose the appropriate boilerplate for the license used by the project (for
+example, Apache 2.0, BSD, LGPL, GPL)
+
+Files should start with a docstring describing the contents and usage of the
+module.
+```python
+"""A one line summary of the module or program, terminated by a period.
+
+Leave one blank line. The rest of this docstring should contain an
+overall description of the module or program. Optionally, it may also
+contain a brief description of exported classes and functions and/or usage
+examples.
+
+ Typical usage example:
+
+ foo = ClassFoo()
+ bar = foo.FunctionBar()
+"""
+```
+
<a id="s3.8.3-functions-and-methods"></a>
+<a id="383-functions-and-methods"></a>
<a id="functions-and-methods"></a>
-#### 3.8.3 Functions and Methods
+
+<a id="function-docs"></a>
+#### 3.8.3 Functions and Methods
In this section, "function" means a method, function, or generator.
@@ -1580,11 +1954,13 @@ A function must have a docstring, unless it meets all of the following criteria:
- obvious
A docstring should give enough information to write a call to the function
-without reading the function's code. The docstring should be descriptive
-(`"""Fetches rows from a Bigtable."""`) rather than imperative
-(`"""Fetch rows from a Bigtable."""`). A docstring should describe the
-function's calling syntax and its semantics, not its implementation. For tricky
-code, comments alongside the code are more appropriate than using docstrings.
+without reading the function's code. The docstring should be descriptive-style
+(`"""Fetches rows from a Bigtable."""`) rather than imperative-style (`"""Fetch
+rows from a Bigtable."""`), except for `@property` data descriptors, which
+should use the <a href="#384-classes">same style as attributes</a>. A docstring
+should describe the function's calling syntax and its semantics, not its
+implementation. For tricky code, comments alongside the code are more
+appropriate than using docstrings.
A method that overrides a method from a base class may have a simple docstring
sending the reader to its overridden method's docstring, such as `"""See base
@@ -1596,31 +1972,38 @@ side effects), a docstring with at least those differences is required on the
overriding method.
Certain aspects of a function should be documented in special sections, listed
-below. Each section begins with a heading line, which ends with a colon.
-Sections should be indented two spaces, except for the heading.
+below. Each section begins with a heading line, which ends with a colon. All
+sections other than the heading should maintain a hanging indent of two or four
+spaces (be consistent within a file). These sections can be omitted in cases
+where the function's name and signature are informative enough that it can be
+aptly described using a one-line docstring.
<a id="doc-function-args"></a>
[*Args:*](#doc-function-args)
: List each parameter by name. A description should follow the name, and be
-separated by a colon and a space. If the description is too long to fit on a
-single 80-character line, use a hanging indent of 2 or 4 spaces (be
-consistent with the rest of the file).<br>
-The description should include required type(s) if the code does not contain
-a corresponding type annotation.<br>
-If a function accepts `*foo` (variable length argument lists) and/or `**bar`
-(arbitrary keyword arguments), they should be listed as `*foo` and `**bar`.
+ separated by a colon and a space. If the description is too long to fit on a
+ single 80-character line, use a hanging indent of 2 or 4 spaces (be
+ consistent with the rest of the file).
+
+ The description should include required type(s) if the code does not contain
+ a corresponding type annotation. If a function accepts `*foo` (variable
+ length argument lists) and/or `**bar` (arbitrary keyword arguments), they
+ should be listed as `*foo` and `**bar`.
<a id="doc-function-returns"></a>
[*Returns:* (or *Yields:* for generators)](#doc-function-returns)
: Describe the type and semantics of the return value. If the function only
-returns None, this section is not required. It may also be omitted if the
-docstring starts with Returns or Yields (e.g.
-`"""Returns row from Bigtable as a tuple of strings."""`) and the opening
-sentence is sufficient to describe return value.
+ returns None, this section is not required. It may also be omitted if the
+ docstring starts with Returns or Yields (e.g. `"""Returns row from Bigtable
+ as a tuple of strings."""`) and the opening sentence is sufficient to
+ describe return value.
<a id="doc-function-raises"></a>
[*Raises:*](#doc-function-raises)
-: List all exceptions that are relevant to the interface.
+: List all exceptions that are relevant to the interface. You should not
+ document exceptions that get raised if the API specified in the docstring is
+ violated (because this would paradoxically make behavior under violation of
+ the API part of the API).
```python
def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):
@@ -1655,8 +2038,11 @@ def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):
```
<a id="s3.8.4-comments-in-classes"></a>
+<a id="384-classes"></a>
<a id="comments-in-classes"></a>
-#### 3.8.4 Classes
+
+<a id="class-docs"></a>
+#### 3.8.4 Classes
Classes should have a docstring below the class definition describing the class.
If your class has public attributes, they should be documented here in an
@@ -1686,7 +2072,10 @@ class SampleClass(object):
<a id="comments-in-block-and-inline"></a>
<a id="s3.8.5-comments-in-block-and-inline"></a>
-#### 3.8.5 Block and Inline Comments
+<a id="385-block-and-inline-comments"></a>
+
+<a id="comments"></a>
+#### 3.8.5 Block and Inline Comments
The final place to have comments is in tricky parts of the code. If you're going
to have to explain it at the next [code
@@ -1703,8 +2092,9 @@ commence. Non-obvious ones get comments at the end of the line.
if i & (i-1) == 0: # True if i is 0 or a power of 2.
```
-To improve legibility, these comments should be at least 2 spaces away from the
-code.
+To improve legibility, these comments should start at least 2 spaces away from
+the code with the comment character `#`, followed by at least one space before
+the text of the comment itself.
On the other hand, never describe the code. Assume the person reading the code
knows Python (though not what you're trying to do) better than you do.
@@ -1715,9 +2105,15 @@ knows Python (though not what you're trying to do) better than you do.
```
<!-- The next section is copied from the C++ style guide. -->
+
<a id="s3.8.6-punctuation-spelling-and-grammar"></a>
-<a id="punctuation-spelling-and-grammar"></a>
-#### 3.8.6 Punctuation, Spelling and Grammar
+<a id="386-punctuation-spelling-and-grammar"></a>
+<a id="spelling"></a>
+<a id="punctuation"></a>
+<a id="grammar"></a>
+
+<a id="punctuation-spelling-grammar"></a>
+#### 3.8.6 Punctuation, Spelling and Grammar
Pay attention to punctuation, spelling, and grammar; it is easier to read
well-written comments than badly written ones.
@@ -1733,8 +2129,10 @@ source code maintain a high level of clarity and readability. Proper
punctuation, spelling, and grammar help with that goal.
<a id="s3.9-classes"></a>
+<a id="39-classes"></a>
+
<a id="classes"></a>
-### 3.9 Classes
+### 3.9 Classes
If a class inherits from no other base classes, explicitly inherit from
`object`. This also applies to nested classes.
@@ -1773,12 +2171,14 @@ including `__new__`, `__init__`, `__delattr__`, `__getattribute__`,
`__setattr__`, `__hash__`, `__repr__`, and `__str__`.
<a id="s3.10-strings"></a>
+<a id="310-strings"></a>
+
<a id="strings"></a>
-### 3.10 Strings
+### 3.10 Strings
Use the `format` method or the `%` operator for formatting strings, even when
-the parameters are all strings. Use your best judgement to decide between `+`
-and `%` (or `format`) though.
+the parameters are all strings. Use your best judgment to decide between `+` and
+`%` (or `format`) though.
```python
Yes: x = a + b
@@ -1819,8 +2219,7 @@ No: employee_table = '<table>'
Be consistent with your choice of string quote character within a file. Pick `'`
or `"` and stick with it. It is okay to use the other quote character on a
-string to avoid the need to `\\` escape within the string. `gpylint` enforces
-this.
+string to avoid the need to `\\ ` escape within the string.
```python
Yes:
@@ -1838,26 +2237,54 @@ No:
Prefer `"""` for multi-line strings rather than `'''`. Projects may choose to
use `'''` for all non-docstring multi-line strings if and only if they also use
-`'` for regular strings. Docstrings must use `"""` regardless. Note that it is
-often cleaner to use implicit line joining since multi-line strings do not flow
-with the indentation of the rest of the program:
+`'` for regular strings. Docstrings must use `"""` regardless.
+
+Multi-line strings do not flow with the indentation of the rest of the program.
+If you need to avoid embedding extra space in the string, use either
+concatenated single-line strings or a multi-line string with
+[`textwrap.dedent()`](https://docs.python.org/3/library/textwrap.html#textwrap.dedent)
+to remove the initial space on each line:
+
+```python
+ No:
+ long_string = """This is pretty ugly.
+Don't do this.
+"""
+```
```python
Yes:
- print("This is much nicer.\n"
- "Do it this way.\n")
+ long_string = """This is fine if your use case can accept
+ extraneous leading spaces."""
```
```python
- No:
- print("""This is pretty ugly.
-Don't do this.
-""")
+ Yes:
+ long_string = ("And this is fine if you can not accept\n" +
+ "extraneous leading spaces.")
+```
+
+```python
+ Yes:
+ long_string = ("And this too is fine if you can not accept\n"
+ "extraneous leading spaces.")
+```
+
+```python
+ Yes:
+ import textwrap
+
+ long_string = textwrap.dedent("""\
+ This is also fine, because textwrap.dedent()
+ will collapse common leading spaces in each line.""")
```
<a id="s3.11-files-and-sockets"></a>
+<a id="311-files-and-sockets"></a>
<a id="files-and-sockets"></a>
-### 3.11 Files and Sockets
+
+<a id="files"></a>
+### 3.11 Files and Sockets
Explicitly close files and sockets when done with them.
@@ -1906,8 +2333,10 @@ with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page:
```
<a id="s3.12-todo-comments"></a>
-<a id="todo-comments"></a>
-### 3.12 TODO Comments
+<a id="312-todo-comments"></a>
+
+<a id="todo"></a>
+### 3.12 TODO Comments
Use `TODO` comments for code that is temporary, a short-term solution, or
good-enough but not perfect.
@@ -1933,8 +2362,10 @@ either include a very specific date ("Fix by November 2009") or a very specific
event ("Remove this code when all clients can handle XML responses.").
<a id="s3.13-imports-formatting"></a>
+<a id="313-imports-formatting"></a>
+
<a id="imports-formatting"></a>
-### 3.13 Imports formatting
+### 3.13 Imports formatting
Imports should be on separate lines.
@@ -1954,21 +2385,31 @@ Imports are always put at the top of the file, just after any module comments
and docstrings and before module globals and constants. Imports should be
grouped from most generic to least generic:
-1. Python standard library imports. For example:
+1. Python future import statements. For example:
+
+ ```python
+ from __future__ import absolute_import
+ from __future__ import division
+ from __future__ import print_function
+ ```
+
+ See [above](#from-future-imports) for more information about those.
+
+2. Python standard library imports. For example:
```python
import sys
```
-2. [third-party](https://pypi.org/)
- module or package imports. For example:
+3. [third-party](https://pypi.org/) module
+ or package imports. For example:
```python
import tensorflow as tf
```
-3. Code repository
+4. Code repository
sub-package imports. For example:
@@ -1976,7 +2417,7 @@ grouped from most generic to least generic:
from otherproject.ai import mind
```
-4. **Deprecated:** application-specific imports that are part of the same
+5. **Deprecated:** application-specific imports that are part of the same
top level
sub-package as this file. For example:
@@ -1986,9 +2427,9 @@ grouped from most generic to least generic:
```
You may find older Google Python Style code doing this, but it is no longer
- required. **New code is encouraged not to bother with this.** Simply
- treat application-specific sub-package imports the same as other
- sub-package imports.
+ required. **New code is encouraged not to bother with this.** Simply treat
+ application-specific sub-package imports the same as other sub-package
+ imports.
Within each grouping, imports should be sorted lexicographically, ignoring case,
@@ -2020,8 +2461,10 @@ from otherproject.ai import soul
<a id="s3.14-statements"></a>
+<a id="314-statements"></a>
+
<a id="statements"></a>
-### 3.14 Statements
+### 3.14 Statements
Generally only one statement per line.
@@ -2051,8 +2494,11 @@ No:
```
<a id="s3.15-access-control"></a>
+<a id="315-access-control"></a>
<a id="access-control"></a>
-### 3.15 Access Control
+
+<a id="accessors"></a>
+### 3.15 Accessors
If an accessor function would be trivial, you should use public variables
instead of accessor functions to avoid the extra cost of function calls in
@@ -2068,20 +2514,15 @@ access the variable by the old method should break visibly so they are made
aware of the change in complexity.
<a id="s3.16-naming"></a>
+<a id="316-naming"></a>
+
<a id="naming"></a>
-### 3.16 Naming
-
-`module_name`,
-`package_name`,
-`ClassName`,
-`method_name`,
-`ExceptionName`,
-`function_name`,
-`GLOBAL_CONSTANT_NAME`,
-`global_var_name`,
-`instance_var_name`,
-`function_parameter_name`,
-`local_var_name`.
+### 3.16 Naming
+
+`module_name`, `package_name`, `ClassName`, `method_name`, `ExceptionName`,
+`function_name`, `GLOBAL_CONSTANT_NAME`, `global_var_name`, `instance_var_name`,
+`function_parameter_name`, `local_var_name`.
+
Function names, variable names, and filenames should be descriptive; eschew
abbreviation. In particular, do not use abbreviations that are ambiguous or
@@ -2091,8 +2532,10 @@ letters within a word.
Always use a `.py` filename extension. Never use dashes.
<a id="s3.16.1-names-to-avoid"></a>
+<a id="3161-names-to-avoid"></a>
+
<a id="names-to-avoid"></a>
-#### 3.16.1 Names to Avoid
+#### 3.16.1 Names to Avoid
- single character names except for counters or iterators. You may use "e" as
an exception identifier in try/except statements.
@@ -2100,8 +2543,10 @@ Always use a `.py` filename extension. Never use dashes.
- `__double_leading_and_trailing_underscore__` names (reserved by Python)
<a id="s3.16.2-naming-conventions"></a>
+<a id="3162-naming-convention"></a>
+
<a id="naming-conventions"></a>
-#### 3.16.2 Naming Convention
+#### 3.16.2 Naming Conventions
- "Internal" means internal to a module, or protected or private within a
class.
@@ -2130,8 +2575,10 @@ Always use a `.py` filename extension. Never use dashes.
test methods.
<a id="s3.16.3-file-naming"></a>
+<a id="3163-file-naming"></a>
+
<a id="file-naming"></a>
-#### 3.16.3 File Naming
+#### 3.16.3 File Naming
Python filenames must have a `.py` extension and must not contain dashes (`-`).
This allows them to be imported and unittested. If you want an executable to be
@@ -2139,8 +2586,10 @@ accessible without the extension, use a symbolic link or a simple bash wrapper
containing `exec "$0.py" "$@"`.
<a id="s3.16.4-guidelines-derived-from-guidos-recommendations"></a>
+<a id="3164-guidelines-derived-from-guidos-recommendations"></a>
+
<a id="guidelines-derived-from-guidos-recommendations"></a>
-#### 3.16.4 Guidelines derived from Guido's Recommendations
+#### 3.16.4 Guidelines derived from Guido's Recommendations
<table rules="all" border="1" summary="Guidelines from Guido's Recommendations"
cellspacing="2" cellpadding="2">
@@ -2226,8 +2675,10 @@ unittests. Lint warnings take care of invalid access to protected members.
<a id="s3.17-main"></a>
+<a id="317-main"></a>
+
<a id="main"></a>
-### 3.17 Main
+### 3.17 Main
Even a file meant to be used as an executable should be importable and a mere
import should not have the side effect of executing the program's main
@@ -2250,8 +2701,10 @@ careful not to call functions, create objects, or perform other operations that
should not be executed when the file is being `pydoc`ed.
<a id="s3.18-function-length"></a>
+<a id="318-function-length"></a>
+
<a id="function-length"></a>
-### 3.18 Function length
+### 3.18 Function length
Prefer small and focused functions.
@@ -2271,12 +2724,16 @@ you want to use a piece of it in several different contexts, consider breaking
up the function into smaller and more manageable pieces.
<a id="s3.19-type-annotations"></a>
+<a id="319-type-annotations"></a>
+
<a id="type-annotations"></a>
-### 3.19 Type Annotations
+### 3.19 Type Annotations
-<a id="typing-general"></a>
<a id="s3.19.1-general"></a>
-#### 3.19.1 General Rules
+<a id="3191-general-rules"></a>
+
+<a id="typing-general"></a>
+#### 3.19.1 General Rules
* Familiarize yourself with [PEP-484](https://www.python.org/dev/peps/pep-0484/).
* In methods, only annotate `self`, or `cls` if it is necessary for proper type
@@ -2295,8 +2752,10 @@ up the function into smaller and more manageable pieces.
<a id="s3.19.2-line-breaking"></a>
+<a id="3192-line-breaking"></a>
+
<a id="typing-line-breaking"></a>
-#### 3.19.2 Line Breaking
+#### 3.19.2 Line Breaking
Try to follow the existing [indentation](#indentation) rules.
@@ -2335,7 +2794,7 @@ closing parenthesis with the def.
```python
Yes:
def my_method(
- self, **kw_args: Optional[MyLongType]
+ self, other_arg: Optional[MyLongType]
) -> Dict[OtherLongType, MyLongType]:
...
```
@@ -2346,7 +2805,7 @@ with the opening one, but this is less readable.
```python
No:
def my_method(self,
- **kw_args: Optional[MyLongType]
+ other_arg: Optional[MyLongType]
) -> Dict[OtherLongType, MyLongType]:
...
```
@@ -2387,8 +2846,10 @@ def my_function(
```
<a id="s3.19.3-forward-declarations"></a>
-<a id="typing-forward-declarations"></a>
-#### 3.19.3 Forward Declarations
+<a id="3193-forward-declarations"></a>
+
+<a id="forward-declarations"></a>
+#### 3.19.3 Forward Declarations
If you need to use a class name from the same module that is not yet defined --
for example, if you need the class inside the class declaration, or if you use a
@@ -2402,8 +2863,10 @@ class MyClass(object):
```
<a id="s3.19.4-default-values"></a>
+<a id="3194-default-values"></a>
+
<a id="typing-default-values"></a>
-#### 3.19.4 Default Values
+#### 3.19.4 Default Values
As per
[PEP-008](https://www.python.org/dev/peps/pep-0008/#other-recommendations), use
@@ -2422,8 +2885,10 @@ def func(a:int=0) -> int:
```
<a id="s3.19.5-none-type"></a>
+<a id="3195-nonetype"></a>
+
<a id="none-type"></a>
-#### 3.19.5 NoneType
+#### 3.19.5 NoneType
In the Python type system, `NoneType` is a "first class" type, and for typing
purposes, `None` is an alias for `NoneType`. If an argument can be `None`, it
@@ -2451,14 +2916,18 @@ def implicit_optional(a: Text = None) -> Text:
```
<a id="s3.19.6-aliases"></a>
+<a id="3196-type-aliases"></a>
<a id="typing-aliases"></a>
-#### 3.19.6 Type Aliases
+
+<a id="type-aliases"></a>
+#### 3.19.6 Type Aliases
You can declare aliases of complex types. The name of an alias should be
CapWorded. If the alias is used only in this module, it should be
\_Private.
-For example, if the name of module together with the type is too long:
+For example, if the name of the module together with the name of the type is too
+long:
```python
_ShortName = module_with_long_name.TypeWithLongName
@@ -2469,8 +2938,10 @@ Other examples are complex nested types and multiple return variables from a
function (as a tuple).
<a id="s3.19.7-ignore"></a>
+<a id="3197-ignoring-types"></a>
+
<a id="typing-ignore"></a>
-#### 3.19.7 Ignoring Types
+#### 3.19.7 Ignoring Types
You can disable type checking on a line with the special comment
`# type: ignore`.
@@ -2482,18 +2953,35 @@ You can disable type checking on a line with the special comment
```
<a id="s3.19.8-comments"></a>
-<a id="typing-comments"></a>
-#### 3.19.8 Typing internal variables
+<a id="3198-typing-internal-variables"></a>
+
+<a id="typing-variables"></a>
+#### 3.19.8 Typing Variables
If an internal variable has a type that is hard or impossible to infer, you can
-supply it as a special comment:
+specify its type in a couple ways.
+
+<a id="type-comments"></a>
+[*Type Comments:*](#type-comments)
+: Use a `# type:` comment on the end of the line
+
+ ```python
+ a = SomeUndecoratedFunction() # type: Foo
+ ```
+
+[*Annotated Assignments*](#annotated-assignments)
+: Use a colon and type between the variable name and value, as with function
+ arguments.
+
+ ```python
+ a: Foo = SomeUndecoratedFunction()
+ ```
-```python
-a = SomeUndecoratedFunction() # type: Foo
-```
<a id="s3.19.9-tuples"></a>
+<a id="3199-tuples-vs-lists"></a>
+
<a id="typing-tuples"></a>
-#### 3.19.9 Tuples vs Lists
+#### 3.19.9 Tuples vs Lists
Unlike Lists, which can only have a single type, Tuples can have either a single
repeated type or a set number of elements with different types. The latter is
@@ -2506,8 +2994,11 @@ c = (1, "2", 3.5) # type: Tuple[int, Text, float]
```
<a id="s3.19.10-type-var"></a>
+<a id="31910-typevar"></a>
<a id="typing-type-var"></a>
-#### 3.19.10 TypeVar
+
+<a id="typevars"></a>
+#### 3.19.10 TypeVars
The Python type system has
[generics](https://www.python.org/dev/peps/pep-0484/#generics). The factory
@@ -2544,9 +3035,10 @@ def check_length(x: AnyStr) -> AnyStr:
```
<a id="s3.19.11-strings"></a>
-<a id="typing-strings"></a>
+<a id="31911-string-types"></a>
-#### 3.19.11 String types
+<a id="typing-strings"></a>
+#### 3.19.11 String types
The proper type for annotating strings depends on what versions of Python the
code is intended for.
@@ -2555,11 +3047,11 @@ For Python 3 only code, prefer to use `str`. `Text` is also acceptable. Be
consistent in using one or the other.
For Python 2 compatible code, use `Text`. In some rare cases, `str` may make
-sense; typically to aid compatiblity when the return types aren't the same
+sense; typically to aid compatibility when the return types aren't the same
between the two Python versions. Avoid using `unicode`: it doesn't exist in
Python 3.
-The reason this discreprency exists is because `str` means different things
+The reason this discrepancy exists is because `str` means different things
depending on the Python version.
```python
@@ -2607,8 +3099,10 @@ return type is the same as the argument type in the code above, use
Writing it like this will simplify the process of porting the code to Python 3.
<a id="s3.19.12-imports"></a>
+<a id="31912-imports-for-typing"></a>
+
<a id="typing-imports"></a>
-#### 3.19.12 Imports For Typing
+#### 3.19.12 Imports For Typing
For classes from the `typing` module, always import the class itself. You are
explicitly allowed to import multiple specific classes on one line from the
@@ -2629,8 +3123,10 @@ from typing import Any as AnyType
```
<a id="s3.19.13-conditional-imports"></a>
+<a id="31913-conditional-imports"></a>
+
<a id="typing-conditional-imports"></a>
-#### 3.19.13 Conditional Imports
+#### 3.19.13 Conditional Imports
Use conditional imports only in exceptional cases where the additional imports
needed for type checking must be avoided at runtime. This pattern is
@@ -2658,8 +3154,10 @@ def f(x: "sketch.Sketch"): ...
```
<a id="s3.19.14-circular-deps"></a>
+<a id="31914-circular-dependencies"></a>
+
<a id="typing-circular-deps"></a>
-#### 3.19.14 Circular Dependencies
+#### 3.19.14 Circular Dependencies
Circular dependencies that are caused by typing are code smells. Such code is a
good candidate for refactoring. Although technically it is possible to keep
@@ -2683,8 +3181,10 @@ def my_method(self, var: some_mod.SomeType) -> None:
<a id="typing-generics"></a>
<a id="s3.19.15-generics"></a>
+<a id="31915-generics"></a>
-#### 3.19.15 Generics
+<a id="generics"></a>
+#### 3.19.15 Generics
When annotating, prefer to specify type parameters for generic types; otherwise,
[the generics' parameters will be assumed to be `Any`](https://www.python.org/dev/peps/pep-0484/#the-any-type).
@@ -2719,7 +3219,10 @@ def get_names(employee_ids: List[T]) -> Dict[T, Text]:
```
-## 4 Parting Words
+<a id="4-parting-words"></a>
+
+<a id="consistency"></a>
+## 4 Parting Words
*BE CONSISTENT*.