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_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_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))