title: Typing __exit__ in 3.5 fails on runtime, but typechecks
body: <p>What is the proper type signature for <code>__exit__</code>? I have the following:</p>
  
  <pre><code>from types import TracebackType
  from typing import Optional, Type
  
  class Foo:
      def __enter__(self) -&gt; 'Foo':
          return self
  
      def __exit__(self, exc_type: Optional[Type[BaseException]],
                   exc_value: Optional[BaseException],
                   traceback: Optional[TracebackType]) -&gt; bool:
          return False
  </code></pre>
  
  <p>On recent mypy (0.560) this typechecks with <code>--strict</code> (and I have moderate faith in this signature, because I stole it from the innards of the typeshed).</p>
  
  <p>When this script is run with python 3.6, as expected nothing happens. But when run with 3.5.2, we get an exception:</p>
  
  <pre><code>Traceback (most recent call last):
    File "/home/student/mypy_test/test.py", line 4, in &lt;module&gt;
      class Foo: #(ContextManager['Foo']):
    File "/home/student/mypy_test/test.py", line 8, in Foo
      def __exit__(self, exc_type: Optional[Type[BaseException]],
    File "/usr/lib/python3.5/typing.py", line 649, in __getitem__
      return Union[arg, type(None)]
    File "/usr/lib/python3.5/typing.py", line 552, in __getitem__
      dict(self.__dict__), parameters, _root=True)
    File "/usr/lib/python3.5/typing.py", line 512, in __new__
      for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
    File "/usr/lib/python3.5/typing.py", line 512, in &lt;genexpr&gt;
      for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
    File "/usr/lib/python3.5/typing.py", line 1077, in __subclasscheck__
      if super().__subclasscheck__(cls):
    File "/home/student/.local/share/virtualenvs/sf_cs328-crowdsourced-QAuuIxFA/lib/python3.5/abc.py", line 225, in __subclasscheck__
      for scls in cls.__subclasses__():
  TypeError: descriptor '__subclasses__' of 'type' object needs an argument
  </code></pre>
  
  <p>If you remove parameters until the exception disappears, we find that the problem type is the first: <code>exc_type: Optional[Type[BaseException]]</code>.</p>
  
  <p><em>Note:</em> To get it to complain if the type signature does not match (when run with mypy), you need to change <code>class Foo:</code> to <code>class Foo(ContextManager['Foo'])</code>. I didn't do this in the snippet, because <code>typing</code> in Python 3.5.2 is missing <code>Coroutine</code>, <code>Awaitable</code>, <code>ContextManager</code>, etc (this is the version in LTS releases of old-ish distros). I wrote about a workaround for this here: <a href="https://stackoverflow.com/a/49952293/568785">https://stackoverflow.com/a/49952293/568785</a>. So I guess, the full reproducible example is:</p>
  
  <pre><code># Workaround for ContextManager missing in 3.5.2 typing
  from typing import Any, TypeVar, TYPE_CHECKING
  try:
      from typing import ContextManager
  except ImportError:
      class _ContextManager:
          def __getitem__(self, index: Any) -&gt; None:
              return type(object())
  
      if not TYPE_CHECKING:
          ContextManager = _ContextManager()
  
  # The actual issue:
  from types import TracebackType
  from typing import Optional, Type
  
  class Foo:
      def __enter__(self) -&gt; 'Foo':
          return self
  
      def __exit__(self, exc_type: Optional[Type[BaseException]],
                   exc_value: Optional[BaseException],
                   traceback: Optional[TracebackType]) -&gt; bool:
          return False
  </code></pre>
  
  <p>I've verified that not inheriting <code>ContextManager</code> for running in Python 3.5.2 still produces the error (so this exception isn't a product of this hack, it's a product of the 3.5.2 runtime's typing library not liking the signature of <code>__exit__</code>).</p>
  
  <p>Presumably, this is another bug in Python 3.5's <code>typing</code> library. Is there a sane way to work around this?</p>