Project import generated by Copybara.

PiperOrigin-RevId: 480954960
This commit is contained in:
Google Python team 2022-10-13 12:19:10 -07:00 committed by Gregory P. Smith [Google LLC]
parent 099770e27c
commit 8638b2665f

View File

@ -272,7 +272,7 @@ package twice.
Exemptions from this rule: Exemptions from this rule:
* Symbols from the following modules and used to support static analysis and * Symbols from the following modules are used to support static analysis and
type checking: type checking:
* [`typing` module](#typing-imports) * [`typing` module](#typing-imports)
* [`collections.abc` module](#typing-imports) * [`collections.abc` module](#typing-imports)
@ -524,7 +524,7 @@ global variables must be done through public module-level functions. See
[Naming](#s3.16-naming) below. [Naming](#s3.16-naming) below.
While module-level constants are technically variables, they are permitted and While module-level constants are technically variables, they are permitted and
encouraged. For example: `MAX_HOLY_HANDGRENADE_COUNT = 3`. Constants must be encouraged. For example: `_MAX_HOLY_HANDGRENADE_COUNT = 3`. Constants must be
named using all caps with underscores. See [Naming](#s3.16-naming) below. named using all caps with underscores. See [Naming](#s3.16-naming) below.
<a id="s2.6-nested"></a> <a id="s2.6-nested"></a>
@ -710,8 +710,8 @@ 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 (unless the
means a dictionary). This is also an advantage. variable has type annotations). This is also an advantage.
<a id="s2.8.4-decision"></a> <a id="s2.8.4-decision"></a>
<a id="284-decision"></a> <a id="284-decision"></a>
@ -726,7 +726,6 @@ container while iterating over it.
```python ```python
Yes: for key in adict: ... Yes: for key in adict: ...
if key not in adict: ...
if obj in alist: ... if obj in alist: ...
for line in afile: ... for line in afile: ...
for k, v in adict.items(): ... for k, v in adict.items(): ...
@ -734,7 +733,6 @@ Yes: for key in adict: ...
```python ```python
No: for key in adict.keys(): ... No: for key in adict.keys(): ...
if not adict.has_key(key): ...
for line in afile.readlines(): ... for line in afile.readlines(): ...
``` ```
@ -964,7 +962,7 @@ Yes: def foo(a, b=None):
Yes: def foo(a, b: Optional[Sequence] = None): Yes: def foo(a, b: Optional[Sequence] = None):
if b is None: if b is None:
b = [] b = []
Yes: def foo(a, b: Sequence = ()): # Empty tuple OK since tuples are immutable Yes: def foo(a, b: Sequence = ()): # Empty tuple OK since tuples are immutable.
... ...
``` ```
@ -978,7 +976,7 @@ No: def foo(a, b=time.time()): # The time the module was loaded???
... ...
No: def foo(a, b=_FOO.value): # sys.argv has not yet been parsed... No: def foo(a, b=_FOO.value): # sys.argv has not yet been parsed...
... ...
No: def foo(a, b: Mapping = {}): # Could still get passed to unchecked code No: def foo(a, b: Mapping = {}): # Could still get passed to unchecked code.
... ...
``` ```
@ -1294,7 +1292,7 @@ more discussion.
Never use `staticmethod` unless forced to in order to integrate with an API Never use `staticmethod` unless forced to in order to integrate with an API
defined in an existing library. Write a module level function instead. defined in an existing library. Write a module level function instead.
Use `classmethod` only when writing a named constructor or a class-specific Use `classmethod` only when writing a named constructor, or a class-specific
routine that modifies necessary global state such as a process-wide cache. routine that modifies necessary global state such as a process-wide cache.
<a id="s2.18-threading"></a> <a id="s2.18-threading"></a>
@ -1659,27 +1657,27 @@ No: if (x):
Indent your code blocks with *4 spaces*. Indent your code blocks with *4 spaces*.
Never use tabs or mix tabs and spaces. In cases of implied line continuation, Never use tabs. Implied line continuation should align wrapped elements
you should align wrapped elements either vertically, as per the examples in the vertically (see [line length examples](#s3.2-line-length)), or use a hanging
[line length](#s3.2-line-length) section; or using a hanging indent of 4 spaces, 4-space indent. Closing (round, square or curly) brackets can be placed at the
in which case there should be nothing after the open parenthesis or bracket on end of the expression, or on separate lines, but then should be indented the
the first line. same as the line with the corresponding opening bracket.
```python ```python
Yes: # Aligned with opening delimiter Yes: # Aligned with opening delimiter.
foo = long_function_name(var_one, var_two, foo = long_function_name(var_one, var_two,
var_three, var_four) var_three, var_four)
meal = (spam, meal = (spam,
beans) beans)
# Aligned with opening delimiter in a dictionary # Aligned with opening delimiter in a dictionary.
foo = { foo = {
'long_dictionary_key': value1 + 'long_dictionary_key': value1 +
value2, value2,
... ...
} }
# 4-space hanging indent; nothing on first line # 4-space hanging indent; nothing on first line.
foo = long_function_name( foo = long_function_name(
var_one, var_two, var_three, var_one, var_two, var_three,
var_four) var_four)
@ -1687,7 +1685,18 @@ Yes: # Aligned with opening delimiter
spam, spam,
beans) beans)
# 4-space hanging indent in a dictionary # 4-space hanging indent; nothing on first line,
# closing parenthesis on a new line.
foo = long_function_name(
var_one, var_two, var_three,
var_four
)
meal = (
spam,
beans,
)
# 4-space hanging indent in a dictionary.
foo = { foo = {
'long_dictionary_key': 'long_dictionary_key':
long_dictionary_value, long_dictionary_value,
@ -1696,18 +1705,18 @@ Yes: # Aligned with opening delimiter
``` ```
```python ```python
No: # Stuff on first line forbidden No: # Stuff on first line forbidden.
foo = long_function_name(var_one, var_two, foo = long_function_name(var_one, var_two,
var_three, var_four) var_three, var_four)
meal = (spam, meal = (spam,
beans) beans)
# 2-space hanging indent forbidden # 2-space hanging indent forbidden.
foo = long_function_name( foo = long_function_name(
var_one, var_two, var_three, var_one, var_two, var_three,
var_four) var_four)
# No hanging indent in a dictionary # No hanging indent in a dictionary.
foo = { foo = {
'long_dictionary_key': 'long_dictionary_key':
long_dictionary_value, long_dictionary_value,
@ -2512,25 +2521,27 @@ documentation must explain clearly how resource lifetime is managed.
Use `TODO` comments for code that is temporary, a short-term solution, or Use `TODO` comments for code that is temporary, a short-term solution, or
good-enough but not perfect. good-enough but not perfect.
A `TODO` comment begins with the string `TODO` in all caps and a parenthesized A `TODO` comment begins with the word `TODO` in all caps, and a parenthesized
name, e-mail address, or other identifier context identifier. Ideally a bug reference, sometimes a username. A bug
of the person or issue with the best context about the problem. This is followed reference like `TODO(https://crbug.com/bug_id_number):` is
by an explanation of what there is to do. preferable, because bugs are tracked and have follow-up comments, whereas
individuals move around and may lose context over time. The `TODO` 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 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 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 referenced will fix the problem. Thus when you create a `TODO` with a username,
`TODO`, it is almost always your name it is almost always your *own* username that is given.
that is given.
```python ```python
# TODO(kl@gmail.com): Use a "*" here for string repetition. # TODO(crbug.com/192795): Investigate cpufreq optimizations.
# TODO(Zeke) Change this to use relations. # TODO(yourusername): File an issue and use a '*' for repetition.
``` ```
If your `TODO` is of the form "At a future date do something" make sure that you 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 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."). event ("Remove this code when all clients can handle XML responses.") that
future code maintainers will comprehend.
<a id="s3.13-imports-formatting"></a> <a id="s3.13-imports-formatting"></a>
<a id="313-imports-formatting"></a> <a id="313-imports-formatting"></a>
@ -2710,7 +2721,7 @@ change in complexity.
`send_acronym_via_https`. `send_acronym_via_https`.
Function names, variable names, and filenames should be descriptive; eschew Function names, variable names, and filenames should be descriptive; avoid
abbreviation. In particular, do not use abbreviations that are ambiguous or abbreviation. In particular, do not use abbreviations that are ambiguous or
unfamiliar to readers outside your project, and do not abbreviate by deleting unfamiliar to readers outside your project, and do not abbreviate by deleting
letters within a word. letters within a word.
@ -2969,7 +2980,7 @@ the function into smaller and more manageable pieces.
```python ```python
@classmethod @classmethod
def create(cls: Type[T]) -> T: def create(cls: Type[_T]) -> _T:
return cls() return cls()
``` ```
@ -2999,12 +3010,16 @@ the function into smaller and more manageable pieces.
Try to follow the existing [indentation](#indentation) rules. Try to follow the existing [indentation](#indentation) rules.
After annotating, many function signatures will become "one parameter per line". After annotating, many function signatures will become "one parameter per line".
To ensure the return type is also given its own line, a comma can be placed
after the last parameter.
```python ```python
def my_method(self, def my_method(
self,
first_var: int, first_var: int,
second_var: Foo, second_var: Foo,
third_var: Optional[Bar]) -> int: third_var: Optional[Bar],
) -> int:
... ...
``` ```
@ -3018,23 +3033,27 @@ def my_method(self, first_var: int) -> int:
``` ```
If the combination of the function name, the last parameter, and the return type If the combination of the function name, the last parameter, and the return type
is too long, indent by 4 in a new line. is too long, indent by 4 in a new line. When using line breaks, prefer putting
each parameter and the return type on their own lines and aligning the closing
```python parenthesis with the `def`:
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 ```python
Yes: Yes:
def my_method( def my_method(
self, other_arg: Optional[MyLongType] self,
) -> dict[OtherLongType, MyLongType]: other_arg: Optional[MyLongType],
) -> tuple[MyLongType1, MyLongType1]:
...
```
Optionally, the return type may be put on the same line as the last parameter:
```python
Okay:
def my_method(
self,
first_var: int,
second_var: int) -> dict[OtherLongType, MyLongType]:
... ...
``` ```
@ -3045,7 +3064,7 @@ opening one, but this is less readable.
```python ```python
No: No:
def my_method(self, def my_method(self,
other_arg: Optional[MyLongType] other_arg: Optional[MyLongType],
) -> dict[OtherLongType, MyLongType]: ) -> dict[OtherLongType, MyLongType]:
... ...
``` ```
@ -3059,7 +3078,8 @@ def my_method(
first_var: tuple[list[MyLongType1], first_var: tuple[list[MyLongType1],
list[MyLongType2]], list[MyLongType2]],
second_var: list[dict[ second_var: list[dict[
MyLongType3, MyLongType4]]) -> None: MyLongType3, MyLongType4]],
) -> None:
... ...
``` ```
@ -3176,8 +3196,8 @@ long:
<!-- Annotate below with `typing.TypeAlias` for 3.10. --> <!-- Annotate below with `typing.TypeAlias` for 3.10. -->
```python ```python
_ShortName = module_with_long_name.TypeWithLongName _LossAndGradient = tuple[tf.Tensor, tf.Tensor]
ComplexMap = Mapping[str, list[tuple[int, int]]] ComplexTFMap = Mapping[str, _LossAndGradient]
``` ```
Other examples are complex nested types and multiple return variables from a Other examples are complex nested types and multiple return variables from a