title: How does mypy use typing.TYPE_CHECKING to resolve the circular import annotation problem?
body: <p>I have the following structure for a package:</p>
  <pre><code>/prog
  -- /ui
  ---- /menus
  ------ __init__.py
  ------ main_menu.py
  ------ file_menu.py
  -- __init__.py
  __init__.py
  prog.py
  </code></pre>
  <p>These are my import/classes statements:</p>
  <p><strong><code>prog.py</code></strong>:</p>
  <pre><code>from prog.ui.menus import MainMenu
  </code></pre>
  <p><strong><code>/prog/ui/menus/__init__.py</code>:</strong></p>
  <pre><code>from prog.ui.menus.file_menu import FileMenu
  from prog.ui.menus.main_menu import MainMenu
  </code></pre>
  <p><strong><code>main_menu.py</code>:</strong></p>
  <pre><code>import tkinter as tk
  from prog.ui.menus import FileMenu
  
  class MainMenu(tk.Menu):
      
      def __init__(self, master: tk.Tk, **kwargs):
          super().__init__(master, **kwargs)
          self.add_cascade(label='File', menu=FileMenu(self, tearoff=False))
  
      [...]
  </code></pre>
  <p><strong><code>file_menu.py</code>:</strong></p>
  <pre><code>import tkinter as tk
  from prog.ui.menus import MainMenu
  
  class FileMenu(tk.Menu):
  
      def __init__(self, master: MainMenu, **kwargs):
          super().__init__(master, **kwargs)
          self.add_command(label='Settings')
  
      [...]
  </code></pre>
  <p>This will lead to a circular import problem in the sequence:</p>
  <p><code>prog.py</code> -&gt; <code>__init__.py</code> -&gt; <code>main_menu.py</code> -&gt; <code>file_menu.py</code> -&gt; <code>main_menu.py</code> -&gt; [...]</p>
  <p>From several searches it was suggested to update the imports to such:</p>
  <p><strong><code>file_menu.py</code></strong></p>
  <pre><code>import tkinter as tk
  from typing import TYPE_CHECKING
  
  if TYPE_CHECKING:
      from prog.ui.menus import MainMenu
  
  class FileMenu(tk.Menu):
  
      def __init__(self, master: 'MainMenu', **kwargs):
          super().__init__(master, **kwargs)
          self.add_command(label='Settings')
  
      [...]
  </code></pre>
  <p>I've read the <a href="https://docs.python.org/3/library/typing.html#typing.TYPE_CHECKING" rel="noreferrer">TYPE_CHECKING docs</a> and the <a href="https://mypy.readthedocs.io/en/stable/common_issues.html#import-cycles" rel="noreferrer">mypy docs</a> on the usage, but I do not follow how using this conditional resolves the cycle. Yes, at runtime it works because it evaluates to <code>False</code> so that is an &quot;operational resolution&quot;, but how does it not reappear during type checking:</p>
  <blockquote>
  <p>The TYPE_CHECKING constant defined by the typing module is False at runtime but True while type checking.</p>
  </blockquote>
  <p>I don't know a great deal about mypy, thus I fail to see how once the conditional evaluates to <code>True</code> that the issue will not reappear. What occurs differently between &quot;runtime&quot; and &quot;type checking&quot;? Does the process of &quot;type checking&quot; mean code is not executed?</p>
  <p><strong>Notes:</strong></p>
  <ul>
  <li><p>This is not a circular import dependency problem so dependency injection isn't needed</p>
  </li>
  <li><p>This is strictly a cycle induced by type hinting for static analysis</p>
  </li>
  <li><p>I am aware of the following import options (which work just fine):</p>
  <ul>
  <li><p>Replace <code>from [...] import [...]</code> with <code>import [...]</code></p>
  </li>
  <li><p>Conduct imports in <code>MainMenu.__init__</code> and leave <code>file_menu.py</code> alone</p>
  </li>
  </ul>
  </li>
  </ul>