aboutsummaryrefslogtreecommitdiff
path: root/pyguide.md
diff options
context:
space:
mode:
Diffstat (limited to 'pyguide.md')
-rw-r--r--pyguide.md3241
1 files changed, 3241 insertions, 0 deletions
diff --git a/pyguide.md b/pyguide.md
new file mode 100644
index 0000000..5d9938c
--- /dev/null
+++ b/pyguide.md
@@ -0,0 +1,3241 @@
+<!--
+AUTHORS:
+Prefer only GitHub-flavored Markdown in external text.
+See README.md for details.
+-->
+
+# Google Python Style Guide
+
+
+<a id="1-background"></a>
+
+<a id="background"></a>
+## 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.
+
+To help you format code correctly, we've created a [settings file for
+Vim](google_python_style.vim). For Emacs, the default settings should be fine.
+
+Many teams use the [yapf](https://github.com/google/yapf/)
+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
+
+<a id="s2.1-lint"></a>
+<a id="21-lint"></a>
+
+<a id="lint"></a>
+### 2.1 Lint
+
+Run `pylint` over your code.
+
+<a id="s2.1.1-definition"></a>
+<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
+languages like C and C++. Because of the dynamic nature of Python, some
+warnings may be incorrect; however, spurious warnings should be fairly
+infrequent.
+
+<a id="s2.1.2-pros"></a>
+<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>
+<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>
+<a id="214-decision"></a>
+
+<a id="lint-decision"></a>
+#### 2.1.4 Decision
+
+Make sure you run `pylint` on your code.
+
+
+Suppress warnings if they are inappropriate so that other issues are not hidden.
+To suppress warnings, you can set a line-level comment:
+
+```python
+dict = 'something awful' # Bad Idea... pylint: disable=redefined-builtin
+```
+
+`pylint` warnings are each identified by symbolic name (`empty-docstring`)
+Google-specific warnings start with `g-`.
+
+If the reason for the suppression is not clear from the symbolic name, add an
+explanation.
+
+Suppressing in this way has the advantage that we can easily search for
+suppressions and revisit them.
+
+You can get a list of `pylint` warnings by doing:
+
+```shell
+pylint --list-msgs
+```
+
+To get more information on a particular message, use:
+
+```shell
+pylint --help-msg=C6409
+```
+
+Prefer `pylint: disable` to the deprecated older form `pylint: disable-msg`.
+
+Unused argument warnings can be suppressed by deleting the variables at the
+beginning of the function. Always include a comment explaining why you are
+deleting it. "Unused." is sufficient. For example:
+
+```python
+def viking_cafe_order(spam, beans, eggs=None):
+ del beans, eggs # Unused by vikings.
+ return spam + spam + spam
+```
+
+Other common forms of suppressing this warning include using '`_`' as the
+identifier for the unused argument, prefixing the argument name with
+'`unused_`', or assigning them to '`_`'. These forms are allowed but no longer
+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
+
+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>
+<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>
+<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>
+<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>
+<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
+name with no prefix.
+* Use `from x import y as z` if two modules named `y` are to be imported or if
+`y` is an inconveniently long name.
+* Use `import y as z` only when `z` is a standard abbreviation (e.g., `np` for
+`numpy`).
+
+For example the module `sound.effects.echo` may be imported as follows:
+
+```python
+from sound.effects import echo
+...
+echo.EchoFilter(input, output, delay=0.7, atten=4)
+```
+
+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) 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
+
+Import each module using the full pathname location of the module.
+
+<a id="s2.3.1-pros"></a>
+<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>
+<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>
+<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.
+
+Imports should be as follows:
+
+Yes:
+
+```python
+# Reference absl.flags in code with the complete name (verbose).
+import absl.flags
+from doctor.who import jodie
+
+FLAGS = absl.flags.FLAGS
+```
+
+```python
+# Reference flags in code with just the module name (common).
+from absl import flags
+from doctor.who import jodie
+
+FLAGS = flags.FLAGS
+```
+
+No: _(assume this file lives in `doctor/who/` where `jodie.py` also exists)_
+
+```python
+# Unclear what module the author wanted and what will be imported. The actual
+# import behavior depends on external factors controlling sys.path.
+# Which possible jodie module did the author intend to import?
+import jodie
+```
+
+The directory the main binary is located in should not be assumed to be in
+`sys.path` despite that happening in some environments. This being the case,
+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
+
+Exceptions are allowed but must be used carefully.
+
+<a id="s2.4.1-definition"></a>
+<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>
+<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
+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>
+<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>
+<a id="244-decision"></a>
+
+<a id="exceptions-decision"></a>
+#### 2.4.4 Decision
+
+Exceptions must follow certain conditions:
+
+- Raise exceptions like this: `raise MyError('Error message')` or `raise
+ MyError()`. Do not use the two-argument form (`raise MyError, 'Error
+ message'`).
+
+- Make use of built-in exception classes when it makes sense. 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
+ Yes:
+ def connect_to_next_port(self, minimum):
+ """Connects to the next available port.
+
+ Args:
+ minimum: A port value greater or equal to 1024.
+
+ 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:
+ raise ConnectionError('Could not connect to service on %d or higher.' % (minimum,))
+ assert port >= minimum, 'Unexpected port %d when minimum was %d.' % (port, minimum)
+ return port
+ ```
+
+ ```python
+ No:
+ def connect_to_next_port(self, minimum):
+ """Connects to the next available port.
+
+ Args:
+ minimum: A port value greater or equal to 1024.
+
+ Returns:
+ The new minimum port.
+ """
+ assert minimum >= 1024, 'Minimum port must be at least 1024.'
+ port = self._find_next_open_port(minimum)
+ assert port is not None
+ return port
+ ```
+
+- Libraries or packages may define their own exceptions. When doing so they
+ must inherit from an existing exception class. Exception names should end in
+ `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
+ - 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
+ code that you didn't expect to raise an exception. In those cases, the
+ `try`/`except` block hides a real error.
+
+- Use the `finally` clause to execute code whether or not an exception is
+ raised in the `try` block. This is often useful for cleanup, i.e., closing a
+ file.
+
+- When capturing an exception, use `as` rather than a comma. For example:
+
+
+ ```python
+ try:
+ raise Error()
+ except Error as error:
+ pass
+ ```
+
+<a id="s2.5-global-variables"></a>
+<a id="25-global-variables"></a>
+
+<a id="global-variables"></a>
+### 2.5 Global variables
+
+Avoid global variables.
+
+<a id="s2.5.1-definition"></a>
+<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>
+<a id="252-pros"></a>
+
+<a id="global-variables-pros"></a>
+#### 2.5.2 Pros
+
+Occasionally useful.
+
+<a id="s2.5.3-cons"></a>
+<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>
+<a id="254-decision"></a>
+
+<a id="global-variables-decision"></a>
+#### 2.5.4 Decision
+
+Avoid global variables.
+
+While they are technically variables, module-level constants are permitted and
+encouraged. For example: `MAX_HOLY_HANDGRENADE_COUNT = 3`. Constants must be
+named using all caps with underscores. See [Naming](#s3.16-naming) below.
+
+If needed, globals should be declared at the module level and made internal to
+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="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>
+<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>
+<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
+[ADT](http://www.google.com/url?sa=D&q=http://en.wikipedia.org/wiki/Abstract_data_type)-y.
+Commonly used for implementing decorators.
+
+<a id="s2.6.3-cons"></a>
+<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>
+<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="s2.7-list_comprehensions"></a>
+<a id="27-list_comprehensions"></a>
+<a id="list_comprehensions"></a>
+<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>
+<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>
+<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>
+<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>
+<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
+expressions are not permitted. Use loops instead when things get more
+complicated.
+
+```python
+Yes:
+ result = [mapping_expr for value in iterable if filter_expr]
+
+ result = [{'key': value} for value in iterable
+ if a_long_filter_expression(value)]
+
+ result = [complicated_transform(x)
+ for x in iterable if predicate(x)]
+
+ descriptive_name = [
+ transform({'key': key, 'value': value}, color='black')
+ for key, value in generate_iterable(some_input)
+ if complicated_condition_is_met(key, value)
+ ]
+
+ result = []
+ for x in range(10):
+ for y in range(5):
+ if x * y > 10:
+ result.append((x, y))
+
+ return {x: complicated_transform(x)
+ for x in long_generator_function(parameter)
+ if x is not None}
+
+ squares_generator = (x**2 for x in range(10))
+
+ unique_names = {user.name for user in users if user is not None}
+
+ eat(jelly_bean for jelly_bean in jelly_beans
+ if jelly_bean.color == 'black')
+```
+
+```python
+No:
+ result = [complicated_transform(
+ x, some_argument=x+1)
+ for x in iterable if predicate(x)]
+
+ result = [(x, y) for x in range(10) for y in range(5) if x * y > 10]
+
+ return ((x, y, z)
+ for x in xrange(5)
+ for y in xrange(5)
+ if x != y
+ for z in xrange(5)
+ if y != z)
+```
+
+<a id="s2.8-default-iterators-and-operators"></a>
+
+<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>
+<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>
+<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>
+<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>
+<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
+these methods to methods that return lists, except that you should not mutate a
+container while iterating over it. Never use Python 2 specific iteration
+methods such as `dict.iter*()` unless necessary.
+
+```python
+Yes: for key in adict: ...
+ if key not in adict: ...
+ if obj in alist: ...
+ for line in afile: ...
+ for k, v in adict.items(): ...
+ for k, v in six.iteritems(adict): ...
+```
+
+```python
+No: for key in adict.keys(): ...
+ if not adict.has_key(key): ...
+ for line in afile.readlines(): ...
+ for k, v in dict.iteritems(): ...
+```
+
+<a id="s2.9-generators"></a>
+<a id="29-generators"></a>
+
+<a id="generators"></a>
+### 2.9 Generators
+
+Use generators as needed.
+
+<a id="s2.9.1-definition"></a>
+<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>
+<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>
+<a id="293-cons"></a>
+
+<a id="generators-cons"></a>
+#### 2.9.3 Cons
+
+None.
+
+<a id="s2.9.4-decision"></a>
+<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="210-lambda-functions"></a>
+
+<a id="lambdas"></a>
+### 2.10 Lambda Functions
+
+Okay for one-liners.
+
+<a id="s2.10.1-definition"></a>
+<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>
+<a id="2102-pros"></a>
+
+<a id="lambdas-pros"></a>
+#### 2.10.2 Pros
+
+Convenient.
+
+<a id="s2.10.3-cons"></a>
+<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>
+<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
+function](#lexical-scoping).
+
+For common operations like multiplication, use the functions from the `operator`
+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
+
+Okay for simple cases.
+
+<a id="s2.11.1-definition"></a>
+<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>
+<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>
+<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>
+<a id="2114-decision"></a>
+
+<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="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>
+<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,
+`b` is set to 0. If it is called with two arguments, `b` has the value of the
+second argument.
+
+<a id="s2.12.2-pros"></a>
+<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 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>
+<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
+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>
+<a id="2124-decision"></a>
+
+<a id="default-arguments-decision"></a>
+#### 2.12.4 Decision
+
+Okay to use with the following caveat:
+
+Do not use mutable objects as default values in the function or method
+definition.
+
+```python
+Yes: def foo(a, b=None):
+ if b is None:
+ b = []
+Yes: def foo(a, b: Optional[Sequence] = None):
+ if b is None:
+ b = []
+Yes: def foo(a, b: Sequence = ()): # Empty tuple OK since tuples are immutable
+ ...
+```
+
+```python
+No: def foo(a, b=[]):
+ ...
+No: def foo(a, b=time.time()): # The time the module was loaded???
+ ...
+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
+
+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>
+<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>
+<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
+way to maintain the interface of a class. In terms of performance, allowing
+properties bypasses needing trivial accessor methods when a direct variable
+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>
+<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>
+<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
+created with the `@property` [decorator](#s2.17-function-and-method-decorators).
+
+Inheritance with properties can be non-obvious if the property itself is not
+overridden. Thus one must make sure that accessor methods are called indirectly
+to ensure methods overridden in subclasses are called by the property (using the
+Template Method DP).
+
+```python
+Yes: import math
+
+ class Square(object):
+ """A square with two properties: a writable area and a read-only perimeter.
+
+ To use:
+ >>> sq = Square(3)
+ >>> sq.area
+ 9
+ >>> sq.perimeter
+ 12
+ >>> sq.area = 16
+ >>> sq.side
+ 4
+ >>> sq.perimeter
+ 16
+ """
+
+ def __init__(self, side):
+ self.side = side
+
+ @property
+ def area(self):
+ """Area of the square."""
+ return self._get_area()
+
+ @area.setter
+ def area(self, area):
+ return self._set_area(area)
+
+ def _get_area(self):
+ """Indirect accessor to calculate the 'area' property."""
+ return self.side ** 2
+
+ def _set_area(self, area):
+ """Indirect setter to set the 'area' property."""
+ self.side = math.sqrt(area)
+
+ @property
+ def perimeter(self):
+ return self.side * 4
+```
+
+<a id="s2.14-truefalse-evaluations"></a>
+<a id="214-truefalse-evaluations"></a>
+
+<a id="truefalse-evaluations"></a>
+### 2.14 True/False Evaluations
+
+Use the "implicit" false if at all possible.
+
+<a id="s2.14.1-definition"></a>
+<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>
+<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>
+<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>
+<a id="2144-decision"></a>
+
+<a id="truefalse-evaluations-decision"></a>
+#### 2.14.4 Decision
+
+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:
+
+- 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
+ expressions, such as `if not x and x is not None:`.
+
+- For sequences (strings, lists, tuples), use the fact that empty sequences
+ are false, so `if seq:` and `if not seq:` are preferable to `if len(seq):`
+ and `if not len(seq):` respectively.
+
+- When handling integers, implicit false may involve more risk than benefit
+ (i.e., accidentally handling `None` as 0). You may compare a value which is
+ known to be an integer (and is not the result of `len()`) against the
+ integer 0.
+
+ ```python
+ Yes: if not users:
+ print('no users')
+
+ if foo == 0:
+ self.handle_zero()
+
+ if i % 10 == 0:
+ self.handle_multiple_of_ten()
+
+ def f(x=None):
+ if x is None:
+ x = []
+ ```
+
+ ```python
+ No: if len(users) == 0:
+ print('no users')
+
+ if foo is not None and not foo:
+ self.handle_zero()
+
+ if not i % 10:
+ self.handle_multiple_of_ten()
+
+ def f(x=None):
+ x = x or []
+ ```
+
+- Note that `'0'` (i.e., `0` as string) evaluates to true.
+
+<a id="s2.15-deprecated-language-features"></a>
+<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
+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>
+<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>
+<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.
+
+```python
+Yes: words = foo.split(':')
+
+ [x[1] for x in my_list if x[2] == 5]
+
+ map(math.sqrt, data) # Ok. No inlined lambda expression.
+
+ fn(*args, **kwargs)
+```
+
+```python
+No: words = string.split(foo, ':')
+
+ map(lambda x: x[1], filter(lambda x: x[2] == 5, my_list))
+
+ apply(fn, args, kwargs)
+```
+
+<a id="s2.16-lexical-scoping"></a>
+<a id="216-lexical-scoping"></a>
+
+<a id="lexical-scoping"></a>
+### 2.16 Lexical Scoping
+
+Okay to use.
+
+<a id="s2.16.1-definition"></a>
+<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
+scoping, that is, based on the static program text. Any assignment to a name in
+a block will cause Python to treat all references to that name as a local
+variable, even if the use precedes the assignment. If a global declaration
+occurs, the name is treated as a global variable.
+
+An example of the use of this feature is:
+
+```python
+def get_adder(summand1):
+ """Returns a function that adds numbers to a given number."""
+ def adder(summand2):
+ return summand1 + summand2
+
+ return adder
+```
+
+<a id="s2.16.2-pros"></a>
+<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>
+<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/):
+
+```python
+i = 4
+def foo(x):
+ def bar():
+ print(i, end='')
+ # ...
+ # A bunch of code here
+ # ...
+ for i in x: # Ah, i *is* local to foo, so this is what bar sees
+ print(i, end='')
+ bar()
+```
+
+So `foo([1, 2, 3])` will print `1 2 3 3`, not `1 2 3
+4`.
+
+<a id="s2.16.4-decision"></a>
+<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>
+
+<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>
+<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)
+(a.k.a "the `@` notation"). One common decorator is `@property`, used for
+converting ordinary methods into dynamically computed attributes. However, the
+decorator syntax allows for user-defined decorators as well. Specifically, for
+some function `my_decorator`, this:
+
+```python
+class C(object):
+ @my_decorator
+ def method(self):
+ # method body ...
+```
+
+is equivalent to:
+
+
+```python
+class C(object):
+ def method(self):
+ # method body ...
+ method = my_decorator(method)
+```
+
+<a id="s2.17.2-pros"></a>
+<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>
+<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
+execute at import time. Failures in decorator code are pretty much impossible to
+recover from.
+
+<a id="s2.17.4-decision"></a>
+<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
+should clearly state that the function is a decorator. Write unit tests for
+decorators.
+
+Avoid external dependencies in the decorator itself (e.g. don't rely on files,
+sockets, database connections, etc.), since they might not be available when the
+decorator runs (at import time, perhaps from `pydoc` or other tools). A
+decorator that is called with valid parameters should (as much as possible) be
+guaranteed to succeed in all cases.
+
+Decorators are a special case of "top level code" - see [main](#s3.17-main) for
+more discussion.
+
+Never use `@staticmethod` unless forced to in order to integrate with an API
+defined in an existing library. Write a module level function instead.
+
+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
+
+Do not rely on the atomicity of built-in types.
+
+While Python's built-in data types such as dictionaries appear to have atomic
+operations, there are corner cases where they aren't atomic (e.g. if `__hash__`
+or `__eq__` are implemented as Python methods) and their atomicity should not be
+relied upon. Neither should you rely on atomic variable assignment (since this
+in turn depends on dictionaries).
+
+Use the Queue module's `Queue` data type as the preferred way to communicate
+data between threads. Otherwise, use the threading module and its locking
+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
+
+Avoid these features.
+
+<a id="s2.19.1-definition"></a>
+<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
+inheritance, object reparenting, import hacks, reflection (e.g. some uses of
+`getattr()`), modification of system internals, etc.
+
+<a id="s2.19.2-pros"></a>
+<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>
+<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
+features underneath. It doesn't seem that way at first (to the original author),
+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>
+<a id="2194-decision"></a>
+
+<a id="power-features-decision"></a>
+#### 2.19.4 Decision
+
+Avoid these features in your code.
+
+Standard library modules and classes that internally use these features are okay
+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
+
+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>
+<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
+more explicit about its intentions and thus better prepared for use under Python
+3 without modification.
+
+<a id="s2.20.2-pros"></a>
+<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>
+<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>
+<a id="2204-decision"></a>
+
+<a id="modern-python-decision"></a>
+#### 2.20.4 Decision
+
+##### from \_\_future\_\_ imports
+
+Use of `from __future__ import` statements is encouraged. All new code should
+contain the following and existing code should be updated to be compatible when
+possible:
+
+```python
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+```
+
+If you are not already familiar with those, read up on each here: [absolute
+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, 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
+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
+
+When your project needs to actively support use under both Python 2 and 3, use
+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>
+
+<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
+build time with a type checking tool like
+[pytype](https://github.com/google/pytype).
+
+
+Type annotations can be in the source or in a [stub pyi
+file](https://www.python.org/dev/peps/pep-0484/#stub-files). Whenever possible,
+annotations should be in the source. Use pyi files for third-party or extension
+modules.
+
+
+<a id="s2.21.1-definition"></a>
+<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:
+
+```python
+def func(a: int) -> List[int]:
+```
+
+You can also declare the type of a variable using a special comment:
+
+```python
+a = SomeFunc() # type: SomeType
+```
+
+<a id="s2.21.2-pros"></a>
+<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>
+<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>
+<a id="2214-decision"></a>
+
+<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
+
+<a id="s3.1-semicolons"></a>
+<a id="31-semicolons"></a>
+
+<a id="semicolons"></a>
+### 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
+
+Maximum line length is *80 characters*.
+
+Explicit exceptions to the 80 character limit:
+
+- Long import statements.
+- URLs, pathnames, or long flags in comments.
+- Long string module level constants not containing whitespace that would be
+ inconvenient to split across lines such as URLs or pathnames.
+- Pylint disable comments. (e.g.: `# pylint: disable=invalid-name`)
+
+Do not use backslash line continuation except for `with` statements requiring
+three or more context managers.
+
+Make use of Python's [implicit line joining inside parentheses, brackets and
+braces](http://docs.python.org/reference/lexical_analysis.html#implicit-line-joining).
+If necessary, you can add an extra pair of parentheses around an expression.
+
+```python
+Yes: foo_bar(self, width, height, color='black', design=None, x='foo',
+ emphasis=None, highlight=0)
+
+ if (width == 0 and height == 0 and
+ color == 'red' and emphasis == 'strong'):
+```
+
+When a literal string won't fit on a single line, use parentheses for implicit
+line joining.
+
+```python
+x = ('This will build a very long long '
+ 'long long long long long long string')
+```
+
+Within comments, put long URLs on their own line if necessary.
+
+```python
+Yes: # See details at
+ # http://www.example.com/us/developer/documentation/api/content/v2.0/csv_file_name_extension_full_specification.html
+```
+
+```python
+No: # See details at
+ # http://www.example.com/us/developer/documentation/api/content/\
+ # v2.0/csv_file_name_extension_full_specification.html
+```
+
+It is permissible to use backslash continuation when defining a `with` statement
+whose expressions span three or more lines. For two lines of expressions, use a
+nested `with` statement:
+
+```python
+Yes: with very_long_first_expression_function() as spam, \
+ very_long_second_expression_function() as beans, \
+ third_thing() as eggs:
+ place_order(eggs, beans, spam, beans)
+```
+
+```python
+No: with VeryLongFirstExpressionFunction() as spam, \
+ VeryLongSecondExpressionFunction() as beans:
+ PlaceOrder(eggs, beans, spam, beans)
+```
+
+```python
+Yes: with very_long_first_expression_function() as spam:
+ with very_long_second_expression_function() as beans:
+ place_order(beans, 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
+
+Use parentheses sparingly.
+
+It is fine, though not required, to use parentheses around tuples. Do not use
+them in return statements or conditional statements unless using parentheses for
+implied line continuation or to indicate a tuple.
+
+```python
+Yes: if foo:
+ bar()
+ while x:
+ x = bar()
+ if x and y:
+ bar()
+ if not x:
+ bar()
+ # For a 1 item tuple the ()s are more visually obvious than the comma.
+ onesie = (foo,)
+ return foo
+ return spam, beans
+ return (spam, beans)
+ for (x, y) in dict.items(): ...
+```
+
+```python
+No: if (x):
+ bar()
+ if not(x):
+ bar()
+ return (foo)
+```
+
+<a id="s3.4-indentation"></a>
+<a id="34-indentation"></a>
+
+<a id="indentation"></a>
+### 3.4 Indentation
+
+Indent your code blocks with *4 spaces*.
+
+Never use tabs or mix tabs and spaces. In cases of implied line continuation,
+you should align wrapped elements either vertically, as per the examples in the
+[line length](#s3.2-line-length) section; or using a hanging indent of 4 spaces,
+in which case there should be nothing after the open parenthesis or bracket on
+the first line.
+
+```python
+Yes: # Aligned with opening delimiter
+ foo = long_function_name(var_one, var_two,
+ var_three, var_four)
+ meal = (spam,
+ beans)
+
+ # Aligned with opening delimiter in a dictionary
+ foo = {
+ long_dictionary_key: value1 +
+ value2,
+ ...
+ }
+
+ # 4-space hanging indent; nothing on first line
+ foo = long_function_name(
+ var_one, var_two, var_three,
+ var_four)
+ meal = (
+ spam,
+ beans)
+
+ # 4-space hanging indent in a dictionary
+ foo = {
+ long_dictionary_key:
+ long_dictionary_value,
+ ...
+ }
+```
+
+```python
+No: # Stuff on first line forbidden
+ foo = long_function_name(var_one, var_two,
+ var_three, var_four)
+ meal = (spam,
+ beans)
+
+ # 2-space hanging indent forbidden
+ foo = long_function_name(
+ var_one, var_two, var_three,
+ var_four)
+
+ # No hanging indent in a dictionary
+ foo = {
+ long_dictionary_key:
+ long_dictionary_value,
+ ...
+ }
+```
+
+<a id="s3.4.1-trailing_comma"></a>
+<a id="341-trailing_comma"></a>
+<a id="trailing_comma"></a>
+
+<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
+element. The presence of a trailing comma is also used as a hint to our Python
+code auto-formatter [YAPF](https://pypi.org/project/yapf/) to direct it to auto-format the container
+of items to one item per line when the `,` after the final element is present.
+
+```python
+Yes: golomb3 = [0, 1, 3]
+Yes: golomb4 = [
+ 0,
+ 1,
+ 4,
+ 6,
+ ]
+```
+
+```python
+No: golomb4 = [
+ 0,
+ 1,
+ 4,
+ 6
+ ]
+```
+
+<a id="s3.5-blank-lines"></a>
+<a id="35-blank-lines"></a>
+
+<a id="blank-lines"></a>
+### 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`
+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
+
+Follow standard typographic rules for the use of spaces around punctuation.
+
+No whitespace inside parentheses, brackets or braces.
+
+```python
+Yes: spam(ham[1], {eggs: 2}, [])
+```
+
+```python
+No: spam( ham[ 1 ], { eggs: 2 }, [ ] )
+```
+
+No whitespace before a comma, semicolon, or colon. Do use whitespace after a
+comma, semicolon, or colon, except at the end of the line.
+
+```python
+Yes: if x == 4:
+ print(x, y)
+ x, y = y, x
+```
+
+```python
+No: if x == 4 :
+ print(x , y)
+ x , y = y , x
+```
+
+No whitespace before the open paren/bracket that starts an argument list,
+indexing or slicing.
+
+```python
+Yes: spam(1)
+```
+
+```python
+No: spam (1)
+```
+
+
+```python
+Yes: dict['key'] = list[index]
+```
+
+```python
+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
+around arithmetic operators (`+`, `-`, `*`, `/`, `//`, `%`, `**`, `@`).
+
+```python
+Yes: x == 1
+```
+
+```python
+No: x<1
+```
+
+Never use spaces around `=` when passing keyword arguments or defining a default
+parameter value, with one exception: [when a type annotation is
+present](#typing-default-values), _do_ use spaces around the `=` for the default
+parameter value.
+
+```python
+Yes: def complex(real, imag=0.0): return Magic(r=real, i=imag)
+Yes: def complex(real, imag: float = 0.0): return Magic(r=real, i=imag)
+```
+
+```python
+No: def complex(real, imag = 0.0): return Magic(r = real, i = imag)
+No: def complex(real, imag: float=0.0): return Magic(r = real, i = imag)
+```
+
+Don't use spaces to vertically align tokens on consecutive lines, since it
+becomes a maintenance burden (applies to `:`, `#`, `=`, etc.):
+
+```python
+Yes:
+ foo = 1000 # comment
+ long_name = 2 # comment that should not be aligned
+
+ dictionary = {
+ 'foo': 1,
+ 'long_name': 2,
+ }
+```
+
+```python
+No:
+ foo = 1000 # comment
+ long_name = 2 # comment that should not be aligned
+
+ dictionary = {
+ 'foo' : 1,
+ 'long_name': 2,
+ }
+```
+
+
+<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
+
+Most `.py` files do not need to start with a `#!` line. Start the main file of a
+program with
+`#!/usr/bin/python` with an optional single digit `2` or `3` suffix per
+[PEP-394](https://www.google.com/url?sa=D&q=http://www.python.org/dev/peps/pep-0394/).
+
+This line is used by the kernel to find the Python interpreter, but is ignored
+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="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>
+
+<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
+extracted automatically through the `__doc__` member of the object and are used
+by `pydoc`.
+(Try running `pydoc` on your module to see how it looks.) Always use the three
+double-quote `"""` format for docstrings (per [PEP
+257](https://www.google.com/url?sa=D&q=http://www.python.org/dev/peps/pep-0257/)).
+A docstring should be organized as a summary line (one physical line) terminated
+by a period, question mark, or exclamation point, followed by a blank line,
+followed by the rest of the docstring starting at the same cursor position as
+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>
+
+<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>
+
+<a id="function-docs"></a>
+#### 3.8.3 Functions and Methods
+
+In this section, "function" means a method, function, or generator.
+
+A function must have a docstring, unless it meets all of the following criteria:
+
+- not externally visible
+- very short
+- 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-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
+class."""`. The rationale is that there is no need to repeat in many places
+documentation that is already present in the base method's docstring. However,
+if the overriding method's behavior is substantially different from the
+overridden method, or details need to be provided (e.g., documenting additional
+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. 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).
+
+ 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.
+
+<a id="doc-function-raises"></a>
+[*Raises:*](#doc-function-raises)
+: 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):
+ """Fetches rows from a Bigtable.
+
+ Retrieves rows pertaining to the given keys from the Table instance
+ represented by big_table. Silly things may happen if
+ other_silly_variable is not None.
+
+ Args:
+ big_table: An open Bigtable Table instance.
+ keys: A sequence of strings representing the key of each table row
+ to fetch.
+ other_silly_variable: Another optional variable, that has a much
+ longer name than the other args, and which does nothing.
+
+ Returns:
+ A dict mapping keys to the corresponding table row data
+ fetched. Each row is represented as a tuple of strings. For
+ example:
+
+ {'Serak': ('Rigel VII', 'Preparer'),
+ 'Zim': ('Irk', 'Invader'),
+ 'Lrrr': ('Omicron Persei 8', 'Emperor')}
+
+ If a key from the keys argument is missing from the dictionary,
+ then that row was not found in the table.
+
+ Raises:
+ IOError: An error occurred accessing the bigtable.Table object.
+ """
+```
+
+<a id="s3.8.4-comments-in-classes"></a>
+<a id="384-classes"></a>
+<a id="comments-in-classes"></a>
+
+<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
+`Attributes` section and follow the same formatting as a
+[function's `Args`](#doc-function-args) section.
+
+```python
+class SampleClass(object):
+ """Summary of class here.
+
+ Longer class information....
+ Longer class information....
+
+ Attributes:
+ likes_spam: A boolean indicating if we like SPAM or not.
+ eggs: An integer count of the eggs we have laid.
+ """
+
+ def __init__(self, likes_spam=False):
+ """Inits SampleClass with blah."""
+ self.likes_spam = likes_spam
+ self.eggs = 0
+
+ def public_method(self):
+ """Performs operation blah."""
+```
+
+<a id="comments-in-block-and-inline"></a>
+<a id="s3.8.5-comments-in-block-and-inline"></a>
+<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
+review](http://en.wikipedia.org/wiki/Code_review), you should comment it
+now. Complicated operations get a few lines of comments before the operations
+commence. Non-obvious ones get comments at the end of the line.
+
+```python
+# We use a weighted dictionary search to find out where i is in
+# the array. We extrapolate position based on the largest num
+# in the array and the array size and then do binary search to
+# get the exact number.
+
+if i & (i-1) == 0: # True if i is 0 or a power of 2.
+```
+
+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.
+
+```python
+# BAD COMMENT: Now go through the b array and make sure whenever i occurs
+# the next element is i+1
+```
+
+<!-- The next section is copied from the C++ style guide. -->
+
+<a id="s3.8.6-punctuation-spelling-and-grammar"></a>
+<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.
+
+Comments should be as readable as narrative text, with proper capitalization and
+punctuation. In many cases, complete sentences are more readable than sentence
+fragments. Shorter comments, such as comments at the end of a line of code, can
+sometimes be less formal, but you should be consistent with your style.
+
+Although it can be frustrating to have a code reviewer point out that you are
+using a comma when you should be using a semicolon, it is very important that
+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
+
+If a class inherits from no other base classes, explicitly inherit from
+`object`. This also applies to nested classes.
+
+```python
+Yes: class SampleClass(object):
+ pass
+
+
+ class OuterClass(object):
+
+ class InnerClass(object):
+ pass
+
+
+ class ChildClass(ParentClass):
+ """Explicitly inherits from another class already."""
+
+```
+
+```python
+No: class SampleClass:
+ pass
+
+
+ class OuterClass:
+
+ class InnerClass:
+ pass
+```
+
+Inheriting from `object` is needed to make properties work properly in Python 2
+and can protect your code from potential incompatibility with Python 3. It also
+defines special methods that implement the default semantics of objects
+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
+
+Use the `format` method or the `%` operator for formatting strings, even when
+the parameters are all strings. Use your best judgment to decide between `+` and
+`%` (or `format`) though.
+
+```python
+Yes: x = a + b
+ x = '%s, %s!' % (imperative, expletive)
+ x = '{}, {}'.format(first, second)
+ x = 'name: %s; score: %d' % (name, n)
+ x = 'name: {}; score: {}'.format(name, n)
+ x = f'name: {name}; score: {n}' # Python 3.6+
+```
+
+```python
+No: x = '%s%s' % (a, b) # use + in this case
+ x = '{}{}'.format(a, b) # use + in this case
+ x = first + ', ' + second
+ x = 'name: ' + name + '; score: ' + str(n)
+```
+
+Avoid using the `+` and `+=` operators to accumulate a string within a loop.
+Since strings are immutable, this creates unnecessary temporary objects and
+results in quadratic rather than linear running time. Instead, add each
+substring to a list and `''.join` the list after the loop terminates (or, write
+each substring to a `io.BytesIO` buffer).
+
+```python
+Yes: items = ['<table>']
+ for last_name, first_name in employee_list:
+ items.append('<tr><td>%s, %s</td></tr>' % (last_name, first_name))
+ items.append('</table>')
+ employee_table = ''.join(items)
+```
+
+```python
+No: employee_table = '<table>'
+ for last_name, first_name in employee_list:
+ employee_table += '<tr><td>%s, %s</td></tr>' % (last_name, first_name)
+ 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.
+
+```python
+Yes:
+ Python('Why are you hiding your eyes?')
+ Gollum("I'm scared of lint errors.")
+ Narrator('"Good!" thought a happy Python reviewer.')
+```
+
+```python
+No:
+ Python("Why are you hiding your eyes?")
+ Gollum('The lint. It burns. It burns us.')
+ Gollum("Always the great lint. Watching. Watching.")
+```
+
+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.
+
+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:
+ long_string = """This is fine if your use case can accept
+ extraneous leading spaces."""
+```
+
+```python
+ 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>
+
+<a id="files"></a>
+### 3.11 Files and Sockets
+
+Explicitly close files and sockets when done with them.
+
+Leaving files, sockets or other file-like objects open unnecessarily has many
+downsides:
+
+- They may consume limited system resources, such as file descriptors. Code
+ that deals with many such objects may exhaust those resources unnecessarily
+ if they're not returned to the system promptly after use.
+- Holding files open may prevent other actions such as moving or deleting
+ them.
+- Files and sockets that are shared throughout a program may inadvertently be
+ read from or written to after logically being closed. If they are actually
+ closed, attempts to read or write from them will throw exceptions, making
+ the problem known sooner.
+
+Furthermore, while files and sockets are automatically closed when the file
+object is destructed, tying the lifetime of the file object to the state of the
+file is poor practice:
+
+- There are no guarantees as to when the runtime will actually run the file's
+ destructor. Different Python implementations use different memory management
+ techniques, such as delayed Garbage Collection, which may increase the
+ object's lifetime arbitrarily and indefinitely.
+- Unexpected references to the file, e.g. in globals or exception tracebacks,
+ may keep it around longer than intended.
+
+The preferred way to manage files is using the ["with"
+statement](http://docs.python.org/reference/compound_stmts.html#the-with-statement):
+
+```python
+with open("hello.txt") as hello_file:
+ for line in hello_file:
+ print(line)
+```
+
+For file-like objects that do not support the "with" statement, use
+`contextlib.closing()`:
+
+```python
+import contextlib
+
+with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page:
+ for line in front_page:
+ print(line)
+```
+
+<a id="s3.12-todo-comments"></a>
+<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.
+
+A `TODO` comment begins with the string `TODO` in all caps and a parenthesized
+name, e-mail address, or other identifier
+of the person or issue with the best context about the problem. This is followed
+by an explanation of what there is to do.
+
+The purpose is to have a consistent `TODO` format that can be searched to find
+out how to get more details. A `TODO` is not a commitment that the person
+referenced will fix the problem. Thus when you create a
+`TODO`, it is almost always your name
+that is given.
+
+```python
+# TODO(kl@gmail.com): Use a "*" here for string repetition.
+# TODO(Zeke) Change this to use relations.
+```
+
+If your `TODO` is of the form "At a future date do something" make sure that you
+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
+
+Imports should be on separate lines.
+
+E.g.:
+
+```python
+Yes: import os
+ import sys
+```
+
+```python
+No: import os, sys
+```
+
+
+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 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
+ ```
+
+3. [third-party](https://pypi.org/) module
+ or package imports. For example:
+
+
+ ```python
+ import tensorflow as tf
+ ```
+
+4. Code repository
+ sub-package imports. For example:
+
+
+ ```python
+ from otherproject.ai import mind
+ ```
+
+5. **Deprecated:** application-specific imports that are part of the same
+ top level
+ sub-package as this file. For example:
+
+
+ ```python
+ from myproject.backend.hgwells import time_machine
+ ```
+
+ 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.
+
+
+Within each grouping, imports should be sorted lexicographically, ignoring case,
+according to each module's full package path. Code may optionally place a blank
+line between import sections.
+
+```python
+import collections
+import queue
+import sys
+
+from absl import app
+from absl import flags
+import bs4
+import cryptography
+import tensorflow as tf
+
+from book.genres import scifi
+from myproject.backend.hgwells import time_machine
+from myproject.backend.state_machine import main_loop
+from otherproject.ai import body
+from otherproject.ai import mind
+from otherproject.ai import soul
+
+# Older style code may have these imports down here instead:
+#from myproject.backend.hgwells import time_machine
+#from myproject.backend.state_machine import main_loop
+```
+
+
+<a id="s3.14-statements"></a>
+<a id="314-statements"></a>
+
+<a id="statements"></a>
+### 3.14 Statements
+
+Generally only one statement per line.
+
+However, you may put the result of a test on the same line as the test only if
+the entire statement fits on one line. In particular, you can never do so with
+`try`/`except` since the `try` and `except` can't both fit on the same line, and
+you can only do so with an `if` if there is no `else`.
+
+```python
+Yes:
+
+ if foo: bar(foo)
+```
+
+```python
+No:
+
+ if foo: bar(foo)
+ else: baz(foo)
+
+ try: bar(foo)
+ except ValueError: baz(foo)
+
+ try:
+ bar(foo)
+ except ValueError: baz(foo)
+```
+
+<a id="s3.15-access-control"></a>
+<a id="315-access-control"></a>
+<a id="access-control"></a>
+
+<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
+Python. When more functionality is added you can use `property` to keep the
+syntax consistent.
+
+On the other hand, if access is more complex, or the cost of accessing the
+variable is significant, you should use function calls (following the
+[Naming](#s3.16-naming) guidelines) such as `get_foo()` and
+`set_foo()`. If the past behavior allowed access through a property, do not
+bind the new accessor functions to the property. Any code still attempting to
+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`.
+
+
+Function names, variable names, and filenames should be descriptive; eschew
+abbreviation. In particular, do not use abbreviations that are ambiguous or
+unfamiliar to readers outside your project, and do not abbreviate by deleting
+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
+
+- single character names except for counters or iterators. You may use "e" as
+ an exception identifier in try/except statements.
+- dashes (`-`) in any package/module name
+- `__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 Conventions
+
+- "Internal" means internal to a module, or protected or private within a
+ class.
+
+- Prepending a single underscore (`_`) has some support for protecting module
+ variables and functions (not included with `from module import *`). While
+ prepending a double underscore (`__` aka "dunder") to an instance variable
+ or method effectively makes the variable or method private to its class
+ (using name mangling) we discourage its use as it impacts readability and
+ testability and isn't *really* private.
+
+- Place related classes and top-level functions together in a
+ module.
+ Unlike Java, there is no need to limit yourself to one class per module.
+
+- Use CapWords for class names, but lower\_with\_under.py for module names.
+ Although there are some old modules named CapWords.py, this is now
+ discouraged because it's confusing when the module happens to be named after
+ a class. ("wait -- did I write `import StringIO` or `from StringIO import
+ StringIO`?")
+
+- Underscores may appear in *unittest* method names starting with `test` to
+ separate logical components of the name, even if those components use
+ CapWords. One possible pattern is `test<MethodUnderTest>_<state>`; for
+ example `testPop_EmptyStack` is okay. There is no One Correct Way to name
+ 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
+
+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
+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
+
+<table rules="all" border="1" summary="Guidelines from Guido's Recommendations"
+ cellspacing="2" cellpadding="2">
+
+ <tr>
+ <th>Type</th>
+ <th>Public</th>
+ <th>Internal</th>
+ </tr>
+
+ <tr>
+ <td>Packages</td>
+ <td><code>lower_with_under</code></td>
+ <td></td>
+ </tr>
+
+ <tr>
+ <td>Modules</td>
+ <td><code>lower_with_under</code></td>
+ <td><code>_lower_with_under</code></td>
+ </tr>
+
+ <tr>
+ <td>Classes</td>
+ <td><code>CapWords</code></td>
+ <td><code>_CapWords</code></td>
+ </tr>
+
+ <tr>
+ <td>Exceptions</td>
+ <td><code>CapWords</code></td>
+ <td></td>
+ </tr>
+
+ <tr>
+ <td>Functions</td>
+ <td><code>lower_with_under()</code></td>
+ <td><code>_lower_with_under()</code></td>
+ </tr>
+
+ <tr>
+ <td>Global/Class Constants</td>
+ <td><code>CAPS_WITH_UNDER</code></td>
+ <td><code>_CAPS_WITH_UNDER</code></td>
+ </tr>
+
+ <tr>
+ <td>Global/Class Variables</td>
+ <td><code>lower_with_under</code></td>
+ <td><code>_lower_with_under</code></td>
+ </tr>
+
+ <tr>
+ <td>Instance Variables</td>
+ <td><code>lower_with_under</code></td>
+ <td><code>_lower_with_under</code> (protected)</td>
+ </tr>
+
+ <tr>
+ <td>Method Names</td>
+ <td><code>lower_with_under()</code></td>
+ <td><code>_lower_with_under()</code> (protected)</td>
+ </tr>
+
+ <tr>
+ <td>Function/Method Parameters</td>
+ <td><code>lower_with_under</code></td>
+ <td></td>
+ </tr>
+
+ <tr>
+ <td>Local Variables</td>
+ <td><code>lower_with_under</code></td>
+ <td></td>
+ </tr>
+
+</table>
+
+While Python supports making things private by using a leading double underscore
+`__` (aka. "dunder") prefix on a name, this is discouraged. Prefer the use of a
+single underscore. They are easier to type, read, and to access from small
+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
+
+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
+functionality. The main functionality should be in a `main()` function.
+
+In Python, `pydoc` as well as unit tests require modules to be importable. Your
+code should always check `if __name__ == '__main__'` before executing your main
+program so that the main program is not executed when the module is imported.
+
+```python
+def main():
+ ...
+
+if __name__ == '__main__':
+ main()
+```
+
+All code at the top level will be executed when the module is imported. Be
+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
+
+Prefer small and focused functions.
+
+We recognize that long functions are sometimes appropriate, so no hard limit is
+placed on function length. If a function exceeds about 40 lines, think about
+whether it can be broken up without harming the structure of the program.
+
+Even if your long function works perfectly now, someone modifying it in a few
+months may add new behavior. This could result in bugs that are hard to find.
+Keeping your functions short and simple makes it easier for other people to read
+and modify your code.
+
+You could find long and complicated functions when working with
+some code. Do not be intimidated by modifying existing code: if working with such
+a function proves to be difficult, you find that errors are hard to debug, or
+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
+
+<a id="s3.19.1-general"></a>
+<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
+ information. e.g., `@classmethod def create(cls: Type[T]) -> T: return cls()`
+* If any other variable or a returned type should not be expressed, use `Any`.
+* You are not required to annotate all the functions in a module.
+ - At least annotate your public APIs.
+ - Use judgment to get to a good balance between safety and clarity on the
+ one hand, and flexibility on the other.
+ - Annotate code that is prone to type-related errors (previous bugs or
+ complexity).
+ - Annotate code that is hard to understand.
+ - Annotate code as it becomes stable from a types perspective. In many
+ cases, you can annotate all the functions in mature code without losing
+ too much flexibility.
+
+
+<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
+
+Try to follow the existing [indentation](#indentation) rules.
+
+After annotating, many function signatures will become "one parameter per line".
+
+```python
+def my_method(self,
+ first_var: int,
+ second_var: Foo,
+ third_var: Optional[Bar]) -> int:
+ ...
+```
+
+Always prefer breaking between variables, and not for example between variable
+names and type annotations. However, if everything fits on the same line,
+go for it.
+
+```python
+def my_method(self, first_var: int) -> int:
+ ...
+```
+
+If the combination of the function name, the last parameter, and the return type
+is too long, indent by 4 in a new line.
+
+```python
+def my_method(
+ self, first_var: int) -> Tuple[MyLongType1, MyLongType1]:
+ ...
+```
+
+When the return type does not fit on the same line as the last parameter, the
+preferred way is to indent the parameters by 4 on a new line and align the
+closing parenthesis with the def.
+
+```python
+Yes:
+def my_method(
+ self, other_arg: Optional[MyLongType]
+) -> Dict[OtherLongType, MyLongType]:
+ ...
+```
+
+`pylint` allows you to move the closing parenthesis to a new line and align
+with the opening one, but this is less readable.
+
+```python
+No:
+def my_method(self,
+ other_arg: Optional[MyLongType]
+ ) -> Dict[OtherLongType, MyLongType]:
+ ...
+```
+
+As in the examples above, prefer not to break types. However, sometimes they are
+too long to be on a single line (try to keep sub-types unbroken).
+
+```python
+def my_method(
+ self,
+ first_var: Tuple[List[MyLongType1],
+ List[MyLongType2]],
+ second_var: List[Dict[
+ MyLongType3, MyLongType4]]) -> None:
+ ...
+```
+
+If a single name and type is too long, consider using an
+[alias](#typing-aliases) for the type. The last resort is to break after the
+colon and indent by 4.
+
+```python
+Yes:
+def my_function(
+ long_variable_name:
+ long_module_name.LongTypeName,
+) -> None:
+ ...
+```
+
+```python
+No:
+def my_function(
+ long_variable_name: long_module_name.
+ LongTypeName,
+) -> None:
+ ...
+```
+
+<a id="s3.19.3-forward-declarations"></a>
+<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
+class that is defined below -- use a string for the class name.
+
+```python
+class MyClass(object):
+
+ def __init__(self,
+ stack: List["MyClass"]) -> None:
+```
+
+<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
+
+As per
+[PEP-008](https://www.python.org/dev/peps/pep-0008/#other-recommendations), use
+spaces around the `=` _only_ for arguments that have both a type annotation and
+a default value.
+
+```python
+Yes:
+def func(a: int = 0) -> int:
+ ...
+```
+```python
+No:
+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
+
+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
+has to be declared! You can use `Union`, but if there is only one other type,
+use `Optional`.
+
+Use explicit `Optional` instead of implicit `Optional`. Earlier versions of PEP
+484 allowed `a: Text = None` to be interpretted as `a: Optional[Text] = None`,
+but that is no longer the preferred behavior.
+
+```python
+Yes:
+def func(a: Optional[Text], b: Optional[Text] = None) -> Text:
+ ...
+def multiple_nullable_union(a: Union[None, Text, int]) -> Text
+ ...
+```
+
+```python
+No:
+def nullable_union(a: Union[None, Text]) -> Text:
+ ...
+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>
+
+<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 the module together with the name of the type is too
+long:
+
+```python
+_ShortName = module_with_long_name.TypeWithLongName
+ComplexMap = Mapping[Text, List[Tuple[int, int]]]
+```
+
+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
+
+You can disable type checking on a line with the special comment
+`# type: ignore`.
+
+`pytype` has a disable option for specific errors (similar to lint):
+
+```python
+# pytype: disable=attribute-error
+```
+
+<a id="s3.19.8-comments"></a>
+<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
+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()
+ ```
+
+<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
+
+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
+commonly used as return type from a function.
+
+```python
+a = [1, 2, 3] # type: List[int]
+b = (1, 2, 3) # type: Tuple[int, ...]
+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>
+
+<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
+function `TypeVar` is a common way to use them.
+
+Example:
+
+```python
+from typing import List, TypeVar
+T = TypeVar("T")
+...
+def next(l: List[T]) -> T:
+ return l.pop()
+```
+
+A TypeVar can be constrained:
+
+```python
+AddableType = TypeVar("AddableType", int, float, Text)
+def add(a: AddableType, b: AddableType) -> AddableType:
+ return a + b
+```
+
+A common predefined type variable in the `typing` module is `AnyStr`. Use it for
+multiple annotations that can be `bytes` or `unicode` and must all be the same
+type.
+
+```python
+from typing import AnyStr
+def check_length(x: AnyStr) -> AnyStr:
+ if len(x) <= 42:
+ return x
+ raise ValueError()
+```
+
+<a id="s3.19.11-strings"></a>
+<a id="31911-string-types"></a>
+
+<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.
+
+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 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 discrepancy exists is because `str` means different things
+depending on the Python version.
+
+```python
+No:
+def py2_code(x: str) -> unicode:
+ ...
+```
+
+For code that deals with binary data, use `bytes`.
+
+```python
+def deals_with_binary_data(x: bytes) -> bytes:
+ ...
+```
+
+For Python 2 compatible code that processes text data (`str` or `unicode` in
+Python 2, `str` in Python 3), use `Text`. For Python 3 only code that process
+text data, prefer `str`.
+
+```python
+from typing import Text
+...
+def py2_compatible(x: Text) -> Text:
+ ...
+def py3_only(x: str) -> str:
+ ...
+```
+
+If the type can be either bytes or text, use `Union`, with the appropriate text
+type.
+
+```python
+from typing import Text, Union
+...
+def py2_compatible(x: Union[bytes, Text]) -> Union[bytes, Text]:
+ ...
+def py3_only(x: Union[bytes, str]) -> Union[bytes, str]:
+ ...
+```
+
+If all the string types of a function are always the same, for example if the
+return type is the same as the argument type in the code above, use
+[AnyStr](#typing-type-var).
+
+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
+
+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
+`typing` module. Ex:
+
+```python
+from typing import Any, Dict, Optional
+```
+
+Given that this way of importing from `typing` adds items to the local
+namespace, any names in `typing` should be treated similarly to keywords, and
+not be defined in your Python code, typed or not. If there is a collision
+between a type and an existing name in a module, import it using
+`import x as y`.
+
+```python
+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
+
+Use conditional imports only in exceptional cases where the additional imports
+needed for type checking must be avoided at runtime. This pattern is
+discouraged; alternatives such as refactoring the code to allow top level
+imports should be preferred.
+
+Imports that are needed only for type annotations can be placed within an
+`if TYPE_CHECKING:` block.
+
+- Conditionally imported types need to be referenced as strings, to be
+ forward compatible with Python 3.6 where the annotation expressions are
+ actually evaluated.
+- Only entities that are used solely for typing should be defined here; this
+ includes aliases. Otherwise it will be a runtime error, as the module will
+ not be imported at runtime.
+- The block should be right after all the normal imports.
+- There should be no empty lines in the typing imports list.
+- Sort this list as if it were a regular imports list.
+
+```python
+import typing
+if typing.TYPE_CHECKING:
+ import sketch
+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
+
+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
+circular dependencies, the [build system](#typing-build-deps) will not let you
+do so because each module has to depend on the other.
+
+Replace modules that create circular dependency imports with `Any`. Set an
+[alias](#typing-aliases) with a meaningful name, and use the real type name from
+this module (any attribute of Any is Any). Alias definitions should be separated
+from the last import by one line.
+
+```python
+from typing import Any
+
+some_mod = Any # some_mod.py imports this module.
+...
+
+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>
+
+<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).
+
+```python
+def get_names(employee_ids: List[int]) -> Dict[int, Any]:
+ ...
+```
+
+```python
+# These are both interpreted as get_names(employee_ids: List[Any]) -> Dict[Any, Any]
+def get_names(employee_ids: list) -> Dict:
+ ...
+
+def get_names(employee_ids: List) -> Dict:
+ ...
+```
+
+If the best type parameter for a generic is `Any`, make it explicit, but
+remember that in many cases [`TypeVar`](#typing-type-var) might be more
+appropriate:
+
+```python
+def get_names(employee_ids: List[Any]) -> Dict[Any, Text]:
+ """Returns a mapping from employee ID to employee name for given IDs."""
+```
+
+```python
+T = TypeVar('T')
+def get_names(employee_ids: List[T]) -> Dict[T, Text]:
+ """Returns a mapping from employee ID to employee name for given IDs."""
+```
+
+
+<a id="4-parting-words"></a>
+
+<a id="consistency"></a>
+## 4 Parting Words
+
+*BE CONSISTENT*.
+
+If you're editing code, take a few minutes to look at the code around you and
+determine its style. If they use spaces around all their arithmetic operators,
+you should too. If their comments have little boxes of hash marks around them,
+make your comments have little boxes of hash marks around them too.
+
+The point of having style guidelines is to have a common vocabulary of coding so
+people can concentrate on what you're saying rather than on how you're saying
+it. We present global style rules here so people know the vocabulary, but local
+style is also important. If code you add to a file looks drastically different
+from the existing code around it, it throws readers out of their rhythm when
+they go to read it. Avoid this.
+
+