I have a simple method on my_module.py
with the signature:
def my_method(value: float, extra: str = "something") -> str:
pass
Then I have a parameterized test on test_my_module.py
for it:
from typing import List
from typing import Union
import pytest
import my_module
@pytest.mark.parametrize(
"params, expected",
[
([1.0], "result1"),
([2.0], "result2"),
([2.0, "extra"], "result3")
],
)
def test_my_method(params: List[Union[int, str]], expected: str) -> None:
assert my_module.my_method(*params) == expected
When I run dynamic type tests such as typeguard
it passes. But with mypy
I get these [arg-type]
errors:
tests/test_my_module.py: note: In function "test_my_method":
tests/test_my_module.py:50:30: error: Argument 1 to "my_method" has incompatible type "*List[Union[int, str]]"; expected "float"
[arg-type]
assert my_module.my_method(*params) == expected
^
tests/test_my_module.py:50:30: error: Argument 1 to "my_method" has incompatible type "*List[Union[int, str]]"; expected "str"
[arg-type]
assert my_module.my_method(*params) == expected
^
Not really sure how should I annotate these types to make it pass. Note that this is a minimal example, so I want to stick unpacking the list of arguments params
in the list I create to parameterize the tests.
Any thoughts?
You can annotate with Tuple
instead of List
:
@pytest.mark.parametrize(
"params, expected",
[
([1.0], "result1"),
([2.0], "result2"),
([2.0, "extra"], "result3")
],
)
def test_my_method(params: Union[Tuple[float], Tuple[float, str]], expected: str) -> None:
assert my_module.my_method(*params) == expected
This promises a fixed number of elements and hence the static type checker can infer that the signature is compatible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With