I am done

This commit is contained in:
2024-10-30 22:14:35 +01:00
parent 720dc28c09
commit 40e2a747cf
36901 changed files with 5011519 additions and 0 deletions

View File

@ -0,0 +1,7 @@
"""
Tests for the array API namespace.
Note, full compliance with the array API can be tested with the official array API test
suite https://github.com/data-apis/array-api-tests. This test suite primarily
focuses on those things that are not tested by the official test suite.
"""

View File

@ -0,0 +1,395 @@
import operator
from numpy.testing import assert_raises, suppress_warnings
import numpy as np
import pytest
from .. import ones, asarray, reshape, result_type, all, equal
from .._array_object import Array
from .._dtypes import (
_all_dtypes,
_boolean_dtypes,
_real_floating_dtypes,
_floating_dtypes,
_complex_floating_dtypes,
_integer_dtypes,
_integer_or_boolean_dtypes,
_real_numeric_dtypes,
_numeric_dtypes,
int8,
int16,
int32,
int64,
uint64,
bool as bool_,
)
def test_validate_index():
# The indexing tests in the official array API test suite test that the
# array object correctly handles the subset of indices that are required
# by the spec. But the NumPy array API implementation specifically
# disallows any index not required by the spec, via Array._validate_index.
# This test focuses on testing that non-valid indices are correctly
# rejected. See
# https://data-apis.org/array-api/latest/API_specification/indexing.html
# and the docstring of Array._validate_index for the exact indexing
# behavior that should be allowed. This does not test indices that are
# already invalid in NumPy itself because Array will generally just pass
# such indices directly to the underlying np.ndarray.
a = ones((3, 4))
# Out of bounds slices are not allowed
assert_raises(IndexError, lambda: a[:4])
assert_raises(IndexError, lambda: a[:-4])
assert_raises(IndexError, lambda: a[:3:-1])
assert_raises(IndexError, lambda: a[:-5:-1])
assert_raises(IndexError, lambda: a[4:])
assert_raises(IndexError, lambda: a[-4:])
assert_raises(IndexError, lambda: a[4::-1])
assert_raises(IndexError, lambda: a[-4::-1])
assert_raises(IndexError, lambda: a[...,:5])
assert_raises(IndexError, lambda: a[...,:-5])
assert_raises(IndexError, lambda: a[...,:5:-1])
assert_raises(IndexError, lambda: a[...,:-6:-1])
assert_raises(IndexError, lambda: a[...,5:])
assert_raises(IndexError, lambda: a[...,-5:])
assert_raises(IndexError, lambda: a[...,5::-1])
assert_raises(IndexError, lambda: a[...,-5::-1])
# Boolean indices cannot be part of a larger tuple index
assert_raises(IndexError, lambda: a[a[:,0]==1,0])
assert_raises(IndexError, lambda: a[a[:,0]==1,...])
assert_raises(IndexError, lambda: a[..., a[0]==1])
assert_raises(IndexError, lambda: a[[True, True, True]])
assert_raises(IndexError, lambda: a[(True, True, True),])
# Integer array indices are not allowed (except for 0-D)
idx = asarray([[0, 1]])
assert_raises(IndexError, lambda: a[idx])
assert_raises(IndexError, lambda: a[idx,])
assert_raises(IndexError, lambda: a[[0, 1]])
assert_raises(IndexError, lambda: a[(0, 1), (0, 1)])
assert_raises(IndexError, lambda: a[[0, 1]])
assert_raises(IndexError, lambda: a[np.array([[0, 1]])])
# Multiaxis indices must contain exactly as many indices as dimensions
assert_raises(IndexError, lambda: a[()])
assert_raises(IndexError, lambda: a[0,])
assert_raises(IndexError, lambda: a[0])
assert_raises(IndexError, lambda: a[:])
def test_operators():
# For every operator, we test that it works for the required type
# combinations and raises TypeError otherwise
binary_op_dtypes = {
"__add__": "numeric",
"__and__": "integer_or_boolean",
"__eq__": "all",
"__floordiv__": "real numeric",
"__ge__": "real numeric",
"__gt__": "real numeric",
"__le__": "real numeric",
"__lshift__": "integer",
"__lt__": "real numeric",
"__mod__": "real numeric",
"__mul__": "numeric",
"__ne__": "all",
"__or__": "integer_or_boolean",
"__pow__": "numeric",
"__rshift__": "integer",
"__sub__": "numeric",
"__truediv__": "floating",
"__xor__": "integer_or_boolean",
}
# Recompute each time because of in-place ops
def _array_vals():
for d in _integer_dtypes:
yield asarray(1, dtype=d)
for d in _boolean_dtypes:
yield asarray(False, dtype=d)
for d in _floating_dtypes:
yield asarray(1.0, dtype=d)
BIG_INT = int(1e30)
for op, dtypes in binary_op_dtypes.items():
ops = [op]
if op not in ["__eq__", "__ne__", "__le__", "__ge__", "__lt__", "__gt__"]:
rop = "__r" + op[2:]
iop = "__i" + op[2:]
ops += [rop, iop]
for s in [1, 1.0, 1j, BIG_INT, False]:
for _op in ops:
for a in _array_vals():
# Test array op scalar. From the spec, the following combinations
# are supported:
# - Python bool for a bool array dtype,
# - a Python int within the bounds of the given dtype for integer array dtypes,
# - a Python int or float for real floating-point array dtypes
# - a Python int, float, or complex for complex floating-point array dtypes
if ((dtypes == "all"
or dtypes == "numeric" and a.dtype in _numeric_dtypes
or dtypes == "real numeric" and a.dtype in _real_numeric_dtypes
or dtypes == "integer" and a.dtype in _integer_dtypes
or dtypes == "integer_or_boolean" and a.dtype in _integer_or_boolean_dtypes
or dtypes == "boolean" and a.dtype in _boolean_dtypes
or dtypes == "floating" and a.dtype in _floating_dtypes
)
# bool is a subtype of int, which is why we avoid
# isinstance here.
and (a.dtype in _boolean_dtypes and type(s) == bool
or a.dtype in _integer_dtypes and type(s) == int
or a.dtype in _real_floating_dtypes and type(s) in [float, int]
or a.dtype in _complex_floating_dtypes and type(s) in [complex, float, int]
)):
if a.dtype in _integer_dtypes and s == BIG_INT:
assert_raises(OverflowError, lambda: getattr(a, _op)(s))
else:
# Only test for no error
with suppress_warnings() as sup:
# ignore warnings from pow(BIG_INT)
sup.filter(RuntimeWarning,
"invalid value encountered in power")
getattr(a, _op)(s)
else:
assert_raises(TypeError, lambda: getattr(a, _op)(s))
# Test array op array.
for _op in ops:
for x in _array_vals():
for y in _array_vals():
# See the promotion table in NEP 47 or the array
# API spec page on type promotion. Mixed kind
# promotion is not defined.
if (x.dtype == uint64 and y.dtype in [int8, int16, int32, int64]
or y.dtype == uint64 and x.dtype in [int8, int16, int32, int64]
or x.dtype in _integer_dtypes and y.dtype not in _integer_dtypes
or y.dtype in _integer_dtypes and x.dtype not in _integer_dtypes
or x.dtype in _boolean_dtypes and y.dtype not in _boolean_dtypes
or y.dtype in _boolean_dtypes and x.dtype not in _boolean_dtypes
or x.dtype in _floating_dtypes and y.dtype not in _floating_dtypes
or y.dtype in _floating_dtypes and x.dtype not in _floating_dtypes
):
assert_raises(TypeError, lambda: getattr(x, _op)(y))
# Ensure in-place operators only promote to the same dtype as the left operand.
elif (
_op.startswith("__i")
and result_type(x.dtype, y.dtype) != x.dtype
):
assert_raises(TypeError, lambda: getattr(x, _op)(y))
# Ensure only those dtypes that are required for every operator are allowed.
elif (dtypes == "all" and (x.dtype in _boolean_dtypes and y.dtype in _boolean_dtypes
or x.dtype in _numeric_dtypes and y.dtype in _numeric_dtypes)
or (dtypes == "real numeric" and x.dtype in _real_numeric_dtypes and y.dtype in _real_numeric_dtypes)
or (dtypes == "numeric" and x.dtype in _numeric_dtypes and y.dtype in _numeric_dtypes)
or dtypes == "integer" and x.dtype in _integer_dtypes and y.dtype in _integer_dtypes
or dtypes == "integer_or_boolean" and (x.dtype in _integer_dtypes and y.dtype in _integer_dtypes
or x.dtype in _boolean_dtypes and y.dtype in _boolean_dtypes)
or dtypes == "boolean" and x.dtype in _boolean_dtypes and y.dtype in _boolean_dtypes
or dtypes == "floating" and x.dtype in _floating_dtypes and y.dtype in _floating_dtypes
):
getattr(x, _op)(y)
else:
assert_raises(TypeError, lambda: getattr(x, _op)(y))
unary_op_dtypes = {
"__abs__": "numeric",
"__invert__": "integer_or_boolean",
"__neg__": "numeric",
"__pos__": "numeric",
}
for op, dtypes in unary_op_dtypes.items():
for a in _array_vals():
if (
dtypes == "numeric"
and a.dtype in _numeric_dtypes
or dtypes == "integer_or_boolean"
and a.dtype in _integer_or_boolean_dtypes
):
# Only test for no error
getattr(a, op)()
else:
assert_raises(TypeError, lambda: getattr(a, op)())
# Finally, matmul() must be tested separately, because it works a bit
# different from the other operations.
def _matmul_array_vals():
for a in _array_vals():
yield a
for d in _all_dtypes:
yield ones((3, 4), dtype=d)
yield ones((4, 2), dtype=d)
yield ones((4, 4), dtype=d)
# Scalars always error
for _op in ["__matmul__", "__rmatmul__", "__imatmul__"]:
for s in [1, 1.0, False]:
for a in _matmul_array_vals():
if (type(s) in [float, int] and a.dtype in _floating_dtypes
or type(s) == int and a.dtype in _integer_dtypes):
# Type promotion is valid, but @ is not allowed on 0-D
# inputs, so the error is a ValueError
assert_raises(ValueError, lambda: getattr(a, _op)(s))
else:
assert_raises(TypeError, lambda: getattr(a, _op)(s))
for x in _matmul_array_vals():
for y in _matmul_array_vals():
if (x.dtype == uint64 and y.dtype in [int8, int16, int32, int64]
or y.dtype == uint64 and x.dtype in [int8, int16, int32, int64]
or x.dtype in _integer_dtypes and y.dtype not in _integer_dtypes
or y.dtype in _integer_dtypes and x.dtype not in _integer_dtypes
or x.dtype in _floating_dtypes and y.dtype not in _floating_dtypes
or y.dtype in _floating_dtypes and x.dtype not in _floating_dtypes
or x.dtype in _boolean_dtypes
or y.dtype in _boolean_dtypes
):
assert_raises(TypeError, lambda: x.__matmul__(y))
assert_raises(TypeError, lambda: y.__rmatmul__(x))
assert_raises(TypeError, lambda: x.__imatmul__(y))
elif x.shape == () or y.shape == () or x.shape[1] != y.shape[0]:
assert_raises(ValueError, lambda: x.__matmul__(y))
assert_raises(ValueError, lambda: y.__rmatmul__(x))
if result_type(x.dtype, y.dtype) != x.dtype:
assert_raises(TypeError, lambda: x.__imatmul__(y))
else:
assert_raises(ValueError, lambda: x.__imatmul__(y))
else:
x.__matmul__(y)
y.__rmatmul__(x)
if result_type(x.dtype, y.dtype) != x.dtype:
assert_raises(TypeError, lambda: x.__imatmul__(y))
elif y.shape[0] != y.shape[1]:
# This one fails because x @ y has a different shape from x
assert_raises(ValueError, lambda: x.__imatmul__(y))
else:
x.__imatmul__(y)
def test_python_scalar_construtors():
b = asarray(False)
i = asarray(0)
f = asarray(0.0)
c = asarray(0j)
assert bool(b) == False
assert int(i) == 0
assert float(f) == 0.0
assert operator.index(i) == 0
# bool/int/float/complex should only be allowed on 0-D arrays.
assert_raises(TypeError, lambda: bool(asarray([False])))
assert_raises(TypeError, lambda: int(asarray([0])))
assert_raises(TypeError, lambda: float(asarray([0.0])))
assert_raises(TypeError, lambda: complex(asarray([0j])))
assert_raises(TypeError, lambda: operator.index(asarray([0])))
# bool should work on all types of arrays
assert bool(b) is bool(i) is bool(f) is bool(c) is False
# int should fail on complex arrays
assert int(b) == int(i) == int(f) == 0
assert_raises(TypeError, lambda: int(c))
# float should fail on complex arrays
assert float(b) == float(i) == float(f) == 0.0
assert_raises(TypeError, lambda: float(c))
# complex should work on all types of arrays
assert complex(b) == complex(i) == complex(f) == complex(c) == 0j
# index should only work on integer arrays
assert operator.index(i) == 0
assert_raises(TypeError, lambda: operator.index(b))
assert_raises(TypeError, lambda: operator.index(f))
assert_raises(TypeError, lambda: operator.index(c))
def test_device_property():
a = ones((3, 4))
assert a.device == 'cpu'
assert all(equal(a.to_device('cpu'), a))
assert_raises(ValueError, lambda: a.to_device('gpu'))
assert all(equal(asarray(a, device='cpu'), a))
assert_raises(ValueError, lambda: asarray(a, device='gpu'))
def test_array_properties():
a = ones((1, 2, 3))
b = ones((2, 3))
assert_raises(ValueError, lambda: a.T)
assert isinstance(b.T, Array)
assert b.T.shape == (3, 2)
assert isinstance(a.mT, Array)
assert a.mT.shape == (1, 3, 2)
assert isinstance(b.mT, Array)
assert b.mT.shape == (3, 2)
def test___array__():
a = ones((2, 3), dtype=int16)
assert np.asarray(a) is a._array
b = np.asarray(a, dtype=np.float64)
assert np.all(np.equal(b, np.ones((2, 3), dtype=np.float64)))
assert b.dtype == np.float64
def test_allow_newaxis():
a = ones(5)
indexed_a = a[None, :]
assert indexed_a.shape == (1, 5)
def test_disallow_flat_indexing_with_newaxis():
a = ones((3, 3, 3))
with pytest.raises(IndexError):
a[None, 0, 0]
def test_disallow_mask_with_newaxis():
a = ones((3, 3, 3))
with pytest.raises(IndexError):
a[None, asarray(True)]
@pytest.mark.parametrize("shape", [(), (5,), (3, 3, 3)])
@pytest.mark.parametrize("index", ["string", False, True])
def test_error_on_invalid_index(shape, index):
a = ones(shape)
with pytest.raises(IndexError):
a[index]
def test_mask_0d_array_without_errors():
a = ones(())
a[asarray(True)]
@pytest.mark.parametrize(
"i", [slice(5), slice(5, 0), asarray(True), asarray([0, 1])]
)
def test_error_on_invalid_index_with_ellipsis(i):
a = ones((3, 3, 3))
with pytest.raises(IndexError):
a[..., i]
with pytest.raises(IndexError):
a[i, ...]
def test_array_keys_use_private_array():
"""
Indexing operations convert array keys before indexing the internal array
Fails when array_api array keys are not converted into NumPy-proper arrays
in __getitem__(). This is achieved by passing array_api arrays with 0-sized
dimensions, which NumPy-proper treats erroneously - not sure why!
TODO: Find and use appropriate __setitem__() case.
"""
a = ones((0, 0), dtype=bool_)
assert a[a].shape == (0,)
a = ones((0,), dtype=bool_)
key = ones((0, 0), dtype=bool_)
with pytest.raises(IndexError):
a[key]

