예제 #1
0
def test_generate_long_ellipsis():
    """Strategy can replace runs of slice(None) with Ellipsis.

    We specifically test if [0,...,0] is generated alongside [0,:,:,:,0]
    """
    strat = xps.indices(shape=(1, 0, 0, 0, 1), max_dims=3, allow_ellipsis=True)
    find_any(strat, lambda ix: len(ix) == 3 and ix[1] == Ellipsis)
    find_any(
        strat,
        lambda ix: len(ix) == 5
        and all(isinstance(key, slice) and key == slice(None) for key in ix[1:3]),
    )
예제 #2
0
def test_generate_valid_indices(shape, allow_ellipsis, data):
    """Strategy generates valid indices."""
    min_dims = data.draw(st.integers(0, len(shape)), label="min_dims")
    max_dims = data.draw(
        st.none() | st.integers(min_dims, len(shape)), label="max_dims"
    )
    indexer = data.draw(
        xps.indices(
            shape,
            min_dims=min_dims,
            max_dims=max_dims,
            allow_ellipsis=allow_ellipsis,
        ),
        label="indexer",
    )

    _indexer = indexer if isinstance(indexer, tuple) else (indexer,)
    # Check that disallowed things are indeed absent
    if not allow_ellipsis:
        assert Ellipsis not in _indexer
    assert None not in _indexer  # i.e. np.newaxis
    # Check index is composed of valid objects
    for i in _indexer:
        assert isinstance(i, int) or isinstance(i, slice) or i == Ellipsis
    # Check indexer does not flat index
    if Ellipsis in _indexer:
        assert sum(i == Ellipsis for i in _indexer) == 1
        assert len(_indexer) <= len(shape) + 1  # Ellipsis can index 0 axes
    else:
        assert len(_indexer) == len(shape)

    if 0 in shape:
        # If there's a zero in the shape, the array will have no elements.
        array = xp.zeros(shape)
        assert array.size == 0  # sanity check
    elif math.prod(shape) <= 10**5:
        # If it's small enough to instantiate, do so with distinct elements.
        array = xp.reshape(xp.arange(math.prod(shape)), shape)
    else:
        # We can't cheat on this one, so just try another.
        assume(False)
    # Finally, check that we can use our indexer without error
    array[indexer]
예제 #3
0
def test_indices_generate_valid_indexers(shape, allow_ellipsis, data):
    """Strategy generates valid indices."""
    min_dims = data.draw(st.integers(0, len(shape)), label="min_dims")
    max_dims = data.draw(st.none() | st.integers(min_dims, len(shape)),
                         label="max_dims")
    indexer = data.draw(
        xps.indices(
            shape,
            min_dims=min_dims,
            max_dims=max_dims,
            allow_ellipsis=allow_ellipsis,
        ),
        label="indexer",
    )

    # Check that disallowed things are indeed absent
    if isinstance(indexer, tuple):
        assert 0 <= len(indexer) <= len(shape) + int(allow_ellipsis)
    else:
        assert 1 <= len(shape) + int(allow_ellipsis)
    assert None not in shape
    if not allow_ellipsis:
        assert Ellipsis not in shape

    if 0 in shape:
        # If there's a zero in the shape, the array will have no elements.
        array = xp.zeros(shape)
        assert array.size == 0
    elif math.prod(shape) <= 10**5:
        # If it's small enough to instantiate, do so with distinct elements.
        array = xp.reshape(xp.arange(math.prod(shape)), shape)
    else:
        # We can't cheat on this one, so just try another.
        assume(False)

    # Finally, check that we can use our indexer without error
    array[indexer]
예제 #4
0
def test_generate_tuples_and_non_tuples_for_1d_shape():
    """Strategy can generate tuple and non-tuple indices with a 1-dimensional shape."""
    strat = xps.indices(shape=(1,), allow_ellipsis=True)
    find_any(strat, lambda ix: isinstance(ix, tuple))
    find_any(strat, lambda ix: not isinstance(ix, tuple))
예제 #5
0
from tests.array_api.common import xp, xps
from tests.common.debug import find_any


def test_generate_indices_with_and_without_ellipsis():
    """Strategy can generate indices with and without Ellipsis."""
    strat = (
        xps.array_shapes(min_dims=1, max_dims=32)
        .flatmap(xps.indices)
        .map(lambda idx: idx if isinstance(idx, tuple) else (idx,))
    )
    find_any(strat, lambda ix: Ellipsis in ix)
    find_any(strat, lambda ix: Ellipsis not in ix)


@given(xps.indices(shape=(), allow_ellipsis=True))
def test_generate_indices_for_0d_shape(idx):
    """Strategy only generates empty tuples or Ellipsis as indices for an empty
    shape."""
    assert idx in [(), Ellipsis, (Ellipsis,)]


def test_generate_tuples_and_non_tuples_for_1d_shape():
    """Strategy can generate tuple and non-tuple indices with a 1-dimensional shape."""
    strat = xps.indices(shape=(1,), allow_ellipsis=True)
    find_any(strat, lambda ix: isinstance(ix, tuple))
    find_any(strat, lambda ix: not isinstance(ix, tuple))


def test_generate_long_ellipsis():
    """Strategy can replace runs of slice(None) with Ellipsis.
예제 #6
0
    # top-level methods by binding the passed xp argument, and so the namespace
    # it returns should not expose xp in any of its function signatures.
    assert "xp" not in signature(func).parameters.keys()


@pytest.mark.parametrize(
    "name, strat",
    [
        ("from_dtype", xps.from_dtype(xp.int8)),
        ("arrays", xps.arrays(xp.int8, 5)),
        ("array_shapes", xps.array_shapes()),
        ("scalar_dtypes", xps.scalar_dtypes()),
        ("boolean_dtypes", xps.boolean_dtypes()),
        ("numeric_dtypes", xps.numeric_dtypes()),
        ("integer_dtypes", xps.integer_dtypes()),
        ("unsigned_integer_dtypes", xps.unsigned_integer_dtypes()),
        ("floating_dtypes", xps.floating_dtypes()),
        ("valid_tuple_axes", xps.valid_tuple_axes(0)),
        ("broadcastable_shapes", xps.broadcastable_shapes(())),
        ("mutually_broadcastable_shapes",
         xps.mutually_broadcastable_shapes(3)),
        ("indices", xps.indices((5, ))),
    ],
)
def test_namespaced_strategies_repr(name, strat):
    """Namespaced strategies have good repr."""
    assert repr(strat).startswith(name +
                                  "("), f"{name} not in strat repr {strat!r}"
    assert len(repr(strat)) < 100, "strat repr looks too long"
    assert xp.__name__ not in repr(strat), f"{xp.__name__} in strat repr"
예제 #7
0
def test_generate_non_tuples():
    """Strategy generates non-tuples as indices."""
    find_any(
        xps.indices(shape=(0, 0), allow_ellipsis=True),
        lambda ix: not isinstance(ix, tuple),
    )
예제 #8
0
def test_generate_empty_tuple():
    """Strategy generates empty tuples as indices."""
    find_any(xps.indices(shape=(0, 0), allow_ellipsis=True), lambda ix: ix ==
             ())