繁体   English   中英

如何在 PyCharm 中正确注释 ContextManager?

[英]How to properly annotate a ContextManager in PyCharm?

我如何在 PyCharm 中注释contextmanager的 yield 类型,以便它正确地猜测with子句中使用的值的类型——就像它猜测在with open(...) as f f创建的 f 是一个文件一样?

例如,我有一个这样的上下文管理器:

@contextlib.contextmanager
def temp_borders_file(geometry: GEOSGeometry, name='borders.json'):
    with TemporaryDirectory() as temp_dir:
        borders_file = Path(dir) / name
        with borders_file.open('w+') as f:
            f.write(geometry.json)
        yield borders_file

with temp_borders_file(my_geom) as borders_f:
    do_some_code_with(borders_f...)

我如何让 PyCharm 知道像这样创建的每个borders_f都是一个pathlib.Path (从而为border_f上的Path方法启用自动完成)? 当然,我可以在每个with语句之后做一个像# type: Path这样的注释,但这似乎可以通过正确注释temp_border_file来完成。

我尝试将Pathtyping.Iterator[Path]typing.Generator[Path, None, None]作为temp_border_file的返回类型,并在上下文管理器的代码中添加# type: Path on borders_file ,但它似乎没有'帮助。

下面的脏解决方法。 会破坏mypy 最好不要使用它。


我相信您可以使用ContextManager from typing ,例如:

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

这是当前的 PyCharm 问题: PY-36444

该问题的解决方法是重写以下示例代码:

from contextlib import contextmanager

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

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

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

还有一个更简单的解决方法是使用ContextManager[str]注释返回类型,但有多种原因反对这样做:

  • mypy 将正确地为此注释发出错误,如 PyCharm 问题中更详细的描述。
  • 这不能保证在未来工作,因为 PyCharm 希望能解决这个问题,从而打破这个解决方法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM