Skip to content

Commit 7a063f1

Browse files
authored
Improve documentation about writing type annotations (#5218)
Fixes #4383
1 parent 529ab21 commit 7a063f1

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

docs/dev/style.md

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,42 @@ Of course, if this import style fundamentally cannot be used, do not let this
5252
block submitting a pull request for the code as we will definitely grant
5353
exceptions.
5454

55-
## Typing based import cycles
55+
## Type annotations
56+
57+
Cirq makes extensive use of type annotations as defined by
58+
[PEP 484](https://peps.python.org/pep-0484/). All new code should use type
59+
annotations where possible, especially on public classes and functions to serve
60+
as documentation, but also on internal code so that the mypy typechecker can
61+
help catch coding errors.
62+
63+
For documentation purposes in particular, type annotations should match the way
64+
classes and functions are accessed by cirq users, which is typically on the
65+
top-level `cirq` namespace (for example, users use `cirq.Sampler` even though
66+
the sampler class is defined in `cirq.work.sampler.Sampler`). Code in cirq-core
67+
typically cannot import and use `cirq.Sampler` directly because this could
68+
create an import cycle where modules import each other (perhaps indirectly).
69+
Instead, the import of the top-level `cirq` library can be guarded by the
70+
`TYPE_CHECKING` constant provided by `typing`, and the type annotation can be
71+
quoted so that it is not evaluated when the module is imported but rather during
72+
type-checking:
5673

57-
An import cycle is where modules need to import each other (perhaps indirectly).
58-
Sometimes in order to add a type annotation you have to add an import which
59-
causes a cycle. To avoid this we use the `TYPE_CHECKING` constant provided
60-
by `typing`:
6174
```python
6275
from typing import TYPE_CHECKING
76+
6377
if TYPE_CHECKING:
64-
# pylint: disable=unused-import
65-
import module.that.causes.cycle
66-
```
67-
Note that if you do this you will need to use the string version of the type,
68-
```python
69-
def my_func() -> 'module.that.causes.cycle.MyClass':
70-
pass
78+
import cirq
79+
80+
def accepts_sampler(sampler: 'cirq.Sampler') -> None:
81+
...
7182
```
7283

84+
Use top-level `cirq.*` annotations like this when annotating new public types
85+
and classes. Older code may not adhere to this style and should be updated.
86+
87+
Note that type annotations may need to be quoted like this in other situations
88+
as well, such as when an annotation is a "forward reference" to a class defined
89+
later in the same file.
90+
7391
## Nomenclature
7492

7593
Using consistent wording across Cirq is important for lowering users

0 commit comments

Comments
 (0)