def find(specifier, condition, settings=None, random=None): settings = settings or Settings( max_examples=2000, min_satisfying_examples=0, ) search = strategy(specifier, settings) random = random or Random() def template_condition(template): return assume(condition(search.reify(template))) template_condition.__name__ = condition.__name__ tracker = Tracker() try: return search.reify( best_satisfying_template( search, random, template_condition, settings, None, tracker=tracker, )) except NoSuchExample: if search.size_upper_bound <= len(tracker): raise DefinitelyNoSuchExample( get_pretty_function_description(condition), search.size_upper_bound, ) raise NoSuchExample(get_pretty_function_description(condition))
def find(specifier, condition, settings=None, random=None, storage=None): settings = settings or Settings( max_examples=2000, min_satisfying_examples=0, max_shrinks=2000, ) search = strategy(specifier, settings) if storage is None and settings.database is not None: storage = settings.database.storage( u'find(%s)' % (binascii.hexlify(function_digest(condition)).decode(u'ascii'), )) random = random or Random() successful_examples = [0] def template_condition(template): with BuildContext(): result = search.reify(template) success = condition(result) if success: successful_examples[0] += 1 if not successful_examples[0]: verbose_report(lambda: u'Trying example %s' % (repr(result), )) elif success: if successful_examples[0] == 1: verbose_report(lambda: u'Found satisfying example %s' % (repr(result), )) else: verbose_report(lambda: u'Shrunk example to %s' % (repr(result), )) return success template_condition.__name__ = condition.__name__ tracker = Tracker() try: template = best_satisfying_template( search, random, template_condition, settings, tracker=tracker, max_parameter_tries=2, storage=storage, ) with BuildContext(): return search.reify(template) except Timeout: raise except NoSuchExample: if search.template_upper_bound <= len(tracker): raise DefinitelyNoSuchExample( get_pretty_function_description(condition), search.template_upper_bound, ) raise NoSuchExample(get_pretty_function_description(condition))
def find(specifier, condition, settings=None, random=None): settings = settings or Settings( max_examples=2000, min_satisfying_examples=0, ) search = strategy(specifier, settings) random = random or Random() successful_examples = [0] def template_condition(template): result = search.reify(template) success = condition(result) if success: successful_examples[0] += 1 if not successful_examples[0]: verbose_report(lambda: 'Trying example %s' % (show(result), )) elif success: if successful_examples[0] == 1: verbose_report(lambda: 'Found satisfying example %s' % (show(result), )) else: verbose_report(lambda: 'Shrunk example to %s' % (show(result), )) return assume(success) template_condition.__name__ = condition.__name__ tracker = Tracker() try: return search.reify( best_satisfying_template( search, random, template_condition, settings, None, tracker=tracker, )) except NoSuchExample: if search.size_upper_bound <= len(tracker): raise DefinitelyNoSuchExample( get_pretty_function_description(condition), search.size_upper_bound, ) raise NoSuchExample(get_pretty_function_description(condition))
def find( specifier: SearchStrategy[Ex], condition: Callable[[Any], bool], *, settings: Settings = None, random: Random = None, database_key: bytes = None ) -> Ex: """Returns the minimal example from the given strategy ``specifier`` that matches the predicate function ``condition``.""" if settings is None: settings = Settings(max_examples=2000) settings = Settings( settings, suppress_health_check=HealthCheck.all(), report_multiple_bugs=False ) if database_key is None and settings.database is not None: database_key = function_digest(condition) if not isinstance(specifier, SearchStrategy): raise InvalidArgument( "Expected SearchStrategy but got %r of type %s" % (specifier, type(specifier).__name__) ) specifier.validate() last = [] # type: List[Ex] @settings @given(specifier) def test(v): if condition(v): last[:] = [v] raise Found() if random is not None: test = seed(random.getrandbits(64))(test) test._hypothesis_internal_is_find = True test._hypothesis_internal_database_key = database_key try: test() except Found: return last[0] raise NoSuchExample(get_pretty_function_description(condition))
def find_satisfying_template(search_strategy, random, condition, tracker, settings, storage=None): """Attempt to find a template for search_strategy such that condition is truthy. Exceptions other than UnsatisfiedAssumption will be immediately propagated. UnsatisfiedAssumption will indicate that similar examples should be avoided in future. Returns such a template as soon as it is found, otherwise stops after settings.max_examples examples have been considered or settings.timeout seconds have passed (if settings.timeout > 0). May raise a variety of exceptions depending on exact circumstances, but these will all subclass either Unsatisfiable (to indicate not enough examples were found which did not raise UnsatisfiedAssumption to consider this a valid test) or NoSuchExample (to indicate that this probably means that condition is true with very high probability). """ satisfying_examples = 0 timed_out = False max_examples = settings.max_examples min_satisfying_examples = settings.min_satisfying_examples start_time = time.time() if storage: for example in storage.fetch(): if time_to_call_it_a_day(settings, start_time): break tracker.track(example) try: if condition(example): return example satisfying_examples += 1 except UnsatisfiedAssumption: pass build_context = BuildContext(random) parameter_source = ParameterSource(context=build_context, strategy=search_strategy, min_parameters=max( 2, int(float(max_examples) / 10))) for parameter in islice(parameter_source, max_examples - len(tracker)): if len(tracker) >= search_strategy.size_upper_bound: break if time_to_call_it_a_day(settings, start_time): break example = search_strategy.produce_template(build_context, parameter) if tracker.track(example) > 1: parameter_source.mark_bad() continue try: if condition(example): return example except UnsatisfiedAssumption: parameter_source.mark_bad() continue satisfying_examples += 1 run_time = time.time() - start_time timed_out = settings.timeout >= 0 and run_time >= settings.timeout if (satisfying_examples and len(tracker) >= search_strategy.size_lower_bound): raise DefinitelyNoSuchExample( get_pretty_function_description(condition), satisfying_examples, ) elif satisfying_examples < min_satisfying_examples: if timed_out: raise Timeout(condition, satisfying_examples, run_time) else: raise Unsatisfiable(condition, satisfying_examples, run_time) else: raise NoSuchExample(get_pretty_function_description(condition))
def find( specifier, # type: SearchStrategy condition, # type: Callable[[Any], bool] settings=None, # type: Settings random=None, # type: Any database_key=None, # type: bytes ): # type: (...) -> Any """Returns the minimal example from the given strategy ``specifier`` that matches the predicate function ``condition``.""" if settings is None: settings = Settings(max_examples=2000) settings = Settings(settings, suppress_health_check=HealthCheck.all()) if database_key is None and settings.database is not None: database_key = function_digest(condition) if not isinstance(specifier, SearchStrategy): raise InvalidArgument("Expected SearchStrategy but got %r of type %s" % (specifier, type(specifier).__name__)) specifier.validate() search = specifier random = random or new_random() successful_examples = [0] last_data = [None] last_repr = [None] def template_condition(data): with BuildContext(data): try: data.is_find = True with deterministic_PRNG(): result = data.draw(search) data.note(result) success = condition(result) except UnsatisfiedAssumption: data.mark_invalid() if success: successful_examples[0] += 1 if settings.verbosity >= Verbosity.verbose: if not successful_examples[0]: report(u"Tried non-satisfying example %s" % (nicerepr(result), )) elif success: if successful_examples[0] == 1: last_repr[0] = nicerepr(result) report(u"Found satisfying example %s" % (last_repr[0], )) last_data[0] = data elif (sort_key(hbytes(data.buffer)) < sort_key( last_data[0].buffer) ) and nicerepr(result) != last_repr[0]: last_repr[0] = nicerepr(result) report(u"Shrunk example to %s" % (last_repr[0], )) last_data[0] = data if success and not data.frozen: data.mark_interesting() runner = ConjectureRunner(template_condition, settings=settings, random=random, database_key=database_key) runner.run() note_engine_for_statistics(runner) if runner.interesting_examples: data = ConjectureData.for_buffer( list(runner.interesting_examples.values())[0].buffer) with BuildContext(data): with deterministic_PRNG(): return data.draw(search) if runner.valid_examples == 0 and (runner.exit_reason != ExitReason.finished): raise Unsatisfiable("Unable to satisfy assumptions of %s." % (get_pretty_function_description(condition), )) raise NoSuchExample(get_pretty_function_description(condition))
def find(specifier, condition, settings=None, random=None, database_key=None): """Returns the minimal example from the given strategy ``specifier`` that matches the predicate function ``condition``.""" settings = settings or Settings( max_examples=2000, min_satisfying_examples=0, max_shrinks=2000, ) settings = Settings(settings, perform_health_check=False) if database_key is None and settings.database is not None: database_key = function_digest(condition) if not isinstance(specifier, SearchStrategy): raise InvalidArgument( 'Expected SearchStrategy but got %r of type %s' % ( specifier, type(specifier).__name__ )) specifier.validate() search = specifier random = random or new_random() successful_examples = [0] last_data = [None] def template_condition(data): with BuildContext(data): try: data.is_find = True result = data.draw(search) data.note(result) success = condition(result) except UnsatisfiedAssumption: data.mark_invalid() if success: successful_examples[0] += 1 if settings.verbosity == Verbosity.verbose: if not successful_examples[0]: report(lambda: u'Trying example %s' % ( nicerepr(result), )) elif success: if successful_examples[0] == 1: report(lambda: u'Found satisfying example %s' % ( nicerepr(result), )) last_data[0] = data elif ( sort_key(hbytes(data.buffer)) < sort_key(last_data[0].buffer) ): report(lambda: u'Shrunk example to %s' % ( nicerepr(result), )) last_data[0] = data if success and not data.frozen: data.mark_interesting() start = time.time() runner = ConjectureRunner( template_condition, settings=settings, random=random, database_key=database_key, ) runner.run() note_engine_for_statistics(runner) run_time = time.time() - start if runner.interesting_examples: data = ConjectureData.for_buffer( list(runner.interesting_examples.values())[0].buffer) with BuildContext(data): return data.draw(search) if ( runner.valid_examples <= settings.min_satisfying_examples and runner.exit_reason != ExitReason.finished ): if settings.timeout > 0 and run_time > settings.timeout: raise Timeout(( 'Ran out of time before finding enough valid examples for ' '%s. Only %d valid examples found in %.2f seconds.' ) % ( get_pretty_function_description(condition), runner.valid_examples, run_time)) else: raise Unsatisfiable(( 'Unable to satisfy assumptions of ' '%s. Only %d examples considered satisfied assumptions' ) % ( get_pretty_function_description(condition), runner.valid_examples,)) raise NoSuchExample(get_pretty_function_description(condition))
def find_satisfying_template( search_strategy, random, condition, tracker, settings, storage=None, max_parameter_tries=None, ): """Attempt to find a template for search_strategy such that condition is truthy. Exceptions other than UnsatisfiedAssumption will be immediately propagated. UnsatisfiedAssumption will indicate that similar examples should be avoided in future. Returns such a template as soon as it is found, otherwise stops after settings.max_examples examples have been considered or settings.timeout seconds have passed (if settings.timeout > 0). May raise a variety of exceptions depending on exact circumstances, but these will all subclass either Unsatisfiable (to indicate not enough examples were found which did not raise UnsatisfiedAssumption to consider this a valid test) or NoSuchExample (to indicate that this probably means that condition is true with very high probability). """ satisfying_examples = 0 examples_considered = 0 timed_out = False max_iterations = max(settings.max_iterations, settings.max_examples) max_examples = min(max_iterations, settings.max_examples) min_satisfying_examples = min( settings.min_satisfying_examples, max_examples, ) start_time = time.time() if storage: for example in storage.fetch(search_strategy): if examples_considered >= max_iterations: break examples_considered += 1 if time_to_call_it_a_day(settings, start_time): break tracker.track(example) try: if condition(example): return example satisfying_examples += 1 except UnsatisfiedAssumption: pass if satisfying_examples >= max_examples: break parameter_source = ParameterSource( random=random, strategy=search_strategy, max_tries=max_parameter_tries, ) assert search_strategy.template_upper_bound >= 0 if isinstance(search_strategy.template_upper_bound, float): assert math.isinf(search_strategy.template_upper_bound) else: assert isinstance(search_strategy.template_upper_bound, int) for parameter in parameter_source: # pragma: no branch if len(tracker) >= search_strategy.template_upper_bound: break if examples_considered >= max_iterations: break if satisfying_examples >= max_examples: break if time_to_call_it_a_day(settings, start_time): break examples_considered += 1 try: example = search_strategy.draw_template(random, parameter) except BadTemplateDraw: debug_report('Failed attempt to draw a template') parameter_source.mark_bad() continue if tracker.track(example) > 1: debug_report('Skipping duplicate example') parameter_source.mark_bad() continue try: if condition(example): return example except UnsatisfiedAssumption: parameter_source.mark_bad() continue satisfying_examples += 1 run_time = time.time() - start_time timed_out = settings.timeout >= 0 and run_time >= settings.timeout if (satisfying_examples and len(tracker) >= search_strategy.template_upper_bound): raise DefinitelyNoSuchExample( get_pretty_function_description(condition), satisfying_examples, ) elif satisfying_examples < min_satisfying_examples: if timed_out: raise Timeout( ('Ran out of time before finding a satisfying example for ' '%s. Only found %d examples (%d satisfying assumptions) in ' + '%.2fs.') % (get_pretty_function_description(condition), len(tracker), satisfying_examples, run_time)) else: raise Unsatisfiable( ('Unable to satisfy assumptions of hypothesis %s. ' + 'Only %d out of %d examples considered satisfied assumptions') % (get_pretty_function_description(condition), satisfying_examples, len(tracker))) else: raise NoSuchExample(get_pretty_function_description(condition))
def find(specifier, condition, settings=None, random=None, database_key=None): settings = settings or Settings( max_examples=2000, min_satisfying_examples=0, max_shrinks=2000, ) if database_key is None and settings.database is not None: database_key = function_digest(condition) if not isinstance(specifier, SearchStrategy): raise InvalidArgument( 'Expected SearchStrategy but got %r of type %s' % ( specifier, type(specifier).__name__ )) specifier.validate() search = specifier random = random or new_random() successful_examples = [0] last_data = [None] def template_condition(data): with BuildContext(data): try: data.is_find = True result = data.draw(search) data.note(result) success = condition(result) except UnsatisfiedAssumption: data.mark_invalid() if success: successful_examples[0] += 1 if settings.verbosity == Verbosity.verbose: if not successful_examples[0]: report(lambda: u'Trying example %s' % ( nicerepr(result), )) elif success: if successful_examples[0] == 1: report(lambda: u'Found satisfying example %s' % ( nicerepr(result), )) else: report(lambda: u'Shrunk example to %s' % ( nicerepr(result), )) last_data[0] = data if success and not data.frozen: data.mark_interesting() from hypothesis.internal.conjecture.engine import ConjectureRunner from hypothesis.internal.conjecture.data import ConjectureData, Status start = time.time() runner = ConjectureRunner( template_condition, settings=settings, random=random, database_key=database_key, ) runner.run() note_engine_for_statistics(runner) run_time = time.time() - start if runner.last_data.status == Status.INTERESTING: data = ConjectureData.for_buffer(runner.last_data.buffer) with BuildContext(data): return data.draw(search) if runner.valid_examples <= settings.min_satisfying_examples: if settings.timeout > 0 and run_time > settings.timeout: raise Timeout(( 'Ran out of time before finding enough valid examples for ' '%s. Only %d valid examples found in %.2f seconds.' ) % ( get_pretty_function_description(condition), runner.valid_examples, run_time)) else: raise Unsatisfiable(( 'Unable to satisfy assumptions of ' '%s. Only %d examples considered satisfied assumptions' ) % ( get_pretty_function_description(condition), runner.valid_examples,)) raise NoSuchExample(get_pretty_function_description(condition))