From 60f4775badfc57e5d7225e70868cdd11e43e5db4 Mon Sep 17 00:00:00 2001 From: Alexander Shorin Date: Thu, 3 Jan 2019 05:32:32 +0300 Subject: [PATCH] PoC of meta strategy, which draws others by a given weight distribution --- .../src/hypothesis/_strategies.py | 6 +++ .../src/hypothesis/provisional.py | 37 +++++++++++++++++++ .../src/hypothesis/strategies.py | 2 + 3 files changed, 45 insertions(+) diff --git a/hypothesis-python/src/hypothesis/_strategies.py b/hypothesis-python/src/hypothesis/_strategies.py index 0974873233..59c328619b 100644 --- a/hypothesis-python/src/hypothesis/_strategies.py +++ b/hypothesis-python/src/hypothesis/_strategies.py @@ -2319,3 +2319,9 @@ def emails(): return builds(u"{}@{}".format, local_part, domains()).filter( lambda addr: len(addr) <= 255 ) + + +def distributed(strategies, weights): + # type: (List[SearchStrategy], List[Union[int, float]]) -> SearchStrategy[Any] + from hypothesis.provisional import distributed + return distributed(strategies, weights) diff --git a/hypothesis-python/src/hypothesis/provisional.py b/hypothesis-python/src/hypothesis/provisional.py index 97d2625305..1aec7f178d 100644 --- a/hypothesis-python/src/hypothesis/provisional.py +++ b/hypothesis-python/src/hypothesis/provisional.py @@ -64,3 +64,40 @@ def ip6_addr_strings(): """ part = st.integers(0, 2 ** 16 - 1).map(u"{:04x}".format) return st.tuples(*[part] * 8).map(lambda a: u":".join(a).upper()) + + +def distributed(strategies, weights): + from hypothesis.internal.conjecture.utils import Sampler + from hypothesis.strategies import SearchStrategy + from hypothesis.searchstrategy.strategies import check_strategy + from hypothesis.internal.validation import check_type, InvalidArgument + + class DistributedStrategy(SearchStrategy): + def __init__(self, strategies, weights): + SearchStrategy.__init__(self) + self.sampler = Sampler(weights) + self.strategies = strategies + + def calc_has_reusable_values(self, recur): + return True + + def do_draw(self, data): + strategy = self.strategies[self.sampler.sample(data)] + return strategy.do_draw(data) + + assert strategies + + for strategy in strategies: + check_strategy(strategy) + + for weight in weights: + check_type((int, float), weight) + if weight < 0: + raise InvalidArgument("weight must be a positive number") + + if len(strategies) != len(weights): + raise InvalidArgument( + "The number of weights must match the number of strategies" + ) + + return DistributedStrategy(strategies, weights) diff --git a/hypothesis-python/src/hypothesis/strategies.py b/hypothesis-python/src/hypothesis/strategies.py index 5015a016ed..1cffcd08d4 100644 --- a/hypothesis-python/src/hypothesis/strategies.py +++ b/hypothesis-python/src/hypothesis/strategies.py @@ -32,6 +32,7 @@ decimals, deferred, dictionaries, + distributed, emails, fixed_dictionaries, floats, @@ -83,6 +84,7 @@ "decimals", "deferred", "dictionaries", + "distributed", "emails", "fixed_dictionaries", "floats",