def array_dtypes( subtype_strategy=scalar_dtypes(), # type: st.SearchStrategy[np.dtype] min_size=1, # type: int max_size=5, # type: int allow_subarrays=False, # type: bool ): # type: (...) -> st.SearchStrategy[np.dtype] """Return a strategy for generating array (compound) dtypes, with members drawn from the given subtype strategy.""" order_check("size", 0, min_size, max_size) # Field names must be native strings and the empty string is weird; see #1963. if PY2: field_names = st.binary(min_size=1) else: field_names = st.text(min_size=1) elements = st.tuples(field_names, subtype_strategy) if allow_subarrays: elements |= st.tuples( field_names, subtype_strategy, array_shapes(max_dims=2, max_side=2) ) return st.lists( elements=elements, min_size=min_size, max_size=max_size, unique_by=lambda d: d[0], )
def convert(expansion): parts = [] for p in expansion: if parts and ignore_names: # Chance to insert ignored substrings between meaningful # tokens, e.g. whitespace between values in JSON. parts.append( st.just(u"") | st.one_of([strategies[name] for name in ignore_names])) if p.name in strategies: # This might be a Terminal, or it might be a NonTerminal # that we've previously handled. parts.append(strategies[p.name]) else: # It must be the first time we've encountered this NonTerminal. # Recurse to handle it, relying on lazy strategy instantiation # to allow forward references, then add it to the strategies # cache to avoid infinite loops. assert isinstance(p, lark.grammar.NonTerminal) s = st.one_of([convert(ex) for ex in nonterminals[p.name]]) parts.append(s) strategies[p.name] = s # Special-case rules with only one expansion; it's worthwhile being # efficient when this includes terminals! Otherwise, join the parts. if len(parts) == 1: return parts[0] return st.tuples(*parts).map(u"".join)
def do_draw(self, data): # 1 - Select a valid top-level domain (TLD) name # 2 - Check that the number of characters in our selected TLD won't # prevent us from generating at least a 1 character subdomain. # 3 - Randomize the TLD between upper and lower case characters. domain = data.draw( st.sampled_from(TOP_LEVEL_DOMAINS).filter(lambda tld: len( tld) + 2 <= self.max_length).flatmap(lambda tld: st.tuples( *[st.sampled_from([c.lower(), c.upper()]) for c in tld]).map(u"".join))) # The maximum possible number of subdomains is 126, # 1 character subdomain + 1 '.' character, * 126 = 252, # with a max of 255, that leaves 3 characters for a TLD. # Allowing any more subdomains would not leave enough # characters for even the shortest possible TLDs. elements = cu.many(data, min_size=1, average_size=1, max_size=126) while elements.more(): # Generate a new valid subdomain using the regex strategy. sub_domain = data.draw( st.from_regex(self.label_regex, fullmatch=True)) if len(domain) + len(sub_domain) >= self.max_length: data.stop_example(discard=True) break domain = sub_domain + "." + domain return domain
def integer_array_indices(shape, result_shape=array_shapes(), dtype="int"): # type: (Shape, SearchStrategy[Shape], np.dtype) -> st.SearchStrategy[Tuple[np.ndarray, ...]] """Return a search strategy for tuples of integer-arrays that, when used to index into an array of shape ``shape``, given an array whose shape was drawn from ``result_shape``. Examples from this strategy shrink towards the tuple of index-arrays:: len(shape) * (np.zeros(drawn_result_shape, dtype), ) * ``shape`` a tuple of integers that indicates the shape of the array, whose indices are being generated. * ``result_shape`` a strategy for generating tuples of integers, which describe the shape of the resulting index arrays. The default is :func:`~hypothesis.extra.numpy.array_shapes`. The shape drawn from this strategy determines the shape of the array that will be produced when the corresponding example from ``integer_array_indices`` is used as an index. * ``dtype`` the integer data type of the generated index-arrays. Negative integer indices can be generated if a signed integer type is specified. Recall that an array can be indexed using a tuple of integer-arrays to access its members in an arbitrary order, producing an array with an arbitrary shape. For example: .. code-block:: pycon >>> from numpy import array >>> x = array([-0, -1, -2, -3, -4]) >>> ind = (array([[4, 0], [0, 1]]),) # a tuple containing a 2D integer-array >>> x[ind] # the resulting array is commensurate with the indexing array(s) array([[-4, 0], [0, -1]]) Note that this strategy does not accommodate all variations of so-called 'advanced indexing', as prescribed by NumPy's nomenclature. Combinations of basic and advanced indexes are too complex to usefully define in a standard strategy; we leave application-specific strategies to the user. Advanced-boolean indexing can be defined as ``arrays(shape=..., dtype=bool)``, and is similarly left to the user. """ check_type(tuple, shape, "shape") check_argument( shape and all(isinstance(x, integer_types) and x > 0 for x in shape), "shape=%r must be a non-empty tuple of integers > 0" % (shape, ), ) check_type(SearchStrategy, result_shape, "result_shape") check_argument(np.issubdtype(dtype, np.integer), "dtype=%r must be an integer dtype" % (dtype, )) signed = np.issubdtype(dtype, np.signedinteger) def array_for(index_shape, size): return arrays( dtype=dtype, shape=index_shape, elements=st.integers(-size if signed else 0, size - 1), ) return result_shape.flatmap(lambda index_shape: st.tuples( *[array_for(index_shape, size) for size in shape]))
def ip6_addr_strings(): """A strategy for IPv6 address strings. This consists of sixteen quads of hex digits (0000 .. FFFF), joined by colons. Values do not currently have zero-segments collapsed. """ part = st.integers(0, 2 ** 16 - 1).map(u"{:04x}".format) return st.tuples(*[part] * 8).map(lambda a: u":".join(a).upper())
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 array_dtypes( subtype_strategy=scalar_dtypes(), # type: st.SearchStrategy[np.dtype] min_size=1, # type: int max_size=5, # type: int allow_subarrays=False, # type: bool ): # type: (...) -> st.SearchStrategy[np.dtype] """Return a strategy for generating array (compound) dtypes, with members drawn from the given subtype strategy.""" order_check("size", 0, min_size, max_size) native_strings = st.from_type(str).filter( bool) # See issue #1798 re: filter! elements = st.tuples(native_strings, subtype_strategy) if allow_subarrays: elements |= st.tuples(native_strings, subtype_strategy, array_shapes(max_dims=2, max_side=2)) return st.lists( elements=elements, min_size=min_size, max_size=max_size, unique_by=lambda d: d[0], )
def array_dtypes( subtype_strategy=scalar_dtypes(), # type: st.SearchStrategy[np.dtype] min_size=1, # type: int max_size=5, # type: int allow_subarrays=False, # type: bool ): # type: (...) -> st.SearchStrategy[np.dtype] """Return a strategy for generating array (compound) dtypes, with members drawn from the given subtype strategy.""" order_check("size", 0, min_size, max_size) native_strings = st.text() # type: SearchStrategy[Any] if text_type is not str: # pragma: no cover native_strings = st.binary() elements = st.tuples(native_strings, subtype_strategy) if allow_subarrays: elements |= st.tuples(native_strings, subtype_strategy, array_shapes(max_dims=2, max_side=2)) return st.lists( elements=elements, min_size=min_size, max_size=max_size, unique_by=lambda d: d[0], )
def all_types(draw): return draw( one_of( text(), integers(), none(), booleans(), floats(), tuples(), times(), uuids(), lists(integers()), dictionaries(text(), text()), ))