How to properly annotate a ContextManager in PyCharm?

This is a current PyCharm issue: PY-36444

A workaround for the issue is to rewrite an example code of:

from contextlib import contextmanager

@contextmanager
def generator_function():
    yield "some value"

with generator_function() as value:
    print(value.upper())  # no PyCharm autocompletion

to

from contextlib import contextmanager
from typing import ContextManager

def wrapper() -> ContextManager[str]:
    @contextmanager
    def generator_function():
        yield "some value"

    return generator_function()

with wrapper() as value:
    print(value.upper())  # PyCharm autocompletion works

There is also an easier workaround of annotating the return type with ContextManager[str] but there are multiple reasons against this:

  • mypy will correctly emit errors for this annotation, as described in more detail in the PyCharm issue.
  • this is not guaranteed to work in the future because PyCharm will hopefully fix the issue and therefore break this workaround

I believe you can use ContextManager from typing, e.g.:

import contextlib
from typing import ContextManager
from pathlib import Path


@contextlib.contextmanager
def temp_borders_file() -> ContextManager[Path]:
    pass


with temp_borders_file() as borders_f:
    borders_f  # has type Path here