request.param如何在间接参数化中注解?

问题描述 投票:0回答:3

间接参数化示例中 我想输入提示

request.param
指示特定类型,例如
str

问题是,由于

fixt
的参数必须是
request
固定装置,因此似乎无法指示通过 “可选
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
python pytest fixtures type-hinting
3个回答
16
投票

截至目前(版本 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
允许在
param
中使用通用的
FixtureRequest
类型,例如

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
的代码库一致 - 我猜它被省略是有原因的......


6
投票

按照 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

0
投票

现在你可以做:

import pytest

@pytest.fixture(scope="function", autouse=True)
def api_setup(redis_client: Redis, request: pytest.FixtureRequest) -> None:
    pass
© www.soinside.com 2019 - 2024. All rights reserved.