View File

@ -0,0 +1,142 @@
from numpy.testing import assert_raises
import numpy as np
from .. import all
from .._creation_functions import (
asarray,
arange,
empty,
empty_like,
eye,
full,
full_like,
linspace,
meshgrid,
ones,
ones_like,
zeros,
zeros_like,
)
from .._dtypes import float32, float64
from .._array_object import Array
def test_asarray_errors():
# Test various protections against incorrect usage
assert_raises(TypeError, lambda: Array([1]))
assert_raises(TypeError, lambda: asarray(["a"]))
assert_raises(ValueError, lambda: asarray([1.0], dtype=np.float16))
assert_raises(OverflowError, lambda: asarray(2**100))
# Preferably this would be OverflowError
# assert_raises(OverflowError, lambda: asarray([2**100]))
assert_raises(TypeError, lambda: asarray([2**100]))
asarray([1], device="cpu") # Doesn't error
assert_raises(ValueError, lambda: asarray([1], device="gpu"))
assert_raises(ValueError, lambda: asarray([1], dtype=int))
assert_raises(ValueError, lambda: asarray([1], dtype="i"))
def test_asarray_copy():
a = asarray([1])
b = asarray(a, copy=True)
a[0] = 0
assert all(b[0] == 1)
assert all(a[0] == 0)
a = asarray([1])
b = asarray(a, copy=np._CopyMode.ALWAYS)
a[0] = 0
assert all(b[0] == 1)
assert all(a[0] == 0)
a = asarray([1])
b = asarray(a, copy=np._CopyMode.NEVER)
a[0] = 0
assert all(b[0] == 0)
assert_raises(NotImplementedError, lambda: asarray(a, copy=False))
assert_raises(NotImplementedError,
lambda: asarray(a, copy=np._CopyMode.IF_NEEDED))
def test_arange_errors():
arange(1, device="cpu") # Doesn't error
assert_raises(ValueError, lambda: arange(1, device="gpu"))
assert_raises(ValueError, lambda: arange(1, dtype=int))
assert_raises(ValueError, lambda: arange(1, dtype="i"))
def test_empty_errors():
empty((1,), device="cpu") # Doesn't error
assert_raises(ValueError, lambda: empty((1,), device="gpu"))
assert_raises(ValueError, lambda: empty((1,), dtype=int))
assert_raises(ValueError, lambda: empty((1,), dtype="i"))
def test_empty_like_errors():
empty_like(asarray(1), device="cpu") # Doesn't error
assert_raises(ValueError, lambda: empty_like(asarray(1), device="gpu"))
assert_raises(ValueError, lambda: empty_like(asarray(1), dtype=int))
assert_raises(ValueError, lambda: empty_like(asarray(1), dtype="i"))
def test_eye_errors():
eye(1, device="cpu") # Doesn't error
assert_raises(ValueError, lambda: eye(1, device="gpu"))
assert_raises(ValueError, lambda: eye(1, dtype=int))
assert_raises(ValueError, lambda: eye(1, dtype="i"))
def test_full_errors():
full((1,), 0, device="cpu") # Doesn't error
assert_raises(ValueError, lambda: full((1,), 0, device="gpu"))
assert_raises(ValueError, lambda: full((1,), 0, dtype=int))
assert_raises(ValueError, lambda: full((1,), 0, dtype="i"))
def test_full_like_errors():
full_like(asarray(1), 0, device="cpu") # Doesn't error
assert_raises(ValueError, lambda: full_like(asarray(1), 0, device="gpu"))
assert_raises(ValueError, lambda: full_like(asarray(1), 0, dtype=int))
assert_raises(ValueError, lambda: full_like(asarray(1), 0, dtype="i"))
def test_linspace_errors():
linspace(0, 1, 10, device="cpu") # Doesn't error
assert_raises(ValueError, lambda: linspace(0, 1, 10, device="gpu"))
assert_raises(ValueError, lambda: linspace(0, 1, 10, dtype=float))
assert_raises(ValueError, lambda: linspace(0, 1, 10, dtype="f"))
def test_ones_errors():
ones((1,), device="cpu") # Doesn't error
assert_raises(ValueError, lambda: ones((1,), device="gpu"))
assert_raises(ValueError, lambda: ones((1,), dtype=int))
assert_raises(ValueError, lambda: ones((1,), dtype="i"))
def test_ones_like_errors():
ones_like(asarray(1), device="cpu") # Doesn't error
assert_raises(ValueError, lambda: ones_like(asarray(1), device="gpu"))
assert_raises(ValueError, lambda: ones_like(asarray(1), dtype=int))
assert_raises(ValueError, lambda: ones_like(asarray(1), dtype="i"))
def test_zeros_errors():
zeros((1,), device="cpu") # Doesn't error
assert_raises(ValueError, lambda: zeros((1,), device="gpu"))
assert_raises(ValueError, lambda: zeros((1,), dtype=int))
assert_raises(ValueError, lambda: zeros((1,), dtype="i"))
def test_zeros_like_errors():
zeros_like(asarray(1), device="cpu") # Doesn't error
assert_raises(ValueError, lambda: zeros_like(asarray(1), device="gpu"))
assert_raises(ValueError, lambda: zeros_like(asarray(1), dtype=int))
assert_raises(ValueError, lambda: zeros_like(asarray(1), dtype="i"))
def test_meshgrid_dtype_errors():
# Doesn't raise
meshgrid()
meshgrid(asarray([1.], dtype=float32))
meshgrid(asarray([1.], dtype=float32), asarray([1.], dtype=float32))
assert_raises(ValueError, lambda: meshgrid(asarray([1.], dtype=float32), asarray([1.], dtype=float64)))

