Aatif Syed
Aatif Syed

Reputation: 71

Given a Hypothesis Strategy, can I get the minimal example?

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

Answers (2)

Zac Hatfield-Dodds
Zac Hatfield-Dodds

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

Aatif Syed
Aatif Syed

Reputation: 71

Found the answer. Use hypothesis.find:

"""Returns the minimal example from the given strategy specifier that matches the predicate function condition.

So we want the following code for the above example:

minimal = hypothesis.find(
    specifier=Foo.strategy(),
    condition=lambda _: True,
)

Upvotes: 3

Related Questions