Pytest 的 "caplog" fixture 的类型提示是什么?

What is the type hint for Pytest's "caplog" fixture?

正如标题所说。我正在使用 pytest 附带的 caplog fixture。我正在使用 mypy 进行类型检查,想知道 caplog 的正确类型提示是什么。

例如:

def test_validate_regs(caplog: Any) -> None:
    validate_regs(df, logger)
    assert caplog.text == "", "No logs should have been made."

在这个例子中,我将它设置为 Any,但我想知道是否有更具体的类型提示我可以使用。

我尝试阅读有关 caplog 的文档,并在 github 中搜索 pytest 代码以查看 caplog 装置 returns,但除了 the following。但是使用 str 类型只是给了我一个错误,说 str 类型没有属性 text,这是有道理的。

当我打印 caplog 的类型时,我得到 _pytest.logging.LogCaptureFixture 虽然我不确定如何从 _pytest 导入它并使用它。

此答案适用于尚未或无法更新到 pytest 6+ 的用户
如果您使用的是 pytest 6+ 及更高版本,请查看更多 .


对于 pytest <6.x,你可以使用 _pytest.logging.LogCaptureFixture.

from _pytest.logging import LogCaptureFixture

def test_logs(caplog: LogCaptureFixture) -> None:
    ...

类型提示确实适用于 MyPy:

from _pytest.logging import LogCaptureFixture

def test_logs(caplog: LogCaptureFixture) -> None:
    caplog.at_level(logging.ERROR)
    caplog.at_level('10')
$ mypy test.py
/path/to/test.py:18: error: Argument 1 to "at_level" of "LogCaptureFixture" has incompatible type "str"; expected "int"
Found 3 errors in 2 files (checked 1 source file)

类型提示也适用于 Intellisense:

(上面的 Intellisense 弹出窗口匹配 API doc for get_records)。

请注意,_pytest 中的 _ 表明它不是“public” API(如前所述 ). Adding typing to fixtures started with this Github issue: Support for static typing:

I would also add that if you import from _pytest we do not guarantee stability. It's OK as long as you are willing to adapt if/when it breaks. We are working on a stable solution for this for pytest 6.1: #7469.

这导致了这个 Github 问题:Typing and public API:

pytest's "official" public API is exported by the pytest package, and everything else is defined in the _pytest package.

...并且“其他所有内容”包括 LogCaptureFixture 类型提示(从该问题的 TODO 列表中可以看出)。关于如何使其“正式”的讨论很多:

How do we want to officialy declare something as public API?

我认为应该有三个标准:

  • pytest导出。
  • 它没有 ___ 前缀。
  • 参考资料中有记载。

从 pytest 6.2.0 开始你应该使用 pytest.LogCaptureFixture

在此之前,您需要导入一个不推荐的私有名称(我们经常更改 _pytest 命名空间内的内部结构,恕不另行通知,并且不承诺向前或向后兼容)


免责声明:我是 pytest 核心开发人员