我正在使用
hypothesis
库,我想用类型提示来注释我的代码。 docs 提到 hypothesis.strategies.SearchStrategy
作为所有搜索策略的类型。
举这个例子:
@composite
def int_strategy(draw: DrawFn) -> hypothesis.strategies.SearchStrategy[int]:
... # some computation here resulting in ``x`` being an ``int``
return x
运行
mypy
将(正确地)导致以下错误:
error: Returning Any from function declared to return "SearchStrategy[Any]" [no-any-return]
我的意思是,我实际上返回的是
int
,而不是 SearchStrategy
。
我该如何输入注释我的
hypothesis
策略?
用
@composite
修饰的函数应该像平常一样进行类型提示:
@composite
def int_strategy(draw: DrawFn) -> int:
...
@composite
然后会自动将其转换为:
# As if it doesn't have the `draw` parameter and that it returns a `SearchStrategy`
def int_strategy() -> SearchStrategy[int]:
...
不相信我? 问Mypy:
# At call site
reveal_type(int_strategy) # () -> SearchStrategy[int]
reveal_type(int_strategy()) # SearchStrategy[int]
这与其他装饰器相同:函数的最终类型由其原始类型提示及其所有
@decorator
决定。在 composite()
的情况下,这就是 的定义方式(至少在类型检查时):
# Takes a function whose first argument is of type `DrawFn`
# and returns a function without that argument,
# returning a `SearchStrategy` that will output
# values of the same type as the original's return type.
def composite(
f: Callable[Concatenate[DrawFn, P], Ex]
) -> Callable[P, SearchStrategy[Ex]]:
...
事实上,使用
SearchStrategy[]
作为返回类型是一个常见的错误,维护者添加了逻辑以确保您会收到运行时警告:
@composite
def int_strategy() -> SearchStrategy[int]:
...
tests/test_foo.py:6
/project/tests/test_foo.py:6: HypothesisWarning: Return-type annotation is `st.SearchStrategy[int]`, but the decorated function should return a value (not a strategy)
您的函数需要返回 SearchStrategy 实例而不是实际值。
def int_strategy() -> hypothesis.strategies.SearchStrategy[int]:
... # some computation here resulting in ``x`` being an ``int``
return st.integers()