Skip to content
Advertisement

How can request.param be annotated in indirect parametrization?

In the Indirect parametrization example I want to type hint request.param indicating a specific type, a str for example.

The problem is since the argument to fixt must be the request fixture there seems to be no way to indicate what type the parameters passed through the “optional param attribute” should be (quoting the documentation).

What are the alternatives? Perhaps documenting the type hint in the fixt docstring, or in the test_indirect docstring?

@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

Advertisement

Answer

As of now (version 6.2), pytest doesn’t provide any type hint for the param attribute. If you need to just type param regardless of the rest of FixtureRequest fields and methods, you can inline your own impl stub:

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

If you want to extend existing typing of FixtureRequest, the stubbing gets somewhat more complex:

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

Ideally, pytest would allow generic param types in FixtureRequest, e.g.

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

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

You would then just do

from pytest import FixtureRequest

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

Not sure, however, whether this typing is agreeable with the current pytest‘s codebase – I guess it was omitted for a reason…

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement