request.param 如何在间接参数化中进行注释?

How can request.param be annotated in indirect parametrization?

Indirect parametrization example 我想输入提示 request.param 指示特定类型,例如 str

问题是因为 fixt 的参数必须是 request fixture 似乎没有办法表明通过 "optional param 属性 应该是(引用文档)。

有哪些选择?也许在 fixt 文档字符串或 test_indirect 文档字符串中记录类型提示?

@pytest.fixture
def fixt(request):
    return request.param * 3

@pytest.mark.parametrize("fixt", ["a", "b"], indirect=True)
def test_indirect(fixt):
    assert len(fixt) == 3

截至目前(版本 6.2),pytest 不为 param 属性提供任何类型提示。如果您只需要键入 param 而不管 FixtureRequest 字段和方法的其余部分,您可以内联您自己的 impl 存根:

from typing import TYPE_CHECKING


if TYPE_CHECKING:
    class FixtureRequest:
        param: str
else:
    from typing import Any
    FixtureRequest = Any


@pytest.fixture
def fixt(request: FixtureRequest) -> str:
    return request.param * 3

如果您想扩展 FixtureRequest 的现有类型,存根会变得更加复杂:

from typing import TYPE_CHECKING


if TYPE_CHECKING:
    from pytest import FixtureRequest as __FixtureRequest
    class FixtureRequest(__FixtureRequest):
        param: str
else:
    from pytest import FixtureRequest


@pytest.fixture
def fixt(request: FixtureRequest) -> str:
    return request.param * 3

理想情况下,pytest 将允许 FixtureRequest 中的泛型 param 类型,例如

P = TypeVar("P")  # generic param type

class FixtureRequest(Generic[P]):
    def __init__(self, param: P, ...):
        ...

然后你就可以

from pytest import FixtureRequest

@pytest.fixture
def fixt(request: FixtureRequest[str]) -> str:
    return request.param * 3

但是,不确定这种类型是否适合当前 pytest 的代码库 - 我想它被省略是有原因的...

跟进 hoefling 关于泛型的回答,您可以将泛型纳入 TYPE_CHECKING 代码:

from typing import TYPE_CHECKING, Generic, TypeVar

if TYPE_CHECKING:
    from pytest import FixtureRequest as _FixtureRequest
    T = TypeVar("T")
    class FixtureRequest(_FixtureRequest, Generic[T]):
        param: T
else:
    from pytest import FixtureRequest

这样的代码将起作用,但您可能需要引用类型提示,因为 pytest 的 FixtureRequest 在运行时不是通用的:

@pytest.fixture
def fixt(request: "FixtureRequest[str]") -> str:
    return request.param * 3