@@ -213,8 +213,8 @@ that the arguments are actually unused.
213213
214214Use ` import ` statements for packages and modules only, not for individual
215215classes or functions. Classes imported from the
216- [ typing module] ( #typing-imports ) ,
217- [ typing_extensions module] ( https://github.com/python/typing/tree/master/typing_extensions ) ,
216+ [ ` typing ` module ] ( #typing-imports ) , [ ` collections.abc ` module] ( #typing-imports ) ,
217+ [ ` typing_extensions ` module] ( https://github.com/python/typing/tree/master/typing_extensions ) ,
218218and redirects from the
219219[ six.moves module] ( https://six.readthedocs.io/#module-six.moves )
220220are exempt from this rule.
@@ -254,8 +254,9 @@ Module names can still collide. Some module names are inconveniently long.
254254* Use ` import x ` for importing packages and modules.
255255* Use ` from x import y ` where ` x ` is the package prefix and ` y ` is the module
256256 name with no prefix.
257- * Use ` from x import y as z ` if two modules named ` y ` are to be imported or if
258- ` y ` is an inconveniently long name.
257+ * Use ` from x import y as z ` if two modules named ` y ` are to be imported, if
258+ ` y ` conflicts with a top-level name defined in the current module, or if ` y `
259+ is an inconveniently long name.
259260* Use ` import y as z ` only when ` z ` is a standard abbreviation (e.g., ` np ` for
260261 ` numpy ` ).
261262
313314 import absl.flags
314315 from doctor.who import jodie
315316
316- FLAGS = absl.flags.FLAGS
317+ _FOO = absl.flags.DEFINE_string( ... )
317318```
318319
319320``` python
322323 from absl import flags
323324 from doctor.who import jodie
324325
325- FLAGS = flags.FLAGS
326+ _FOO = flags.DEFINE_string( ... )
326327```
327328
328329* (assume this file lives in ` doctor/who/ ` where ` jodie.py ` also exists)*
@@ -416,7 +417,7 @@ Exceptions must follow certain conditions:
416417 # guarantee this specific behavioral reaction to API misuse.
417418 raise ValueError (f ' Min. port must be at least 1024, not { minimum} . ' )
418419 port = self ._find_next_open_port(minimum)
419- if not port:
420+ if port is None :
420421 raise ConnectionError (
421422 f ' Could not connect to service on port { minimum} or higher. ' )
422423 assert port >= minimum, (
@@ -509,13 +510,14 @@ assignments to global variables are done when the module is first imported.
509510
510511Avoid global variables.
511512
512- While they are technically variables, module- level constants are permitted and
513- encouraged. For example: `_MAX_HOLY_HANDGRENADE_COUNT = 3 ` . Constants must be
514- named using all caps with underscores. See [Naming](# s3.16-naming) below.
513+ If needed, global variables should be declared at the module level and made
514+ internal to the module by prepending an `_` to the name. External access to
515+ global variables must be done through public module- level functions. See
516+ [Naming](# s3.16-naming) below.
515517
516- If needed, globals should be declared at the module level and made internal to
517- the module by prepending an `_` to the name. External access must be done
518- through public module - level functions . See [Naming](# s3.16-naming) below.
518+ While module - level constants are technically variables, they are permitted and
519+ encouraged. For example: ` MAX_HOLY_HANDGRENADE_COUNT = 3 ` . Constants must be
520+ named using all caps with underscores . See [Naming](# s3.16-naming) below.
519521
520522< a id = " s2.6-nested" >< / a>
521523< a id = " 26-nested" >< / a>
@@ -955,11 +957,14 @@ Yes: def foo(a, b: Sequence = ()): # Empty tuple OK since tuples are immutable
955957```
956958
957959```python
960+ from absl import flags
961+ _FOO = flags.DEFINE_string(... )
962+
958963No: def foo(a, b = []):
959964 ...
960965No: def foo(a, b = time.time()): # The time the module was loaded???
961966 ...
962- No: def foo(a, b = FLAGS .my_thing ): # sys.argv has not yet been parsed...
967+ No: def foo(a, b = _FOO .value ): # sys.argv has not yet been parsed...
963968 ...
964969No: def foo(a, b: Mapping = {}): # Could still get passed to unchecked code
965970 ...
@@ -1471,7 +1476,7 @@ Type annotations (or "type hints") are for function or method arguments and
14711476return values:
14721477
14731478```python
1474- def func(a: int ) -> List [int ]:
1479+ def func(a: int ) -> list [int ]:
14751480```
14761481
14771482You can also declare the type of a variable using similar
@@ -2026,7 +2031,7 @@ aptly described using a one-line docstring.
20262031 ([example](http://numpy.org/doc/stable/reference/generated/numpy.linalg.qr.html)),
20272032 which frequently documents a tuple return value as if it were multiple
20282033 return values with individual names (never mentioning the tuple). Instead,
2029- describe such a return value as: "Returns a tuple (mat_a, mat_b), where
2034+ describe such a return value as: "Returns: A tuple (mat_a, mat_b), where
20302035 mat_a is ..., and ...". The auxiliary names in the docstring need not
20312036 necessarily correspond to any internal names used in the function body (as
20322037 those are not part of the API).
@@ -2044,7 +2049,7 @@ aptly described using a one-line docstring.
20442049def fetch_smalltable_rows(table_handle: smalltable.Table,
20452050 keys: Sequence[Union[bytes, str]],
20462051 require_all_keys: bool = False,
2047- ) -> Mapping[bytes, Tuple [str, ...]]:
2052+ ) -> Mapping[bytes, tuple [str, ...]]:
20482053 """ Fetches rows from a Smalltable.
20492054
20502055 Retrieves rows pertaining to the given keys from the Table instance
@@ -2081,7 +2086,7 @@ Similarly, this variation on `Args:` with a line break is also allowed:
20812086def fetch_smalltable_rows(table_handle: smalltable.Table,
20822087 keys: Sequence[Union[bytes, str]],
20832088 require_all_keys: bool = False,
2084- ) -> Mapping[bytes, Tuple [str, ...]]:
2089+ ) -> Mapping[bytes, tuple [str, ...]]:
20852090 """ Fetches rows from a Smalltable.
20862091
20872092 Retrieves rows pertaining to the given keys from the Table instance
@@ -2215,23 +2220,20 @@ punctuation, spelling, and grammar help with that goal.
22152220Use an
22162221[f-string](https://docs.python.org/3/reference/lexical_analysis.html#f-strings),
22172222the `%` operator, or the `format` method for formatting strings, even when the
2218- parameters are all strings. Use your best judgment to decide between `+` and `%`
2219- (or `format`) though. Do not use `%` or the `format` method for pure
2220- concatenation.
2223+ parameters are all strings. Use your best judgment to decide between `+` and
2224+ string formatting.
22212225
22222226```python
2223- Yes: x = a + b
2227+ Yes: x = f'name: {name} ; score: {n} '
22242228 x = '%s , %s !' % (imperative, expletive)
22252229 x = '{} , {} '.format(first, second)
22262230 x = 'name: %s ; score: %d ' % (name, n)
22272231 x = 'name: {} ; score: {} '.format(name, n)
2228- x = f'name: {name} ; score: {n} '
2232+ x = a + b
22292233```
22302234
22312235```python
2232- No: x = '%s%s ' % (a, b) # use + in this case
2233- x = '{}{} '.format(a, b) # use + in this case
2234- x = first + ', ' + second
2236+ No: x = first + ', ' + second
22352237 x = 'name: ' + name + '; score: ' + str(n)
22362238```
22372239
@@ -2524,7 +2526,7 @@ event ("Remove this code when all clients can handle XML responses.").
25242526# ## 3.13 Imports formatting
25252527
25262528Imports should be on separate lines; there are
2527- [exceptions for `typing` imports](# typing-imports).
2529+ [exceptions for `typing` and `collections.abc` imports](# typing-imports).
25282530
25292531E.g.:
25302532
@@ -2692,7 +2694,8 @@ change in complexity.
26922694
26932695`module_name` , `package_name` , `ClassName` , `method_name` , `ExceptionName` ,
26942696`function_name` , `GLOBAL_CONSTANT_NAME ` , `global_var_name` , `instance_var_name` ,
2695- `function_parameter_name` , `local_var_name` .
2697+ `function_parameter_name` , `local_var_name` , `query_proper_noun_for_thing` ,
2698+ `send_acronym_via_https` .
26962699
26972700
26982701Function names, variable names, and filenames should be descriptive; eschew
@@ -2713,6 +2716,8 @@ Always use a `.py` filename extension. Never use dashes.
27132716 - counters or iterators (e.g. `i` , `j` , `k` , `v` , et al.)
27142717 - `e` as an exception identifier in `try / except ` statements.
27152718 - `f` as a file handle in `with ` statements
2719+ - private [`TypeVar` s](# typing-type-var) with no constraints (e.g. `_T`,
2720+ `_U` , `_V` )
27162721
27172722 Please be mindful not to abuse single- character naming. Generally speaking,
27182723 descriptiveness should be proportional to the name' s scope of visibility.
@@ -2949,6 +2954,8 @@ the function into smaller and more manageable pieces.
29492954* In methods, only annotate `self ` , or `cls ` if it is necessary for proper
29502955 type information. e.g., `@ classmethod def create(cls : Type[T]) -> T: return
29512956 cls ()`
2957+ * Similarly, don' t feel compelled to annotate the return value of `__init__`
2958+ (where `None ` is the only valid option).
29522959* If any other variable or a returned type should not be expressed, use `Any` .
29532960* You are not required to annotate all the functions in a module.
29542961 - At least annotate your public APIs.
@@ -2993,7 +3000,7 @@ is too long, indent by 4 in a new line.
29933000
29943001```python
29953002def my_method(
2996- self , first_var: int ) -> Tuple [MyLongType1, MyLongType1]:
3003+ self , first_var: int ) -> tuple [MyLongType1, MyLongType1]:
29973004 ...
29983005```
29993006
@@ -3005,7 +3012,7 @@ closing parenthesis with the `def`.
30053012Yes:
30063013def my_method(
30073014 self , other_arg: Optional[MyLongType]
3008- ) -> Dict [OtherLongType, MyLongType]:
3015+ ) -> dict [OtherLongType, MyLongType]:
30093016 ...
30103017```
30113018
@@ -3017,7 +3024,7 @@ opening one, but this is less readable.
30173024No:
30183025def my_method(self ,
30193026 other_arg: Optional[MyLongType]
3020- ) -> Dict [OtherLongType, MyLongType]:
3027+ ) -> dict [OtherLongType, MyLongType]:
30213028 ...
30223029```
30233030
@@ -3027,9 +3034,9 @@ too long to be on a single line (try to keep sub-types unbroken).
30273034```python
30283035def my_method(
30293036 self ,
3030- first_var: Tuple[List [MyLongType1],
3031- List [MyLongType2]],
3032- second_var: List[Dict [
3037+ first_var: tuple[list [MyLongType1],
3038+ list [MyLongType2]],
3039+ second_var: list[dict [
30333040 MyLongType3, MyLongType4]]) -> None :
30343041 ...
30353042```
@@ -3146,7 +3153,7 @@ long:
31463153
31473154```python
31483155_ShortName = module_with_long_name.TypeWithLongName
3149- ComplexMap = Mapping[str , List[Tuple [int , int ]]]
3156+ ComplexMap = Mapping[str , list[tuple [int , int ]]]
31503157```
31513158
31523159Other examples are complex nested types and multiple return variables from a
@@ -3207,9 +3214,9 @@ have a single repeated type or a set number of elements with different types.
32073214The latter is commonly used as the return type from a function.
32083215
32093216```python
3210- a = [1 , 2 , 3 ] # type: List [ int ]
3211- b = (1 , 2 , 3 ) # type: Tuple [ int , ...]
3212- c = (1 , " 2" , 3.5 ) # type: Tuple [ int , str , float ]
3217+ a = [1 , 2 , 3 ] # type: list [ int ]
3218+ b = (1 , 2 , 3 ) # type: tuple [ int , ...]
3219+ c = (1 , " 2" , 3.5 ) # type: tuple [ int , str , float ]
32133220```
32143221
32153222< a id = " s3.19.10-typevars" >< / a>
@@ -3227,10 +3234,10 @@ function `TypeVar` is a common way to use them.
32273234Example:
32283235
32293236```python
3230- from typing import List, TypeVar
3231- T = TypeVar(" T " )
3237+ from typing import TypeVar
3238+ _T = TypeVar(" _T " )
32323239...
3233- def next (l: List[T ]) -> T :
3240+ def next (l: list[_T ]) -> _T :
32343241 return l.pop()
32353242```
32363243
@@ -3254,6 +3261,26 @@ def check_length(x: AnyStr) -> AnyStr:
32543261 raise ValueError ()
32553262```
32563263
3264+ A TypeVar must have a descriptive name, unless it meets all of the following
3265+ criteria:
3266+
3267+ * not externally visible
3268+ * not constrained
3269+
3270+ ```python
3271+ Yes:
3272+ _T = TypeVar(" _T" )
3273+ AddableType = TypeVar(" AddableType" , int , float , str )
3274+ AnyFunction = TypeVar(" AnyFunction" , bound = Callable)
3275+ ```
3276+
3277+ ```python
3278+ No:
3279+ T = TypeVar(" T" )
3280+ _T = TypeVar(" _T" , int , float , str )
3281+ _F = TypeVar(" _F" , bound = Callable)
3282+ ```
3283+
32573284< a id = " s3.19.11-string-types" >< / a>
32583285< a id = " s3.19.11-strings" >< / a>
32593286< a id = " 31911-string-types" >< / a>
@@ -3314,19 +3341,21 @@ return type is the same as the argument type in the code above, use
33143341< a id = " typing-imports" >< / a>
33153342# ### 3.19.12 Imports For Typing
33163343
3317- For classes from the `typing` module, always import the class itself. You are
3318- explicitly allowed to import multiple specific classes on one line from the
3319- `typing` module. Ex:
3344+ For classes from the `typing` and `collections.abc` modules for use in
3345+ annotations, always import the class itself. This keeps common annotations more
3346+ concise and matches typing practices used around the world. You are explicitly
3347+ allowed to import multiple specific classes on one line from the `typing` and
3348+ `collections.abc` modules. Ex:
33203349
33213350```python
3322- from typing import Any, Dict, Optional
3351+ from collections.abc import Mapping, Sequence
3352+ from typing import Any, Union
33233353```
33243354
3325- Given that this way of importing from `typing` adds items to the local
3326- namespace, any names in `typing` should be treated similarly to keywords, and
3327- not be defined in your Python code, typed or not . If there is a collision
3328- between a type and an existing name in a module, import it using `import x as
3329- y`.
3355+ Given that this way of importing adds items to the local namespace, names in
3356+ `typing` or `collections.abc` should be treated similarly to keywords, and not
3357+ be defined in your Python code, typed or not . If there is a collision between a
3358+ type and an existing name in a module, import it using `import x as y` .
33303359
33313360```python
33323361from typing import Any as AnyType
@@ -3400,12 +3429,12 @@ When annotating, prefer to specify type parameters for generic types; otherwise,
34003429[the generics' parameters will be assumed to be `Any`](https://www.python.org/dev/peps/pep-0484/#the-any-type).
34013430
34023431```python
3403- def get_names(employee_ids: List [int ]) -> Dict [int , Any]:
3432+ def get_names(employee_ids: list [int ]) -> dict [int , Any]:
34043433 ...
34053434```
34063435
34073436```python
3408- # These are both interpreted as get_names(employee_ids: List [Any]) -> Dict [Any, Any]
3437+ # These are both interpreted as get_names(employee_ids: list [Any]) -> dict [Any, Any]
34093438def get_names(employee_ids: list ) -> Dict:
34103439 ...
34113440
@@ -3418,13 +3447,13 @@ remember that in many cases [`TypeVar`](#typing-type-var) might be more
34183447appropriate:
34193448
34203449```python
3421- def get_names(employee_ids: List [Any]) -> Dict [Any, str ]:
3450+ def get_names(employee_ids: list [Any]) -> dict [Any, str ]:
34223451 """ Returns a mapping from employee ID to employee name for given IDs."""
34233452```
34243453
34253454```python
3426- T = TypeVar(' T ' )
3427- def get_names(employee_ids: List[T ]) -> Dict[T , str ]:
3455+ _T = TypeVar(' _T ' )
3456+ def get_names(employee_ids: list[_T ]) -> dict[_T , str ]:
34283457 """ Returns a mapping from employee ID to employee name for given IDs."""
34293458```
34303459
0 commit comments