Hypothesis strategies for Array API¶
-
hypothesis_array.get_strategies_namespace(xp)¶ Creates a strategies namespace for the given array module.
xpis the Array API library to automatically pass to the namespaced methods.
A
types.SimpleNamespaceis returned which contains all the strategy methods in this module but without requiring thexpargument.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.dtypemay be a dtype object or the string name of a valid dtype.
Compatible
**kwargsare 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 thewidthor other representable bounds for you.
-
hypothesis_array.arrays(xp, dtype, shape, *, elements=None, fill=None, unique=False)¶ Returns a strategy for arrays.
dtypemay be a valid dtype object or name, or a strategy that generates such values.shapemay be an integer >= 0, a tuple of such integers, or a strategy that generates such values.elementsis a strategy for values to put in the array. IfNonethen 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**kwargstofrom_dtype()when inferring based on the dtype.fillis 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.uniquespecifies 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
dtypeandshapeare 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
dictof the kwargs to pass tofrom_dtype()will ensuredtypebounds 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
filltonothing()if you want to disable this behaviour and draw a value for every element.By default
arrayswill attempt to infer the correct fill behaviour: ifuniqueis 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_dimsis the smallest length that the generated shape can possess.max_dimsis the largest length that the generated shape can possess, defaulting tomin_dims + 2.min_sideis the smallest size that a dimension can possess.max_sideis 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.
sizescontains 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.
sizescontains 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.
sizescontains 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
axisargument in Array API sequential methods e.g.sum, given the specified dimensionality.All tuples will have a length >=
min_sizeand <=max_size. The default value formax_sizeisndim.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_axescan 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.shapeis a tuple of integers.min_dimsis the smallest length that the generated shape can possess.max_dimsis the largest length that the generated shape can possess, defaulting tomin(32, max(len(shape), min_dims) + 2).min_sideis the smallest size that an unaligned dimension can possess.max_sideis 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_shapesis the number of mutually broadcast-compatible shapes to generate.base_shapeis 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.shapeis a tuple of integers.min_dimsis the smallest length that the generated shape can possess.max_dimsis the largest length that the generated shape can possess, defaulting tomin(32, max(len(shape), min_dims) + 2).min_sideis the smallest size that an unaligned dimension can possess.max_sideis 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.NamedTuplecontaining:input_shapesas a tuple of the N generated shapes.result_shapeas 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,
sliceobjects,...(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.5instead of(5,).shapeis 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_dimsis the minimum dimensionality of the resulting array from use of the generated index. Ifmin_dims == 0, zero-dimensional arrays are allowed.max_dimsis the the maximum dimensionality of the resulting array, defaulting tomax(len(shape), min_dims) + 2.allow_ellipsisspecifies whether...is allowed in the index.allow_nonespecifies whetherNoneis allowed in the index.