pytest
pytest copied to clipboard
Add typing information for parameterized fixtures
What's the problem this feature will solve?
Add typing information for parameterized fixtures to have better support for type checkers.
Describe the solution you'd like
Given a fixture like
@pytest.fixture(params=["--setup-only", "--setup-plan", "--setup-show"])
def mode(request):
return request.param
what is the type of request? I thought it would be FixtureRequest but this class doesn't have a param object. Thus I suggest to add a generic class ParametrizedFixtureRequest[T] where T is the type of the parameter. Thus in the above example one could annotate request: ParametrizedFixtureRequest[str] and then the type checker would know that request.param is a string.
Alternative Solutions
Additional context
@bluetech would it be sensible to introduce a generic protocol here ?
Thanks for bringing this up @tobiasdiez.
This seems doable but would require some work:
The param is only found on SubRequest and not on FixtureRequest, and I'm not yet sufficiently familiar with it and its weird relationship with FixtureRequest to say whether and how it should be exposed.
For unparametrized fixtures, pytest currently leaves request.param entirely undefined, i.e. accessing it leads to AttributeError. That's no good for static typing: Python/mypy does not provide a way to model this, there is no undefined type like in JavaScript (luckily).
Python/mypy currently does not support giving defaults to type parameters, so this will be a bit of an ergonomic hit for annotating with FixtureRequest in the non-parametrized case when using the disallow_any_generics mypy option. It will have to be FixtureRequest[None] (or something else depending on the solution to the previous point).
im happy to have 2 types for that, the fixture decorator could even apply it based on params and/or a flag for the param type required
then mypy would fail with missing attribute for non-parameterized fixtures while giving off the exxact type in the other case
On a related note: I'm happy to just add a param = None to FixtureRequest rather than leave it undefined (or a UNDEFINED sentinel if we want to distinguish between no parametrization vs parametrization with a None value, but I'm not sure of a use case where the distinction makes a difference). The current AttributeError a user gets is very unfriendly.
We did something similar with cached_result.
Parameter values may be none, we either have to have a extra flag for indication, or a singleton type
Any plans to implement this feature anytime soon?