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:

  1. from typing import List, TYPE_CHECKING
  2.  
  3. if TYPE_CHECKING:
  4. import bar
  5.  
  6. def listify(arg: 'bar.BarClass') -> 'List[bar.BarClass]':
  7. return [arg]

File bar.py:

  1. from typing import List
  2. from foo import listify
  3.  
  4. class BarClass:
  5. def listifyme(self) -> 'List[BarClass]':
  6. 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 Falseat runtime. Mypy considers it to be True when type checking.Here’s the above example modified to use MYPY:

  1. from typing import List
  2.  
  3. MYPY = False
  4. if MYPY:
  5. import bar
  6.  
  7. def listify(arg: 'bar.BarClass') -> 'List[bar.BarClass]':
  8. return [arg]