Import cycles
An import cycle occurs where module A imports module B and module Bimports module A (perhaps indirectly, e.g. A -> B -> C -> A
).Sometimes in order to add type annotations you have to add extraimports to a module and those imports cause cycles that didn’t existbefore. If those cycles become a problem when running your program,there’s a trick: if the import is only needed for type annotations inforward references (string literals) or comments, you can write theimports inside if TYPE_CHECKING:
so that they are not executed at runtime.Example:
File foo.py
:
- from typing import List, TYPE_CHECKING
- if TYPE_CHECKING:
- import bar
- def listify(arg: 'bar.BarClass') -> 'List[bar.BarClass]':
- return [arg]
File bar.py
:
- from typing import List
- from foo import listify
- class BarClass:
- def listifyme(self) -> 'List[BarClass]':
- return listify(self)
Note
The TYPE_CHECKING
constant defined by the typing
moduleis False
at runtime but True
while type checking.
Python 3.5.1 doesn’t have TYPE_CHECKING
. An alternative isto define a constant named MYPY
that has the value False
at runtime. Mypy considers it to be True
when type checking.Here’s the above example modified to use MYPY
:
- from typing import List
- MYPY = False
- if MYPY:
- import bar
- def listify(arg: 'bar.BarClass') -> 'List[bar.BarClass]':
- return [arg]