hypothesis
hypothesis copied to clipboard
register_type_strategy is not annotated that it accepts TypeAlias
This doesn't type check:
def is_hashable(v) -> bool:
try:
hash(v)
return True
except Exception:
return False
def hashables() -> st.SearchStrategy[Hashable]:
# not all values of all Hashable types are actually hashable
# e.g. Signalling NaNs
return st.from_type(Hashable).filter(is_hashable)
type HashableValue = Hashable
# this doesn't type check
st.register_type_strategy(HashableValue, hashables())
Diagnostics:
- Argument of type "TypeAliasType" cannot be assigned to parameter "custom_type" of type "type[Ex@register_type_strategy]" in function "register_type_strategy" Type "TypeAliasType" is not assignable to type "type[Hashable]" [reportArgumentType]
But it looks like it works as I intended:
@given(...)
def test_hashables(h: Hashable):
# still fails on Decimal("sNaN")
hash(h)
@settings(max_examples=1000)
@given(...)
def test_hashable_values(h: HashableValue):
# hasn't generated Decimal("sNaN")
hash(h)
type Annie = Any
@given(...)
def test_annie(x: Annie):
# still raises InvalidArgument, so TypeAliasses don't seem to circumvent checks
pass
Is this intended and should I not rely on this current behaviour? Or shall I write a PR?
This might be worth reporting upstream to mypy (and pyright). Type checker behavior differs for TypeAliasType when compared to TypeAlias and NewType:
from typing import TypeAliasType, TypeAlias, NewType, cast
from hypothesis import strategies as st
A: TypeAlias = int
B = NewType("B", int)
C = TypeAliasType("C", int) # or type C = int
# reveal_type(A) # type[int]
# reveal_type(B) # type[B]
# reveal_type(C) # TypeAliasType
st.register_type_strategy(A, st.just(1)) # works
st.register_type_strategy(B, st.just(cast(B, 1))) # works
st.register_type_strategy(C, st.just(1)) # type error (mypy and pyright)
This behavior is supported by Hypothesis. register_type_strategy accepts any of the following:
def is_a_type(thing: object) -> bool:
"""Return True if thing is a type or a generic type like thing."""
return (
isinstance(thing, type)
or is_generic_type(thing)
or is_a_new_type(thing)
or is_a_type_alias_type(thing)
)