Reputation: 71
I'd like to get the minimum for a complicated class, for which I have already written a strategy.
Is it possible to ask hypothesis to simply give me the minimum example for a given strategy?
Context here is writing a strategy and a default minimum (for use in @hypothesis.example
) - surely the information for the latter is already contained in the former?
import dataclasses
import hypothesis
from hypothesis import strategies
@dataclasses.dataclass
class Foo:
bar: int
# Foo has many more attributes which are strategised over...
@classmethod
def strategy(cls):
return hypothesis.builds(cls, bar=strategies.integers())
@classmethod
def minimal(cls):
return hypothesis.minimal(cls.strategy())
Upvotes: 1
Views: 497
Reputation: 3003
You're correct that hypothesis.find(s, lambda _: True)
is the way to do this.
Context here is writing a strategy and a default minimum (for use in
@hypothesis.example()
) - surely the information for the latter is already contained in the former?
It's not just contained in it, but generating examples will almost always start by generating the minimal example* - because if that fails, we can stop immediately! So you might not need to do this at all ;-)
(the rare exceptions are strategies with complicated filters, where the attempted-minimal example is rejected by a filter - and we just move on to reasonably-minimal examples rather than shrinking to find the minimal one)
I'd also note that st.builds()
has native support for dataclasses, so you can omit the strategies (or pass hypothesis.infer
) for any argument where you don't have more specific constraints than "any instance of the type". For example, there's no need to pass bar=st.integers()
above!
Upvotes: 1
Reputation: 71
Found the answer.
Use hypothesis.find
:
"""Returns the minimal example from the given strategy
specifier
that matches the predicate functioncondition
.
So we want the following code for the above example:
minimal = hypothesis.find(
specifier=Foo.strategy(),
condition=lambda _: True,
)
Upvotes: 3