How to properly annotate a ContextManager in PyCharm?

前端 未结 2 1515
走了就别回头了
走了就别回头了 2021-01-18 09:45

How can I annotate the yield type of a contextmanager in PyCharm so that it properly guesses the type of the value used in the with clauses - just

相关标签:
2条回答
  • 2021-01-18 10:11

    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
    
    0 讨论(0)
  • 2021-01-18 10:15

    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
    0 讨论(0)
提交回复
热议问题