View File

@ -0,0 +1,31 @@
import pytest
from numpy.testing import assert_raises
from numpy import array_api as xp
import numpy as np
@pytest.mark.parametrize(
"from_, to, expected",
[
(xp.int8, xp.int16, True),
(xp.int16, xp.int8, False),
(xp.bool, xp.int8, False),
(xp.asarray(0, dtype=xp.uint8), xp.int8, False),
],
)
def test_can_cast(from_, to, expected):
"""
can_cast() returns correct result
"""
assert xp.can_cast(from_, to) == expected
def test_isdtype_strictness():
assert_raises(TypeError, lambda: xp.isdtype(xp.float64, 64))
assert_raises(ValueError, lambda: xp.isdtype(xp.float64, 'f8'))
assert_raises(TypeError, lambda: xp.isdtype(xp.float64, (('integral',),)))
assert_raises(TypeError, lambda: xp.isdtype(xp.float64, np.object_))
# TODO: These will require https://github.com/numpy/numpy/issues/23883
# assert_raises(TypeError, lambda: xp.isdtype(xp.float64, None))
# assert_raises(TypeError, lambda: xp.isdtype(xp.float64, np.float64))

View File

@ -0,0 +1,114 @@
from inspect import getfullargspec
from numpy.testing import assert_raises
from .. import asarray, _elementwise_functions
from .._elementwise_functions import bitwise_left_shift, bitwise_right_shift
from .._dtypes import (
_dtype_categories,
_boolean_dtypes,
_floating_dtypes,
_integer_dtypes,
)
def nargs(func):
return len(getfullargspec(func).args)
def test_function_types():
# Test that every function accepts only the required input types. We only
# test the negative cases here (error). The positive cases are tested in
# the array API test suite.
elementwise_function_input_types = {
"abs": "numeric",
"acos": "floating-point",
"acosh": "floating-point",
"add": "numeric",
"asin": "floating-point",
"asinh": "floating-point",
"atan": "floating-point",
"atan2": "real floating-point",
"atanh": "floating-point",
"bitwise_and": "integer or boolean",
"bitwise_invert": "integer or boolean",
"bitwise_left_shift": "integer",
"bitwise_or": "integer or boolean",
"bitwise_right_shift": "integer",
"bitwise_xor": "integer or boolean",
"ceil": "real numeric",
"conj": "complex floating-point",
"cos": "floating-point",
"cosh": "floating-point",
"divide": "floating-point",
"equal": "all",
"exp": "floating-point",
"expm1": "floating-point",
"floor": "real numeric",
"floor_divide": "real numeric",
"greater": "real numeric",
"greater_equal": "real numeric",
"imag": "complex floating-point",
"isfinite": "numeric",
"isinf": "numeric",
"isnan": "numeric",
"less": "real numeric",
"less_equal": "real numeric",
"log": "floating-point",
"logaddexp": "real floating-point",
"log10": "floating-point",
"log1p": "floating-point",
"log2": "floating-point",
"logical_and": "boolean",
"logical_not": "boolean",
"logical_or": "boolean",
"logical_xor": "boolean",
"multiply": "numeric",
"negative": "numeric",
"not_equal": "all",
"positive": "numeric",
"pow": "numeric",
"real": "complex floating-point",
"remainder": "real numeric",
"round": "numeric",
"sign": "numeric",
"sin": "floating-point",
"sinh": "floating-point",
"sqrt": "floating-point",
"square": "numeric",
"subtract": "numeric",
"tan": "floating-point",
"tanh": "floating-point",
"trunc": "real numeric",
}
def _array_vals():
for d in _integer_dtypes:
yield asarray(1, dtype=d)
for d in _boolean_dtypes:
yield asarray(False, dtype=d)
for d in _floating_dtypes:
yield asarray(1.0, dtype=d)
for x in _array_vals():
for func_name, types in elementwise_function_input_types.items():
dtypes = _dtype_categories[types]
func = getattr(_elementwise_functions, func_name)
if nargs(func) == 2:
for y in _array_vals():
if x.dtype not in dtypes or y.dtype not in dtypes:
assert_raises(TypeError, lambda: func(x, y))
else:
if x.dtype not in dtypes:
assert_raises(TypeError, lambda: func(x))
def test_bitwise_shift_error():
# bitwise shift functions should raise when the second argument is negative
assert_raises(
ValueError, lambda: bitwise_left_shift(asarray([1, 1]), asarray([1, -1]))
)
assert_raises(
ValueError, lambda: bitwise_right_shift(asarray([1, 1]), asarray([1, -1]))
)

