From 59def004352a127bcad66ab7cccd9cbf6b5c0ba9 Mon Sep 17 00:00:00 2001 From: Google Python team Date: Mon, 29 Jun 2020 20:39:32 +0000 Subject: [PATCH] Project import generated by Copybara. PiperOrigin-RevId: 318884292 --- pyguide.md | 387 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 283 insertions(+), 104 deletions(-) diff --git a/pyguide.md b/pyguide.md index c39542b..5eb2565 100644 --- a/pyguide.md +++ b/pyguide.md @@ -7,6 +7,161 @@ See README.md for details. # Google Python Style Guide +
+ Table of Contents + +- [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) + +
+ + @@ -15,8 +170,7 @@ See README.md for details. 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. +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. @@ -115,10 +269,10 @@ def viking_cafe_order(spam, beans, eggs=None): ``` 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 -encouraged. The first two break callers that pass arguments by name, while the -last does not enforce that the arguments are actually unused. +encouraged. These break callers that pass arguments by name and do not enforce +that the arguments are actually unused. @@ -332,11 +486,13 @@ Exceptions must follow certain conditions: # 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,)) + raise ValueError(f'Min. port must be at least 1024, not {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) + raise ConnectionError( + f'Could not connect to service on port {minimum} or higher.') + assert port >= minimum, ( + f'Unexpected port {port} when minimum was {minimum}.') 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 can still be accessed by tests. + @@ -625,7 +782,7 @@ operators is generic. It can be used with any type that supports the operation. #### 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. @@ -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 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). +[template method design pattern](https://en.wikipedia.org/wiki/Template_method_pattern)). ```python Yes: import math - class Square(object): + class Square: """A square with two properties: a writable area and a read-only perimeter. 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 != []:`. 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! +- 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 @@ -1144,11 +1301,11 @@ Okay to use. #### 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. +but cannot 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: @@ -1227,7 +1384,7 @@ decorator syntax allows for user-defined decorators as well. Specifically, for some function `my_decorator`, this: ```python -class C(object): +class C: @my_decorator def method(self): # method body ... @@ -1235,9 +1392,8 @@ class C(object): is equivalent to: - ```python -class C(object): +class C: def method(self): # method body ... 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 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. +primitives. Prefer condition variables and `threading.Condition` instead of +using lower-level locks. @@ -1417,10 +1573,10 @@ 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/). +For more information on these imports, see +[absolute imports](https://www.python.org/dev/peps/pep-0328/), +[`/` 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 @@ -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 `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 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 make your code cleaner and life easier. - - - + + + + ### 2.21 Type Annotated Code @@ -1474,10 +1631,17 @@ return values: 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 -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 ``` @@ -1714,9 +1878,14 @@ No: # Stuff on first line forbidden } ``` + + + + + ### 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 executed directly. + @@ -2052,7 +2222,7 @@ If your class has public attributes, they should be documented here in an [function's `Args`](#doc-function-args) section. ```python -class SampleClass(object): +class SampleClass: """Summary of class here. Longer class information.... @@ -2072,6 +2242,7 @@ class SampleClass(object): """Performs operation blah.""" ``` + @@ -2136,42 +2307,33 @@ punctuation, spelling, and grammar help with that goal. ### 3.9 Classes -If a class inherits from no other base classes, explicitly inherit from -`object`. This also applies to nested classes. +Classes need not explicitly inherit from `object` (unless for compatibility with +Python 2). ```python -Yes: class SampleClass(object): +Modern: + class SampleClass: pass - class OuterClass(object): + class OuterClass: - class InnerClass(object): + class InnerClass: pass - - - class ChildClass(ParentClass): - """Explicitly inherits from another class already.""" - ``` ```python -No: class SampleClass: +Ancient: + class SampleClass(object): pass - class OuterClass: + class OuterClass(object): - class InnerClass: + class InnerClass(object): 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__`. - @@ -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 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). +each substring to an `io.BytesIO` buffer). ```python Yes: items = [''] @@ -2262,13 +2424,13 @@ Don't do this. ```python Yes: - long_string = ("And this is fine if you can not accept\n" + + long_string = ("And this is fine if you cannot accept\n" + "extraneous leading spaces.") ``` ```python Yes: - long_string = ("And this too is fine if you can not accept\n" + long_string = ("And this too is fine if you cannot accept\n" "extraneous leading spaces.") ``` @@ -2309,13 +2471,13 @@ 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 + 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): +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: @@ -2323,7 +2485,7 @@ with open("hello.txt") as hello_file: 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()`: ```python @@ -2369,13 +2531,15 @@ event ("Remove this code when all clients can handle XML responses."). ### 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.: ```python Yes: import os import sys + from typing import Mapping, Sequence ``` ```python @@ -2495,6 +2659,7 @@ No: except ValueError: baz(foo) ``` + @@ -2509,11 +2674,11 @@ 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. +[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. @@ -2539,29 +2704,22 @@ Always use a `.py` filename extension. Never use dashes. #### 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. +- single character names, except for specifically allowed cases: + + - 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 + - `__double_leading_and_trailing_underscore__` names (reserved by Python) - - - - -#### 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. +- 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. @@ -2591,7 +2749,7 @@ containing `exec "$0.py" "$@"`. -#### 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
@@ -2670,11 +2828,6 @@ containing `exec "$0.py" "$@"`.
-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. - @@ -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 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 def main(): ... @@ -2731,6 +2900,7 @@ up the function into smaller and more manageable pieces. ### 3.19 Type Annotations + @@ -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 too much flexibility. - @@ -2771,9 +2940,9 @@ def my_method(self, ... ``` -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. +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: @@ -2791,7 +2960,7 @@ def my_method( 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. +closing parenthesis with the `def`. ```python 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. ```python -class MyClass(object): +class MyClass: def __init__(self, stack: List["MyClass"]) -> None: @@ -2886,6 +3055,7 @@ def func(a:int=0) -> int: ... ``` + @@ -2917,6 +3087,7 @@ def implicit_optional(a: Text = None) -> Text: ... ``` + @@ -2939,6 +3110,7 @@ ComplexMap = Mapping[Text, List[Tuple[int, int]]] Other examples are complex nested types and multiple return variables from a function (as a tuple). + @@ -2954,6 +3126,7 @@ You can disable type checking on a line with the special comment # pytype: disable=attribute-error ``` + @@ -2971,6 +3144,7 @@ specify its type in a couple ways. a = SomeUndecoratedFunction() # type: Foo ``` + [*Annotated Assignments*](#annotated-assignments) : Use a colon and type between the variable name and value, as with function arguments. @@ -2979,15 +3153,16 @@ a = SomeUndecoratedFunction() # type: Foo a: Foo = SomeUndecoratedFunction() ``` + #### 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. +Typed lists can only contain objects of a single type. Typed tuples can either +have a single repeated type or a set number of elements with different types. +The latter is commonly used as the return type from a function. ```python 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] ``` + @@ -3036,6 +3212,7 @@ def check_length(x: AnyStr) -> AnyStr: raise ValueError() ``` + @@ -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. + @@ -3154,6 +3332,7 @@ if typing.TYPE_CHECKING: def f(x: "sketch.Sketch"): ... ``` + @@ -3176,7 +3355,7 @@ from typing import Any 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: ... ```