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?