View File

@ -0,0 +1,24 @@
import pytest
from numpy import array_api as xp
@pytest.mark.parametrize(
"x, indices, axis, expected",
[
([2, 3], [1, 1, 0], 0, [3, 3, 2]),
([2, 3], [1, 1, 0], -1, [3, 3, 2]),
([[2, 3]], [1], -1, [[3]]),
([[2, 3]], [0, 0], 0, [[2, 3], [2, 3]]),
],
)
def test_take_function(x, indices, axis, expected):
"""
Indices respect relative order of a descending stable-sort
See https://github.com/numpy/numpy/issues/20778
"""
x = xp.asarray(x)
indices = xp.asarray(indices)
out = xp.take(x, indices, axis=axis)
assert xp.all(out == xp.asarray(expected))

View File

@ -0,0 +1,37 @@
from numpy.testing import assert_raises
import numpy as np
from .. import all
from .._creation_functions import asarray
from .._dtypes import float64, int8
from .._manipulation_functions import (
concat,
reshape,
stack
)
def test_concat_errors():
assert_raises(TypeError, lambda: concat((1, 1), axis=None))
assert_raises(TypeError, lambda: concat([asarray([1], dtype=int8),
asarray([1], dtype=float64)]))
def test_stack_errors():
assert_raises(TypeError, lambda: stack([asarray([1, 1], dtype=int8),
asarray([2, 2], dtype=float64)]))
def test_reshape_copy():
a = asarray(np.ones((2, 3)))
b = reshape(a, (3, 2), copy=True)
assert not np.shares_memory(a._array, b._array)
a = asarray(np.ones((2, 3)))
b = reshape(a, (3, 2), copy=False)
assert np.shares_memory(a._array, b._array)
a = asarray(np.ones((2, 3)).T)
b = reshape(a, (3, 2), copy=True)
assert_raises(AttributeError, lambda: reshape(a, (2, 3), copy=False))

