Project import generated by Copybara.

PiperOrigin-RevId: 318884292
This commit is contained in:
Google Python team 2020-06-29 20:39:32 +00:00 committed by Gregory P. Smith [Google LLC]
parent 64de8439e3
commit 59def00435

View File

@ -7,6 +7,161 @@ See README.md for details.
# Google Python Style Guide # Google Python Style Guide
<details>
<summary>Table of Contents</summary>
- [1 Background](#s1-background)
- [2 Python Language Rules](#s2-python-language-rules)
* [2.1 Lint](#s2.1-lint)
+ [2.1.1 Definition](#s2.1.1-definition)
+ [2.1.2 Pros](#s2.1.2-pros)
+ [2.1.3 Cons](#s2.1.3-cons)
+ [2.1.4 Decision](#s2.1.4-decision)
* [2.2 Imports](#s2.2-imports)
+ [2.2.1 Definition](#s2.2.1-definition)
+ [2.2.2 Pros](#s2.2.2-pros)
+ [2.2.3 Cons](#s2.2.3-cons)
+ [2.2.4 Decision](#s2.2.4-decision)
* [2.3 Packages](#s2.3-packages)
+ [2.3.1 Pros](#s2.3.1-pros)
+ [2.3.2 Cons](#s2.3.2-cons)
+ [2.3.3 Decision](#s2.3.3-decision)
* [2.4 Exceptions](#s2.4-exceptions)
+ [2.4.1 Definition](#s2.4.1-definition)
+ [2.4.2 Pros](#s2.4.2-pros)
+ [2.4.3 Cons](#s2.4.3-cons)
+ [2.4.4 Decision](#s2.4.4-decision)
* [2.5 Global variables](#s2.5-global-variables)
+ [2.5.1 Definition](#s2.5.1-definition)
+ [2.5.2 Pros](#s2.5.2-pros)
+ [2.5.3 Cons](#s2.5.3-cons)
+ [2.5.4 Decision](#s2.5.4-decision)
* [2.6 Nested/Local/Inner Classes and Functions](#s2.6-nested)
+ [2.6.1 Definition](#s2.6.1-definition)
+ [2.6.2 Pros](#s2.6.2-pros)
+ [2.6.3 Cons](#s2.6.3-cons)
+ [2.6.4 Decision](#s2.6.4-decision)
* [2.7 Comprehensions & Generator Expressions](#s2.7-comprehensions)
+ [2.7.1 Definition](#s2.7.1-definition)
+ [2.7.2 Pros](#s2.7.2-pros)
+ [2.7.3 Cons](#s2.7.3-cons)
+ [2.7.4 Decision](#s2.7.4-decision)
* [2.8 Default Iterators and Operators](#s2.8-default-iterators-and-operators)
+ [2.8.1 Definition](#s2.8.1-definition)
+ [2.8.2 Pros](#s2.8.2-pros)
+ [2.8.3 Cons](#s2.8.3-cons)
+ [2.8.4 Decision](#s2.8.4-decision)
* [2.9 Generators](#s2.9-generators)
+ [2.9.1 Definition](#s2.9.1-definition)
+ [2.9.2 Pros](#s2.9.2-pros)
+ [2.9.3 Cons](#s2.9.3-cons)
+ [2.9.4 Decision](#s2.9.4-decision)
* [2.10 Lambda Functions](#s2.10-lambda-functions)
+ [2.10.1 Definition](#s2.10.1-definition)
+ [2.10.2 Pros](#s2.10.2-pros)
+ [2.10.3 Cons](#s2.10.3-cons)
+ [2.10.4 Decision](#s2.10.4-decision)
* [2.11 Conditional Expressions](#s2.11-conditional-expressions)
+ [2.11.1 Definition](#s2.11.1-definition)
+ [2.11.2 Pros](#s2.11.2-pros)
+ [2.11.3 Cons](#s2.11.3-cons)
+ [2.11.4 Decision](#s2.11.4-decision)
* [2.12 Default Argument Values](#s2.12-default-argument-values)
+ [2.12.1 Definition](#s2.12.1-definition)
+ [2.12.2 Pros](#s2.12.2-pros)
+ [2.12.3 Cons](#s2.12.3-cons)
+ [2.12.4 Decision](#s2.12.4-decision)
* [2.13 Properties](#s2.13-properties)
+ [2.13.1 Definition](#s2.13.1-definition)
+ [2.13.2 Pros](#s2.13.2-pros)
+ [2.13.3 Cons](#s2.13.3-cons)
+ [2.13.4 Decision](#s2.13.4-decision)
* [2.14 True/False Evaluations](#s2.14-truefalse-evaluations)
+ [2.14.1 Definition](#s2.14.1-definition)
+ [2.14.2 Pros](#s2.14.2-pros)
+ [2.14.3 Cons](#s2.14.3-cons)
+ [2.14.4 Decision](#s2.14.4-decision)
* [2.15 Deprecated Language Features](#s2.15-deprecated-language-features)
+ [2.15.1 Definition](#s2.15.1-definition)
+ [2.15.2 Decision](#s2.15.2-decision)
* [2.16 Lexical Scoping](#s2.16-lexical-scoping)
+ [2.16.1 Definition](#s2.16.1-definition)
+ [2.16.2 Pros](#s2.16.2-pros)
+ [2.16.3 Cons](#s2.16.3-cons)
+ [2.16.4 Decision](#s2.16.4-decision)
* [2.17 Function and Method Decorators](#s2.17-function-and-method-decorators)
+ [2.17.1 Definition](#s2.17.1-definition)
+ [2.17.2 Pros](#s2.17.2-pros)
+ [2.17.3 Cons](#s2.17.3-cons)
+ [2.17.4 Decision](#s2.17.4-decision)
* [2.18 Threading](#s2.18-threading)
* [2.19 Power Features](#s2.19-power-features)
+ [2.19.1 Definition](#s2.19.1-definition)
+ [2.19.2 Pros](#s2.19.2-pros)
+ [2.19.3 Cons](#s2.19.3-cons)
+ [2.19.4 Decision](#s2.19.4-decision)
* [2.20 Modern Python: Python 3 and from \_\_future\_\_ imports](#s2.20-modern-python)
+ [2.20.1 Definition](#s2.20.1-definition)
+ [2.20.2 Pros](#s2.20.2-pros)
+ [2.20.3 Cons](#s2.20.3-cons)
+ [2.20.4 Decision](#s2.20.4-decision)
* [2.21 Type Annotated Code](#s2.21-type-annotated-code)
+ [2.21.1 Definition](#s2.21.1-definition)
+ [2.21.2 Pros](#s2.21.2-pros)
+ [2.21.3 Cons](#s2.21.3-cons)
+ [2.21.4 Decision](#s2.21.4-decision)
- [3 Python Style Rules](#s3-python-style-rules)
* [3.1 Semicolons](#s3.1-semicolons)
* [3.2 Line length](#s3.2-line-length)
* [3.3 Parentheses](#s3.3-parentheses)
* [3.4 Indentation](#s3.4-indentation)
* [3.4.1 Trailing commas in sequences of items?](#s3.4.1-trailing-commas)
* [3.5 Blank Lines](#s3.5-blank-lines)
* [3.6 Whitespace](#s3.6-whitespace)
* [3.7 Shebang Line](#s3.7-shebang-line)
* [3.8 Comments and Docstrings](#s3.8-comments-and-docstrings)
+ [3.8.1 Docstrings](#s3.8.1-comments-in-doc-strings)
+ [3.8.2 Modules](#s3.8.2-comments-in-modules)
+ [3.8.3 Functions and Methods](#s3.8.3-functions-and-methods)
+ [3.8.4 Classes](#s3.8.4-comments-in-classes)
+ [3.8.5 Block and Inline Comments](#s3.8.5-block-and-inline-comments)
+ [3.8.6 Punctuation, Spelling, and Grammar](#s3.8.6-punctuation-spelling-and-grammar)
* [3.9 Classes](#s3.9-classes)
* [3.10 Strings](#s3.10-strings)
* [3.11 Files and Sockets](#s3.11-files-and-sockets)
* [3.12 TODO Comments](#s3.12-todo-comments)
* [3.13 Imports formatting](#s3.13-imports-formatting)
* [3.14 Statements](#s3.14-statements)
* [3.15 Accessors](#s3.15-accessors)
* [3.16 Naming](#s3.16-naming)
+ [3.16.1 Names to Avoid](#s3.16.1-names-to-avoid)
+ [3.16.2 Naming Conventions](#s3.16.2-naming-conventions)
+ [3.16.3 File Naming](#s3.16.3-file-naming)
+ [3.16.4 Guidelines derived from Guido's Recommendations](#s3.16.4-guidelines-derived-from-guidos-recommendations)
* [3.17 Main](#s3.17-main)
* [3.18 Function length](#s3.18-function-length)
* [3.19 Type Annotations](#s3.19-type-annotations)
+ [3.19.1 General Rules](#s3.19.1-general-rules)
+ [3.19.2 Line Breaking](#s3.19.2-line-breaking)
+ [3.19.3 Forward Declarations](#s3.19.3-forward-declarations)
+ [3.19.4 Default Values](#s3.19.4-default-values)
+ [3.19.5 NoneType](#s3.19.5-nonetype)
+ [3.19.6 Type Aliases](#s3.19.6-type-aliases)
+ [3.19.7 Ignoring Types](#s3.19.7-ignoring-types)
+ [3.19.8 Typing Variables](#s3.19.8-typing-variables)
+ [3.19.9 Tuples vs Lists](#s3.19.9-tuples-vs-lists)
+ [3.19.10 TypeVars](#s3.19.10-typevars)
+ [3.19.11 String types](#s3.19.11-string-types)
+ [3.19.12 Imports For Typing](#s3.19.12-imports-for-typing)
+ [3.19.13 Conditional Imports](#s3.19.13-conditional-imports)
+ [3.19.14 Circular Dependencies](#s3.19.14-circular-dependencies)
+ [3.19.15 Generics](#s3.19.15-generics)
+ [3.19.16 Build Dependencies](#s3.19.16-build-dependencies)
- [4 Parting Words](#4-parting-words)
</details>
<a id="s1-background"></a>
<a id="1-background"></a> <a id="1-background"></a>
<a id="background"></a> <a id="background"></a>
@ -15,8 +170,7 @@ See README.md for details.
Python is the main dynamic language used at Google. This style guide is a list Python is the main dynamic language used at Google. This style guide is a list
of *dos and don'ts* for Python programs. of *dos and don'ts* for Python programs.
To help you format code correctly, we've created a [settings file for 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.
Vim](google_python_style.vim). For Emacs, the default settings should be fine.
Many teams use the [yapf](https://github.com/google/yapf/) Many teams use the [yapf](https://github.com/google/yapf/)
auto-formatter to avoid arguing over formatting. auto-formatter to avoid arguing over formatting.
@ -115,10 +269,10 @@ def viking_cafe_order(spam, beans, eggs=None):
``` ```
Other common forms of suppressing this warning include using '`_`' as the Other common forms of suppressing this warning include using '`_`' as the
identifier for the unused argument, prefixing the argument name with identifier for the unused argument or prefixing the argument name with
'`unused_`', or assigning them to '`_`'. These forms are allowed but no longer '`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 encouraged. These break callers that pass arguments by name and do not enforce
last does not enforce that the arguments are actually unused. that the arguments are actually unused.
<a id="s2.2-imports"></a> <a id="s2.2-imports"></a>
<a id="22-imports"></a> <a id="22-imports"></a>
@ -332,11 +486,13 @@ Exceptions must follow certain conditions:
# Note that this raising of ValueError is not mentioned in the doc # Note that this raising of ValueError is not mentioned in the doc
# string's "Raises:" section because it is not appropriate to # string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse. # guarantee this specific behavioral reaction to API misuse.
raise ValueError('Minimum port must be at least 1024, not %d.' % (minimum,)) raise ValueError(f'Min. port must be at least 1024, not {minimum}.')
port = self._find_next_open_port(minimum) port = self._find_next_open_port(minimum)
if not port: if not port:
raise ConnectionError('Could not connect to service on %d or higher.' % (minimum,)) raise ConnectionError(
assert port >= minimum, 'Unexpected port %d when minimum was %d.' % (port, minimum) f'Could not connect to service on port {minimum} or higher.')
assert port >= minimum, (
f'Unexpected port {port} when minimum was {minimum}.')
return port return port
``` ```
@ -493,6 +649,7 @@ 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 of a module. Instead, prefix its name with an \_ at the module level so that it
can still be accessed by tests. can still be accessed by tests.
<a id="s2.7-comprehensions"></a>
<a id="s2.7-list_comprehensions"></a> <a id="s2.7-list_comprehensions"></a>
<a id="27-list_comprehensions"></a> <a id="27-list_comprehensions"></a>
<a id="list_comprehensions"></a> <a id="list_comprehensions"></a>
@ -625,7 +782,7 @@ operators is generic. It can be used with any type that supports the operation.
<a id="default-iterators-operators-cons"></a> <a id="default-iterators-operators-cons"></a>
#### 2.8.3 Cons #### 2.8.3 Cons
You can't tell the type of objects by reading the method names (e.g. has\_key() 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. means a dictionary). This is also an advantage.
<a id="s2.8.4-decision"></a> <a id="s2.8.4-decision"></a>
@ -943,12 +1100,12 @@ created with the `@property` [decorator](#s2.17-function-and-method-decorators).
Inheritance with properties can be non-obvious if the property itself is not 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 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 to ensure methods overridden in subclasses are called by the property (using the
Template Method DP). [template method design pattern](https://en.wikipedia.org/wiki/Template_method_pattern)).
```python ```python
Yes: import math Yes: import math
class Square(object): class Square:
"""A square with two properties: a writable area and a read-only perimeter. """A square with two properties: a writable area and a read-only perimeter.
To use: To use:
@ -1033,10 +1190,10 @@ May look strange to C/C++ developers.
Use the "implicit" false if possible, e.g., `if foo:` rather than `if foo != 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: []:`. 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` - Always use `if foo is None:` (or `is not None`) to check for a `None` value.
value-e.g., when testing whether a variable or argument that defaults to E.g., when testing whether a variable or argument that defaults to `None`
`None` was set to some other value. The other value might be a value that's was set to some other value. The other value might be a value that's false
false in a boolean context! in a boolean context!
- Never compare a boolean variable to `False` using `==`. Use `if not x:` - Never compare a boolean variable to `False` using `==`. Use `if not x:`
instead. If you need to distinguish `False` from `None` then chain the instead. If you need to distinguish `False` from `None` then chain the
@ -1144,11 +1301,11 @@ Okay to use.
#### 2.16.1 Definition #### 2.16.1 Definition
A nested Python function can refer to variables defined in enclosing functions, A nested Python function can refer to variables defined in enclosing functions,
but can not assign to them. Variable bindings are resolved using lexical but cannot assign to them. Variable bindings are resolved using lexical scoping,
scoping, that is, based on the static program text. Any assignment to a name in that is, based on the static program text. Any assignment to a name in a block
a block will cause Python to treat all references to that name as a local will cause Python to treat all references to that name as a local variable, even
variable, even if the use precedes the assignment. If a global declaration if the use precedes the assignment. If a global declaration occurs, the name is
occurs, the name is treated as a global variable. treated as a global variable.
An example of the use of this feature is: An example of the use of this feature is:
@ -1227,7 +1384,7 @@ decorator syntax allows for user-defined decorators as well. Specifically, for
some function `my_decorator`, this: some function `my_decorator`, this:
```python ```python
class C(object): class C:
@my_decorator @my_decorator
def method(self): def method(self):
# method body ... # method body ...
@ -1235,9 +1392,8 @@ class C(object):
is equivalent to: is equivalent to:
```python ```python
class C(object): class C:
def method(self): def method(self):
# method body ... # method body ...
method = my_decorator(method) method = my_decorator(method)
@ -1305,8 +1461,8 @@ in turn depends on dictionaries).
Use the Queue module's `Queue` data type as the preferred way to communicate 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 data between threads. Otherwise, use the threading module and its locking
primitives. Learn about the proper use of condition variables so you can use primitives. Prefer condition variables and `threading.Condition` instead of
`threading.Condition` instead of using lower-level locks. using lower-level locks.
<a id="s2.19-power-features"></a> <a id="s2.19-power-features"></a>
<a id="219-power-features"></a> <a id="219-power-features"></a>
@ -1417,10 +1573,10 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
``` ```
If you are not already familiar with those, read up on each here: [absolute For more information on these imports, see
imports](https://www.python.org/dev/peps/pep-0328/), [new `/` division [absolute imports](https://www.python.org/dev/peps/pep-0328/),
behavior](https://www.python.org/dev/peps/pep-0238/), and [the print [`/` division behavior](https://www.python.org/dev/peps/pep-0238/), and
function](https://www.python.org/dev/peps/pep-3105/). [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 Please don't omit or remove these imports, even if they're not currently used in
@ -1434,7 +1590,7 @@ 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 places within Python 2.7. Most code is better off with explicit use of `b''` and
`u''` bytes and unicode string literals as necessary. `u''` bytes and unicode string literals as necessary.
##### The six, future, or past libraries ##### The six, future, and past libraries
When your project needs to actively support use under both Python 2 and 3, use When your project needs to actively support use under both Python 2 and 3, use
the [six](https://pypi.org/project/six/), the [six](https://pypi.org/project/six/),
@ -1442,9 +1598,10 @@ the [six](https://pypi.org/project/six/),
[past](https://pypi.org/project/past/) libraries as you see fit. They exist to [past](https://pypi.org/project/past/) libraries as you see fit. They exist to
make your code cleaner and life easier. make your code cleaner and life easier.
<a name="s2.21-typed-code"></a> <a id="s2.21-type-annotated-code"></a>
<a name="221-type-annotated-code"></a> <a id="s2.21-typed-code"></a>
<a name="typed-code"></a> <a id="221-type-annotated-code"></a>
<a id="typed-code"></a>
<a id="typed-code"></a> <a id="typed-code"></a>
### 2.21 Type Annotated Code ### 2.21 Type Annotated Code
@ -1474,10 +1631,17 @@ return values:
def func(a: int) -> List[int]: def func(a: int) -> List[int]:
``` ```
You can also declare the type of a variable using a special comment: You can also declare the type of a variable using similar
[PEP-526](https://www.python.org/dev/peps/pep-0526/) syntax:
```python ```python
a = SomeFunc() # type: SomeType a: SomeType = some_func()
```
Or by using a type comment in code that must support legacy Python versions.
```python
a = some_func() # type: SomeType
``` ```
<a id="s2.21.2-pros"></a> <a id="s2.21.2-pros"></a>
@ -1714,9 +1878,14 @@ No: # Stuff on first line forbidden
} }
``` ```
<a id="s3.4.1-trailing-comma"></a>
<a id="s3.4.1-trailing-commas"></a>
<a id="s3.4.1-trailing_comma"></a> <a id="s3.4.1-trailing_comma"></a>
<a id="s3.4.1-trailing_commas"></a>
<a id="341-trailing_comma"></a> <a id="341-trailing_comma"></a>
<a id="341-trailing_commas"></a>
<a id="trailing_comma"></a> <a id="trailing_comma"></a>
<a id="trailing_commas"></a>
<a id="trailing-comma"></a> <a id="trailing-comma"></a>
### 3.4.1 Trailing commas in sequences of items? ### 3.4.1 Trailing commas in sequences of items?
@ -1882,6 +2051,7 @@ 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 by Python when importing modules. It is only necessary on a file that will be
executed directly. executed directly.
<a id="s3.8-comments-and-docstrings"></a>
<a id="s3.8-comments"></a> <a id="s3.8-comments"></a>
<a id="38-comments-and-docstrings"></a> <a id="38-comments-and-docstrings"></a>
@ -2052,7 +2222,7 @@ If your class has public attributes, they should be documented here in an
[function's `Args`](#doc-function-args) section. [function's `Args`](#doc-function-args) section.
```python ```python
class SampleClass(object): class SampleClass:
"""Summary of class here. """Summary of class here.
Longer class information.... Longer class information....
@ -2072,6 +2242,7 @@ class SampleClass(object):
"""Performs operation blah.""" """Performs operation blah."""
``` ```
<a id="s3.8.5-block-and-inline-comments"></a>
<a id="comments-in-block-and-inline"></a> <a id="comments-in-block-and-inline"></a>
<a id="s3.8.5-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="385-block-and-inline-comments"></a>
@ -2136,27 +2307,12 @@ punctuation, spelling, and grammar help with that goal.
<a id="classes"></a> <a id="classes"></a>
### 3.9 Classes ### 3.9 Classes
If a class inherits from no other base classes, explicitly inherit from Classes need not explicitly inherit from `object` (unless for compatibility with
`object`. This also applies to nested classes. Python 2).
```python ```python
Yes: class SampleClass(object): Modern:
pass class SampleClass:
class OuterClass(object):
class InnerClass(object):
pass
class ChildClass(ParentClass):
"""Explicitly inherits from another class already."""
```
```python
No: class SampleClass:
pass pass
@ -2166,11 +2322,17 @@ No: class SampleClass:
pass pass
``` ```
Inheriting from `object` is needed to make properties work properly in Python 2 ```python
and can protect your code from potential incompatibility with Python 3. It also Ancient:
defines special methods that implement the default semantics of objects class SampleClass(object):
including `__new__`, `__init__`, `__delattr__`, `__getattribute__`, pass
`__setattr__`, `__hash__`, `__repr__`, and `__str__`.
class OuterClass(object):
class InnerClass(object):
pass
```
<a id="s3.10-strings"></a> <a id="s3.10-strings"></a>
<a id="310-strings"></a> <a id="310-strings"></a>
@ -2202,7 +2364,7 @@ Avoid using the `+` and `+=` operators to accumulate a string within a loop.
Since strings are immutable, this creates unnecessary temporary objects and Since strings are immutable, this creates unnecessary temporary objects and
results in quadratic rather than linear running time. Instead, add each 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 substring to a list and `''.join` the list after the loop terminates (or, write
each substring to a `io.BytesIO` buffer). each substring to an `io.BytesIO` buffer).
```python ```python
Yes: items = ['<table>'] Yes: items = ['<table>']
@ -2309,13 +2471,13 @@ file is poor practice:
- There are no guarantees as to when the runtime will actually run the file's - There are no guarantees as to when the runtime will actually run the file's
destructor. Different Python implementations use different memory management destructor. Different Python implementations use different memory management
techniques, such as delayed Garbage Collection, which may increase the techniques, such as delayed garbage collection, which may increase the
object's lifetime arbitrarily and indefinitely. object's lifetime arbitrarily and indefinitely.
- Unexpected references to the file, e.g. in globals or exception tracebacks, - Unexpected references to the file, e.g. in globals or exception tracebacks,
may keep it around longer than intended. may keep it around longer than intended.
The preferred way to manage files is using the ["with" The preferred way to manage files is using the
statement](http://docs.python.org/reference/compound_stmts.html#the-with-statement): [`with` statement](http://docs.python.org/reference/compound_stmts.html#the-with-statement):
```python ```python
with open("hello.txt") as hello_file: with open("hello.txt") as hello_file:
@ -2323,7 +2485,7 @@ with open("hello.txt") as hello_file:
print(line) print(line)
``` ```
For file-like objects that do not support the "with" statement, use For file-like objects that do not support the `with` statement, use
`contextlib.closing()`: `contextlib.closing()`:
```python ```python
@ -2369,13 +2531,15 @@ event ("Remove this code when all clients can handle XML responses.").
<a id="imports-formatting"></a> <a id="imports-formatting"></a>
### 3.13 Imports formatting ### 3.13 Imports formatting
Imports should be on separate lines. Imports should be on separate lines; there are
[exceptions for `typing` imports](#typing-imports).
E.g.: E.g.:
```python ```python
Yes: import os Yes: import os
import sys import sys
from typing import Mapping, Sequence
``` ```
```python ```python
@ -2495,6 +2659,7 @@ No:
except ValueError: baz(foo) except ValueError: baz(foo)
``` ```
<a id="s3.15-accessors"></a>
<a id="s3.15-access-control"></a> <a id="s3.15-access-control"></a>
<a id="315-access-control"></a> <a id="315-access-control"></a>
<a id="access-control"></a> <a id="access-control"></a>
@ -2509,11 +2674,11 @@ syntax consistent.
On the other hand, if access is more complex, or the cost of accessing the 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 variable is significant, you should use function calls (following the
[Naming](#s3.16-naming) guidelines) such as `get_foo()` and [Naming](#s3.16-naming) guidelines) such as `get_foo()` and `set_foo()`. If the
`set_foo()`. If the past behavior allowed access through a property, do not past behavior allowed access through a property, do not bind the new accessor
bind the new accessor functions to the property. Any code still attempting to functions to the property. Any code still attempting to access the variable by
access the variable by the old method should break visibly so they are made the old method should break visibly so they are made aware of the change in
aware of the change in complexity. complexity.
<a id="s3.16-naming"></a> <a id="s3.16-naming"></a>
<a id="316-naming"></a> <a id="316-naming"></a>
@ -2539,29 +2704,22 @@ Always use a `.py` filename extension. Never use dashes.
<a id="names-to-avoid"></a> <a id="names-to-avoid"></a>
#### 3.16.1 Names to Avoid #### 3.16.1 Names to Avoid
- single character names except for counters or iterators. You may use "e" as - single character names, except for specifically allowed cases:
an exception identifier in try/except statements.
- counters or iterators (e.g. `i`, `j`, `k`, `v`, et al)
- `e` as an exception identifier in `try/except` statements.
- `f` as a file handle in `with` statements
Please be mindful not to abuse single-character naming. Generally speaking,
descriptiveness should be proportional to the name's scope of visibility.
For example, `i` might be a fine name for 5-line code block but within
multiple nested scopes, it is likely too vague.
- dashes (`-`) in any package/module name - dashes (`-`) in any package/module name
- `__double_leading_and_trailing_underscore__` names (reserved by Python) - `__double_leading_and_trailing_underscore__` names (reserved by Python)
<a id="s3.16.2-naming-conventions"></a> - module.
<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. 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. - Use CapWords for class names, but lower\_with\_under.py for module names.
@ -2591,7 +2749,7 @@ containing `exec "$0.py" "$@"`.
<a id="3164-guidelines-derived-from-guidos-recommendations"></a> <a id="3164-guidelines-derived-from-guidos-recommendations"></a>
<a id="guidelines-derived-from-guidos-recommendations"></a> <a id="guidelines-derived-from-guidos-recommendations"></a>
#### 3.16.4 Guidelines derived from Guido's Recommendations #### 3.16.4 Guidelines derived from [Guido](https://en.wikipedia.org/wiki/Guido_van_Rossum)'s Recommendations
<table rules="all" border="1" summary="Guidelines from Guido's Recommendations" <table rules="all" border="1" summary="Guidelines from Guido's Recommendations"
cellspacing="2" cellpadding="2"> cellspacing="2" cellpadding="2">
@ -2670,11 +2828,6 @@ containing `exec "$0.py" "$@"`.
</table> </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="s3.17-main"></a>
<a id="317-main"></a> <a id="317-main"></a>
@ -2690,6 +2843,22 @@ 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 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. program so that the main program is not executed when the module is imported.
When using [absl](https://github.com/abseil/abseil-py), use `app.run`:
```python
from absl import app
...
def main(argv):
# process non-flag arguments
...
if __name__ == '__main__':
app.run(main)
```
Otherwise, use:
```python ```python
def main(): def main():
... ...
@ -2731,6 +2900,7 @@ up the function into smaller and more manageable pieces.
<a id="type-annotations"></a> <a id="type-annotations"></a>
### 3.19 Type Annotations ### 3.19 Type Annotations
<a id="s3.19.1-general-rules"></a>
<a id="s3.19.1-general"></a> <a id="s3.19.1-general"></a>
<a id="3191-general-rules"></a> <a id="3191-general-rules"></a>
@ -2752,7 +2922,6 @@ up the function into smaller and more manageable pieces.
cases, you can annotate all the functions in mature code without losing cases, you can annotate all the functions in mature code without losing
too much flexibility. too much flexibility.
<a id="s3.19.2-line-breaking"></a> <a id="s3.19.2-line-breaking"></a>
<a id="3192-line-breaking"></a> <a id="3192-line-breaking"></a>
@ -2771,9 +2940,9 @@ def my_method(self,
... ...
``` ```
Always prefer breaking between variables, and not for example between variable Always prefer breaking between variables, and not, for example, between variable
names and type annotations. However, if everything fits on the same line, names and type annotations. However, if everything fits on the same line, go for
go for it. it.
```python ```python
def my_method(self, first_var: int) -> int: def my_method(self, first_var: int) -> int:
@ -2791,7 +2960,7 @@ def my_method(
When the return type does not fit on the same line as the last parameter, the 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 preferred way is to indent the parameters by 4 on a new line and align the
closing parenthesis with the def. closing parenthesis with the `def`.
```python ```python
Yes: Yes:
@ -2858,7 +3027,7 @@ 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. class that is defined below -- use a string for the class name.
```python ```python
class MyClass(object): class MyClass:
def __init__(self, def __init__(self,
stack: List["MyClass"]) -> None: stack: List["MyClass"]) -> None:
@ -2886,6 +3055,7 @@ def func(a:int=0) -> int:
... ...
``` ```
<a id="s3.19.5-nonetype"></a>
<a id="s3.19.5-none-type"></a> <a id="s3.19.5-none-type"></a>
<a id="3195-nonetype"></a> <a id="3195-nonetype"></a>
@ -2917,6 +3087,7 @@ def implicit_optional(a: Text = None) -> Text:
... ...
``` ```
<a id="s3.19.6-type-aliases"></a>
<a id="s3.19.6-aliases"></a> <a id="s3.19.6-aliases"></a>
<a id="3196-type-aliases"></a> <a id="3196-type-aliases"></a>
<a id="typing-aliases"></a> <a id="typing-aliases"></a>
@ -2939,6 +3110,7 @@ ComplexMap = Mapping[Text, List[Tuple[int, int]]]
Other examples are complex nested types and multiple return variables from a Other examples are complex nested types and multiple return variables from a
function (as a tuple). function (as a tuple).
<a id="s3.19.7-ignoring-types"></a>
<a id="s3.19.7-ignore"></a> <a id="s3.19.7-ignore"></a>
<a id="3197-ignoring-types"></a> <a id="3197-ignoring-types"></a>
@ -2954,6 +3126,7 @@ You can disable type checking on a line with the special comment
# pytype: disable=attribute-error # pytype: disable=attribute-error
``` ```
<a id="s3.19.8-typing-variables"></a>
<a id="s3.19.8-comments"></a> <a id="s3.19.8-comments"></a>
<a id="3198-typing-internal-variables"></a> <a id="3198-typing-internal-variables"></a>
@ -2971,6 +3144,7 @@ specify its type in a couple ways.
a = SomeUndecoratedFunction() # type: Foo a = SomeUndecoratedFunction() # type: Foo
``` ```
<a id="annotated-assignments"></a>
[*Annotated Assignments*](#annotated-assignments) [*Annotated Assignments*](#annotated-assignments)
: Use a colon and type between the variable name and value, as with function : Use a colon and type between the variable name and value, as with function
arguments. arguments.
@ -2979,15 +3153,16 @@ a = SomeUndecoratedFunction() # type: Foo
a: Foo = SomeUndecoratedFunction() a: Foo = SomeUndecoratedFunction()
``` ```
<a id="s3.19.9-tuples-vs-lists"></a>
<a id="s3.19.9-tuples"></a> <a id="s3.19.9-tuples"></a>
<a id="3199-tuples-vs-lists"></a> <a id="3199-tuples-vs-lists"></a>
<a id="typing-tuples"></a> <a id="typing-tuples"></a>
#### 3.19.9 Tuples vs Lists #### 3.19.9 Tuples vs Lists
Unlike Lists, which can only have a single type, Tuples can have either a single Typed lists can only contain objects of a single type. Typed tuples can either
repeated type or a set number of elements with different types. The latter is have a single repeated type or a set number of elements with different types.
commonly used as return type from a function. The latter is commonly used as the return type from a function.
```python ```python
a = [1, 2, 3] # type: List[int] a = [1, 2, 3] # type: List[int]
@ -2995,6 +3170,7 @@ b = (1, 2, 3) # type: Tuple[int, ...]
c = (1, "2", 3.5) # type: Tuple[int, Text, float] c = (1, "2", 3.5) # type: Tuple[int, Text, float]
``` ```
<a id="s3.19.10-typevars"></a>
<a id="s3.19.10-type-var"></a> <a id="s3.19.10-type-var"></a>
<a id="31910-typevar"></a> <a id="31910-typevar"></a>
<a id="typing-type-var"></a> <a id="typing-type-var"></a>
@ -3036,6 +3212,7 @@ def check_length(x: AnyStr) -> AnyStr:
raise ValueError() raise ValueError()
``` ```
<a id="s3.19.11-string-types"></a>
<a id="s3.19.11-strings"></a> <a id="s3.19.11-strings"></a>
<a id="31911-string-types"></a> <a id="31911-string-types"></a>
@ -3100,6 +3277,7 @@ return type is the same as the argument type in the code above, use
Writing it like this will simplify the process of porting the code to Python 3. Writing it like this will simplify the process of porting the code to Python 3.
<a id="s3.19.12-imports-for-typing"></a>
<a id="s3.19.12-imports"></a> <a id="s3.19.12-imports"></a>
<a id="31912-imports-for-typing"></a> <a id="31912-imports-for-typing"></a>
@ -3154,6 +3332,7 @@ if typing.TYPE_CHECKING:
def f(x: "sketch.Sketch"): ... def f(x: "sketch.Sketch"): ...
``` ```
<a id="s3.19.14-circular-dependencies"></a>
<a id="s3.19.14-circular-deps"></a> <a id="s3.19.14-circular-deps"></a>
<a id="31914-circular-dependencies"></a> <a id="31914-circular-dependencies"></a>
@ -3176,7 +3355,7 @@ from typing import Any
some_mod = Any # some_mod.py imports this module. some_mod = Any # some_mod.py imports this module.
... ...
def my_method(self, var: some_mod.SomeType) -> None: def my_method(self, var: "some_mod.SomeType") -> None:
... ...
``` ```