Hypothesis strategies for Array API¶
-
hypothesis_array.
get_strategies_namespace
(xp)¶ Creates a strategies namespace for the given array module.
xp
is the Array API library to automatically pass to the namespaced methods.
A
types.SimpleNamespace
is returned which contains all the strategy methods in this module but without requiring thexp
argument.Creating and using a strategies namespace for NumPy’s Array API implemention would go like this:
>>> from numpy import array_api as xp >>> xps = get_strategies_namespace(xp) >>> x = xps.arrays(xp.int8, (2, 3)).example() >>> x Array([[-8, 6, 3], [-6, 4, 6]], dtype=int8) >>> x.__array_namespace__() is xp True
-
hypothesis_array.
from_dtype
(xp, dtype, *, min_value=None, max_value=None, allow_nan=None, allow_infinity=None, exclude_min=None, exclude_max=None)¶ Return a strategy for any value of the given dtype.
Values generated are of the Python scalar which is promotable to
dtype
, where the values do not exceed its bounds.dtype
may be a dtype object or the string name of a valid dtype.
Compatible
**kwargs
are passed to the inferred strategy function for integers and floats. This allows you to customise the min and max values, and exclude non-finite numbers. This is particularly useful when kwargs are passed through fromarrays()
, as it seamlessly handles thewidth
or other representable bounds for you.
-
hypothesis_array.
arrays
(xp, dtype, shape, *, elements=None, fill=None, unique=False)¶ Returns a strategy for arrays.
dtype
may be a valid dtype object or name, or a strategy that generates such values.shape
may be an integer >= 0, a tuple of such integers, or a strategy that generates such values.elements
is a strategy for values to put in the array. IfNone
then a suitable value will be inferred based on the dtype, which may give any legal value (including e.g. NaN for floats). If a mapping, it will be passed as**kwargs
tofrom_dtype()
when inferring based on the dtype.fill
is a strategy that may be used to generate a single background value for the array. IfNone
, a suitable default will be inferred based on the other arguments. If set tonothing()
then filling behaviour will be disabled entirely and every element will be generated independently.unique
specifies if the elements of the array should all be distinct from one another. Note that in this case multiple NaN values may still be allowed. If fill is also set, the only valid values for fill to return are NaN values.
Arrays of specified
dtype
andshape
are generated for example like this:>>> from numpy import array_api as xp >>> arrays(xp, xp.int8, (2, 3)).example() Array([[-8, 6, 3], [-6, 4, 6]], dtype=int8)
Specifying element boundaries by a
dict
of the kwargs to pass tofrom_dtype()
will ensuredtype
bounds will be respected.>>> arrays(xp, xp.int8, 3, elements={"min_value": 10}).example() Array([125, 13, 79], dtype=int8)
Refer to What you can generate and how for passing your own elements strategy.
>>> arrays(xp, xp.float32, 3, elements=floats(0, 1, width=32)).example() Array([ 0.88974794, 0.77387938, 0.1977879 ], dtype=float32)
Array values are generated in two parts:
A single value is drawn from the fill strategy and is used to create a filled array.
Some subset of the coordinates of the array are populated with a value drawn from the elements strategy (or its inferred form).
You can set
fill
tonothing()
if you want to disable this behaviour and draw a value for every element.By default
arrays
will attempt to infer the correct fill behaviour: ifunique
is alsoTrue
, no filling will occur. Otherwise, if it looks safe to reuse the values of elements across multiple coordinates (this will be the case for any inferred strategy, and for most of the builtins, but is not the case for mutable values or strategies built with flatmap, map, composite, etc.) then it will use the elements strategy as the fill, else it will default to having no fill.Having a fill helps Hypothesis craft high quality examples, but its main importance is when the array generated is large: Hypothesis is primarily designed around testing small examples. If you have arrays with hundreds or more elements, having a fill value is essential if you want your tests to run in reasonable time.
-
hypothesis_array.
array_shapes
(*, min_dims=1, max_dims=None, min_side=1, max_side=None)¶ Return a strategy for array shapes (tuples of int >= 1).
min_dims
is the smallest length that the generated shape can possess.max_dims
is the largest length that the generated shape can possess, defaulting tomin_dims + 2
.min_side
is the smallest size that a dimension can possess.max_side
is the largest size that a dimension can possess, defaulting tomin_side + 5
.
-
hypothesis_array.
scalar_dtypes
(xp)¶ Return a strategy for all valid dtype objects.
-
hypothesis_array.
numeric_dtypes
(xp)¶ Return a strategy for all numeric dtype objects.
-
hypothesis_array.
integer_dtypes
(xp, *, sizes=(8, 16, 32, 64))¶ Return a strategy for signed integer dtype objects.
sizes
contains the signed integer sizes in bits, defaulting to(8, 16, 32, 64)
which covers all valid sizes.
-
hypothesis_array.
unsigned_integer_dtypes
(xp, *, sizes=(8, 16, 32, 64))¶ Return a strategy for unsigned integer dtype objects.
sizes
contains the unsigned integer sizes in bits, defaulting to(8, 16, 32, 64)
which covers all valid sizes.
-
hypothesis_array.
floating_dtypes
(xp, *, sizes=(32, 64))¶ Return a strategy for floating-point dtype objects.
sizes
contains the floating-point sizes in bits, defaulting to(32, 64)
which covers all valid sizes.
-
hypothesis_array.
valid_tuple_axes
(ndim, *, min_size=0, max_size=None)¶ Return a strategy for permissable tuple-values for the
axis
argument in Array API sequential methods e.g.sum
, given the specified dimensionality.All tuples will have a length >=
min_size
and <=max_size
. The default value formax_size
isndim
.Examples from this strategy shrink towards an empty tuple, which render most sequential functions as no-ops.
The following are some examples drawn from this strategy.
>>> [valid_tuple_axes(3).example() for i in range(4)] [(-3, 1), (0, 1, -1), (0, 2), (0, -2, 2)]
valid_tuple_axes
can be joined with other strategies to generate any type of valid axis object, i.e. integers, tuples, andNone
:any_axis_strategy = none() | integers(-ndim, ndim - 1) | valid_tuple_axes(ndim)
-
hypothesis_array.
broadcastable_shapes
(shape, *, min_dims=0, max_dims=None, min_side=1, max_side=None)¶ Return a strategy for shapes that are broadcast-compatible with the provided shape.
Examples from this strategy shrink towards a shape with length
min_dims
. The size of an aligned dimension shrinks towards size1
. The size of an unaligned dimension shrink towardsmin_side
.shape
is a tuple of integers.min_dims
is the smallest length that the generated shape can possess.max_dims
is the largest length that the generated shape can possess, defaulting tomin(32, max(len(shape), min_dims) + 2)
.min_side
is the smallest size that an unaligned dimension can possess.max_side
is the largest size that an unaligned dimension can possess, defaulting to 2 plus the size of the largest aligned dimension.
The following are some examples drawn from this strategy.
>>> [broadcastable_shapes(shape=(2, 3)).example() for i in range(5)] [(1, 3), (), (2, 3), (2, 1), (4, 1, 3), (3, )]
-
hypothesis_array.
mutually_broadcastable_shapes
(num_shapes, *, base_shape=(), min_dims=0, max_dims=None, min_side=1, max_side=None)¶ Return a strategy for a specified number of shapes N that are mutually-broadcastable with one another and with the provided base shape.
num_shapes
is the number of mutually broadcast-compatible shapes to generate.base_shape
is the shape against which all generated shapes can broadcast. The default shape is empty, which corresponds to a scalar and thus does not constrain broadcasting at all.shape
is a tuple of integers.min_dims
is the smallest length that the generated shape can possess.max_dims
is the largest length that the generated shape can possess, defaulting tomin(32, max(len(shape), min_dims) + 2)
.min_side
is the smallest size that an unaligned dimension can possess.max_side
is the largest size that an unaligned dimension can possess, defaulting to 2 plus the size of the largest aligned dimension.
The strategy will generate a
typing.NamedTuple
containing:input_shapes
as a tuple of the N generated shapes.result_shape
as the resulting shape produced by broadcasting the N shapes with the base shape.
The following are some examples drawn from this strategy.
>>> # Draw three shapes where each shape is broadcast-compatible with (2, 3) ... strat = mutually_broadcastable_shapes(num_shapes=3, base_shape=(2, 3)) >>> for _ in range(5): ... print(strat.example()) BroadcastableShapes(input_shapes=((3,), (1,), (2, 1)), result_shape=(2, 3)) BroadcastableShapes(input_shapes=((3,), (1, 3), (2, 3)), result_shape=(2, 3)) BroadcastableShapes(input_shapes=((), (), ()), result_shape=(2, 3)) BroadcastableShapes(input_shapes=((3,), (), (3,)), result_shape=(2, 3)) BroadcastableShapes(input_shapes=((1, 2, 3), (3,), ()), result_shape=(1, 2, 3))
-
hypothesis_array.
indices
(shape, *, min_dims=1, max_dims=None, allow_ellipsis=True, allow_none=False)¶ Return a strategy for valid indices of arrays with the specified shape.
It generates tuples containing some mix of integers,
slice
objects,...
(anEllipsis
), andNone
. When a length-one tuple would be generated, this strategy may instead return the element which will index the first axis, e.g.5
instead of(5,)
.shape
is the shape of the array that will be indexed, as a tuple of integers >= 0. This must be at least two-dimensional for a tuple to be a valid index; for one-dimensional arrays useslices()
instead.min_dims
is the minimum dimensionality of the resulting array from use of the generated index. Ifmin_dims == 0
, zero-dimensional arrays are allowed.max_dims
is the the maximum dimensionality of the resulting array, defaulting tomax(len(shape), min_dims) + 2
.allow_ellipsis
specifies whether...
is allowed in the index.allow_none
specifies whetherNone
is allowed in the index.