View File

@ -0,0 +1,19 @@
import pytest
from hypothesis import given
from hypothesis.extra.array_api import make_strategies_namespace
from numpy import array_api as xp
xps = make_strategies_namespace(xp)
@pytest.mark.parametrize("func", [xp.unique_all, xp.unique_inverse])
@given(xps.arrays(dtype=xps.scalar_dtypes(), shape=xps.array_shapes()))
def test_inverse_indices_shape(func, x):
"""
Inverse indices share shape of input array
See https://github.com/numpy/numpy/issues/20638
"""
out = func(x)
assert out.inverse_indices.shape == x.shape

View File

@ -0,0 +1,23 @@
import pytest
from numpy import array_api as xp
@pytest.mark.parametrize(
"obj, axis, expected",
[
([0, 0], -1, [0, 1]),
([0, 1, 0], -1, [1, 0, 2]),
([[0, 1], [1, 1]], 0, [[1, 0], [0, 1]]),
([[0, 1], [1, 1]], 1, [[1, 0], [0, 1]]),
],
)
def test_stable_desc_argsort(obj, axis, expected):
"""
Indices respect relative order of a descending stable-sort
See https://github.com/numpy/numpy/issues/20778
"""
x = xp.asarray(obj)
out = xp.argsort(x, axis=axis, stable=True, descending=True)
assert xp.all(out == xp.asarray(expected))

View File

@ -0,0 +1,27 @@
from typing import Callable
import pytest
from numpy import array_api as xp
def p(func: Callable, *args, **kwargs):
f_sig = ", ".join(
[str(a) for a in args] + [f"{k}={v}" for k, v in kwargs.items()]
)
id_ = f"{func.__name__}({f_sig})"
return pytest.param(func, args, kwargs, id=id_)
@pytest.mark.parametrize(
"func, args, kwargs",
[
p(xp.can_cast, 42, xp.int8),
p(xp.can_cast, xp.int8, 42),
p(xp.result_type, 42),
],
)
def test_raises_on_invalid_types(func, args, kwargs):
"""Function raises TypeError when passed invalidly-typed inputs"""
with pytest.raises(TypeError):
func(*args, **kwargs)