summaryrefslogtreecommitdiff
path: root/numpy/core/tests/test_multiarray.py
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core/tests/test_multiarray.py')
-rw-r--r--numpy/core/tests/test_multiarray.py513
1 files changed, 402 insertions, 111 deletions
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 027384fba..196c2dc13 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import collections.abc
import tempfile
import sys
@@ -9,6 +11,7 @@ import functools
import ctypes
import os
import gc
+import re
import weakref
import pytest
from contextlib import contextmanager
@@ -27,11 +30,12 @@ from numpy.testing import (
assert_, assert_raises, assert_warns, assert_equal, assert_almost_equal,
assert_array_equal, assert_raises_regex, assert_array_almost_equal,
assert_allclose, IS_PYPY, IS_PYSTON, HAS_REFCOUNT, assert_array_less,
- runstring, temppath, suppress_warnings, break_cycles,
+ runstring, temppath, suppress_warnings, break_cycles, _SUPPORTS_SVE,
)
from numpy.testing._private.utils import requires_memory, _no_tracing
from numpy.core.tests._locales import CommaDecimalPointLocale
from numpy.lib.recfunctions import repack_fields
+from numpy.core.multiarray import _get_ndarray_c_version
# Need to test an object that does not fully implement math interface
from datetime import timedelta, datetime
@@ -402,6 +406,13 @@ class TestAttributes:
assert_array_equal(x['a'], [3.5, 3.5])
assert_array_equal(x['b'], [-2, -2])
+ def test_fill_readonly(self):
+ # gh-22922
+ a = np.zeros(11)
+ a.setflags(write=False)
+ with pytest.raises(ValueError, match=".*read-only"):
+ a.fill(0)
+
class TestArrayConstruction:
def test_array(self):
@@ -1185,6 +1196,17 @@ class TestCreation:
expected = expected * (arr.nbytes // len(expected))
assert arr.tobytes() == expected
+ @pytest.mark.parametrize("func", [
+ np.array, np.asarray, np.asanyarray, np.ascontiguousarray,
+ np.asfortranarray])
+ def test_creation_from_dtypemeta(self, func):
+ dtype = np.dtype('i')
+ arr1 = func([1, 2, 3], dtype=dtype)
+ arr2 = func([1, 2, 3], dtype=type(dtype))
+ assert_array_equal(arr1, arr2)
+ assert arr2.dtype == dtype
+
+
class TestStructured:
def test_subarray_field_access(self):
a = np.zeros((3, 5), dtype=[('a', ('i4', (2, 2)))])
@@ -1257,9 +1279,9 @@ class TestStructured:
# The main importance is that it does not return True:
with pytest.raises(TypeError):
x == y
-
+
def test_empty_structured_array_comparison(self):
- # Check that comparison works on empty arrays with nontrivially
+ # Check that comparison works on empty arrays with nontrivially
# shaped fields
a = np.zeros(0, [('a', '<f8', (1, 1))])
assert_equal(a, a)
@@ -1270,6 +1292,13 @@ class TestStructured:
a = np.zeros((1, 0, 1), [('a', '<f8', (1, 1))])
assert_equal(a, a)
+ @pytest.mark.parametrize("op", [operator.eq, operator.ne])
+ def test_structured_array_comparison_bad_broadcasts(self, op):
+ a = np.zeros(3, dtype='i,i')
+ b = np.array([], dtype="i,i")
+ with pytest.raises(ValueError):
+ op(a, b)
+
def test_structured_comparisons_with_promotion(self):
# Check that structured arrays can be compared so long as their
# dtypes promote fine:
@@ -1290,7 +1319,10 @@ class TestStructured:
assert_equal(a == b, [False, True])
assert_equal(a != b, [True, False])
- def test_void_comparison_failures(self):
+ @pytest.mark.parametrize("op", [
+ operator.eq, lambda x, y: operator.eq(y, x),
+ operator.ne, lambda x, y: operator.ne(y, x)])
+ def test_void_comparison_failures(self, op):
# In principle, one could decide to return an array of False for some
# if comparisons are impossible. But right now we return TypeError
# when "void" dtype are involved.
@@ -1298,18 +1330,18 @@ class TestStructured:
y = np.zeros(3)
# Cannot compare non-structured to structured:
with pytest.raises(TypeError):
- x == y
+ op(x, y)
# Added title prevents promotion, but casts are OK:
y = np.zeros(3, dtype=[(('title', 'a'), 'i1')])
assert np.can_cast(y.dtype, x.dtype)
with pytest.raises(TypeError):
- x == y
+ op(x, y)
x = np.zeros(3, dtype="V7")
y = np.zeros(3, dtype="V8")
with pytest.raises(TypeError):
- x == y
+ op(x, y)
def test_casting(self):
# Check that casting a structured array to change its byte order
@@ -1687,7 +1719,7 @@ class TestBool:
@pytest.mark.xfail(reason="See gh-9847")
def test_cast_from_unicode(self):
- self._test_cast_from_flexible(np.unicode_)
+ self._test_cast_from_flexible(np.str_)
@pytest.mark.xfail(reason="See gh-9847")
def test_cast_from_bytes(self):
@@ -1902,8 +1934,9 @@ class TestMethods:
assert_array_equal(a2.prod(axis=-1),
np.array([24, 1890, 600], ctype))
- def test_repeat(self):
- m = np.array([1, 2, 3, 4, 5, 6])
+ @pytest.mark.parametrize('dtype', [None, object])
+ def test_repeat(self, dtype):
+ m = np.array([1, 2, 3, 4, 5, 6], dtype=dtype)
m_rect = m.reshape((2, 3))
A = m.repeat([1, 3, 2, 1, 1, 2])
@@ -2069,7 +2102,7 @@ class TestMethods:
msg = 'byte-swapped complex sort, dtype={0}'.format(dt)
assert_equal(c, arr, msg)
- @pytest.mark.parametrize('dtype', [np.bytes_, np.unicode_])
+ @pytest.mark.parametrize('dtype', [np.bytes_, np.str_])
def test_sort_string(self, dtype):
# np.array will perform the encoding to bytes for us in the bytes test
a = np.array(['aaaaaaaa' + chr(i) for i in range(101)], dtype=dtype)
@@ -2097,19 +2130,26 @@ class TestMethods:
c.sort(kind=kind)
assert_equal(c, a, msg)
- def test_sort_structured(self):
+ @pytest.mark.parametrize("dt", [
+ np.dtype([('f', float), ('i', int)]),
+ np.dtype([('f', float), ('i', object)])])
+ @pytest.mark.parametrize("step", [1, 2])
+ def test_sort_structured(self, dt, step):
# test record array sorts.
- dt = np.dtype([('f', float), ('i', int)])
- a = np.array([(i, i) for i in range(101)], dtype=dt)
+ a = np.array([(i, i) for i in range(101*step)], dtype=dt)
b = a[::-1]
for kind in ['q', 'h', 'm']:
msg = "kind=%s" % kind
- c = a.copy()
+ c = a.copy()[::step]
+ indx = c.argsort(kind=kind)
c.sort(kind=kind)
- assert_equal(c, a, msg)
- c = b.copy()
+ assert_equal(c, a[::step], msg)
+ assert_equal(a[::step][indx], a[::step], msg)
+ c = b.copy()[::step]
+ indx = c.argsort(kind=kind)
c.sort(kind=kind)
- assert_equal(c, a, msg)
+ assert_equal(c, a[step-1::step], msg)
+ assert_equal(b[::step][indx], a[step-1::step], msg)
@pytest.mark.parametrize('dtype', ['datetime64[D]', 'timedelta64[D]'])
def test_sort_time(self, dtype):
@@ -2232,7 +2272,7 @@ class TestMethods:
assert_c(a.copy('C'))
assert_fortran(a.copy('F'))
assert_c(a.copy('A'))
-
+
@pytest.mark.parametrize("dtype", ['O', np.int32, 'i,O'])
def test__deepcopy__(self, dtype):
# Force the entry of NULLs into array
@@ -2343,7 +2383,7 @@ class TestMethods:
# test unicode argsorts.
s = 'aaaaaaaa'
- a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode_)
+ a = np.array([s + chr(i) for i in range(101)], dtype=np.str_)
b = a[::-1]
r = np.arange(101)
rr = r[::-1]
@@ -2426,7 +2466,7 @@ class TestMethods:
a = np.array(['aaaaaaaaa' for i in range(100)])
assert_equal(a.argsort(kind='m'), r)
# unicode
- a = np.array(['aaaaaaaaa' for i in range(100)], dtype=np.unicode_)
+ a = np.array(['aaaaaaaaa' for i in range(100)], dtype=np.str_)
assert_equal(a.argsort(kind='m'), r)
def test_sort_unicode_kind(self):
@@ -2441,7 +2481,7 @@ class TestMethods:
np.array([0, 1, np.nan]),
])
def test_searchsorted_floats(self, a):
- # test for floats arrays containing nans. Explicitly test
+ # test for floats arrays containing nans. Explicitly test
# half, single, and double precision floats to verify that
# the NaN-handling is correct.
msg = "Test real (%s) searchsorted with nans, side='l'" % a.dtype
@@ -2457,7 +2497,7 @@ class TestMethods:
assert_equal(y, 2)
def test_searchsorted_complex(self):
- # test for complex arrays containing nans.
+ # test for complex arrays containing nans.
# The search sorted routines use the compare functions for the
# array type, so this checks if that is consistent with the sort
# order.
@@ -2479,7 +2519,7 @@ class TestMethods:
a = np.array([0, 128], dtype='>i4')
b = a.searchsorted(np.array(128, dtype='>i4'))
assert_equal(b, 1, msg)
-
+
def test_searchsorted_n_elements(self):
# Check 0 elements
a = np.ones(0)
@@ -2570,7 +2610,7 @@ class TestMethods:
'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100197_1',
'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100198_1',
'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100199_1'],
- dtype=np.unicode_)
+ dtype=np.str_)
ind = np.arange(len(a))
assert_equal([a.searchsorted(v, 'left') for v in a], ind)
assert_equal([a.searchsorted(v, 'right') for v in a], ind + 1)
@@ -3605,9 +3645,13 @@ class TestMethods:
msg = 'dtype: {0}'.format(dt)
ap = complex(a)
assert_equal(ap, a, msg)
- bp = complex(b)
+
+ with assert_warns(DeprecationWarning):
+ bp = complex(b)
assert_equal(bp, b, msg)
- cp = complex(c)
+
+ with assert_warns(DeprecationWarning):
+ cp = complex(c)
assert_equal(cp, c, msg)
def test__complex__should_not_work(self):
@@ -3630,7 +3674,8 @@ class TestMethods:
assert_raises(TypeError, complex, d)
e = np.array(['1+1j'], 'U')
- assert_raises(TypeError, complex, e)
+ with assert_warns(DeprecationWarning):
+ assert_raises(TypeError, complex, e)
class TestCequenceMethods:
def test_array_contains(self):
@@ -3692,7 +3737,7 @@ class TestBinop:
'and': (np.bitwise_and, True, int),
'xor': (np.bitwise_xor, True, int),
'or': (np.bitwise_or, True, int),
- 'matmul': (np.matmul, False, float),
+ 'matmul': (np.matmul, True, float),
# 'ge': (np.less_equal, False),
# 'gt': (np.less, False),
# 'le': (np.greater_equal, False),
@@ -4710,23 +4755,23 @@ class TestArgmax:
a = np.array([1, 2**7 - 1, -2**7], dtype=np.int8)
assert_equal(np.argmax(a), 1)
- a.repeat(129)
- assert_equal(np.argmax(a), 1)
+ a = a.repeat(129)
+ assert_equal(np.argmax(a), 129)
a = np.array([1, 2**15 - 1, -2**15], dtype=np.int16)
assert_equal(np.argmax(a), 1)
- a.repeat(129)
- assert_equal(np.argmax(a), 1)
+ a = a.repeat(129)
+ assert_equal(np.argmax(a), 129)
a = np.array([1, 2**31 - 1, -2**31], dtype=np.int32)
assert_equal(np.argmax(a), 1)
- a.repeat(129)
- assert_equal(np.argmax(a), 1)
+ a = a.repeat(129)
+ assert_equal(np.argmax(a), 129)
a = np.array([1, 2**63 - 1, -2**63], dtype=np.int64)
assert_equal(np.argmax(a), 1)
- a.repeat(129)
- assert_equal(np.argmax(a), 1)
+ a = a.repeat(129)
+ assert_equal(np.argmax(a), 129)
class TestArgmin:
usg_data = [
@@ -4852,23 +4897,23 @@ class TestArgmin:
a = np.array([1, -2**7, -2**7 + 1, 2**7 - 1], dtype=np.int8)
assert_equal(np.argmin(a), 1)
- a.repeat(129)
- assert_equal(np.argmin(a), 1)
+ a = a.repeat(129)
+ assert_equal(np.argmin(a), 129)
a = np.array([1, -2**15, -2**15 + 1, 2**15 - 1], dtype=np.int16)
assert_equal(np.argmin(a), 1)
- a.repeat(129)
- assert_equal(np.argmin(a), 1)
+ a = a.repeat(129)
+ assert_equal(np.argmin(a), 129)
a = np.array([1, -2**31, -2**31 + 1, 2**31 - 1], dtype=np.int32)
assert_equal(np.argmin(a), 1)
- a.repeat(129)
- assert_equal(np.argmin(a), 1)
+ a = a.repeat(129)
+ assert_equal(np.argmin(a), 129)
a = np.array([1, -2**63, -2**63 + 1, 2**63 - 1], dtype=np.int64)
assert_equal(np.argmin(a), 1)
- a.repeat(129)
- assert_equal(np.argmin(a), 1)
+ a = a.repeat(129)
+ assert_equal(np.argmin(a), 129)
class TestMinMax:
@@ -5066,6 +5111,22 @@ class TestPutmask:
with pytest.raises(ValueError):
np.putmask(a, a >= 2, 3)
+ def test_kwargs(self):
+ x = np.array([0, 0])
+ np.putmask(x, [0, 1], [-1, -2])
+ assert_array_equal(x, [0, -2])
+
+ x = np.array([0, 0])
+ np.putmask(x, mask=[0, 1], values=[-1, -2])
+ assert_array_equal(x, [0, -2])
+
+ x = np.array([0, 0])
+ np.putmask(x, values=[-1, -2], mask=[0, 1])
+ assert_array_equal(x, [0, -2])
+
+ with pytest.raises(TypeError):
+ np.putmask(a=x, values=[-1, -2], mask=[0, 1])
+
class TestTake:
def tst_basic(self, x):
@@ -5517,33 +5578,6 @@ class TestIO:
tmp_filename,
dtype='<f4')
- @pytest.mark.slow # takes > 1 minute on mechanical hard drive
- def test_big_binary(self):
- """Test workarounds for 32-bit limit for MSVC fwrite, fseek, and ftell
-
- These normally would hang doing something like this.
- See : https://github.com/numpy/numpy/issues/2256
- """
- if sys.platform != 'win32' or '[GCC ' in sys.version:
- return
- try:
- # before workarounds, only up to 2**32-1 worked
- fourgbplus = 2**32 + 2**16
- testbytes = np.arange(8, dtype=np.int8)
- n = len(testbytes)
- flike = tempfile.NamedTemporaryFile()
- f = flike.file
- np.tile(testbytes, fourgbplus // testbytes.nbytes).tofile(f)
- flike.seek(0)
- a = np.fromfile(f, dtype=np.int8)
- flike.close()
- assert_(len(a) == fourgbplus)
- # check only start and end for speed:
- assert_((a[:n] == testbytes).all())
- assert_((a[-n:] == testbytes).all())
- except (MemoryError, ValueError):
- pass
-
def test_string(self, tmp_filename):
self._check_from(b'1,2,3,4', [1., 2., 3., 4.], tmp_filename, sep=',')
@@ -6196,7 +6230,7 @@ class TestStats:
def test_mean_axis_error(self):
# Ensure that AxisError is raised instead of IndexError when axis is
# out of bounds, see gh-15817.
- with assert_raises(np.core._exceptions.AxisError):
+ with assert_raises(np.exceptions.AxisError):
np.arange(10).mean(axis=2)
def test_mean_where(self):
@@ -6280,7 +6314,7 @@ class TestStats:
def test_var_axis_error(self):
# Ensure that AxisError is raised instead of IndexError when axis is
# out of bounds, see gh-15817.
- with assert_raises(np.core._exceptions.AxisError):
+ with assert_raises(np.exceptions.AxisError):
np.arange(10).var(axis=2)
def test_var_where(self):
@@ -6647,6 +6681,22 @@ class TestDot:
r = np.empty((1024, 32), dtype=int)
assert_raises(ValueError, dot, f, v, r)
+ def test_dot_out_result(self):
+ x = np.ones((), dtype=np.float16)
+ y = np.ones((5,), dtype=np.float16)
+ z = np.zeros((5,), dtype=np.float16)
+ res = x.dot(y, out=z)
+ assert np.array_equal(res, y)
+ assert np.array_equal(z, y)
+
+ def test_dot_out_aliasing(self):
+ x = np.ones((), dtype=np.float16)
+ y = np.ones((5,), dtype=np.float16)
+ z = np.zeros((5,), dtype=np.float16)
+ res = x.dot(y, out=z)
+ z[0] = 2
+ assert np.array_equal(res, z)
+
def test_dot_array_order(self):
a = np.array([[1, 2], [3, 4]], order='C')
b = np.array([[1, 2], [3, 4]], order='F')
@@ -6731,6 +6781,18 @@ class TestDot:
res = np.dot(data, data)
assert res == 2**30+100
+ def test_dtype_discovery_fails(self):
+ # See gh-14247, error checking was missing for failed dtype discovery
+ class BadObject(object):
+ def __array__(self):
+ raise TypeError("just this tiny mint leaf")
+
+ with pytest.raises(TypeError):
+ np.dot(BadObject(), BadObject())
+
+ with pytest.raises(TypeError):
+ np.dot(3.0, BadObject())
+
class MatmulCommon:
"""Common tests for '@' operator and numpy.matmul.
@@ -7142,16 +7204,69 @@ class TestMatmulOperator(MatmulCommon):
assert_raises(TypeError, self.matmul, np.void(b'abc'), np.void(b'abc'))
assert_raises(TypeError, self.matmul, np.arange(10), np.void(b'abc'))
-def test_matmul_inplace():
- # It would be nice to support in-place matmul eventually, but for now
- # we don't have a working implementation, so better just to error out
- # and nudge people to writing "a = a @ b".
- a = np.eye(3)
- b = np.eye(3)
- assert_raises(TypeError, a.__imatmul__, b)
- import operator
- assert_raises(TypeError, operator.imatmul, a, b)
- assert_raises(TypeError, exec, "a @= b", globals(), locals())
+
+class TestMatmulInplace:
+ DTYPES = {}
+ for i in MatmulCommon.types:
+ for j in MatmulCommon.types:
+ if np.can_cast(j, i):
+ DTYPES[f"{i}-{j}"] = (np.dtype(i), np.dtype(j))
+
+ @pytest.mark.parametrize("dtype1,dtype2", DTYPES.values(), ids=DTYPES)
+ def test_basic(self, dtype1: np.dtype, dtype2: np.dtype) -> None:
+ a = np.arange(10).reshape(5, 2).astype(dtype1)
+ a_id = id(a)
+ b = np.ones((2, 2), dtype=dtype2)
+
+ ref = a @ b
+ a @= b
+
+ assert id(a) == a_id
+ assert a.dtype == dtype1
+ assert a.shape == (5, 2)
+ if dtype1.kind in "fc":
+ np.testing.assert_allclose(a, ref)
+ else:
+ np.testing.assert_array_equal(a, ref)
+
+ SHAPES = {
+ "2d_large": ((10**5, 10), (10, 10)),
+ "3d_large": ((10**4, 10, 10), (1, 10, 10)),
+ "1d": ((3,), (3,)),
+ "2d_1d": ((3, 3), (3,)),
+ "1d_2d": ((3,), (3, 3)),
+ "2d_broadcast": ((3, 3), (3, 1)),
+ "2d_broadcast_reverse": ((1, 3), (3, 3)),
+ "3d_broadcast1": ((3, 3, 3), (1, 3, 1)),
+ "3d_broadcast2": ((3, 3, 3), (1, 3, 3)),
+ "3d_broadcast3": ((3, 3, 3), (3, 3, 1)),
+ "3d_broadcast_reverse1": ((1, 3, 3), (3, 3, 3)),
+ "3d_broadcast_reverse2": ((3, 1, 3), (3, 3, 3)),
+ "3d_broadcast_reverse3": ((1, 1, 3), (3, 3, 3)),
+ }
+
+ @pytest.mark.parametrize("a_shape,b_shape", SHAPES.values(), ids=SHAPES)
+ def test_shapes(self, a_shape: tuple[int, ...], b_shape: tuple[int, ...]):
+ a_size = np.prod(a_shape)
+ a = np.arange(a_size).reshape(a_shape).astype(np.float64)
+ a_id = id(a)
+
+ b_size = np.prod(b_shape)
+ b = np.arange(b_size).reshape(b_shape)
+
+ ref = a @ b
+ if ref.shape != a_shape:
+ with pytest.raises(ValueError):
+ a @= b
+ return
+ else:
+ a @= b
+
+ assert id(a) == a_id
+ assert a.dtype.type == np.float64
+ assert a.shape == a_shape
+ np.testing.assert_allclose(a, ref)
+
def test_matmul_axes():
a = np.arange(3*4*5).reshape(3, 4, 5)
@@ -8647,14 +8762,16 @@ class TestConversion:
int_funcs = (int, lambda x: x.__int__())
for int_func in int_funcs:
assert_equal(int_func(np.array(0)), 0)
- assert_equal(int_func(np.array([1])), 1)
- assert_equal(int_func(np.array([[42]])), 42)
+ with assert_warns(DeprecationWarning):
+ assert_equal(int_func(np.array([1])), 1)
+ with assert_warns(DeprecationWarning):
+ assert_equal(int_func(np.array([[42]])), 42)
assert_raises(TypeError, int_func, np.array([1, 2]))
# gh-9972
assert_equal(4, int_func(np.array('4')))
assert_equal(5, int_func(np.bytes_(b'5')))
- assert_equal(6, int_func(np.unicode_('6')))
+ assert_equal(6, int_func(np.str_('6')))
# The delegation of int() to __trunc__ was deprecated in
# Python 3.11.
@@ -8663,7 +8780,8 @@ class TestConversion:
def __trunc__(self):
return 3
assert_equal(3, int_func(np.array(HasTrunc())))
- assert_equal(3, int_func(np.array([HasTrunc()])))
+ with assert_warns(DeprecationWarning):
+ assert_equal(3, int_func(np.array([HasTrunc()])))
else:
pass
@@ -8672,8 +8790,9 @@ class TestConversion:
raise NotImplementedError
assert_raises(NotImplementedError,
int_func, np.array(NotConvertible()))
- assert_raises(NotImplementedError,
- int_func, np.array([NotConvertible()]))
+ with assert_warns(DeprecationWarning):
+ assert_raises(NotImplementedError,
+ int_func, np.array([NotConvertible()]))
class TestWhere:
@@ -8840,6 +8959,11 @@ class TestWhere:
result = array.nonzero()
assert_array_equal(benchmark, result)
+ def test_kwargs(self):
+ a = np.zeros(1)
+ with assert_raises(TypeError):
+ np.where(a, x=a, y=a)
+
if not IS_PYPY:
# sys.getsizeof() is not valid on PyPy
@@ -9021,33 +9145,33 @@ class TestUnicodeEncoding:
def test_assign_scalar(self):
# gh-3258
l = np.array(['aa', 'bb'])
- l[:] = np.unicode_('cc')
+ l[:] = np.str_('cc')
assert_equal(l, ['cc', 'cc'])
def test_fill_scalar(self):
# gh-7227
l = np.array(['aa', 'bb'])
- l.fill(np.unicode_('cc'))
+ l.fill(np.str_('cc'))
assert_equal(l, ['cc', 'cc'])
class TestUnicodeArrayNonzero:
def test_empty_ustring_array_is_falsey(self):
- assert_(not np.array([''], dtype=np.unicode_))
+ assert_(not np.array([''], dtype=np.str_))
def test_whitespace_ustring_array_is_falsey(self):
- a = np.array(['eggs'], dtype=np.unicode_)
+ a = np.array(['eggs'], dtype=np.str_)
a[0] = ' \0\0'
assert_(not a)
def test_all_null_ustring_array_is_falsey(self):
- a = np.array(['eggs'], dtype=np.unicode_)
+ a = np.array(['eggs'], dtype=np.str_)
a[0] = '\0\0\0\0'
assert_(not a)
def test_null_inside_ustring_array_is_truthy(self):
- a = np.array(['eggs'], dtype=np.unicode_)
+ a = np.array(['eggs'], dtype=np.str_)
a[0] = ' \0 \0'
assert_(a)
@@ -9312,6 +9436,61 @@ class TestArange:
assert len(keyword_start_stop) == 6
assert_array_equal(keyword_stop, keyword_zerotostop)
+ def test_arange_booleans(self):
+ # Arange makes some sense for booleans and works up to length 2.
+ # But it is weird since `arange(2, 4, dtype=bool)` works.
+ # Arguably, much or all of this could be deprecated/removed.
+ res = np.arange(False, dtype=bool)
+ assert_array_equal(res, np.array([], dtype="bool"))
+
+ res = np.arange(True, dtype="bool")
+ assert_array_equal(res, [False])
+
+ res = np.arange(2, dtype="bool")
+ assert_array_equal(res, [False, True])
+
+ # This case is especially weird, but drops out without special case:
+ res = np.arange(6, 8, dtype="bool")
+ assert_array_equal(res, [True, True])
+
+ with pytest.raises(TypeError):
+ np.arange(3, dtype="bool")
+
+ @pytest.mark.parametrize("dtype", ["S3", "U", "5i"])
+ def test_rejects_bad_dtypes(self, dtype):
+ dtype = np.dtype(dtype)
+ DType_name = re.escape(str(type(dtype)))
+ with pytest.raises(TypeError,
+ match=rf"arange\(\) not supported for inputs .* {DType_name}"):
+ np.arange(2, dtype=dtype)
+
+ def test_rejects_strings(self):
+ # Explicitly test error for strings which may call "b" - "a":
+ DType_name = re.escape(str(type(np.array("a").dtype)))
+ with pytest.raises(TypeError,
+ match=rf"arange\(\) not supported for inputs .* {DType_name}"):
+ np.arange("a", "b")
+
+ def test_byteswapped(self):
+ res_be = np.arange(1, 1000, dtype=">i4")
+ res_le = np.arange(1, 1000, dtype="<i4")
+ assert res_be.dtype == ">i4"
+ assert res_le.dtype == "<i4"
+ assert_array_equal(res_le, res_be)
+
+ @pytest.mark.parametrize("which", [0, 1, 2])
+ def test_error_paths_and_promotion(self, which):
+ args = [0, 1, 2] # start, stop, and step
+ args[which] = np.float64(2.) # should ensure float64 output
+
+ assert np.arange(*args).dtype == np.float64
+
+ # Cover stranger error path, test only to achieve code coverage!
+ args[which] = [None, []]
+ with pytest.raises(ValueError):
+ # Fails discovering start dtype
+ np.arange(*args)
+
class TestArrayFinalize:
""" Tests __array_finalize__ """
@@ -9425,6 +9604,105 @@ def test_equal_override():
assert_equal(array != my_always_equal, 'ne')
+@pytest.mark.parametrize("op", [operator.eq, operator.ne])
+@pytest.mark.parametrize(["dt1", "dt2"], [
+ ([("f", "i")], [("f", "i")]), # structured comparison (successful)
+ ("M8", "d"), # impossible comparison: result is all True or False
+ ("d", "d"), # valid comparison
+ ])
+def test_equal_subclass_no_override(op, dt1, dt2):
+ # Test how the three different possible code-paths deal with subclasses
+
+ class MyArr(np.ndarray):
+ called_wrap = 0
+
+ def __array_wrap__(self, new):
+ type(self).called_wrap += 1
+ return super().__array_wrap__(new)
+
+ numpy_arr = np.zeros(5, dtype=dt1)
+ my_arr = np.zeros(5, dtype=dt2).view(MyArr)
+
+ assert type(op(numpy_arr, my_arr)) is MyArr
+ assert type(op(my_arr, numpy_arr)) is MyArr
+ # We expect 2 calls (more if there were more fields):
+ assert MyArr.called_wrap == 2
+
+
+@pytest.mark.parametrize(["dt1", "dt2"], [
+ ("M8[ns]", "d"),
+ ("M8[s]", "l"),
+ ("m8[ns]", "d"),
+ # Missing: ("m8[ns]", "l") as timedelta currently promotes ints
+ ("M8[s]", "m8[s]"),
+ ("S5", "U5"),
+ # Structured/void dtypes have explicit paths not tested here.
+])
+def test_no_loop_gives_all_true_or_false(dt1, dt2):
+ # Make sure they broadcast to test result shape, use random values, since
+ # the actual value should be ignored
+ arr1 = np.random.randint(5, size=100).astype(dt1)
+ arr2 = np.random.randint(5, size=99)[:, np.newaxis].astype(dt2)
+
+ res = arr1 == arr2
+ assert res.shape == (99, 100)
+ assert res.dtype == bool
+ assert not res.any()
+
+ res = arr1 != arr2
+ assert res.shape == (99, 100)
+ assert res.dtype == bool
+ assert res.all()
+
+ # incompatible shapes raise though
+ arr2 = np.random.randint(5, size=99).astype(dt2)
+ with pytest.raises(ValueError):
+ arr1 == arr2
+
+ with pytest.raises(ValueError):
+ arr1 != arr2
+
+ # Basic test with another operation:
+ with pytest.raises(np.core._exceptions._UFuncNoLoopError):
+ arr1 > arr2
+
+
+@pytest.mark.parametrize("op", [
+ operator.eq, operator.ne, operator.le, operator.lt, operator.ge,
+ operator.gt])
+def test_comparisons_forwards_error(op):
+ class NotArray:
+ def __array__(self):
+ raise TypeError("run you fools")
+
+ with pytest.raises(TypeError, match="run you fools"):
+ op(np.arange(2), NotArray())
+
+ with pytest.raises(TypeError, match="run you fools"):
+ op(NotArray(), np.arange(2))
+
+
+def test_richcompare_scalar_boolean_singleton_return():
+ # These are currently guaranteed to be the boolean singletons, but maybe
+ # returning NumPy booleans would also be OK:
+ assert (np.array(0) == "a") is False
+ assert (np.array(0) != "a") is True
+ assert (np.int16(0) == "a") is False
+ assert (np.int16(0) != "a") is True
+
+
+@pytest.mark.parametrize("op", [
+ operator.eq, operator.ne, operator.le, operator.lt, operator.ge,
+ operator.gt])
+def test_ragged_comparison_fails(op):
+ # This needs to convert the internal array to True/False, which fails:
+ a = np.array([1, np.array([1, 2, 3])], dtype=object)
+ b = np.array([1, np.array([1, 2, 3])], dtype=object)
+
+ with pytest.raises(ValueError, match="The truth value.*ambiguous"):
+ op(a, b)
+
+
@pytest.mark.parametrize(
["fun", "npfun"],
[
@@ -9651,40 +9929,50 @@ class TestViewDtype:
assert_array_equal(x.view('<i2'), expected)
+@pytest.mark.xfail(_SUPPORTS_SVE, reason="gh-22982")
# Test various array sizes that hit different code paths in quicksort-avx512
-@pytest.mark.parametrize("N", [8, 16, 24, 32, 48, 64, 96, 128, 151, 191,
- 256, 383, 512, 1023, 2047])
-def test_sort_float(N):
+@pytest.mark.parametrize("N", np.arange(1, 512))
+@pytest.mark.parametrize("dtype", ['e', 'f', 'd'])
+def test_sort_float(N, dtype):
# Regular data with nan sprinkled
np.random.seed(42)
- arr = -0.5 + np.random.sample(N).astype('f')
+ arr = -0.5 + np.random.sample(N).astype(dtype)
arr[np.random.choice(arr.shape[0], 3)] = np.nan
assert_equal(np.sort(arr, kind='quick'), np.sort(arr, kind='heap'))
# (2) with +INF
- infarr = np.inf*np.ones(N, dtype='f')
+ infarr = np.inf*np.ones(N, dtype=dtype)
infarr[np.random.choice(infarr.shape[0], 5)] = -1.0
assert_equal(np.sort(infarr, kind='quick'), np.sort(infarr, kind='heap'))
# (3) with -INF
- neginfarr = -np.inf*np.ones(N, dtype='f')
+ neginfarr = -np.inf*np.ones(N, dtype=dtype)
neginfarr[np.random.choice(neginfarr.shape[0], 5)] = 1.0
assert_equal(np.sort(neginfarr, kind='quick'),
np.sort(neginfarr, kind='heap'))
# (4) with +/-INF
- infarr = np.inf*np.ones(N, dtype='f')
+ infarr = np.inf*np.ones(N, dtype=dtype)
infarr[np.random.choice(infarr.shape[0], (int)(N/2))] = -np.inf
assert_equal(np.sort(infarr, kind='quick'), np.sort(infarr, kind='heap'))
-
-def test_sort_int():
- # Random data with NPY_MAX_INT32 and NPY_MIN_INT32 sprinkled
- rng = np.random.default_rng(42)
- N = 2047
- minv = np.iinfo(np.int32).min
- maxv = np.iinfo(np.int32).max
- arr = rng.integers(low=minv, high=maxv, size=N).astype('int32')
+def test_sort_float16():
+ arr = np.arange(65536, dtype=np.int16)
+ temp = np.frombuffer(arr.tobytes(), dtype=np.float16)
+ data = np.copy(temp)
+ np.random.shuffle(data)
+ data_backup = data
+ assert_equal(np.sort(data, kind='quick'),
+ np.sort(data_backup, kind='heap'))
+
+
+@pytest.mark.parametrize("N", np.arange(1, 512))
+@pytest.mark.parametrize("dtype", ['h', 'H', 'i', 'I', 'l', 'L'])
+def test_sort_int(N, dtype):
+ # Random data with MAX and MIN sprinkled
+ minv = np.iinfo(dtype).min
+ maxv = np.iinfo(dtype).max
+ arr = np.random.randint(low=minv, high=maxv-1, size=N, dtype=dtype)
arr[np.random.choice(arr.shape[0], 10)] = minv
arr[np.random.choice(arr.shape[0], 10)] = maxv
assert_equal(np.sort(arr, kind='quick'), np.sort(arr, kind='heap'))
@@ -9698,3 +9986,6 @@ def test_sort_uint():
arr = rng.integers(low=0, high=maxv, size=N).astype('uint32')
arr[np.random.choice(arr.shape[0], 10)] = maxv
assert_equal(np.sort(arr, kind='quick'), np.sort(arr, kind='heap'))
+
+def test_private_get_ndarray_c_version():
+ assert isinstance(_get_ndarray_c_version(), int)