Closed tybug closed 4 months ago
Oh this is fun. So I think hypothesis generates a max_value bound when it draws the integer for the day part (because the max day number varies depending on the year and month) - here. I hadn't anticipated that the draw parameters might be symbolic, but after a skim of the code, I think this should still work from the crosshair side.
I'd look for you on suggestions about what to do next though. We might just need to realize
every key or something?
Nice call, that's what's happening. We'll run into similar issues with dependent draws in user strategies too (eg draw an int then draw a list of that size), so we'll have to support symbolic kwargs.
I think in principle we can just realize the kwargs...I get a new error when trying to do so though:
any ideas?
well, I have something that works, but I doubt you'll be happy about it š
I think the root cause of the above error is nondeterminism from hypothesis operating on symbolic kwargs, before we do anything with them. For instance, caching kwargs to reduce memory.
I've worked around this by realizing all symbolic kwargs as soon as we get them, via post_test_case_hook
(renamed realize
): https://github.com/HypothesisWorks/hypothesis/compare/master...tybug:hypothesis:backend-realize?expand=1. If I understand correctly this handicaps crosshair's ability to reason about the value after the point this occurs. At the same time, I'm not sure avoiding prematurely realizing kwargs is practical in the hypothesis engine...though @Zac-HD may have opinions there. For instance, we'd probably have to disable this pooling behavior.
Here's a minimal example exhibiting this behavior (currently broken, fixed with the above branch):
@given(st.data())
def f(data):
n = data.draw(st.integers())
n2 = data.draw(st.integers(n, n))
f()
Under the branch, I believe n
would become non-symbolic as soon as it's passed to a strategy, preventing crosshair from reasoning about it further.
well... strategies where the arguments are provided by other strategies is a core feature for Hypothesis - see for example the .flatmap()
method! We're going to have to find some way of dealing with this, at whatever cost to our internals š«
Would a avoid_realization = False
variable that backends like crosshair can set to True
be acceptable? We can disable anything that would realize if set, like DataTree
or kwargs pooling. I'd like to avoid disabling optimizations for other (slightly more sane š) backends that don't need this.
Yeah, that seems pretty good to me - and skipping DataTree
when it's basically redundant with crosshair's internals seems pretty reasonable tbh. Or maybe we can insert into the DataTree
after we realize the sequence at the end of the test?
and skipping DataTree when it's basically redundant with crosshair's internals
I also thought this at first, but if we mix backends in the future it'd be nice to share deduplication information! That's far enough away that I'm not thinking about it too much though. post-inserting into DataTree
is probably doable, though there's enough subtle interactions there that I'd have to try it to see.
Seems to work well enough: https://github.com/HypothesisWorks/hypothesis/compare/master...tybug:hypothesis:backend-realize?expand=1. I also had to disable @cacheable
strategies - we'll see how bad of a performance hit that is š
works with hypothesis-crosshair v0.0.7 š (+ the above branch)
Somehow,
kwargs["max_value"]
(and onlymax_value
) on an integer ir node becomes symbolic here and errors when we go to cache based off it. This only happens on dates/datetimes so I'm suspecting crosshair interception there causes some of our code to be colored symbolically, but hypothesis' date strategy code may also be at fault.patch
Here's a logging patch that narrows the problem, if it's helpful:
With this, I get
followed by the above stacktrace error.