def s_codes_extend(codes): return s.one_of( s.builds(app, codes, codes), s.builds(abstract, codes), s.builds(join, codes, codes), s.builds(QUOTE, codes), )
def models( model, # type: Type[dm.Model] **field_strategies # type: Union[st.SearchStrategy[Any], DefaultValueType] ): # type: (...) -> st.SearchStrategy[Any] """Return a strategy for examples of ``model``. .. warning:: Hypothesis creates saved models. This will run inside your testing transaction when using the test runner, but if you use the dev console this will leave debris in your database. ``model`` must be an subclass of :class:`~django:django.db.models.Model`. Strategies for fields may be passed as keyword arguments, for example ``is_staff=st.just(False)``. Hypothesis can often infer a strategy based the field type and validators - for best results, make sure your validators are derived from Django's and therefore have the known types and attributes. Passing a keyword argument skips inference for that field; pass a strategy or pass ``hypothesis.extra.django.models.default_value`` to skip inference for that field. Foreign keys are not automatically derived. If they're nullable they will default to always being null, otherwise you always have to specify them. For example, examples of a Shop type with a foreign key to Company could be generated with:: shop_strategy = models(Shop, company=models(Company)) """ result = {} for k, v in field_strategies.items(): if not isinstance(v, DefaultValueType): result[k] = v missed = [] # type: List[Text] for f in model._meta.concrete_fields: if not (f.name in field_strategies or isinstance(f, dm.AutoField)): result[f.name] = _get_strategy_for_field(f) if result[f.name].is_empty: missed.append(f.name) if missed: raise InvalidArgument( u'Missing arguments for mandatory field%s %s for model %s' % (u's' if missed else u'', u', '.join(missed), model.__name__)) for field in result: if model._meta.get_field(field).primary_key: # The primary key is generated as part of the strategy. We # want to find any existing row with this primary key and # overwrite its contents. kwargs = {field: result.pop(field)} kwargs['defaults'] = st.fixed_dictionaries(result) return _models_impl( st.builds(model.objects.update_or_create, **kwargs) ) # The primary key is not generated as part of the strategy, so we # just match against any row that has the same value for all # fields. return _models_impl(st.builds(model.objects.get_or_create, **result))
def s_codes_extend(terms): return s.one_of( s.builds(APP, terms, terms), s.builds(JOIN, terms, terms), s.builds(QUOTE, terms), s.builds(ABS, terms), s.builds(FUN, s_vars, terms), )
def s_terms_extend(terms): return s.one_of( s.builds(app, terms, terms), s.builds( bohm.abstract, terms.filter(lambda c: i0 not in quoted_vars(c)), ), s.builds(join, terms, terms), s.builds(QUOTE, terms), )
def from_dtype(dtype): # type: (np.dtype) -> st.SearchStrategy[Any] """Creates a strategy which can generate any value of the given dtype.""" check_type(np.dtype, dtype, 'dtype') # Compound datatypes, eg 'f4,f4,f4' if dtype.names is not None: # mapping np.void.type over a strategy is nonsense, so return now. return st.tuples( *[from_dtype(dtype.fields[name][0]) for name in dtype.names]) # Subarray datatypes, eg '(2, 3)i4' if dtype.subdtype is not None: subtype, shape = dtype.subdtype return arrays(subtype, shape) # Scalar datatypes if dtype.kind == u'b': result = st.booleans() # type: SearchStrategy[Any] elif dtype.kind == u'f': if dtype.itemsize == 2: result = st.floats(width=16) elif dtype.itemsize == 4: result = st.floats(width=32) else: result = st.floats() elif dtype.kind == u'c': if dtype.itemsize == 8: float32 = st.floats(width=32) result = st.builds(complex, float32, float32) else: result = st.complex_numbers() elif dtype.kind in (u'S', u'a'): # Numpy strings are null-terminated; only allow round-trippable values. # `itemsize == 0` means 'fixed length determined at array creation' result = st.binary(max_size=dtype.itemsize or None ).filter(lambda b: b[-1:] != b'\0') elif dtype.kind == u'u': result = st.integers(min_value=0, max_value=2 ** (8 * dtype.itemsize) - 1) elif dtype.kind == u'i': overflow = 2 ** (8 * dtype.itemsize - 1) result = st.integers(min_value=-overflow, max_value=overflow - 1) elif dtype.kind == u'U': # Encoded in UTF-32 (four bytes/codepoint) and null-terminated result = st.text(max_size=(dtype.itemsize or 0) // 4 or None ).filter(lambda b: b[-1:] != u'\0') elif dtype.kind in (u'm', u'M'): if '[' in dtype.str: res = st.just(dtype.str.split('[')[-1][:-1]) else: res = st.sampled_from(TIME_RESOLUTIONS) result = st.builds(dtype.type, st.integers(-2**63, 2**63 - 1), res) else: raise InvalidArgument(u'No strategy inference for {}'.format(dtype)) return result.map(dtype.type)
def steps(self): values = self.values() if not self.forked: return ( s.just(FORK_NOW) | s.builds(Insert, values, values, s.none()) | s.builds(Delete, values, values, s.none()) ) else: targets = s.sampled_from((self.left, self.right)) return s.builds(Insert, values, values, targets) | s.builds(Delete, values, values, targets)
def regex_strategy(regex, fullmatch): if not hasattr(regex, "pattern"): regex = re.compile(regex) is_unicode = isinstance(regex.pattern, text_type) parsed = sre_parse.parse(regex.pattern, flags=regex.flags) if not parsed: if is_unicode: return st.text() else: return st.binary() if is_unicode: base_padding_strategy = st.text() empty = st.just(u"") newline = st.just(u"\n") else: base_padding_strategy = st.binary() empty = st.just(b"") newline = st.just(b"\n") right_pad = base_padding_strategy left_pad = base_padding_strategy if fullmatch: right_pad = empty elif parsed[-1][0] == sre.AT: if parsed[-1][1] == sre.AT_END_STRING: right_pad = empty elif parsed[-1][1] == sre.AT_END: if regex.flags & re.MULTILINE: right_pad = st.one_of( empty, st.builds(operator.add, newline, right_pad) ) else: right_pad = st.one_of(empty, newline) if fullmatch: left_pad = empty elif parsed[0][0] == sre.AT: if parsed[0][1] == sre.AT_BEGINNING_STRING: left_pad = empty elif parsed[0][1] == sre.AT_BEGINNING: if regex.flags & re.MULTILINE: left_pad = st.one_of(empty, st.builds(operator.add, left_pad, newline)) else: left_pad = empty base = base_regex_strategy(regex, parsed).filter(regex.search) return maybe_pad(regex, base, left_pad, right_pad)
def make_radix(base): """ Build a radix from base. :param int base: the base of the radix """ list1 = build_nat(base, max_len) list2 = build_nat(base, max_len) list3 = build_nat(base, max_len) if list1 == [] and list2 == [] and list3 == []: return strategies.builds(Radix, strategies.just(0), list1, list2, list3, strategies.just(base)) else: return strategies.builds( Radix, strategies.sampled_from((-1, 1)), list1, list2, list3, strategies.just(base) )
def steps(self): strategies = [] for rule in self.rules(): converted_arguments = {} valid = True if rule.precondition is not None and not rule.precondition(self): continue for k, v in sorted(rule.arguments.items()): if isinstance(v, Bundle): bundle = self.bundle(v.name) if not bundle: valid = False break converted_arguments[k] = v if valid: strategies.append(TupleStrategy(( just(rule), FixedKeysDictStrategy(converted_arguments) ), tuple)) if not strategies: raise InvalidDefinition( u'No progress can be made from state %r' % (self,) ) for name, bundle in self.bundles.items(): if len(bundle) > 1: strategies.append( builds( ShuffleBundle, just(name), lists(integers(0, len(bundle) - 1)))) return one_of(strategies)
def ip4_addr_strings(): """A strategy for IPv4 address strings. This consists of four strings representing integers [0..255], without zero-padding, joined by dots. """ return st.builds('{}.{}.{}.{}'.format, *(4 * [st.integers(0, 255)]))
def subtitles(strict=True): '''A Hypothesis strategy to generate Subtitle objects.''' # max_value settings are just to avoid overflowing TIMEDELTA_MAX_DAYS by # using arbitrary low enough numbers timestamp_strategy = timedeltas(min_value=0, max_value=999999) # If we want to test \r, we'll test it by ourselves. It makes testing # harder without because we don't get the same outputs as inputs on Unix. content_strategy = st.text(min_size=1).filter(lambda x: '\r' not in x) proprietary_strategy = st.text().filter( lambda x: all(eol not in x for eol in '\r\n') ) if strict: content_strategy = content_strategy.filter(is_strictly_legal_content) subtitle_strategy = st.builds( srt.Subtitle, index=st.integers(min_value=0), start=timestamp_strategy, end=timestamp_strategy, proprietary=proprietary_strategy, content=content_strategy, ) return subtitle_strategy
def subtitles(strict=True): """A Hypothesis strategy to generate Subtitle objects.""" # max_value settings are just to avoid overflowing TIMEDELTA_MAX_DAYS by # using arbitrary low enough numbers. # # We also skip subs with start time >= end time, so we split them into two # groups to avoid overlap. start_timestamp_strategy = timedeltas(min_value=0, max_value=500000) end_timestamp_strategy = timedeltas(min_value=500001, max_value=999999) # If we want to test \r, we'll test it by ourselves. It makes testing # harder without because we don't get the same outputs as inputs on Unix. content_strategy = st.text(min_size=1).filter(lambda x: "\r" not in x) proprietary_strategy = st.text().filter( lambda x: all(eol not in x for eol in "\r\n") ) if strict: content_strategy = content_strategy.filter(is_strictly_legal_content) subtitle_strategy = st.builds( srt.Subtitle, index=st.integers(min_value=0), start=start_timestamp_strategy, end=end_timestamp_strategy, proprietary=proprietary_strategy, content=content_strategy, ) return subtitle_strategy
def reusable(): return st.one_of( st.sampled_from(base_reusable_strategies), st.builds( st.floats, min_value=st.none() | st.floats(), max_value=st.none() | st.floats(), allow_infinity=st.booleans(), allow_nan=st.booleans() ), st.builds(st.just, st.lists(max_size=0)), st.builds(st.sampled_from, st.lists(st.lists(max_size=0))), st.lists(reusable).map(st.one_of), st.lists(reusable).map(lambda ls: st.tuples(*ls)), )
def patches(): """Returns a strategy which generates a Patch object. At present, planex.patchqueue.Patchqueue only supports a single guard on each patch. """ # If support for multiple guards is added, the max_size constraint # can be increased. return st.builds(Patch, files(), st.sets(guards(), min_size=0, max_size=1))
def test_reports_repr_diff_in_flaky_error(): @given(builds(DifferentReprEachTime)) def rude(x): assert not any(t[3] == u"best_satisfying_template" for t in inspect.getouterframes(inspect.currentframe())) with raises(Flaky) as e: rude() assert u"Call 1:" in e.value.args[0]
def patchqueues(): """Returns a strategy which generates a PatchQueue object containing a list of uniquely-named Patch objects. """ return st.builds(PatchQueue, st.lists(patches(), unique_by=lambda x: x.patch.name, max_size=5))
def ip(cls): """ Strategy for IP generation. """ def format_ip(o1, o2, o3, o4): return '{:d}.{:d}.{:d}.{:d}'.format(o1, o2, o3, o4) octet = integers(1, 254) return builds(format_ip, octet, octet, octet, octet)
def offline_instruments(): """ Returns a strategy for any instrument that does not need the internet to do a query. """ offline_instr = ['lyra', 'noaa-indices', 'noaa-predict', 'soon', 'goes'] offline_instr = st.builds(a.Instrument, st.sampled_from(offline_instr)) return st.one_of(offline_instr)
def emails(): # Not capable of generating the full range of legal email # addresses (RFC 5321 ``Mailbox`` productions). Might be worth # expanding someday. Or might not. return strategies.builds( u"{local}@{domain}".format, local=_local_part(), domain=domains(), )
def urls(): """ Strategy for generating ``twisted.python.url.URL``\s. """ return s.builds( URL, scheme=s.just(u'https'), host=dns_names(), path=s.lists(s.text(max_size=64), min_size=1, max_size=10))
def network(cls): """ Strategy for generation of networks in CIDR notation. """ def format_network(ip, routing_prefix): return '{0:s}/{1:d}'.format(ip, routing_prefix) routing_prefix = integers(0, 32) return builds(format_network, cls.ip(), routing_prefix)
def online_instruments(): """ Returns a strategy for any instrument that does not need the internet to do a query """ online_instr = ['rhessi'] online_instr = st.builds(a.Instrument, st.sampled_from(online_instr)) return online_instr
def export_line(cls): """ Strategy that generates nfs export lines. """ def format_export(path, clients): return '{0:s} {1:s}'.format(path, ' '.join(clients)) path = cls.path() clients = lists(cls.client(), min_size=1) return builds(format_export, path, clients)
def client_string(cls): """ Strategy for generation of nfs clients. """ def format_client(host, options): return '{0:s}{1:s}'.format(host, options) host = cls.host() options = cls.options_string() return builds(format_client, host, options)
def steps(self): if not self.space: return builds(Action, just('setup'), tuples(st_keys, st_values)) global_actions = [Action('copydict', ()), Action('cleardict', ())] if self.space.reference: return ( self.st_setitem() | sampled_from(global_actions) | self.st_updateitem() | self.st_delitem()) else: return (self.st_setitem() | sampled_from(global_actions))
def offline_instruments(): """ Returns a strategy for any instrument that does not need the internet to do a query """ offline_instr = ['lyra', 'norh', 'noaa-indices', 'noaa-predict', 'goes'] offline_instr = st.builds(a.Instrument, st.sampled_from(offline_instr)) eve = st.just(a.Instrument('eve') & a.Level(0)) return st.one_of(offline_instr, eve)
def domains(): """A strategy for :rfc:`1035` fully qualified domain names.""" atoms = st.text(string.ascii_letters + '0123456789-', min_size=1, max_size=63 ).filter(lambda s: '-' not in s[0] + s[-1]) return st.builds( lambda x, y: '.'.join(x + [y]), st.lists(atoms, min_size=1), # TODO: be more devious about top-level domains st.sampled_from(['com', 'net', 'org', 'biz', 'info']) ).filter(lambda url: len(url) <= 255)
def test_resolving_recursive_type(): try: assert isinstance(st.builds(Tree).example(), Tree) except ResolutionFailed: assert sys.version_info[:2] == (3, 5) pytest.xfail("python 3.5 typing module may not resolve annotations") except TypeError: # TypeError raised if typing.get_type_hints(Tree.__init__) fails; see # https://github.com/HypothesisWorks/hypothesis-python/issues/1074 assert sys.version_info[:2] == (3, 5) pytest.skip("Could not find type hints to resolve")
def test_errors_are_deferred_until_repr_is_calculated(): s = st.builds( lambda x, y: 1, st.just(IHaveABadRepr()), y=st.one_of( st.sampled_from((IHaveABadRepr(),)), st.just(IHaveABadRepr())) ).map(lambda t: t).filter(lambda t: True).flatmap( lambda t: st.just(IHaveABadRepr())) with pytest.raises(ValueError): repr(s)
def from_attrs_attribute(attrib, target): """Infer a strategy from the metadata on an attr.Attribute object.""" # Try inferring from the default argument. Note that this will only help # the user passed `infer` to builds() for this attribute, but in that case # we use it as the minimal example. default = st.nothing() if isinstance(attrib.default, attr.Factory): if not getattr(attrib.default, "takes_self", False): # new in 17.1 default = st.builds(attrib.default.factory) elif attrib.default is not attr.NOTHING: default = st.just(attrib.default) # Try inferring None, exact values, or type from attrs provided validators. null = st.nothing() # updated to none() on seeing an OptionalValidator in_collections = [] # list of in_ validator collections to sample from validator_types = set() # type constraints to pass to types_to_strategy() if attrib.validator is not None: validator = attrib.validator if isinstance(validator, attr.validators._OptionalValidator): null = st.none() validator = validator.validator if isinstance(validator, attr.validators._AndValidator): vs = validator._validators else: vs = [validator] for v in vs: if isinstance(v, attr.validators._InValidator): if isinstance(v.options, string_types): in_collections.append(list(all_substrings(v.options))) else: in_collections.append(v.options) elif isinstance(v, attr.validators._InstanceOfValidator): validator_types.add(v.type) # This is the important line. We compose the final strategy from various # parts. The default value, if any, is the minimal shrink, followed by # None (again, if allowed). We then prefer to sample from values passed # to an in_ validator if available, but infer from a type otherwise. # Pick one because (sampled_from((1, 2)) | from_type(int)) would usually # fail validation by generating e.g. zero! if in_collections: sample = st.sampled_from(list(ordered_intersection(in_collections))) strat = default | null | sample else: strat = default | null | types_to_strategy(attrib, validator_types) # Better to give a meaningful error here than an opaque "could not draw" # when we try to get a value but have lost track of where this was created. if strat.is_empty: raise ResolutionFailed( "Cannot infer a strategy from the default, validator, type, or " "converter for attribute=%r of class=%r" % (attrib, target) ) return strat
def object_schema(schema: dict) -> st.SearchStrategy[Dict[str, JSONType]]: """Handle a manageable subset of possible schemata for objects.""" required = schema.get("required", []) # required keys min_size = max(len(required), schema.get("minProperties", 0)) max_size = schema.get("maxProperties", math.inf) assert min_size <= max_size, (min_size, max_size) names = schema.get("propertyNames", {}) # schema for optional keys if names == FALSEY: assert min_size == 0, schema return st.builds(dict) names["type"] = "string" properties = schema.get("properties", {}) # exact name: value schema patterns = schema.get("patternProperties", {}) # regex for names: value schema # schema for other values; handled specially if nothing matches additional = schema.get("additionalProperties", {}) additional_allowed = additional != FALSEY dependencies = schema.get("dependencies", {}) dep_names = {k: v for k, v in dependencies.items() if isinstance(v, list)} dep_schemas = {k: v for k, v in dependencies.items() if k not in dep_names} del dependencies name_strats = ( st.sampled_from( sorted(dep_names) + sorted(dep_schemas) + sorted(properties)) if (dep_names or dep_schemas or properties) else st.nothing(), from_schema(names) if additional_allowed else st.nothing(), st.one_of([st.from_regex(p) for p in sorted(patterns)]), ) all_names_strategy = st.one_of([s for s in name_strats if not s.is_empty ]).filter(make_validator(names).is_valid) @st.composite # type: ignore def from_object_schema(draw: Any) -> Any: """Do some black magic with private Hypothesis internals for objects. It's unfortunate, but also the only way that I know of to satisfy all the interacting constraints without making shrinking totally hopeless. If any Hypothesis maintainers are reading this... I'm so, so sorry. """ # Hypothesis internals are not type-annotated... I do mean *black* magic! elements = cu.many( draw(st.data()).conjecture_data, min_size=min_size, max_size=max_size, average_size=min(min_size + 5, (min_size + max_size) / 2), ) out: dict = {} while elements.more(): for key in required: if key not in out: break else: for k in set(dep_names).intersection(out): # pragma: no cover # nocover because some of these conditionals are rare enough # that not all test runs hit them, but are still essential. key = next((n for n in dep_names[k] if n not in out), None) if key is not None: break else: key = draw( all_names_strategy.filter(lambda s: s not in out)) pattern_schemas = [ patterns[rgx] for rgx in sorted(patterns) if re.search(rgx, string=key) is not None ] if key in properties: pattern_schemas.insert(0, properties[key]) if pattern_schemas: out[key] = draw(merged_as_strategies(pattern_schemas)) else: out[key] = draw(from_schema(additional)) for k, v in dep_schemas.items(): if k in out and not make_validator(v).is_valid(out): out.pop(key) elements.reject() for k in set(dep_names).intersection(out): assume(set(out).issuperset(dep_names[k])) return out return from_object_schema()
def test_may_not_fill_with_non_nan_when_unique_is_set_and_type_is_not_number(): @given(nps.arrays( dtype='U', shape=10, unique=True, fill=st.just(u''))) def test(arr): pass with pytest.raises(InvalidArgument): test() @given(st.data(), st.builds('{}[{}]'.format, st.sampled_from(('datetime64', 'timedelta64')), st.sampled_from(nps.TIME_RESOLUTIONS) ).map(np.dtype) ) def test_inferring_from_time_dtypes_gives_same_dtype(data, dtype): ex = data.draw(nps.from_dtype(dtype)) assert dtype == ex.dtype @given(st.data(), nps.byte_string_dtypes() | nps.unicode_string_dtypes()) def test_inferred_string_strategies_roundtrip(data, dtype): # Check that we never generate too-long or nul-terminated strings, which # cannot be read back out of an array. arr = np.zeros(shape=1, dtype=dtype) ex = data.draw(nps.from_dtype(arr.dtype)) arr[0] = ex assert arr[0] == ex
def points(): x = integers(min_value=-100, max_value=100) y = integers(min_value=-100, max_value=100) return builds(Point, x, y)
def test_cannot_force_inference_for_unannotated_arg(): with pytest.raises(InvalidArgument): st.builds(non_annotated_func, a=infer, c=st.none()).example() with pytest.raises(InvalidArgument): st.builds(non_annotated_func, a=st.none(), c=infer).example()
def test_required_args(target, args, kwargs): # Mostly checking that `self` (and only self) is correctly excluded st.builds( target, *map(st.just, args), **{k: st.just(v) for k, v in kwargs.items()} ).example()
)) def test_replaces_decimals_unaffected(x, persister): assert persister._replace_decimals(x) == x texts = st.text(max_size=5) events = st.builds( Event, kind=st.sampled_from(['task', 'control']), task_id=texts, timestamp=st.floats(min_value=0, allow_nan=False, allow_infinity=False), terminal=st.booleans(), success=st.booleans(), task_config=st.dictionaries( max_size=5, keys=texts, values=st.lists( st.one_of( texts, st.dictionaries(max_size=5, keys=texts, values=texts), ), max_size=5, ) ), raw=st.sampled_from([None]), ) @settings(max_examples=50) @given(x=events) def test_event_to_item_timestamp(x, persister): res = persister._event_to_item(x)['M']
of 2D points on the surface of an ellipse. n (int, optional): The number of points on the surface of the ellipsoid (ellipse). Returns: :math:`(N, 3)` or :math:`(N, 2)` :class:`numpy.ndarray`: The points. """ points = [] points = np.zeros((n, 3)) points[:, 0] = np.random.normal(0, a, n) points[:, 1] = np.random.normal(0, b, n) if c > 0: points[:, 2] = np.random.normal(0, c, n) ds = np.linalg.norm(points / [a, b, c if c else 1], axis=-1) points /= ds[:, np.newaxis] return points if c else points[:, :2] EllipsoidSurfaceStrategy = builds( points_from_ellipsoid_surface, floats(0.1, 5), floats(0.1, 5), floats(0.1, 5), integers(5, 15), ) EllipseSurfaceStrategy = builds(points_from_ellipsoid_surface, floats(0.1, 5), floats(0.1, 5), n=integers(5, 15))
def test_build_class_with_target_kwarg(): NamedTupleWithTargetField = collections.namedtuple('Something', ['target']) ds.builds(NamedTupleWithTargetField, target=ds.integers()).example()
def dicts(keys, vals, max_size=3): return s.builds(Dict, s.lists(s.tuples(keys, vals), max_size=max_size))
def lists(vals, max_size=3): return s.builds(List, s.lists(vals, max_size=max_size))
def subscripts(values, slice_): return s.builds(Subscript, values, slice_)
return self.s.repr_tree() class Subscript(Node): node_class = astroid.Subscript class List(Node): node_class = astroid.List class Dict(Node): node_class = astroid.Dict consts = s.builds(astroid.Const, s.none() | s.integers() | s.text()) def subscripts(values, slice_): return s.builds(Subscript, values, slice_) def lists(vals, max_size=3): return s.builds(List, s.lists(vals, max_size=max_size)) def dicts(keys, vals, max_size=3): return s.builds(Dict, s.lists(s.tuples(keys, vals), max_size=max_size)) NestedLists = s.deferred(lambda: consts | lists(NestedLists))
BYearBegin, ) # ---------------------------------------------------------------- # Helpers for generating random data with warnings.catch_warnings(): warnings.simplefilter('ignore') min_dt = pd.Timestamp(1900, 1, 1).to_pydatetime(), max_dt = pd.Timestamp(1900, 1, 1).to_pydatetime(), gen_date_range = st.builds( pd.date_range, start=st.datetimes( # TODO: Choose the min/max values more systematically min_value=pd.Timestamp(1900, 1, 1).to_pydatetime(), max_value=pd.Timestamp(2100, 1, 1).to_pydatetime()), periods=st.integers(min_value=2, max_value=100), freq=st.sampled_from('Y Q M D H T s ms us ns'.split()), tz=st.one_of(st.none(), dateutil_timezones(), pytz_timezones()), ) gen_random_datetime = st.datetimes(min_value=min_dt, max_value=max_dt, timezones=st.one_of(st.none(), dateutil_timezones(), pytz_timezones())) # The strategy for each type is registered in conftest.py, as they don't carry # enough runtime information (e.g. type hints) to infer how to build them. gen_yqm_offset = st.one_of(*map(st.from_type, [ MonthBegin, MonthEnd, BMonthBegin, BMonthEnd, QuarterBegin, QuarterEnd,
"""Similar to ascii_text, but does not generate multiline strings.""" return text(_ascii_inline, min_size=min_size, max_size=max_size) # Strategy for identifiers, i.e. strings that can be used as symbols (function # names, etc.) in Python programs. # Unqualified identifiers cannot contain ".", qualified identifiers can # (but only between unqualified identifiers, i.e. not at the beginning or end). unqualified_identifiers = text(string.ascii_letters, min_size=1, max_size=5) qualified_identifiers = lists(unqualified_identifiers, min_size=2, max_size=3).map( ".".join ) identifiers = unqualified_identifiers | qualified_identifiers # Strategy for python.Line objects. lines = builds(py.Line, ascii_inline_text(), indent_levels) # Strategy for lists of strings to be used as comment text in tests. comments = lists(ascii_inline_text(), max_size=3) # Strategy for python.Statement objects. Basically, if you ask for a Statement, # you get an instance of one of Statement's subclasses. # All Statement subclasses should be mentioned here. # We need deferred to break the cyclic dependency between builds() that depend statements. statements = deferred( lambda: one_of( opaque_blocks, functions, decorations, classes, standalones,
def test_does_not_error_on_unhashable_kwarg(): with pytest.raises(InvalidArgument): st.builds(lambda alphabet: 1, alphabet=['a', 'b', 'c']).validate()
def test_builds_can_specify_target_with_target_kwarg(): ds.builds(x=ds.integers(), target=lambda x: x).example()
return [ Segment(start, end) for start, end in combinations(points_list, 2) ] return (strategies.lists(points, min_size=2, max_size=8, unique=True).map(to_net)) rational_segments_lists = ((rational_coordinates_strategies.map( planar.segments).flatmap(strategies.lists)) | (rational_coordinates_strategies.map( planar.points).flatmap(points_to_nets))) segments_lists = ( (coordinates_strategies.map(planar.segments).flatmap(strategies.lists)) | (coordinates_strategies.map(planar.points).flatmap(points_to_nets))) empty_multipolygons = strategies.builds(Multipolygon, strategies.builds(list)) empty_multiregions = strategies.builds(list) empty_multisegments = strategies.builds(Multisegment, strategies.builds(list)) multipolygons = coordinates_strategies.flatmap(planar.multipolygons) multiregions = coordinates_strategies.flatmap(planar.multicontours) multisegments = coordinates_strategies.flatmap(planar.multisegments) empty_multisegments_with_multisegments = strategies.tuples( empty_multisegments, multisegments) rational_multisegments_strategies = (rational_coordinates_strategies.map( planar.multisegments)) rational_multisegments_pairs = ( rational_multisegments_strategies.flatmap(to_pairs)) rational_multisegments_triplets = ( rational_multisegments_strategies.flatmap(to_triplets)) multisegments_strategies = coordinates_strategies.map(planar.multisegments) multisegments_pairs = multisegments_strategies.flatmap(to_pairs)
def test_builds_raises_with_no_target(): with pytest.raises(InvalidArgument): ds.builds().example()
def to_json(self): return json.dumps(self.value) @classmethod def from_json(cls, string): value = string return cls(value) # Passing a zero-arg function to `deferred` lets us write recursive definitions! json_strat = st.deferred(lambda: st.one_of( # JSON values are defined as nil, false, true, number, string, ... st.none(), st.booleans(), st.floats(), st.text(), # or arrays of json, or "objects" ie string: json dictionaries. st.lists(json_strat), st.dictionaries(st.text(), json_strat))) # `builds` draws an example from `json_strat`, then calls Record(value=...) @given(st.builds(Record, value=json_strat)) def test_record_json_roundtrip(record): string = record.to_json() new = Record.from_json(string) #assert record == new # TODO: fix the first problem in the code being tested # TODO: fix the second problem by using hypothesis.assume in the test, # or an argument to one of the strategies defining json
def test_force_builds_to_infer_strategies_for_default_args(): # By default, leaves args with defaults and minimises to 2+4=6 assert minimal(st.builds(annotated_func), lambda ex: True) == 6 # Inferring integers() for args makes it minimise to zero assert minimal(st.builds(annotated_func, b=infer, d=infer), lambda ex: True) == 0
def test_raises_for_arg_with_unresolvable_annotation(): with pytest.raises(ResolutionFailed): st.builds(unknown_annotated_func).example() with pytest.raises(ResolutionFailed): st.builds(unknown_annotated_func, a=st.none(), c=infer).example()
class Foo: def __init__(self, x): pass class Bar(Foo): pass class Baz(Foo): pass st.register_type_strategy(Bar, st.builds(Bar, st.integers())) st.register_type_strategy(Baz, st.builds(Baz, st.integers())) @pytest.mark.parametrize( "var,expected", [ (typing.TypeVar("V"), object), (typing.TypeVar("V", bound=int), int), (typing.TypeVar("V", bound=Foo), (Bar, Baz)), (typing.TypeVar("V", bound=typing.Union[int, str]), (int, str)), (typing.TypeVar("V", int, str), (int, str)), ], ) @settings(suppress_health_check=[HealthCheck.too_slow]) @given(data=st.data())
def test_cannot_pass_infer_as_posarg(): with pytest.raises(InvalidArgument): st.builds(annotated_func, infer).example()
thread.start() thread.join() assert results == ["success", "success"] @given(integers()) def test_can_call_an_argument_f(f): # See issue https://github.com/HypothesisWorks/hypothesis-python/issues/38 # for details pass Litter = namedtuple("Litter", ("kitten1", "kitten2")) @given(builds(Litter, integers(), integers())) def test_named_tuples_are_of_right_type(litter): assert isinstance(litter, Litter) @fails_with(AttributeError) @given(integers().map(lambda x: x.nope)) @settings(suppress_health_check=HealthCheck.all()) def test_fails_in_reify(x): pass @given(text("a")) def test_a_text(x): assert set(x).issubset(set("a"))
def test_issue_946_regression(): # Turned type hints into kwargs even if the required posarg was passed st.builds(annotated_func, st.integers()).example()
def strat_two(draw): return draw(st.builds(dict, some_text=st.text(min_size=1)))
def strat_one(draw): return draw(st.builds(dict, val=st.builds(dict, two=strat_two())))
def strat(): return st.builds(dict, one=strat_one())
return importlib.import_module("unittest.mock") else: return pytest.importorskip("mock") # ---------------------------------------------------------------- # Global setup for tests using Hypothesis # Registering these strategies makes them globally available via st.from_type, # which is use for offsets in tests/tseries/offsets/test_offsets_properties.py for name in 'MonthBegin MonthEnd BMonthBegin BMonthEnd'.split(): cls = getattr(pd.tseries.offsets, name) st.register_type_strategy( cls, st.builds( cls, n=st.integers(-99, 99), normalize=st.booleans(), )) for name in 'YearBegin YearEnd BYearBegin BYearEnd'.split(): cls = getattr(pd.tseries.offsets, name) st.register_type_strategy( cls, st.builds( cls, n=st.integers(-5, 5), normalize=st.booleans(), month=st.integers(min_value=1, max_value=12), )) for name in 'QuarterBegin QuarterEnd BQuarterBegin BQuarterEnd'.split():
def test_builds_repr(): assert repr(st.builds(foo, st.just(1), x=st.just(10))) == \ u'builds(foo, just(1), x=just(10))'