Skip to content

Commit

Permalink
move realize to data.py, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tybug committed Jul 4, 2024
1 parent 22e9e52 commit 3d4fc6f
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 10 deletions.
19 changes: 18 additions & 1 deletion hypothesis-python/src/hypothesis/internal/conjecture/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,16 @@ def __init__(self, conjecturedata: Optional["ConjectureData"], /) -> None:
def per_test_case_context_manager(self):
return contextlib.nullcontext()

def realize(self, value):
def realize(self, value: T) -> T:
"""
Called whenever hypothesis requires a concrete (non-symbolic) value from
a potentially symbolic value. Hypothesis will not check that `value` is
symbolic before calling `realize`, so you should handle the case where
`value` is non-symbolic.
The returned value should be non-symbolic.
"""

return value

@abc.abstractmethod
Expand Down Expand Up @@ -1897,6 +1906,14 @@ def permitted(f):
}


# eventually we'll want to expose this publicly, but for now it lives as psuedo-internal.
def realize(value: object) -> object:
from hypothesis.control import current_build_context

context = current_build_context()
return context.data.provider.realize(value)


class ConjectureData:
@classmethod
def for_buffer(
Expand Down
13 changes: 10 additions & 3 deletions hypothesis-python/src/hypothesis/internal/conjecture/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
Set,
Tuple,
Union,
cast,
overload,
)

Expand All @@ -56,6 +57,7 @@
Example,
HypothesisProvider,
InterestingOrigin,
IRKWargsType,
IRNode,
Overrun,
PrimitiveProvider,
Expand Down Expand Up @@ -470,10 +472,15 @@ def test_function(self, data: ConjectureData) -> None:
f"got {type(value)}"
)

kwargs = cast(
IRKWargsType,
{
k: data.provider.realize(v)
for k, v in node.kwargs.items()
},
)
node.value = value
node.kwargs = {
k: data.provider.realize(v) for k, v in node.kwargs.items()
}
node.kwargs = kwargs

self._cache(data)
if data.invalid_at is not None: # pragma: no branch # coverage bug?
Expand Down
6 changes: 0 additions & 6 deletions hypothesis-python/src/hypothesis/provisional.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
from importlib import resources

from hypothesis import strategies as st
from hypothesis.control import current_build_context
from hypothesis.errors import InvalidArgument
from hypothesis.internal.conjecture import utils as cu
from hypothesis.strategies._internal.utils import defines_strategy
Expand Down Expand Up @@ -181,8 +180,3 @@ def url_encode(s):
paths,
st.just("") | _url_fragments_strategy,
)


def realize(value):
context = current_build_context()
return context.data.provider.realize(value)
25 changes: 25 additions & 0 deletions hypothesis-python/tests/conjecture/test_alt_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
AVAILABLE_PROVIDERS,
ConjectureData,
PrimitiveProvider,
realize,
)
from hypothesis.internal.conjecture.engine import ConjectureRunner
from hypothesis.internal.floats import SIGNALING_NAN
Expand Down Expand Up @@ -390,3 +391,27 @@ def test_function(n):
match="expected .* from BadRealizeProvider.realize",
):
test_function()


class RealizeProvider(TrivialProvider):
avoid_realization = True

def realize(self, value):
if isinstance(value, int):
return 42
return value


def test_realize():
with temp_register_backend("realize", RealizeProvider):

values = []

@given(st.integers())
@settings(backend="realize")
def test_function(n):
values.append(realize(n))

test_function()

assert all(n == 42 for n in values)

0 comments on commit 3d4fc6f

Please sign in to comment.