NumPy 源码解析(八十二)
.\numpy\numpy\_core\tests\test_errstate.py
import pytest
import sysconfig
import numpy as np
from numpy.testing import assert_, assert_raises, IS_WASM
hosttype = sysconfig.get_config_var('HOST_GNU_TYPE')
arm_softfloat = False if hosttype is None else hosttype.endswith('gnueabi')
class TestErrstate:
@pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
@pytest.mark.skipif(arm_softfloat,
reason='platform/cpu issue with FPU (gh-413,-15562)')
def test_invalid(self):
with np.errstate(all='raise', under='ignore'):
a = -np.arange(3)
with np.errstate(invalid='ignore'):
np.sqrt(a)
with assert_raises(FloatingPointError):
np.sqrt(a)
@pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
@pytest.mark.skipif(arm_softfloat,
reason='platform/cpu issue with FPU (gh-15562)')
def test_divide(self):
with np.errstate(all='raise', under='ignore'):
a = -np.arange(3)
with np.errstate(divide='ignore'):
a // 0
with assert_raises(FloatingPointError):
a // 0
with assert_raises(FloatingPointError):
a // a
def test_errcall(self):
count = 0
def foo(*args):
nonlocal count
count += 1
olderrcall = np.geterrcall()
with np.errstate(call=foo):
assert np.geterrcall() is foo
with np.errstate(call=None):
assert np.geterrcall() is None
assert np.geterrcall() is olderrcall
assert count == 0
with np.errstate(call=foo, invalid="call"):
np.array(np.inf) - np.array(np.inf)
assert count == 1
def test_errstate_decorator(self):
@np.errstate(all='ignore')
def foo():
a = -np.arange(3)
a // 0
foo()
def test_errstate_enter_once(self):
errstate = np.errstate(invalid="warn")
with errstate:
pass
with pytest.raises(TypeError,
match="Cannot enter `np.errstate` twice"):
with errstate:
pass
@pytest.mark.skipif(IS_WASM, reason="wasm doesn't support asyncio")
def test_asyncio_safe(self):
asyncio = pytest.importorskip("asyncio")
@np.errstate(invalid="ignore")
def decorated():
assert np.geterr()["invalid"] == "ignore"
async def func1():
decorated()
await asyncio.sleep(0.1)
decorated()
async def func2():
with np.errstate(invalid="raise"):
assert np.geterr()["invalid"] == "raise"
await asyncio.sleep(0.125)
assert np.geterr()["invalid"] == "raise"
async def func3():
with np.errstate(invalid="print"):
assert np.geterr()["invalid"] == "print"
await asyncio.sleep(0.11)
assert np.geterr()["invalid"] == "print"
async def main():
await asyncio.gather(
func1(), func2(), func3(), func1(), func2(), func3(),
func1(), func2(), func3(), func1(), func2(), func3())
loop = asyncio.new_event_loop()
with np.errstate(invalid="warn"):
asyncio.run(main())
assert np.geterr()["invalid"] == "warn"
assert np.geterr()["invalid"] == "warn"
loop.close()
.\numpy\numpy\_core\tests\test_extint128.py
import itertools
import contextlib
import operator
import pytest
import numpy as np
import numpy._core._multiarray_tests as mt
from numpy.testing import assert_raises, assert_equal
INT64_MAX = np.iinfo(np.int64).max
INT64_MIN = np.iinfo(np.int64).min
INT64_MID = 2**32
INT128_MAX = 2**128 - 1
INT128_MIN = -INT128_MAX
INT128_MID = 2**64
INT64_VALUES = (
[INT64_MIN + j for j in range(20)] +
[INT64_MAX - j for j in range(20)] +
[INT64_MID + j for j in range(-20, 20)] +
[2*INT64_MID + j for j in range(-20, 20)] +
[INT64_MID//2 + j for j in range(-20, 20)] +
list(range(-70, 70))
)
INT128_VALUES = (
[INT128_MIN + j for j in range(20)] +
[INT128_MAX - j for j in range(20)] +
[INT128_MID + j for j in range(-20, 20)] +
[2*INT128_MID + j for j in range(-20, 20)] +
[INT128_MID//2 + j for j in range(-20, 20)] +
list(range(-70, 70)) +
[False]
)
INT64_POS_VALUES = [x for x in INT64_VALUES if x > 0]
@contextlib.contextmanager
def exc_iter(*args):
"""
创建一个上下文管理器,用于迭代*args的笛卡尔积,如果发生异常,则添加当前迭代的信息。
"""
value = [None]
def iterate():
for v in itertools.product(*args):
value[0] = v
yield v
try:
yield iterate()
except Exception:
import traceback
msg = "At: %r\n%s" % (repr(value[0]),
traceback.format_exc())
raise AssertionError(msg)
def test_safe_binop():
ops = [
(operator.add, 1),
(operator.sub, 2),
(operator.mul, 3)
]
with exc_iter(ops, INT64_VALUES, INT64_VALUES) as it:
for xop, a, b in it:
pyop, op = xop
c = pyop(a, b)
if not (INT64_MIN <= c <= INT64_MAX):
assert_raises(OverflowError, mt.extint_safe_binop, a, b, op)
else:
d = mt.extint_safe_binop(a, b, op)
if c != d:
assert_equal(d, c)
def test_to_128():
with exc_iter(INT64_VALUES) as it:
for a, in it:
b = mt.extint_to_128(a)
if a != b:
assert_equal(b, a)
def test_to_64():
with exc_iter(INT128_VALUES) as it:
for a, in it:
if not (INT64_MIN <= a <= INT64_MAX):
assert_raises(OverflowError, mt.extint_to_64, a)
else:
b = mt.extint_to_64(a)
if a != b:
assert_equal(b, a)
def test_mul_64_64():
with exc_iter(INT64_VALUES, INT64_VALUES) as it:
for a, b in it:
c = a * b
d = mt.extint_mul_64_64(a, b)
if c != d:
assert_equal(d, c)
def test_add_128():
with exc_iter(INT128_VALUES, INT128_VALUES) as it:
for a, b in it:
c = a + b
if not (INT128_MIN <= c <= INT128_MAX):
assert_raises(OverflowError, mt.extint_add_128, a, b)
else:
d = mt.extint_add_128(a, b)
if c != d:
assert_equal(d, c)
def test_sub_128():
with exc_iter(INT128_VALUES, INT128_VALUES) as it:
for a, b in it:
c = a - b
if not (INT128_MIN <= c <= INT128_MAX):
assert_raises(OverflowError, mt.extint_sub_128, a, b)
else:
d = mt.extint_sub_128(a, b)
if c != d:
assert_equal(d, c)
def test_neg_128():
with exc_iter(INT128_VALUES) as it:
for a, in it:
b = -a
c = mt.extint_neg_128(a)
if b != c:
assert_equal(c, b)
def test_shl_128():
with exc_iter(INT128_VALUES) as it:
for a, in it:
if a < 0:
b = -(((-a) << 1) & (2**128-1))
else:
b = (a << 1) & (2**128-1)
c = mt.extint_shl_128(a)
if b != c:
assert_equal(c, b)
def test_shr_128():
with exc_iter(INT128_VALUES) as it:
for a, in it:
if a < 0:
b = -((-a) >> 1)
else:
b = a >> 1
c = mt.extint_shr_128(a)
if b != c:
assert_equal(c, b)
def test_gt_128():
with exc_iter(INT128_VALUES, INT128_VALUES) as it:
for a, b in it:
c = a > b
d = mt.extint_gt_128(a, b)
if c != d:
assert_equal(d, c)
@pytest.mark.slow
def test_divmod_128_64():
with exc_iter(INT128_VALUES, INT64_POS_VALUES) as it:
for a, b in it:
if a >= 0:
c, cr = divmod(a, b)
else:
c, cr = divmod(-a, b)
c = -c
cr = -cr
d, dr = mt.extint_divmod_128_64(a, b)
if c != d or d != dr or b * d + dr != a:
assert_equal(d, c)
assert_equal(dr, cr)
assert_equal(b * d + dr, a)
def test_floordiv_128_64():
with exc_iter(INT128_VALUES, INT64_POS_VALUES) as it:
for a, b in it:
c = a // b
d = mt.extint_floordiv_128_64(a, b)
if c != d:
assert_equal(d, c)
def test_ceildiv_128_64():
with exc_iter(INT128_VALUES, INT64_POS_VALUES) as it:
for a, b in it:
c = (a + b - 1) // b
d = mt.extint_ceildiv_128_64(a, b)
if c != d:
assert_equal(d, c)
.\numpy\numpy\_core\tests\test_function_base.py
import sys
import pytest
import numpy as np
from numpy import (
logspace, linspace, geomspace, dtype, array, arange, isnan,
ndarray, sqrt, nextafter, stack, errstate
)
from numpy._core import sctypes
from numpy._core.function_base import add_newdoc
from numpy.testing import (
assert_, assert_equal, assert_raises, assert_array_equal, assert_allclose,
IS_PYPY
)
class PhysicalQuantity(float):
def __new__(cls, value):
return float.__new__(cls, value)
def __add__(self, x):
assert_(isinstance(x, PhysicalQuantity))
return PhysicalQuantity(float(x) + float(self))
__radd__ = __add__
def __sub__(self, x):
assert_(isinstance(x, PhysicalQuantity))
return PhysicalQuantity(float(self) - float(x))
def __rsub__(self, x):
assert_(isinstance(x, PhysicalQuantity))
return PhysicalQuantity(float(x) - float(self))
def __mul__(self, x):
return PhysicalQuantity(float(x) * float(self))
__rmul__ = __mul__
def __div__(self, x):
return PhysicalQuantity(float(self) / float(x))
def __rdiv__(self, x):
return PhysicalQuantity(float(x) / float(self))
class PhysicalQuantity2(ndarray):
__array_priority__ = 10
class TestLogspace:
def test_basic(self):
y = logspace(0, 6)
assert_(len(y) == 50)
y = logspace(0, 6, num=100)
assert_(y[-1] == 10 ** 6)
y = logspace(0, 6, endpoint=False)
assert_(y[-1] < 10 ** 6)
y = logspace(0, 6, num=7)
assert_array_equal(y, [1, 10, 100, 1e3, 1e4, 1e5, 1e6])
def test_start_stop_array(self):
start = array([0., 1.])
stop = array([6., 7.])
t1 = logspace(start, stop, 6)
t2 = stack([logspace(_start, _stop, 6)
for _start, _stop in zip(start, stop)], axis=1)
assert_equal(t1, t2)
t3 = logspace(start, stop[0], 6)
t4 = stack([logspace(_start, stop[0], 6)
for _start in start], axis=1)
assert_equal(t3, t4)
t5 = logspace(start, stop, 6, axis=-1)
assert_equal(t5, t2.T)
@pytest.mark.parametrize("axis", [0, 1, -1])
def test_base_array(self, axis: int):
start = 1
stop = 2
num = 6
base = array([1, 2])
t1 = logspace(start, stop, num=num, base=base, axis=axis)
t2 = stack(
[logspace(start, stop, num=num, base=_base) for _base in base],
axis=(axis + 1) % t1.ndim,
)
assert_equal(t1, t2)
@pytest.mark.parametrize("axis", [0, 1, -1])
def test_stop_base_array(self, axis: int):
start = 1
stop = array([2, 3])
num = 6
base = array([1, 2])
t1 = logspace(start, stop, num=num, base=base, axis=axis)
t2 = stack(
[logspace(start, _stop, num=num, base=_base)
for _stop, _base in zip(stop, base)],
axis=(axis + 1) % t1.ndim,
)
assert_equal(t1, t2)
def test_dtype(self):
y = logspace(0, 6, dtype='float32')
assert_equal(y.dtype, dtype('float32'))
y = logspace(0, 6, dtype='float64')
assert_equal(y.dtype, dtype('float64'))
y = logspace(0, 6, dtype='int32')
assert_equal(y.dtype, dtype('int32'))
def test_physical_quantities(self):
a = PhysicalQuantity(1.0)
b = PhysicalQuantity(5.0)
assert_equal(logspace(a, b), logspace(1.0, 5.0))
def test_subclass(self):
a = array(1).view(PhysicalQuantity2)
b = array(7).view(PhysicalQuantity2)
ls = logspace(a, b)
assert type(ls) is PhysicalQuantity2
assert_equal(ls, logspace(1.0, 7.0))
ls = logspace(a, b, 1)
assert type(ls) is PhysicalQuantity2
assert_equal(ls, logspace(1.0, 7.0, 1))
class TestGeomspace:
def test_basic(self):
y = geomspace(1, 1e6)
assert_(len(y) == 50)
y = geomspace(1, 1e6, num=100)
assert_(y[-1] == 10 ** 6)
y = geomspace(1, 1e6, endpoint=False)
assert_(y[-1] < 10 ** 6)
y = geomspace(1, 1e6, num=7)
assert_array_equal(y, [1, 10, 100, 1e3, 1e4, 1e5, 1e6])
y = geomspace(8, 2, num=3)
assert_allclose(y, [8, 4, 2])
assert_array_equal(y.imag, 0)
y = geomspace(-1, -100, num=3)
assert_array_equal(y, [-1, -10, -100])
assert_array_equal(y.imag, 0)
y = geomspace(-100, -1, num=3)
assert_array_equal(y, [-100, -10, -1])
assert_array_equal(y.imag, 0)
def test_boundaries_match_start_and_stop_exactly(self):
start = 0.3
stop = 20.3
y = geomspace(start, stop, num=1)
assert_equal(y[0], start)
y = geomspace(start, stop, num=1, endpoint=False)
assert_equal(y[0], start)
y = geomspace(start, stop, num=3)
assert_equal(y[0], start)
assert_equal(y[-1], stop)
y = geomspace(start, stop, num=3, endpoint=False)
assert_equal(y[0], start)
def test_nan_interior(self):
with errstate(invalid='ignore'):
y = geomspace(-3, 3, num=4)
assert_equal(y[0], -3.0)
assert_(isnan(y[1:-1]).all())
assert_equal(y[3], 3.0)
with errstate(invalid='ignore'):
y = geomspace(-3, 3, num=4, endpoint=False)
assert_equal(y[0], -3.0)
assert_(isnan(y[1:]).all())
def test_complex(self):
y = geomspace(1j, 16j, num=5)
assert_allclose(y, [1j, 2j, 4j, 8j, 16j])
assert_array_equal(y.real, 0)
y = geomspace(-4j, -324j, num=5)
assert_allclose(y, [-4j, -12j, -36j, -108j, -324j])
assert_array_equal(y.real, 0)
y = geomspace(1+1j, 1000+1000j, num=4)
assert_allclose(y, [1+1j, 10+10j, 100+100j, 1000+1000j])
y = geomspace(-1+1j, -1000+1000j, num=4)
assert_allclose(y, [-1+1j, -10+10j, -100+100j, -1000+1000j])
y = geomspace(-1, 1, num=3, dtype=complex)
assert_allclose(y, [-1, 1j, +1])
y = geomspace(0+3j, -3+0j, 3)
assert_allclose(y, [0+3j, -3/sqrt(2)+3j/sqrt(2), -3+0j])
y = geomspace(0+3j, 3+0j, 3)
assert_allclose(y, [0+3j, 3/sqrt(2)+3j/sqrt(2), 3+0j])
y = geomspace(-3+0j, 0-3j, 3)
assert_allclose(y, [-3+0j, -3/sqrt(2)-3j/sqrt(2), 0-3j])
y = geomspace(0+3j, -3+0j, 3)
assert_allclose(y, [0+3j, -3/sqrt(2)+3j/sqrt(2), -3+0j])
y = geomspace(-2-3j, 5+7j, 7)
assert_allclose(y, [-2-3j, -0.29058977-4.15771027j,
2.08885354-4.34146838j, 4.58345529-3.16355218j,
6.41401745-0.55233457j, 6.75707386+3.11795092j,
5+7j])
y = geomspace(3j, -5, 2)
assert_allclose(y, [3j, -5])
y = geomspace(-5, 3j, 2)
assert_allclose(y, [-5, 3j])
def test_complex_shortest_path(self):
x = 1.2 + 3.4j
y = np.exp(1j*(np.pi-.1)) * x
z = np.geomspace(x, y, 5)
expected = np.array([1.2 + 3.4j, -1.47384 + 3.2905616j,
-3.33577588 + 1.36842949j, -3.36011056 - 1.30753855j,
-1.53343861 - 3.26321406j])
np.testing.assert_array_almost_equal(z, expected)
def test_dtype(self):
y = geomspace(1, 1e6, dtype='float32')
assert_equal(y.dtype, dtype('float32'))
y = geomspace(1, 1e6, dtype='float64')
assert_equal(y.dtype, dtype('float64'))
y = geomspace(1, 1e6, dtype='int32')
assert_equal(y.dtype, dtype('int32'))
y = geomspace(1, 1e6, dtype=float)
assert_equal(y.dtype, dtype('float64'))
y = geomspace(1, 1e6, dtype=complex)
assert_equal(y.dtype, dtype('complex128'))
def test_start_stop_array_scalar(self):
lim1 = array([120, 100], dtype="int8")
lim2 = array([-120, -100], dtype="int8")
lim3 = array([1200, 1000], dtype="uint16")
t1 = geomspace(lim1[0], lim1[1], 5)
t2 = geomspace(lim2[0], lim2[1], 5)
t3 = geomspace(lim3[0], lim3[1], 5)
t4 = geomspace(120.0, 100.0, 5)
t5 = geomspace(-120.0, -100.0, 5)
t6 = geomspace(1200.0, 1000.0, 5)
assert_allclose(t1, t4, rtol=1e-2)
assert_allclose(t2, t5, rtol=1e-2)
assert_allclose(t3, t6, rtol=1e-5)
def test_start_stop_array(self):
start = array([1.e0, 32., 1j, -4j, 1+1j, -1])
stop = array([1.e4, 2., 16j, -324j, 10000+10000j, 1])
t1 = geomspace(start, stop, 5)
t2 = stack([geomspace(_start, _stop, 5)
for _start, _stop in zip(start, stop)], axis=1)
assert_equal(t1, t2)
t3 = geomspace(start, stop[0], 5)
t4 = stack([geomspace(_start, stop[0], 5)
for _start in start], axis=1)
assert_equal(t3, t4)
t5 = geomspace(start, stop, 5, axis=-1)
assert_equal(t5, t2.T)
def test_physical_quantities(self):
a = PhysicalQuantity(1.0)
b = PhysicalQuantity(5.0)
assert_equal(geomspace(a, b), geomspace(1.0, 5.0))
def test_subclass(self):
a = array(1).view(PhysicalQuantity2)
b = array(7).view(PhysicalQuantity2)
gs = geomspace(a, b)
assert type(gs) is PhysicalQuantity2
assert_equal(gs, geomspace(1.0, 7.0))
gs = geomspace(a, b, 1)
assert type(gs) is PhysicalQuantity2
def test_bounds(self):
assert_raises(ValueError, geomspace, 0, 10)
assert_raises(ValueError, geomspace, 10, 0)
assert_raises(ValueError, geomspace, 0, 0)
class TestLinspace:
def test_basic(self):
y = linspace(0, 10)
assert_(len(y) == 50)
y = linspace(2, 10, num=100)
assert_(y[-1] == 10)
y = linspace(2, 10, endpoint=False)
assert_(y[-1] < 10)
assert_raises(ValueError, linspace, 0, 10, num=-1)
def test_corner(self):
y = list(linspace(0, 1, 1))
assert_(y == [0.0], y)
assert_raises(TypeError, linspace, 0, 1, num=2.5)
def test_type(self):
t1 = linspace(0, 1, 0).dtype
t2 = linspace(0, 1, 1).dtype
t3 = linspace(0, 1, 2).dtype
assert_equal(t1, t2)
assert_equal(t2, t3)
def test_dtype(self):
y = linspace(0, 6, dtype='float32')
assert_equal(y.dtype, dtype('float32'))
y = linspace(0, 6, dtype='float64')
assert_equal(y.dtype, dtype('float64'))
y = linspace(0, 6, dtype='int32')
assert_equal(y.dtype, dtype('int32'))
def test_start_stop_array_scalar(self):
lim1 = array([-120, 100], dtype="int8")
lim2 = array([120, -100], dtype="int8")
lim3 = array([1200, 1000], dtype="uint16")
t1 = linspace(lim1[0], lim1[1], 5)
t2 = linspace(lim2[0], lim2[1], 5)
t3 = linspace(lim3[0], lim3[1], 5)
t4 = linspace(-120.0, 100.0, 5)
t5 = linspace(120.0, -100.0, 5)
t6 = linspace(1200.0, 1000.0, 5)
assert_equal(t1, t4)
assert_equal(t2, t5)
assert_equal(t3, t6)
def test_start_stop_array(self):
start = array([-120, 120], dtype="int8")
stop = array([100, -100], dtype="int8")
t1 = linspace(start, stop, 5)
t2 = stack([linspace(_start, _stop, 5)
for _start, _stop in zip(start, stop)], axis=1)
assert_equal(t1, t2)
t3 = linspace(start, stop[0], 5)
t4 = stack([linspace(_start, stop[0], 5)
for _start in start], axis=1)
assert_equal(t3, t4)
t5 = linspace(start, stop, 5, axis=-1)
assert_equal(t5, t2.T)
def test_complex(self):
lim1 = linspace(1 + 2j, 3 + 4j, 5)
t1 = array([1.0+2.j, 1.5+2.5j, 2.0+3j, 2.5+3.5j, 3.0+4j])
lim2 = linspace(1j, 10, 5)
t2 = array([0.0+1.j, 2.5+0.75j, 5.0+0.5j, 7
def test_array_interface(self):
class Arrayish:
"""
支持 __array_interface__ 的通用对象,因此理论上可以转换为数值标量,
但不被认为是数值型,同时也支持浮点数乘法。
数据应该是一个实现了缓冲区接口的对象,至少包含 4 个字节。
"""
def __init__(self, data):
self._data = data
@property
def __array_interface__(self):
return {'shape': (), 'typestr': '<i4', 'data': self._data,
'version': 3}
def __mul__(self, other):
return self
one = Arrayish(array(1, dtype='<i4'))
five = Arrayish(array(5, dtype='<i4'))
assert_equal(linspace(one, five), linspace(1, 5))
def test_denormal_numbers(self):
for ftype in sctypes['float']:
stop = nextafter(ftype(0), ftype(1)) * 5
assert_(any(linspace(0, stop, 10, endpoint=False, dtype=ftype)))
def test_equivalent_to_arange(self):
for j in range(1000):
assert_equal(linspace(0, j, j+1, dtype=int),
arange(j+1, dtype=int))
def test_retstep(self):
for num in [0, 1, 2]:
for ept in [False, True]:
y = linspace(0, 1, num, endpoint=ept, retstep=True)
assert isinstance(y, tuple) and len(y) == 2
if num == 2:
y0_expect = [0.0, 1.0] if ept else [0.0, 0.5]
assert_array_equal(y[0], y0_expect)
assert_equal(y[1], y0_expect[1])
elif num == 1 and not ept:
assert_array_equal(y[0], [0.0])
assert_equal(y[1], 1.0)
else:
assert_array_equal(y[0], [0.0][:num])
assert isnan(y[1])
def test_object(self):
start = array(1, dtype='O')
stop = array(2, dtype='O')
y = linspace(start, stop, 3)
assert_array_equal(y, array([1., 1.5, 2.]))
def test_round_negative(self):
y = linspace(-1, 3, num=8, dtype=int)
t = array([-1, -1, 0, 0, 1, 1, 2, 3], dtype=int)
assert_array_equal(y, t)
def test_any_step_zero_and_not_mult_inplace(self):
start = array([0.0, 1.0])
stop = array([2.0, 1.0])
y = linspace(start, stop, 3)
assert_array_equal(y, array([[0.0, 1.0], [1.0, 1.0], [2.0, 1.0]]))
class TestAdd_newdoc:
@pytest.mark.skipif(sys.flags.optimize == 2, reason="Python running -OO")
@pytest.mark.xfail(IS_PYPY, reason="PyPy does not modify tp_doc")
def test_add_doc(self):
tgt = "Current flat index into the array."
assert_equal(np._core.flatiter.index.__doc__[:len(tgt)], tgt)
assert_(len(np._core.ufunc.identity.__doc__) > 300)
assert_(len(np.lib._index_tricks_impl.mgrid.__doc__) > 300)
@pytest.mark.skipif(sys.flags.optimize == 2, reason="Python running -OO")
def test_errors_are_ignored(self):
prev_doc = np._core.flatiter.index.__doc__
add_newdoc("numpy._core", "flatiter", ("index", "bad docstring"))
assert prev_doc == np._core.flatiter.index.__doc__
.\numpy\numpy\_core\tests\test_getlimits.py
import warnings
import numpy as np
import pytest
from numpy._core import finfo, iinfo
from numpy import half, single, double, longdouble
from numpy.testing import assert_equal, assert_, assert_raises
class TestPythonFloat:
def test_singleton(self):
ftype = finfo(float)
ftype2 = finfo(float)
assert_equal(id(ftype), id(ftype2))
class TestHalf:
def test_singleton(self):
ftype = finfo(half)
ftype2 = finfo(half)
assert_equal(id(ftype), id(ftype2))
class TestSingle:
def test_singleton(self):
ftype = finfo(single)
ftype2 = finfo(single)
assert_equal(id(ftype), id(ftype2))
class TestDouble:
def test_singleton(self):
ftype = finfo(double)
ftype2 = finfo(double)
assert_equal(id(ftype), id(ftype2))
class TestLongdouble:
def test_singleton(self):
ftype = finfo(longdouble)
ftype2 = finfo(longdouble)
assert_equal(id(ftype), id(ftype2))
def assert_finfo_equal(f1, f2):
for attr in ('bits', 'eps', 'epsneg', 'iexp', 'machep',
'max', 'maxexp', 'min', 'minexp', 'negep', 'nexp',
'nmant', 'precision', 'resolution', 'tiny',
'smallest_normal', 'smallest_subnormal'):
assert_equal(getattr(f1, attr), getattr(f2, attr),
f'finfo instances {f1} and {f2} differ on {attr}')
def assert_iinfo_equal(i1, i2):
for attr in ('bits', 'min', 'max'):
assert_equal(getattr(i1, attr), getattr(i2, attr),
f'iinfo instances {i1} and {i2} differ on {attr}')
class TestFinfo:
def test_basic(self):
dts = list(zip(['f2', 'f4', 'f8', 'c8', 'c16'],
[np.float16, np.float32, np.float64, np.complex64,
np.complex128]))
for dt1, dt2 in dts:
assert_finfo_equal(finfo(dt1), finfo(dt2))
assert_raises(ValueError, finfo, 'i4')
def test_regression_gh23108(self):
f1 = np.finfo(np.float32(1.0))
f2 = np.finfo(np.float64(1.0))
assert f1 != f2
def test_regression_gh23867(self):
class NonHashableWithDtype:
__hash__ = None
dtype = np.dtype('float32')
x = NonHashableWithDtype()
assert np.finfo(x) == np.finfo(x.dtype)
class TestIinfo:
def test_basic(self):
dts = list(zip(['i1', 'i2', 'i4', 'i8',
'u1', 'u2', 'u4', 'u8'],
[np.int8, np.int16, np.int32, np.int64,
np.uint8, np.uint16, np.uint32, np.uint64]))
for dt1, dt2 in dts:
assert_iinfo_equal(iinfo(dt1), iinfo(dt2))
assert_raises(ValueError, iinfo, 'f4')
def test_unsigned_max(self):
types = np._core.sctypes['uint']
for T in types:
with np.errstate(over="ignore"):
max_calculated = T(0) - T(1)
assert_equal(iinfo(T).max, max_calculated)
class TestRepr:
def test_iinfo_repr(self):
expected = "iinfo(min=-32768, max=32767, dtype=int16)"
assert_equal(repr(np.iinfo(np.int16)), expected)
def test_finfo_repr(self):
expected = "finfo(resolution=1e-06, min=-3.4028235e+38," + \
" max=3.4028235e+38, dtype=float32)"
assert_equal(repr(np.finfo(np.float32)), expected)
def test_instances():
for c in [int, np.int16, np.int32, np.int64]:
class_iinfo = iinfo(c)
instance_iinfo = iinfo(c(12))
assert_iinfo_equal(class_iinfo, instance_iinfo)
for c in [float, np.float16, np.float32, np.float64]:
class_finfo = finfo(c)
instance_finfo = finfo(c(1.2))
assert_finfo_equal(class_finfo, instance_finfo)
with pytest.raises(ValueError):
iinfo(10.)
with pytest.raises(ValueError):
iinfo('hi')
with pytest.raises(ValueError):
finfo(np.int64(1))
def assert_ma_equal(discovered, ma_like):
for key, value in discovered.__dict__.items():
assert_equal(value, getattr(ma_like, key))
if hasattr(value, 'shape'):
assert_equal(value.shape, getattr(ma_like, key).shape)
assert_equal(value.dtype, getattr(ma_like, key).dtype)
def test_known_types():
for ftype, ma_like in ((np.float16, _float_ma[16]),
(np.float32, _float_ma[32]),
(np.float64, _float_ma[64])):
assert_ma_equal(_discovered_machar(ftype), ma_like)
with np.errstate(all='ignore'):
ld_ma = _discovered_machar(np.longdouble)
bytes = np.dtype(np.longdouble).itemsize
if (ld_ma.it, ld_ma.maxexp) == (63, 16384) and bytes in (12, 16):
assert_ma_equal(ld_ma, _float_ma[80])
elif (ld_ma.it, ld_ma.maxexp) == (112, 16384) and bytes == 16:
assert_ma_equal(ld_ma, _float_ma[128])
def test_subnormal_warning():
"""测试是否会引发次正常为零的警告"""
with np.errstate(all='ignore'):
ld_ma = _discovered_machar(np.longdouble)
bytes = np.dtype(np.longdouble).itemsize
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
if (ld_ma.it, ld_ma.maxexp) == (63, 16384) and bytes in (12, 16):
ld_ma.smallest_subnormal
assert len(w) == 0
elif (ld_ma.it, ld_ma.maxexp) == (112, 16384) and bytes == 16:
ld_ma.smallest_subnormal
assert len(w) == 0
else:
ld_ma.smallest_subnormal
assert len(w) == 0
def test_plausible_finfo():
for ftype in np._core.sctypes['float'] + np._core.sctypes['complex']:
info = np.finfo(ftype)
assert_(info.nmant > 1)
assert_(info.minexp < -1)
assert_(info.maxexp > 1)
.\numpy\numpy\_core\tests\test_half.py
import platform
import pytest
import numpy as np
from numpy import uint16, float16, float32, float64
from numpy.testing import assert_, assert_equal, _OLD_PROMOTION, IS_WASM
def assert_raises_fpe(strmatch, callable, *args, **kwargs):
try:
callable(*args, **kwargs)
except FloatingPointError as exc:
assert_(str(exc).find(strmatch) >= 0,
"Did not raise floating point %s error" % strmatch)
else:
assert_(False,
"Did not raise floating point %s error" % strmatch)
class TestHalf:
def setup_method(self):
self.all_f16 = np.arange(0x10000, dtype=uint16)
self.all_f16.dtype = float16
with np.errstate(invalid='ignore'):
self.all_f32 = np.array(self.all_f16, dtype=float32)
self.all_f64 = np.array(self.all_f16, dtype=float64)
self.nonan_f16 = np.concatenate(
(np.arange(0xfc00, 0x7fff, -1, dtype=uint16),
np.arange(0x0000, 0x7c01, 1, dtype=uint16)))
self.nonan_f16.dtype = float16
self.nonan_f32 = np.array(self.nonan_f16, dtype=float32)
self.nonan_f64 = np.array(self.nonan_f16, dtype=float64)
self.finite_f16 = self.nonan_f16[1:-1]
self.finite_f32 = self.nonan_f32[1:-1]
self.finite_f64 = self.nonan_f64[1:-1]
def test_half_conversions(self):
"""Checks that all 16-bit values survive conversion
to/from 32-bit and 64-bit float"""
with np.errstate(invalid='ignore'):
b = np.array(self.all_f32, dtype=float16)
b_nn = b == b
assert_equal(self.all_f16[b_nn].view(dtype=uint16),
b[b_nn].view(dtype=uint16))
with np.errstate(invalid='ignore'):
b = np.array(self.all_f64, dtype=float16)
b_nn = b == b
assert_equal(self.all_f16[b_nn].view(dtype=uint16),
b[b_nn].view(dtype=uint16))
a_ld = np.array(self.nonan_f16, dtype=np.longdouble)
b = np.array(a_ld, dtype=float16)
assert_equal(self.nonan_f16.view(dtype=uint16),
b.view(dtype=uint16))
i_int = np.arange(-2048, 2049)
i_f16 = np.array(i_int, dtype=float16)
j = np.array(i_f16, dtype=int)
assert_equal(i_int, j)
def test_half_conversion_rounding(self, float_t, shift, offset):
max_pattern = np.float16(np.finfo(np.float16).max).view(np.uint16)
f16s_patterns = np.arange(0, max_pattern+1, dtype=np.uint16)
f16s_float = f16s_patterns.view(np.float16).astype(float_t)
if shift == "up":
f16s_float = 0.5 * (f16s_float[:-1] + f16s_float[1:])[1:]
elif shift == "down":
f16s_float = 0.5 * (f16s_float[:-1] + f16s_float[1:])[:-1]
else:
f16s_float = f16s_float[1:-1]
if offset == "up":
f16s_float = np.nextafter(f16s_float, float_t(np.inf))
elif offset == "down":
f16s_float = np.nextafter(f16s_float, float_t(-np.inf))
res_patterns = f16s_float.astype(np.float16).view(np.uint16)
cmp_patterns = f16s_patterns[1:-1].copy()
if shift == "down" and offset != "up":
shift_pattern = -1
elif shift == "up" and offset != "down":
shift_pattern = 1
else:
shift_pattern = 0
if offset is None:
cmp_patterns[0::2].view(np.int16)[...] += shift_pattern
else:
cmp_patterns.view(np.int16)[...] += shift_pattern
assert_equal(res_patterns, cmp_patterns)
@pytest.mark.parametrize(["float_t", "uint_t", "bits"],
[(np.float32, np.uint32, 23),
(np.float64, np.uint64, 52)])
def test_half_conversion_denormal_round_even(self, float_t, uint_t, bits):
smallest_value = np.uint16(1).view(np.float16).astype(float_t)
assert smallest_value == 2**-24
rounded_to_zero = smallest_value / float_t(2)
assert rounded_to_zero.astype(np.float16) == 0
for i in range(bits):
larger_pattern = rounded_to_zero.view(uint_t) | uint_t(1 << i)
larger_value = larger_pattern.view(float_t)
assert larger_value.astype(np.float16) == smallest_value
def test_nans_infs(self):
with np.errstate(all='ignore'):
assert_equal(np.isnan(self.all_f16), np.isnan(self.all_f32))
assert_equal(np.isinf(self.all_f16), np.isinf(self.all_f32))
assert_equal(np.isfinite(self.all_f16), np.isfinite(self.all_f32))
assert_equal(np.signbit(self.all_f16), np.signbit(self.all_f32))
assert_equal(np.spacing(float16(65504)), np.inf)
nan = float16(np.nan)
assert_(not (self.all_f16 == nan).any())
assert_(not (nan == self.all_f16).any())
assert_((self.all_f16 != nan).all())
assert_((nan != self.all_f16).all())
assert_(not (self.all_f16 < nan).any())
assert_(not (nan < self.all_f16).any())
assert_(not (self.all_f16 <= nan).any())
assert_(not (nan <= self.all_f16).any())
assert_(not (self.all_f16 > nan).any())
assert_(not (nan > self.all_f16).any())
assert_(not (self.all_f16 >= nan).any())
assert_(not (nan >= self.all_f16).any())
def test_half_values(self):
"""Confirms a small number of known half values"""
a = np.array([1.0, -1.0,
2.0, -2.0,
0.0999755859375, 0.333251953125,
65504, -65504,
2.0**(-14), -2.0**(-14),
2.0**(-24), -2.0**(-24),
0, -1/1e1000,
np.inf, -np.inf])
b = np.array([0x3c00, 0xbc00,
0x4000, 0xc000,
0x2e66, 0x3555,
0x7bff, 0xfbff,
0x0400, 0x8400,
0x0001, 0x8001,
0x0000, 0x8000,
0x7c00, 0xfc00], dtype=np.uint16)
b.dtype = np.float16
assert_equal(a, b)
def test_half_rounding(self):
"""Checks that rounding when converting to half is correct"""
a = np.array([2.0**-25 + 2.0**-35,
2.0**-25,
2.0**-26,
1.0+2.0**-11 + 2.0**-16,
1.0+2.0**-11,
1.0+2.0**-12,
65519,
65520],
dtype=np.float64)
rounded = [2.0**-24,
0.0,
0.0,
1.0+2.0**(-10),
1.0,
1.0,
65504,
np.inf]
with np.errstate(over="ignore"):
b = np.array(a, dtype=np.float16)
assert_equal(b, rounded)
a = np.array(a, dtype=np.float32)
with np.errstate(over="ignore"):
b = np.array(a, dtype=np.float16)
assert_equal(b, rounded)
def test_half_correctness(self):
"""Take every finite float16, and check the casting functions with
a manual conversion."""
a_bits = self.finite_f16.view(dtype=uint16)
a_sgn = (-1.0)**((a_bits & 0x8000) >> 15)
a_exp = np.array((a_bits & 0x7c00) >> 10, dtype=np.int32) - 15
a_man = (a_bits & 0x03ff) * 2.0**(-10)
a_man[a_exp != -15] += 1
a_exp[a_exp == -15] = -14
a_manual = a_sgn * a_man * 2.0**a_exp
a32_fail = np.nonzero(self.finite_f32 != a_manual)[0]
if len(a32_fail) != 0:
bad_index = a32_fail[0]
assert_equal(self.finite_f32, a_manual,
"First non-equal is half value 0x%x -> %g != %g" %
(a_bits[bad_index],
self.finite_f32[bad_index],
a_manual[bad_index]))
a64_fail = np.nonzero(self.finite_f64 != a_manual)[0]
if len(a64_fail) != 0:
bad_index = a64_fail[0]
assert_equal(self.finite_f64, a_manual,
"First non-equal is half value 0x%x -> %g != %g" %
(a_bits[bad_index],
self.finite_f64[bad_index],
a_manual[bad_index]))
def test_half_ordering(self):
"""Make sure comparisons are working right"""
a = self.nonan_f16[::-1].copy()
b = np.array(a, dtype=float32)
a.sort()
b.sort()
assert_equal(a, b)
assert_((a[:-1] <= a[1:]).all())
assert_(not (a[:-1] > a[1:]).any())
assert_((a[1:] >= a[:-1]).all())
assert_(not (a[1:] < a[:-1]).any())
assert_equal(np.nonzero(a[:-1] < a[1:])[0].size, a.size-2)
assert_equal(np.nonzero(a[1:] > a[:-1])[0].size, a.size-2)
def test_half_funcs(self):
"""Test the various ArrFuncs"""
assert_equal(np.arange(10, dtype=float16),
np.arange(10, dtype=float32))
a = np.zeros((5,), dtype=float16)
a.fill(1)
assert_equal(a, np.ones((5,), dtype=float16))
a = np.array([0, 0, -1, -1/1e20, 0, 2.0**-24, 7.629e-6], dtype=float16)
assert_equal(a.nonzero()[0],
[2, 5, 6])
a = a.byteswap()
a = a.view(a.dtype.newbyteorder())
assert_equal(a.nonzero()[0],
[2, 5, 6])
a = np.arange(0, 10, 0.5, dtype=float16)
b = np.ones((20,), dtype=float16)
assert_equal(np.dot(a, b),
95)
a = np.array([0, -np.inf, -2, 0.5, 12.55, 7.3, 2.1, 12.4], dtype=float16)
assert_equal(a.argmax(),
4)
a = np.array([0, -np.inf, -2, np.inf, 12.55, np.nan, 2.1, 12.4], dtype=float16)
assert_equal(a.argmax(),
5)
a = np.arange(10, dtype=float16)
for i in range(10):
assert_equal(a.item(i), i)
def test_spacing_nextafter(self):
"""Test np.spacing and np.nextafter"""
a = np.arange(0x7c00, dtype=uint16)
hinf = np.array((np.inf,), dtype=float16)
hnan = np.array((np.nan,), dtype=float16)
a_f16 = a.view(dtype=float16)
assert_equal(np.spacing(a_f16[:-1]), a_f16[1:] - a_f16[:-1])
assert_equal(np.nextafter(a_f16[:-1], hinf), a_f16[1:])
assert_equal(np.nextafter(a_f16[0], -hinf), -a_f16[1])
assert_equal(np.nextafter(a_f16[1:], -hinf), a_f16[:-1])
assert_equal(np.nextafter(hinf, a_f16), a_f16[-1])
assert_equal(np.nextafter(-hinf, a_f16), -a_f16[-1])
assert_equal(np.nextafter(hinf, hinf), hinf)
assert_equal(np.nextafter(hinf, -hinf), a_f16[-1])
assert_equal(np.nextafter(-hinf, hinf), -a_f16[-1])
assert_equal(np.nextafter(-hinf, -hinf), -hinf)
assert_equal(np.nextafter(a_f16, hnan), hnan[0])
assert_equal(np.nextafter(hnan, a_f16), hnan[0])
assert_equal(np.nextafter(hnan, hnan), hnan)
assert_equal(np.nextafter(hinf, hnan), hnan)
assert_equal(np.nextafter(hnan, hinf), hnan)
a |= 0x8000
assert_equal(np.spacing(a_f16[0]), np.spacing(a_f16[1]))
assert_equal(np.spacing(a_f16[1:]), a_f16[:-1] - a_f16[1:])
assert_equal(np.nextafter(a_f16[0], hinf), -a_f16[1])
assert_equal(np.nextafter(a_f16[1:], hinf), a_f16[:-1])
assert_equal(np.nextafter(a_f16[:-1], -hinf), a_f16[1:])
assert_equal(np.nextafter(hinf, a_f16), -a_f16[-1])
assert_equal(np.nextafter(-hinf, a_f16), a_f16[-1])
assert_equal(np.nextafter(a_f16, hnan), hnan[0])
assert_equal(np.nextafter(hnan, a_f16), hnan[0])
def test_half_coercion(self, weak_promotion):
"""Test that half gets coerced properly with the other types"""
a16 = np.array((1,), dtype=float16)
a32 = np.array((1,), dtype=float32)
b16 = float16(1)
b32 = float32(1)
assert np.power(a16, 2).dtype == float16
assert np.power(a16, 2.0).dtype == float16
assert np.power(a16, b16).dtype == float16
expected_dt = float32 if weak_promotion else float16
assert np.power(a16, b32).dtype == expected_dt
assert np.power(a16, a16).dtype == float16
assert np.power(a16, a32).dtype == float32
expected_dt = float16 if weak_promotion else float64
assert np.power(b16, 2).dtype == expected_dt
assert np.power(b16, 2.0).dtype == expected_dt
assert np.power(b16, b16).dtype, float16
assert np.power(b16, b32).dtype, float32
assert np.power(b16, a16).dtype, float16
assert np.power(b16, a32).dtype, float32
assert np.power(a32, a16).dtype == float32
assert np.power(a32, b16).dtype == float32
expected_dt = float32 if weak_promotion else float16
assert np.power(b32, a16).dtype == expected_dt
assert np.power(b32, b16).dtype == float32
@pytest.mark.skipif(platform.machine() == "armv5tel",
reason="See gh-413.")
@pytest.mark.skipif(IS_WASM,
reason="fp exceptions don't work in wasm.")
def test_half_array_interface(self):
"""Test that half is compatible with __array_interface__"""
class Dummy:
pass
a = np.ones((1,), dtype=float16)
b = Dummy()
b.__array_interface__ = a.__array_interface__
c = np.array(b)
assert_(c.dtype == float16)
assert_equal(a, c)
.\numpy\numpy\_core\tests\test_hashtable.py
import pytest
import random
from numpy._core._multiarray_tests import identityhash_tester
@pytest.mark.parametrize("key_length", [1, 3, 6])
@pytest.mark.parametrize("length", [1, 16, 2000])
def test_identity_hashtable(key_length, length):
pool = [object() for i in range(20)]
keys_vals = []
for i in range(length):
keys = tuple(random.choices(pool, k=key_length))
keys_vals.append((keys, random.choice(pool)))
dictionary = dict(keys_vals)
keys_vals.append(random.choice(keys_vals))
expected = dictionary[keys_vals[-1][0]]
res = identityhash_tester(key_length, keys_vals, replace=True)
assert res is expected
if length == 1:
return
new_key = (keys_vals[1][0], object())
keys_vals[0] = new_key
with pytest.raises(RuntimeError):
identityhash_tester(key_length, keys_vals)
.\numpy\numpy\_core\tests\test_indexerrors.py
import numpy as np
from numpy.testing import (
assert_raises, assert_raises_regex,
)
class TestIndexErrors:
'''Tests to exercise indexerrors not covered by other tests.'''
def test_arraytypes_fasttake(self):
'take from a 0-length dimension'
x = np.empty((2, 3, 0, 4))
assert_raises(IndexError, x.take, [0], axis=2)
assert_raises(IndexError, x.take, [1], axis=2)
assert_raises(IndexError, x.take, [0], axis=2, mode='wrap')
assert_raises(IndexError, x.take, [0], axis=2, mode='clip')
def test_take_from_object(self):
d = np.zeros(5, dtype=object)
assert_raises(IndexError, d.take, [6])
d = np.zeros((5, 0), dtype=object)
assert_raises(IndexError, d.take, [1], axis=1)
assert_raises(IndexError, d.take, [0], axis=1)
assert_raises(IndexError, d.take, [0])
assert_raises(IndexError, d.take, [0], mode='wrap')
assert_raises(IndexError, d.take, [0], mode='clip')
def test_multiindex_exceptions(self):
a = np.empty(5, dtype=object)
assert_raises(IndexError, a.item, 20)
a = np.empty((5, 0), dtype=object)
assert_raises(IndexError, a.item, (0, 0))
def test_put_exceptions(self):
a = np.zeros((5, 5))
assert_raises(IndexError, a.put, 100, 0)
a = np.zeros((5, 5), dtype=object)
assert_raises(IndexError, a.put, 100, 0)
a = np.zeros((5, 5, 0))
assert_raises(IndexError, a.put, 100, 0)
a = np.zeros((5, 5, 0), dtype=object)
assert_raises(IndexError, a.put, 100, 0)
def test_iterators_exceptions(self):
def assign(obj, ind, val):
obj[ind] = val
a = np.zeros([1, 2, 3])
assert_raises(IndexError, lambda: a[0, 5, None, 2])
assert_raises(IndexError, lambda: a[0, 5, 0, 2])
assert_raises(IndexError, lambda: assign(a, (0, 5, None, 2), 1))
assert_raises(IndexError, lambda: assign(a, (0, 5, 0, 2), 1))
a = np.zeros([1, 0, 3])
assert_raises(IndexError, lambda: a[0, 0, None, 2])
assert_raises(IndexError, lambda: assign(a, (0, 0, None, 2), 1))
a = np.zeros([1, 2, 3])
assert_raises(IndexError, lambda: a.flat[10])
assert_raises(IndexError, lambda: assign(a.flat, 10, 5))
a = np.zeros([1, 0, 3])
assert_raises(IndexError, lambda: a.flat[10])
assert_raises(IndexError, lambda: assign(a.flat, 10, 5))
a = np.zeros([1, 2, 3])
assert_raises(IndexError, lambda: a.flat[np.array(10)])
assert_raises(IndexError, lambda: assign(a.flat, np.array(10), 5))
a = np.zeros([1, 0, 3])
assert_raises(IndexError, lambda: a.flat[np.array(10)])
assert_raises(IndexError, lambda: assign(a.flat, np.array(10), 5))
a = np.zeros([1, 2, 3])
assert_raises(IndexError, lambda: a.flat[np.array([10])])
assert_raises(IndexError, lambda: assign(a.flat, np.array([10]), 5))
a = np.zeros([1, 0, 3])
assert_raises(IndexError, lambda: a.flat[np.array([10])])
assert_raises(IndexError, lambda: assign(a.flat, np.array([10]), 5))
def test_mapping(self):
def assign(obj, ind, val):
obj[ind] = val
a = np.zeros((0, 10))
assert_raises(IndexError, lambda: a[12])
a = np.zeros((3, 5))
assert_raises(IndexError, lambda: a[(10, 20)])
assert_raises(IndexError, lambda: assign(a, (10, 20), 1))
a = np.zeros((3, 0))
assert_raises(IndexError, lambda: a[(1, 0)])
assert_raises(IndexError, lambda: assign(a, (1, 0), 1))
a = np.zeros((10,))
assert_raises(IndexError, lambda: assign(a, 10, 1))
a = np.zeros((0,))
assert_raises(IndexError, lambda: assign(a, 10, 1))
a = np.zeros((3, 5))
assert_raises(IndexError, lambda: a[(1, [1, 20])])
assert_raises(IndexError, lambda: assign(a, (1, [1, 20]), 1))
a = np.zeros((3, 0))
assert_raises(IndexError, lambda: a[(1, [0, 1])])
assert_raises(IndexError, lambda: assign(a, (1, [0, 1]), 1))
def test_mapping_error_message(self):
a = np.zeros((3, 5))
index = (1, 2, 3, 4, 5)
assert_raises_regex(
IndexError,
"too many indices for array: "
"array is 2-dimensional, but 5 were indexed",
lambda: a[index])
def test_methods(self):
a = np.zeros((3, 3))
assert_raises(IndexError, lambda: a.item(100))
.\numpy\numpy\_core\tests\test_indexing.py
import sys
import warnings
import functools
import operator
import pytest
import numpy as np
from numpy._core._multiarray_tests import array_indexing
from itertools import product
from numpy.exceptions import ComplexWarning, VisibleDeprecationWarning
from numpy.testing import (
assert_, assert_equal, assert_raises, assert_raises_regex,
assert_array_equal, assert_warns, HAS_REFCOUNT, IS_WASM
)
class TestIndexing:
def test_index_no_floats(self):
a = np.array([[[5]]])
assert_raises(IndexError, lambda: a[0.0])
assert_raises(IndexError, lambda: a[0, 0.0])
assert_raises(IndexError, lambda: a[0.0, 0])
assert_raises(IndexError, lambda: a[0.0,:])
assert_raises(IndexError, lambda: a[:, 0.0])
assert_raises(IndexError, lambda: a[:, 0.0,:])
assert_raises(IndexError, lambda: a[0.0,:,:])
assert_raises(IndexError, lambda: a[0, 0, 0.0])
assert_raises(IndexError, lambda: a[0.0, 0, 0])
assert_raises(IndexError, lambda: a[0, 0.0, 0])
assert_raises(IndexError, lambda: a[-1.4])
assert_raises(IndexError, lambda: a[0, -1.4])
assert_raises(IndexError, lambda: a[-1.4, 0])
assert_raises(IndexError, lambda: a[-1.4,:])
assert_raises(IndexError, lambda: a[:, -1.4])
assert_raises(IndexError, lambda: a[:, -1.4,:])
assert_raises(IndexError, lambda: a[-1.4,:,:])
assert_raises(IndexError, lambda: a[0, 0, -1.4])
assert_raises(IndexError, lambda: a[-1.4, 0, 0])
assert_raises(IndexError, lambda: a[0, -1.4, 0])
assert_raises(IndexError, lambda: a[0.0:, 0.0])
assert_raises(IndexError, lambda: a[0.0:, 0.0,:])
def test_slicing_no_floats(self):
a = np.array([[5]])
assert_raises(TypeError, lambda: a[0.0:])
assert_raises(TypeError, lambda: a[0:, 0.0:2])
assert_raises(TypeError, lambda: a[0.0::2, :0])
assert_raises(TypeError, lambda: a[0.0:1:2, :])
assert_raises(TypeError, lambda: a[:, 0.0:])
assert_raises(TypeError, lambda: a[:0.0])
assert_raises(TypeError, lambda: a[:0, 1:2.0])
assert_raises(TypeError, lambda: a[:0.0:2, :0])
assert_raises(TypeError, lambda: a[:0.0, :])
assert_raises(TypeError, lambda: a[:, 0:4.0:2])
assert_raises(TypeError, lambda: a[::1.0])
assert_raises(TypeError, lambda: a[0:, :2:2.0])
assert_raises(TypeError, lambda: a[1::4.0, :0])
assert_raises(TypeError, lambda: a[::5.0, :])
assert_raises(TypeError, lambda: a[:, 0:4:2.0])
assert_raises(TypeError, lambda: a[1.0:2:2.0])
assert_raises(TypeError, lambda: a[1.0::2.0])
assert_raises(TypeError, lambda: a[0:, :2.0:2.0])
assert_raises(TypeError, lambda: a[1.0:1:4.0, :0])
assert_raises(TypeError, lambda: a[1.0:5.0:5.0, :])
assert_raises(TypeError, lambda: a[:, 0.4:4.0:2.0])
assert_raises(TypeError, lambda: a[::0.0])
def test_index_no_array_to_index(self):
a = np.array([[[1]]])
assert_raises(TypeError, lambda: a[a:a:a])
def test_none_index(self):
a = np.array([1, 2, 3])
assert_equal(a[None], a[np.newaxis])
assert_equal(a[None].ndim, a.ndim + 1)
def test_empty_tuple_index(self):
a = np.array([1, 2, 3])
assert_equal(a[()], a)
assert_(a[()].base is a)
a = np.array(0)
assert_(isinstance(a[()], np.int_))
def test_void_scalar_empty_tuple(self):
s = np.zeros((), dtype='V4')
assert_equal(s[()].dtype, s.dtype)
assert_equal(s[()], s)
assert_equal(type(s[...]), np.ndarray)
def test_same_kind_index_casting(self):
index = np.arange(5)
u_index = index.astype(np.uintp)
arr = np.arange(10)
assert_array_equal(arr[index], arr[u_index])
arr[u_index] = np.arange(5)
assert_array_equal(arr, np.arange(10))
arr = np.arange(10).reshape(5, 2)
assert_array_equal(arr[index], arr[u_index])
arr[u_index] = np.arange(5)[:, None]
assert_array_equal(arr, np.arange(5)[:, None].repeat(2, axis=1))
arr = np.arange(25).reshape(5, 5)
assert_array_equal(arr[u_index, u_index], arr[index, index])
def test_empty_fancy_index(self):
a = np.array([1, 2, 3])
assert_equal(a[[]], [])
assert_equal(a[[]].dtype, a.dtype)
b = np.array([], dtype=np.intp)
assert_equal(a[[]], [])
assert_equal(a[[]].dtype, a.dtype)
b = np.array([])
assert_raises(IndexError, a.__getitem__, b)
def test_ellipsis_index(self):
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
assert_(a[...] is not a)
assert_equal(a[...], a)
assert_(a[...].base is a)
assert_equal(a[0, ...], a[0])
assert_equal(a[0, ...], a[0, :])
assert_equal(a[..., 0], a[:, 0])
assert_equal(a[0, ..., 1], np.array(2))
b = np.array(1)
b[(Ellipsis,)] = 2
assert_equal(b, 2)
def test_single_int_index(self):
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
assert_equal(a[0], [1, 2, 3])
assert_equal(a[-1], [7, 8, 9])
assert_raises(IndexError, a.__getitem__, 1 << 30)
assert_raises(IndexError, a.__getitem__, 1 << 64)
def test_single_bool_index(self):
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
assert_equal(a[np.array(True)], a[None])
assert_equal(a[np.array(False)], a[None][0:0])
def test_boolean_shape_mismatch(self):
arr = np.ones((5, 4, 3))
index = np.array([True])
assert_raises(IndexError, arr.__getitem__, index)
index = np.array([False] * 6)
assert_raises(IndexError, arr.__getitem__, index)
index = np.zeros((4, 4), dtype=bool)
assert_raises(IndexError, arr.__getitem__, index)
assert_raises(IndexError, arr.__getitem__, (slice(None), index))
def test_boolean_indexing_onedim(self):
a = np.array([[ 0., 0., 0.]])
b = np.array([ True], dtype=bool)
assert_equal(a[b], a)
a[b] = 1.
assert_equal(a, [[1., 1., 1.]])
def test_boolean_assignment_value_mismatch(self):
a = np.arange(4)
def f(a, v):
a[a > -1] = v
assert_raises(ValueError, f, a, [])
assert_raises(ValueError, f, a, [1, 2, 3])
assert_raises(ValueError, f, a[:1], [1, 2, 3])
def test_boolean_assignment_needs_api(self):
arr = np.zeros(1000)
indx = np.zeros(1000, dtype=bool)
indx[:100] = True
arr[indx] = np.ones(100, dtype=object)
expected = np.zeros(1000)
expected[:100] = 1
assert_array_equal(arr, expected)
def test_boolean_indexing_twodim(self):
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
b = np.array([[ True, False, True],
[False, True, False],
[ True, False, True]])
assert_equal(a[b], [1, 3, 5, 7, 9])
assert_equal(a[b[1]], [[4, 5, 6]])
assert_equal(a[b[0]], a[b[2]])
a[b] = 0
assert_equal(a, [[0, 2, 0],
[4, 0, 6],
[0, 8, 0]])
def test_boolean_indexing_list(self):
a = np.array([1, 2, 3])
b = [True, False, True]
assert_equal(a[b], [1, 3])
assert_equal(a[None, b], [[1, 3]])
def test_reverse_strides_and_subspace_bufferinit(self):
a = np.ones(5)
b = np.zeros(5, dtype=np.intp)[::-1]
c = np.arange(5)[::-1]
a[b] = c
assert_equal(a[0], 0)
a = np.ones((5, 2))
c = np.arange(10).reshape(5, 2)[::-1]
a[b, :] = c
assert_equal(a[0], [0, 1])
def test_reversed_strides_result_allocation(self):
a = np.arange(10)[:, None]
i = np.arange(10)[::-1]
assert_array_equal(a[i], a[i.copy('C')])
a = np.arange(20).reshape(-1, 2)
def test_uncontiguous_subspace_assignment(self):
a = np.full((3, 4, 2), -1)
b = np.full((3, 4, 2), -1)
a[[0, 1]] = np.arange(2 * 4 * 2).reshape(2, 4, 2).T
b[[0, 1]] = np.arange(2 * 4 * 2).reshape(2, 4, 2).T.copy()
assert_equal(a, b)
def test_too_many_fancy_indices_special_case(self):
a = np.ones((1,) * 64)
assert_raises(IndexError, a.__getitem__, (np.array([0]),) * 64)
def test_scalar_array_bool(self):
a = np.array(1)
assert_equal(a[np.bool(True)], a[np.array(True)])
assert_equal(a[np.bool(False)], a[np.array(False)])
def test_everything_returns_views(self):
a = np.arange(5)
assert_(a is not a[()])
assert_(a is not a[...])
assert_(a is not a[:])
def test_broaderrors_indexing(self):
a = np.zeros((5, 5))
assert_raises(IndexError, a.__getitem__, ([0, 1], [0, 1, 2]))
assert_raises(IndexError, a.__setitem__, ([0, 1], [0, 1, 2]), 0)
def test_trivial_fancy_out_of_bounds(self):
a = np.zeros(5)
ind = np.ones(20, dtype=np.intp)
ind[-1] = 10
assert_raises(IndexError, a.__getitem__, ind)
assert_raises(IndexError, a.__setitem__, ind, 0)
ind = np.ones(20, dtype=np.intp)
ind[0] = 11
assert_raises(IndexError, a.__getitem__, ind)
assert_raises(IndexError, a.__setitem__, ind, 0)
def test_trivial_fancy_not_possible(self):
a = np.arange(6)
idx = np.arange(6, dtype=np.intp).reshape(2, 1, 3)[:, :, 0]
assert_array_equal(a[idx], idx)
a[idx] = -1
res = np.arange(6)
res[0] = -1
res[3] = -1
assert_array_equal(a, res)
def test_nonbaseclass_values(self):
class SubClass(np.ndarray):
def __array_finalize__(self, old):
self.fill(99)
a = np.zeros((5, 5))
s = a.copy().view(type=SubClass)
s.fill(1)
a[[0, 1, 2, 3, 4], :] = s
assert_((a == 1).all())
a[:, [0, 1, 2, 3, 4]] = s
assert_((a == 1).all())
a.fill(0)
a[...] = s
assert_((a == 1).all())
def test_array_like_values(self):
a = np.zeros((5, 5))
s = np.arange(25, dtype=np.float64).reshape(5, 5)
a[[0, 1, 2, 3, 4], :] = memoryview(s)
assert_array_equal(a, s)
a[:, [0, 1, 2, 3, 4]] = memoryview(s)
assert_array_equal(a, s)
a[...] = memoryview(s)
assert_array_equal(a, s)
def test_subclass_writeable(self):
d = np.rec.array([('NGC1001', 11), ('NGC1002', 1.), ('NGC1003', 1.)],
dtype=[('target', 'S20'), ('V_mag', '>f4')])
ind = np.array([False, True, True], dtype=bool)
assert_(d[ind].flags.writeable)
ind = np.array([0, 1])
assert_(d[ind].flags.writeable)
assert_(d[...].flags.writeable)
assert_(d[0].flags.writeable)
def test_memory_order(self):
a = np.arange(10)
b = np.arange(10).reshape(5,2).T
assert_(a[b].flags.f_contiguous)
a = a.reshape(-1, 1)
assert_(a[b, 0].flags.f_contiguous)
def test_scalar_return_type(self):
class Zero:
def __index__(self):
return 0
z = Zero()
class ArrayLike:
def __array__(self, dtype=None, copy=None):
return np.array(0)
a = np.zeros(())
assert_(isinstance(a[()], np.float64))
a = np.zeros(1)
assert_(isinstance(a[z], np.float64))
a = np.zeros((1, 1))
assert_(isinstance(a[z, np.array(0)], np.float64))
assert_(isinstance(a[z, ArrayLike()], np.float64))
b = np.array(0)
a = np.array(0, dtype=object)
assert_(isinstance(a[()], np.ndarray))
a = np.array([b, None])
assert_(isinstance(a[z], np.ndarray))
a = np.array([[b, None]])
assert_(isinstance(a[z, ArrayLike()], np.ndarray))
def test_small_regressions(self):
a = np.array([0])
if HAS_REFCOUNT:
refcount = sys.getrefcount(np.dtype(np.intp))
a[np.array([0], dtype=np.intp)] = 1
a[np.array([0], dtype=np.uint8)] = 1
assert_raises(IndexError, a.__setitem__,
np.array([1], dtype=np.intp), 1)
assert_raises(IndexError, a.__setitem__,
np.array([1], dtype=np.uint8), 1)
if HAS_REFCOUNT:
assert_equal(sys.getrefcount(np.dtype(np.intp)), refcount)
def test_unaligned(self):
v = (np.zeros(64, dtype=np.int8) + ord('a'))[1:-7]
d = v.view(np.dtype("S8"))
x = (np.zeros(16, dtype=np.int8) + ord('a'))[1:-7]
x = x.view(np.dtype("S8"))
x[...] = np.array("b" * 8, dtype="S")
b = np.arange(d.size)
assert_equal(d[b], d)
d[b] = x
b = np.zeros(d.size + 1).view(np.int8)[1:-(np.intp(0).itemsize - 1)]
b = b.view(np.intp)[:d.size]
d[b.astype(np.int16)] = x
d[b % 2 == 0]
d[b % 2 == 0] = x[::2]
def test_tuple_subclass(self):
arr = np.ones((5, 5))
class TupleSubclass(tuple):
pass
index = ([1], [1])
index = TupleSubclass(index)
assert_(arr[index].shape == (1,))
assert_(arr[index,].shape != (1,))
def test_broken_sequence_not_nd_index(self):
class SequenceLike:
def __index__(self):
return 0
def __len__(self):
return 1
def __getitem__(self, item):
raise IndexError('Not possible')
arr = np.arange(10)
assert_array_equal(arr[SequenceLike()], arr[SequenceLike(),])
arr = np.zeros((1,), dtype=[('f1', 'i8'), ('f2', 'i8')])
assert_array_equal(arr[SequenceLike()], arr[SequenceLike(),])
def test_indexing_array_weird_strides(self):
x = np.ones(10)
x2 = np.ones((10, 2))
ind = np.arange(10)[:, None, None, None]
ind = np.broadcast_to(ind, (10, 55, 4, 4))
assert_array_equal(x[ind], x[ind.copy()])
zind = np.zeros(4, dtype=np.intp)
assert_array_equal(x2[ind, zind], x2[ind.copy(), zind])
def test_indexing_array_negative_strides(self):
arro = np.zeros((4, 4))
arr = arro[::-1, ::-1]
slices = (slice(None), [0, 1, 2, 3])
arr[slices] = 10
assert_array_equal(arr, 10.)
def test_character_assignment(self):
arr = np.zeros((1, 5), dtype="c")
arr[0] = np.str_("asdfg")
assert_array_equal(arr[0], np.array("asdfg", dtype="c"))
assert arr[0, 1] == b"s"
@pytest.mark.parametrize("index",
[True, False, np.array([0])])
@pytest.mark.parametrize("num", [64, 80])
@pytest.mark.parametrize("original_ndim", [1, 64])
def test_too_many_advanced_indices(self, index, num, original_ndim):
arr = np.ones((1,) * original_ndim)
with pytest.raises(IndexError):
arr[(index,) * num]
with pytest.raises(IndexError):
arr[(index,) * num] = 1.
@pytest.mark.skipif(IS_WASM, reason="no threading")
from concurrent.futures import ThreadPoolExecutor
dt = np.dtype([("", "f8")])
dt = np.dtype([("", dt)] * 2)
dt = np.dtype([("", dt)] * 2)
arr = np.random.uniform(size=(6000, 8)).view(dt)[:, 0]
rng = np.random.default_rng()
def func(arr):
indx = rng.integers(0, len(arr), size=6000, dtype=np.intp)
arr[indx]
tpe = ThreadPoolExecutor(max_workers=8)
futures = [tpe.submit(func, arr) for _ in range(10)]
for f in futures:
f.result()
assert arr.dtype is dt
def test_nontuple_ndindex(self):
a = np.arange(25).reshape((5, 5))
assert_equal(a[[0, 1]], np.array([a[0], a[1]]))
assert_equal(a[[0, 1], [0, 1]], np.array([0, 6]))
assert_raises(IndexError, a.__getitem__, [slice(None)])
class TestFieldIndexing:
def test_scalar_return_type(self):
a = np.zeros((), [('a','f8')])
assert_(isinstance(a['a'], np.ndarray))
assert_(isinstance(a[['a']], np.ndarray))
class TestBroadcastedAssignments:
def assign(self, a, ind, val):
a[ind] = val
return a
def test_prepending_ones(self):
a = np.zeros((3, 2))
a[...] = np.ones((1, 3, 2))
a[[0, 1, 2], :] = np.ones((1, 3, 2))
a[:, [0, 1]] = np.ones((1, 3, 2))
a[[[0], [1], [2]], [0, 1]] = np.ones((1, 3, 2))
def test_prepend_not_one(self):
assign = self.assign
s_ = np.s_
a = np.zeros(5)
assert_raises(ValueError, assign, a, s_[...], np.ones((2, 1)))
assert_raises(ValueError, assign, a, s_[[1, 2, 3],], np.ones((2, 1)))
assert_raises(ValueError, assign, a, s_[[[1], [2]],], np.ones((2,2,1)))
def test_simple_broadcasting_errors(self):
assign = self.assign
s_ = np.s_
a = np.zeros((5, 1))
assert_raises(ValueError, assign, a, s_[...], np.zeros((5, 2)))
assert_raises(ValueError, assign, a, s_[...], np.zeros((5, 0)))
assert_raises(ValueError, assign, a, s_[:, [0]], np.zeros((5, 2)))
assert_raises(ValueError, assign, a, s_[:, [0]], np.zeros((5, 0)))
assert_raises(ValueError, assign, a, s_[[0], :], np.zeros((2, 1)))
@pytest.mark.parametrize("index", [
(..., [1, 2], slice(None)),
([0, 1], ..., 0),
(..., [1, 2], [1, 2])])
def test_broadcast_error_reports_correct_shape(self, index):
values = np.zeros((100, 100))
arr = np.zeros((3, 4, 5, 6, 7))
shape_str = str(arr[index].shape).replace(" ", "")
with pytest.raises(ValueError) as e:
arr[index] = values
assert str(e.value).endswith(shape_str)
def test_index_is_larger(self):
a = np.zeros((5, 5))
a[[[0], [1], [2]], [0, 1, 2]] = [2, 3, 4]
assert_((a[:3, :3] == [2, 3, 4]).all())
def test_broadcast_subspace(self):
a = np.zeros((100, 100))
v = np.arange(100)[:,None]
b = np.arange(100)[::-1]
a[b] = v
assert_((a[::-1] == v).all())
def test_basic(self):
class SubClass(np.ndarray):
pass
a = np.arange(5)
s = a.view(SubClass)
s_slice = s[:3]
assert_(type(s_slice) is SubClass)
assert_(s_slice.base is s)
assert_array_equal(s_slice, a[:3])
s_fancy = s[[0, 1, 2]]
assert_(type(s_fancy) is SubClass)
assert_(s_fancy.base is not s)
assert_(type(s_fancy.base) is np.ndarray)
assert_array_equal(s_fancy, a[[0, 1, 2]])
assert_array_equal(s_fancy.base, a[[0, 1, 2]])
s_bool = s[s > 0]
assert_(type(s_bool) is SubClass)
assert_(s_bool.base is not s)
assert_(type(s_bool.base) is np.ndarray)
assert_array_equal(s_bool, a[a > 0])
assert_array_equal(s_bool.base, a[a > 0])
def test_fancy_on_read_only(self):
class SubClass(np.ndarray):
pass
a = np.arange(5)
s = a.view(SubClass)
s.flags.writeable = False
s_fancy = s[[0, 1, 2]]
assert_(s_fancy.flags.writeable)
def test_finalize_gets_full_info(self):
class SubClass(np.ndarray):
def __array_finalize__(self, old):
self.finalize_status = np.array(self)
self.old = old
s = np.arange(10).view(SubClass)
new_s = s[:3]
assert_array_equal(new_s.finalize_status, new_s)
assert_array_equal(new_s.old, s)
new_s = s[[0,1,2,3]]
assert_array_equal(new_s.finalize_status, new_s)
assert_array_equal(new_s.old, s)
new_s = s[s > 0]
assert_array_equal(new_s.finalize_status, new_s)
assert_array_equal(new_s.old, s)
class TestFancyIndexingCast:
def test_boolean_index_cast_assign(self):
shape = (8, 63)
bool_index = np.zeros(shape).astype(bool)
bool_index[0, 1] = True
zero_array = np.zeros(shape)
zero_array[bool_index] = np.array([1])
assert_equal(zero_array[0, 1], 1)
assert_warns(ComplexWarning,
zero_array.__setitem__, ([0], [1]), np.array([2 + 1j]))
assert_equal(zero_array[0, 1], 2)
assert_warns(ComplexWarning,
zero_array.__setitem__, bool_index, np.array([1j]))
assert_equal(zero_array[0, 1], 0)
class TestFancyIndexingEquivalence:
def test_object_assign(self):
a = np.arange(5, dtype=object)
b = a.copy()
a[:3] = [1, (1,2), 3]
b[[0, 1, 2]] = [1, (1,2), 3]
assert_array_equal(a, b)
b = np.arange(5, dtype=object)[None, :]
b[[0], :3] = [[1, (1,2), 3]]
assert_array_equal(a, b[0])
b = b.T
b[:3, [0]] = [[1], [(1,2)], [3]]
assert_array_equal(a, b[:, 0])
arr = np.ones((3, 4, 5), dtype=object)
cmp_arr = arr.copy()
cmp_arr[:1, ...] = [[[1], [2], [3], [4]]]
arr[[0], ...] = [[[1], [2], [3], [4]]]
assert_array_equal(arr, cmp_arr)
arr = arr.copy('F')
arr[[0], ...] = [[[1], [2], [3], [4]]]
assert_array_equal(arr, cmp_arr)
def test_cast_equivalence(self):
a = np.arange(5)
b = a.copy()
a[:3] = np.array(['2', '-3', '-1'])
b[[0, 2, 1]] = np.array(['2', '-1', '-3'])
assert_array_equal(a, b)
b = np.arange(5)[None, :]
b[[0], :3] = np.array([['2', '-3', '-1']])
assert_array_equal(a, b[0])
class TestMultiIndexingAutomated:
"""
These tests use code to mimic the C-Code indexing for selection.
"""
NOTE:
* This still lacks tests for complex item setting.
* If you change behavior of indexing, you might want to modify
these tests to try more combinations.
* Behavior was written to match numpy version 1.8. (though a
first version matched 1.7.)
* Only tuple indices are supported by the mimicking code.
(and tested as of writing this)
* Error types should match most of the time as long as there
is only one error. For multiple errors, what gets raised
will usually not be the same one. They are *not* tested.
Update 2016-11-30: It is probably not worth maintaining this test
indefinitely and it can be dropped if maintenance becomes a burden.
"""
# 设置测试环境的方法
def setup_method(self):
# 创建一个四维的 numpy 数组 a,其形状为 (3, 1, 5, 6),并填充 arange 生成的数据
self.a = np.arange(np.prod([3, 1, 5, 6])).reshape(3, 1, 5, 6)
# 创建一个空的 numpy 数组 b,形状为 (3, 0, 5, 6)
self.b = np.empty((3, 0, 5, 6))
# 复杂索引的测试集合,包含多种不同类型的索引对象
self.complex_indices = ['skip', Ellipsis,
0,
# 布尔索引,特殊情况下可以吃掉维度,需要测试所有 False 的情况
np.array([True, False, False]),
np.array([[True, False], [False, True]]),
np.array([[[False, False], [False, False]]]),
# 一些切片:
slice(-5, 5, 2),
slice(1, 1, 100),
slice(4, -1, -2),
slice(None, None, -3),
# 一些高级索引:
np.empty((0, 1, 1), dtype=np.intp), # 空数组,可以广播
np.array([0, 1, -2]),
np.array([[2], [0], [1]]),
np.array([[0, -1], [0, 1]], dtype=np.dtype('intp').newbyteorder()),
np.array([2, -1], dtype=np.int8),
np.zeros([1]*31, dtype=int), # 触发太大的数组
np.array([0., 1.])] # 无效的数据类型
# 一些简单的索引,涵盖更多情况
self.simple_indices = [Ellipsis, None, -1, [1], np.array([True]),
'skip']
# 简单的索引以填充其余情况
self.fill_indices = [slice(None, None), 0]
def _check_multi_index(self, arr, index):
"""检查多索引项的获取和简单设置。
Parameters
----------
arr : ndarray
要索引的数组,必须是重塑后的 arange。
index : tuple of indexing objects
正在测试的索引。
"""
# 测试获取索引项
try:
mimic_get, no_copy = self._get_multi_index(arr, index)
except Exception as e:
if HAS_REFCOUNT:
prev_refcount = sys.getrefcount(arr)
# 断言引发的异常类型与期望一致
assert_raises(type(e), arr.__getitem__, index)
assert_raises(type(e), arr.__setitem__, index, 0)
if HAS_REFCOUNT:
assert_equal(prev_refcount, sys.getrefcount(arr))
return
# 比较索引结果
self._compare_index_result(arr, index, mimic_get, no_copy)
def _check_single_index(self, arr, index):
"""Check a single index item getting and simple setting.
Parameters
----------
arr : ndarray
要进行索引的数组,必须是一个 arange。
index : indexing object
被测试的索引。必须是单个索引对象,不能是索引对象的元组
(参见 `_check_multi_index`)。
"""
try:
# 调用 `_get_multi_index` 方法获取模仿的索引结果和是否复制的标志
mimic_get, no_copy = self._get_multi_index(arr, (index,))
except Exception as e:
if HAS_REFCOUNT:
# 获取数组的引用计数
prev_refcount = sys.getrefcount(arr)
# 断言索引操作抛出的异常类型
assert_raises(type(e), arr.__getitem__, index)
assert_raises(type(e), arr.__setitem__, index, 0)
if HAS_REFCOUNT:
# 断言操作后数组的引用计数不变
assert_equal(prev_refcount, sys.getrefcount(arr))
return
# 比较索引结果和模仿的索引结果
self._compare_index_result(arr, index, mimic_get, no_copy)
def _compare_index_result(self, arr, index, mimic_get, no_copy):
"""Compare mimicked result to indexing result.
"""
# 复制数组以防止影响原始数据
arr = arr.copy()
# 执行索引操作
indexed_arr = arr[index]
# 断言索引操作的结果与模仿的索引结果相等
assert_array_equal(indexed_arr, mimic_get)
# 检查是否得到视图,除非是大小为0或者0维的数组(这时候不是视图,也不重要)
if indexed_arr.size != 0 and indexed_arr.ndim != 0:
# 检查是否共享内存
assert_(np.may_share_memory(indexed_arr, arr) == no_copy)
# 检查原始数组的引用计数
if HAS_REFCOUNT:
if no_copy:
# 如果没有复制,引用计数增加1
assert_equal(sys.getrefcount(arr), 3)
else:
assert_equal(sys.getrefcount(arr), 2)
# 测试非广播的赋值操作
b = arr.copy()
b[index] = mimic_get + 1000
if b.size == 0:
return # 没有可比较的内容...
if no_copy and indexed_arr.ndim != 0:
# 如果没有复制且索引数组不是0维,则原地修改索引数组以操纵原始数据
indexed_arr += 1000
assert_array_equal(arr, b)
return
# 利用数组原本是 arange 的特性进行赋值操作
arr.flat[indexed_arr.ravel()] += 1000
assert_array_equal(arr, b)
def test_boolean(self):
a = np.array(5)
# 断言布尔索引返回正确的值
assert_equal(a[np.array(True)], 5)
# 布尔索引赋值
a[np.array(True)] = 1
assert_equal(a, 1)
# 注意:这与正常的广播操作不同,因为 arr[boolean_array] 的工作方式类似于多索引。
# 这意味着它被对齐到左边。这对于与 arr[boolean_array,] 保持一致可能是正确的,而且根本不进行广播操作。
self._check_multi_index(
self.a, (np.zeros_like(self.a, dtype=bool),))
self._check_multi_index(
self.a, (np.zeros_like(self.a, dtype=bool)[..., 0],))
self._check_multi_index(
self.a, (np.zeros_like(self.a, dtype=bool)[None, ...],))
def test_multidim(self):
# 测试多维索引的功能
# 捕获警告,防止 np.array(True) 在完整整数索引中被接受,当单独运行文件时
with warnings.catch_warnings():
# 忽略 DeprecationWarning 类型的警告
warnings.filterwarnings('error', '', DeprecationWarning)
# 忽略 VisibleDeprecationWarning 类型的警告
warnings.filterwarnings('error', '', VisibleDeprecationWarning)
# 定义一个函数,用来判断是否需要跳过某个索引
def isskip(idx):
return isinstance(idx, str) and idx == "skip"
# 针对简单的位置(0、2、3)循环进行测试
for simple_pos in [0, 2, 3]:
# 准备索引的组合进行检查
tocheck = [self.fill_indices, self.complex_indices,
self.fill_indices, self.fill_indices]
# 将简单位置替换为简单索引
tocheck[simple_pos] = self.simple_indices
# 遍历所有可能的索引组合
for index in product(*tocheck):
# 过滤掉需要跳过的索引,然后执行多维索引检查
index = tuple(i for i in index if not isskip(i))
self._check_multi_index(self.a, index)
self._check_multi_index(self.b, index)
# 对非常简单的获取单个元素进行检查
self._check_multi_index(self.a, (0, 0, 0, 0))
self._check_multi_index(self.b, (0, 0, 0, 0))
# 同时也检查(简单情况下的)索引过多的情况
assert_raises(IndexError, self.a.__getitem__, (0, 0, 0, 0, 0))
assert_raises(IndexError, self.a.__setitem__, (0, 0, 0, 0, 0), 0)
assert_raises(IndexError, self.a.__getitem__, (0, 0, [1], 0, 0))
assert_raises(IndexError, self.a.__setitem__, (0, 0, [1], 0, 0), 0)
def test_1d(self):
# 测试一维数组的功能
a = np.arange(10)
for index in self.complex_indices:
# 对单个索引进行检查
self._check_single_index(a, index)
class TestFloatNonIntegerArgument:
"""
These test that ``TypeError`` is raised when you try to use
non-integers as arguments to for indexing and slicing e.g. ``a[0.0:5]``
and ``a[0.5]``, or other functions like ``array.reshape(1., -1)``.
"""
def test_valid_indexing(self):
# These should raise no errors.
a = np.array([[[5]]])
# 索引操作,使用整数数组
a[np.array([0])]
# 索引操作,使用整数列表
a[[0, 0]]
# 切片操作,使用整数列表
a[:, [0, 0]]
# 切片操作,使用整数
a[:, 0, :]
# 完整切片操作
a[:, :, :]
def test_valid_slicing(self):
# These should raise no errors.
a = np.array([[[5]]])
# 完整切片操作
a[::]
# 从索引0开始切片
a[0:]
# 切片到索引1(不包含)
a[:2]
# 切片从索引0到2(不包含)
a[0:2]
# 步长为2的切片
a[::2]
# 从索引1开始,步长为2的切片
a[1::2]
# 切片从索引0到2(不包含),步长为2
a[:2:2]
# 切片从索引1到2(不包含),步长为2
a[1:2:2]
def test_non_integer_argument_errors(self):
a = np.array([[5]])
# 测试reshape函数使用非整数参数抛出TypeError异常
assert_raises(TypeError, np.reshape, a, (1., 1., -1))
assert_raises(TypeError, np.reshape, a, (np.array(1.), -1))
# 测试take函数使用非整数参数抛出TypeError异常
assert_raises(TypeError, np.take, a, [0], 1.)
assert_raises(TypeError, np.take, a, [0], np.float64(1.))
def test_non_integer_sequence_multiplication(self):
# NumPy标量序列乘法不应使用非整数
def mult(a, b):
return a * b
# 测试使用非整数参数抛出TypeError异常
assert_raises(TypeError, mult, [1], np.float64(3))
# 以下应该正常运行
mult([1], np.int_(3))
def test_reduce_axis_float_index(self):
d = np.zeros((3, 3, 3))
# 测试使用浮点数作为reduce操作的轴索引抛出TypeError异常
assert_raises(TypeError, np.min, d, 0.5)
assert_raises(TypeError, np.min, d, (0.5, 1))
assert_raises(TypeError, np.min, d, (1, 2.2))
assert_raises(TypeError, np.min, d, (.2, 1.2))
class TestBooleanIndexing:
# Using a boolean as integer argument/indexing is an error.
def test_bool_as_int_argument_errors(self):
a = np.array([[[1]]])
# 测试reshape函数使用布尔值参数抛出TypeError异常
assert_raises(TypeError, np.reshape, a, (True, -1))
assert_raises(TypeError, np.reshape, a, (np.bool(True), -1))
# 注意,operator.index(np.array(True))不能工作,布尔数组因此也被弃用,但错误信息不同:
assert_raises(TypeError, operator.index, np.array(True))
assert_warns(DeprecationWarning, operator.index, np.True_)
# 测试take函数使用布尔值参数抛出TypeError异常
assert_raises(TypeError, np.take, args=(a, [0], False))
def test_boolean_indexing_weirdness(self):
# Weird boolean indexing things
a = np.ones((2, 3, 4))
# 使用False作为索引时返回的形状应为空
assert a[False, True, ...].shape == (0, 2, 3, 4)
# 使用True和其他混合索引方式返回的形状应为(1, 2)
assert a[True, [0, 1], True, True, [1], [[2]]].shape == (1, 2)
# 使用False和其他索引方式应该抛出IndexError异常
assert_raises(IndexError, lambda: a[False, [0, 1], ...])
# 定义一个测试函数,测试快速路径下的布尔索引情况
def test_boolean_indexing_fast_path(self):
# 创建一个3x3的全1数组
a = np.ones((3, 3))
# 使用错误的布尔索引,预期引发IndexError异常,错误信息为:
# "boolean index did not match indexed array along axis 0; size of axis is 3 but size of corresponding boolean axis is 1"
idx1 = np.array([[False]*9])
assert_raises_regex(IndexError,
"boolean index did not match indexed array along axis 0; "
"size of axis is 3 but size of corresponding boolean axis is 1",
lambda: a[idx1])
# 使用错误的布尔索引,预期引发IndexError异常,错误信息同上
idx2 = np.array([[False]*8 + [True]])
assert_raises_regex(IndexError,
"boolean index did not match indexed array along axis 0; "
"size of axis is 3 but size of corresponding boolean axis is 1",
lambda: a[idx2])
# 使用正确长度的布尔索引,预期引发IndexError异常,错误信息同上
idx3 = np.array([[False]*10])
assert_raises_regex(IndexError,
"boolean index did not match indexed array along axis 0; "
"size of axis is 3 but size of corresponding boolean axis is 1",
lambda: a[idx3])
# 使用错误的布尔索引,预期引发IndexError异常,错误信息为:
# "boolean index did not match indexed array along axis 1; size of axis is 1 but size of corresponding boolean axis is 2"
a = np.ones((1, 1, 2))
idx = np.array([[[True], [False]]])
assert_raises_regex(IndexError,
"boolean index did not match indexed array along axis 1; "
"size of axis is 1 but size of corresponding boolean axis is 2",
lambda: a[idx])
class TestArrayToIndexDeprecation:
"""Creating an index from array not 0-D is an error.
This class tests scenarios where creating an index from arrays that are not 0-dimensional raises errors.
"""
def test_array_to_index_error(self):
# Define a 3-dimensional numpy array
a = np.array([[[1]]])
# Assert that attempting to convert a non-0-D array to index raises a TypeError
assert_raises(TypeError, operator.index, np.array([1]))
# Assert that reshaping 'a' with an invalid shape (-1) raises a TypeError
assert_raises(TypeError, np.reshape, a, (a, -1))
# Assert that using 'np.take' with invalid arguments raises a TypeError
assert_raises(TypeError, np.take, a, [0], a)
class TestNonIntegerArrayLike:
"""Tests that array_likes are only valid if they can be safely cast to integers.
This class tests scenarios where array-like objects should only allow safe casting to integers,
otherwise IndexError should be raised.
"""
def test_basic(self):
# Create a numpy array with range 0 to 9
a = np.arange(10)
# Assert that attempting to access non-integer indices raises an IndexError
assert_raises(IndexError, a.__getitem__, [0.5, 1.5])
assert_raises(IndexError, a.__getitem__, (['1', '2'],))
# Assert that accessing with an empty list is valid
a.__getitem__([])
class TestMultipleEllipsisError:
"""An index can only have a single ellipsis.
This class tests scenarios where using multiple ellipses (ellipsis objects) in numpy indexing raises an IndexError.
"""
def test_basic(self):
# Create a numpy array with range 0 to 9
a = np.arange(10)
# Assert that using multiple ellipses raises an IndexError
assert_raises(IndexError, lambda: a[..., ...])
assert_raises(IndexError, a.__getitem__, ((Ellipsis,) * 2,))
assert_raises(IndexError, a.__getitem__, ((Ellipsis,) * 3,))
class TestCApiAccess:
"""Tests for C-API access functionalities.
This class tests various functionalities related to C-API access in numpy arrays.
"""
def test_getitem(self):
# Define a partial function 'subscript' using 'array_indexing' function with fixed first argument as 0
subscript = functools.partial(array_indexing, 0)
# Test cases for '__getitem__' method
# Assert that accessing element of a 0-dimensional array raises IndexError
assert_raises(IndexError, subscript, np.ones(()), 0)
# Assert that accessing out-of-bounds values raises IndexError
assert_raises(IndexError, subscript, np.ones(10), 11)
assert_raises(IndexError, subscript, np.ones(10), -11)
assert_raises(IndexError, subscript, np.ones((10, 10)), 11)
assert_raises(IndexError, subscript, np.ones((10, 10)), -11)
# Create a numpy array with range 0 to 9
a = np.arange(10)
# Assert that array indexing behaves correctly for a 1-dimensional array
assert_array_equal(a[4], subscript(a, 4))
# Reshape 'a' to a 2-dimensional array and test indexing
a = a.reshape(5, 2)
assert_array_equal(a[-4], subscript(a, -4))
def test_setitem(self):
# Define a partial function 'assign' using 'array_indexing' function with fixed first argument as 1
assign = functools.partial(array_indexing, 1)
# Test cases for '__setitem__' method
# Assert that deletion operation raises ValueError
assert_raises(ValueError, assign, np.ones(10), 0)
# Assert that assigning values to elements of a 0-dimensional array raises IndexError
assert_raises(IndexError, assign, np.ones(()), 0, 0)
# Assert that assigning to out-of-bounds indices raises IndexError
assert_raises(IndexError, assign, np.ones(10), 11, 0)
assert_raises(IndexError, assign, np.ones(10), -11, 0)
assert_raises(IndexError, assign, np.ones((10, 10)), 11, 0)
assert_raises(IndexError, assign, np.ones((10, 10)), -11, 0)
# Create a numpy array with range 0 to 9
a = np.arange(10)
# Assign a new value to index 4 and assert the change
assign(a, 4, 10)
assert_(a[4] == 10)
# Reshape 'a' to a 2-dimensional array and test assignment
a = a.reshape(5, 2)
assign(a, 4, 10)
assert_array_equal(a[-1], [10, 10])
.\numpy\numpy\_core\tests\test_item_selection.py
import sys
import pytest
import numpy as np
from numpy.testing import (
assert_, assert_raises, assert_array_equal, HAS_REFCOUNT
)
class TestTake:
def test_simple(self):
a = [[1, 2], [3, 4]]
a_str = [[b'1', b'2'], [b'3', b'4']]
modes = ['raise', 'wrap', 'clip']
indices = [-1, 4]
index_arrays = [np.empty(0, dtype=np.intp),
np.empty(tuple(), dtype=np.intp),
np.empty((1, 1), dtype=np.intp)]
real_indices = {'raise': {-1: 1, 4: IndexError},
'wrap': {-1: 1, 4: 0},
'clip': {-1: 0, 4: 1}}
types = int, object, np.dtype([('', 'i2', 3)])
for t in types:
ta = np.array(a if np.issubdtype(t, np.number) else a_str, dtype=t)
tresult = list(ta.T.copy())
for index_array in index_arrays:
if index_array.size != 0:
tresult[0].shape = (2,) + index_array.shape
tresult[1].shape = (2,) + index_array.shape
for mode in modes:
for index in indices:
real_index = real_indices[mode][index]
if real_index is IndexError and index_array.size != 0:
index_array.put(0, index)
assert_raises(IndexError, ta.take, index_array,
mode=mode, axis=1)
elif index_array.size != 0:
index_array.put(0, index)
res = ta.take(index_array, mode=mode, axis=1)
assert_array_equal(res, tresult[real_index])
else:
res = ta.take(index_array, mode=mode, axis=1)
assert_(res.shape == (2,) + index_array.shape)
def test_refcounting(self):
objects = [object() for i in range(10)]
for mode in ('raise', 'clip', 'wrap'):
a = np.array(objects)
b = np.array([2, 2, 4, 5, 3, 5])
a.take(b, out=a[:6], mode=mode)
del a
if HAS_REFCOUNT:
assert_(all(sys.getrefcount(o) == 3 for o in objects))
a = np.array(objects * 2)[::2]
a.take(b, out=a[:6], mode=mode)
del a
if HAS_REFCOUNT:
assert_(all(sys.getrefcount(o) == 3 for o in objects))
def test_unicode_mode(self):
d = np.arange(10)
k = b'\xc3\xa4'.decode("UTF8")
assert_raises(ValueError, d.take, 5, mode=k)
def test_empty_partition(self):
a_original = np.array([0, 2, 4, 6, 8, 10])
a = a_original.copy()
a.partition(np.array([], dtype=np.int16))
assert_array_equal(a, a_original)
def test_empty_argpartition(self):
a = np.array([0, 2, 4, 6, 8, 10])
a = a.argpartition(np.array([], dtype=np.int16))
b = np.array([0, 1, 2, 3, 4, 5])
assert_array_equal(a, b)
class TestPutMask:
@pytest.mark.parametrize("dtype", list(np.typecodes["All"]) + ["i,O"])
def test_simple(self, dtype):
if dtype.lower() == "m":
dtype += "8[ns]"
vals = np.arange(1001).astype(dtype=dtype)
mask = np.random.randint(2, size=1000).astype(bool)
arr = np.zeros(1000, dtype=vals.dtype)
zeros = arr.copy()
np.putmask(arr, mask, vals)
assert_array_equal(arr[mask], vals[:len(mask)][mask])
assert_array_equal(arr[~mask], zeros[~mask])
@pytest.mark.parametrize("dtype", list(np.typecodes["All"])[1:] + ["i,O"])
@pytest.mark.parametrize("mode", ["raise", "wrap", "clip"])
def test_empty(self, dtype, mode):
arr = np.zeros(1000, dtype=dtype)
arr_copy = arr.copy()
mask = np.random.randint(2, size=1000).astype(bool)
np.put(arr, mask, [])
assert_array_equal(arr, arr_copy)
class TestPut:
@pytest.mark.parametrize("dtype", list(np.typecodes["All"])[1:] + ["i,O"])
@pytest.mark.parametrize("mode", ["raise", "wrap", "clip"])
def test_simple(self, dtype, mode):
if dtype.lower() == "m":
dtype += "8[ns]"
vals = np.arange(1001).astype(dtype=dtype)
arr = np.zeros(1000, dtype=vals.dtype)
zeros = arr.copy()
if mode == "clip":
indx = np.random.permutation(len(arr) - 2)[:-500] + 1
indx[-1] = 0
indx[-2] = len(arr) - 1
indx_put = indx.copy()
indx_put[-1] = -1389
indx_put[-2] = 1321
else:
indx = np.random.permutation(len(arr) - 3)[:-500]
indx_put = indx
if mode == "wrap":
indx_put = indx_put + len(arr)
np.put(arr, indx_put, vals, mode=mode)
assert_array_equal(arr[indx], vals[:len(indx)])
untouched = np.ones(len(arr), dtype=bool)
untouched[indx] = False
assert_array_equal(arr[untouched], zeros[untouched])
@pytest.mark.parametrize("dtype", list(np.typecodes["All"])[1:] + ["i,O"])
@pytest.mark.parametrize("mode", ["raise", "wrap", "clip"])
def test_empty(self, dtype, mode):
arr = np.zeros(1000, dtype=dtype)
arr_copy = arr.copy()
np.put(arr, [1, 2, 3], [])
assert_array_equal(arr, arr_copy)
.\numpy\numpy\_core\tests\test_limited_api.py
import os
import shutil
import subprocess
import sys
import sysconfig
import pytest
from numpy.testing import IS_WASM, IS_PYPY, NOGIL_BUILD, IS_EDITABLE
try:
import cython
from Cython.Compiler.Version import version as cython_version
except ImportError:
cython = None
else:
from numpy._utils import _pep440
required_version = "3.0.6"
if _pep440.parse(cython_version) < _pep440.Version(required_version):
cython = None
pytestmark = pytest.mark.skipif(cython is None, reason="requires cython")
if IS_EDITABLE:
pytest.skip(
"Editable install doesn't support tests with a compile step",
allow_module_level=True
)
def install_temp(tmpdir_factory):
if IS_WASM:
pytest.skip("No subprocess")
srcdir = os.path.join(os.path.dirname(__file__), 'examples', 'limited_api')
build_dir = tmpdir_factory.mktemp("limited_api") / "build"
os.makedirs(build_dir, exist_ok=True)
try:
subprocess.check_call(["meson", "--version"])
except FileNotFoundError:
pytest.skip("No usable 'meson' found")
if sys.platform == "win32":
subprocess.check_call(["meson", "setup",
"--buildtype=release",
"--vsenv", str(srcdir)],
cwd=build_dir,
)
else:
subprocess.check_call(["meson", "setup", str(srcdir)],
cwd=build_dir
)
try:
subprocess.check_call(["meson", "compile", "-vv"], cwd=build_dir)
except subprocess.CalledProcessError as p:
print(f"{p.stdout=}")
print(f"{p.stderr=}")
raise
sys.path.append(str(build_dir))
@pytest.mark.skipif(IS_WASM, reason="Can't start subprocess")
@pytest.mark.xfail(
sysconfig.get_config_var("Py_DEBUG"),
reason=(
"Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, "
"and Py_REF_DEBUG"
),
)
@pytest.mark.xfail(
NOGIL_BUILD,
reason="Py_GIL_DISABLED builds do not currently support the limited API",
)
@pytest.mark.skipif(IS_PYPY, reason="no support for limited API in PyPy")
def test_limited_api(install_temp):
"""Test building a third-party C extension with the limited API
and building a cython extension with the limited API
"""
import limited_api1
import limited_api2
.\numpy\numpy\_core\tests\test_longdouble.py
import warnings
import platform
import pytest
import numpy as np
from numpy.testing import (
assert_, assert_equal, assert_raises, assert_warns, assert_array_equal,
temppath, IS_MUSL
)
from numpy._core.tests._locales import CommaDecimalPointLocale
LD_INFO = np.finfo(np.longdouble)
longdouble_longer_than_double = (LD_INFO.eps < np.finfo(np.double).eps)
_o = 1 + LD_INFO.eps
string_to_longdouble_inaccurate = (_o != np.longdouble(str(_o)))
del _o
def test_scalar_extraction():
"""确认提取值时不会转换为 Python 的浮点数"""
o = 1 + LD_INFO.eps
a = np.array([o, o, o])
assert_equal(a[1], o)
repr_precision = len(repr(np.longdouble(0.1)))
@pytest.mark.skipif(IS_MUSL,
reason="test flaky on musllinux")
@pytest.mark.skipif(LD_INFO.precision + 2 >= repr_precision,
reason="repr precision not enough to show eps")
def test_str_roundtrip():
o = 1 + LD_INFO.eps
assert_equal(np.longdouble(str(o)), o, "str was %s" % str(o))
@pytest.mark.skipif(string_to_longdouble_inaccurate, reason="Need strtold_l")
def test_str_roundtrip_bytes():
o = 1 + LD_INFO.eps
assert_equal(np.longdouble(str(o).encode("ascii")), o)
@pytest.mark.skipif(string_to_longdouble_inaccurate, reason="Need strtold_l")
@pytest.mark.parametrize("strtype", (np.str_, np.bytes_, str, bytes))
def test_array_and_stringlike_roundtrip(strtype):
"""
测试长双精度浮点数的字符串表示在数组转换和标量强制转换中的往返,
参见 gh-15608。
"""
o = 1 + LD_INFO.eps
if strtype in (np.bytes_, bytes):
o_str = strtype(str(o).encode("ascii"))
else:
o_str = strtype(str(o))
assert o == np.longdouble(o_str)
o_strarr = np.asarray([o] * 3, dtype=strtype)
assert (o == o_strarr.astype(np.longdouble)).all()
assert (o_strarr == o_str).all()
assert (np.asarray([o] * 3).astype(strtype) == o_str).all()
def test_bogus_string():
assert_raises(ValueError, np.longdouble, "spam")
assert_raises(ValueError, np.longdouble, "1.0 flub")
@pytest.mark.skipif(string_to_longdouble_inaccurate, reason="Need strtold_l")
def test_fromstring():
o = 1 + LD_INFO.eps
s = (" " + str(o))*5
a = np.array([o]*5)
assert_equal(np.fromstring(s, sep=" ", dtype=np.longdouble), a,
err_msg="reading '%s'" % s)
def test_fromstring_complex():
for ctype in ["complex", "cdouble"]:
assert_equal(np.fromstring("1, 2 , 3 ,4", sep=",", dtype=ctype),
np.array([1., 2., 3., 4.]))
assert_equal(np.fromstring("1j, -2j, 3j, 4e1j", sep=",", dtype=ctype),
np.array([1.j, -2.j, 3.j, 40.j]))
assert_equal(np.fromstring("1+1j,2-2j, -3+3j, -4e1+4j", sep=",", dtype=ctype),
np.array([1. + 1.j, 2. - 2.j, - 3. + 3.j, - 40. + 4j]))
with assert_warns(DeprecationWarning):
assert_equal(np.fromstring("1+2 j,3", dtype=ctype, sep=","),
np.array([1.]))
with assert_warns(DeprecationWarning):
assert_equal(np.fromstring("1+ 2j,3", dtype=ctype, sep=","),
np.array([1.]))
with assert_warns(DeprecationWarning):
assert_equal(np.fromstring("1 +2j,3", dtype=ctype, sep=","),
np.array([1.]))
with assert_warns(DeprecationWarning):
assert_equal(np.fromstring("1+j", dtype=ctype, sep=","),
np.array([1.]))
with assert_warns(DeprecationWarning):
assert_equal(np.fromstring("1+", dtype=ctype, sep=","),
np.array([1.]))
with assert_warns(DeprecationWarning):
assert_equal(np.fromstring("1j+1", dtype=ctype, sep=","),
np.array([1j]))
def test_fromstring_bogus():
with assert_warns(DeprecationWarning):
assert_equal(np.fromstring("1. 2. 3. flop 4.", dtype=float, sep=" "),
np.array([1., 2., 3.]))
def test_fromstring_empty():
with assert_warns(DeprecationWarning):
assert_equal(np.fromstring("xxxxx", sep="x"),
np.array([]))
def test_fromstring_missing():
with assert_warns(DeprecationWarning):
assert_equal(np.fromstring("1xx3x4x5x6", sep="x"),
np.array([1]))
class TestFileBased:
ldbl = 1 + LD_INFO.eps
tgt = np.array([ldbl]*5)
out = ''.join([str(t) + '\n' for t in tgt])
def test_fromfile_bogus(self):
with temppath() as path:
with open(path, 'w') as f:
f.write("1. 2. 3. flop 4.\n")
with assert_warns(DeprecationWarning):
res = np.fromfile(path, dtype=float, sep=" ")
assert_equal(res, np.array([1., 2., 3.]))
def test_fromfile_complex(self):
for ctype in ["complex", "cdouble"]:
with temppath() as path:
with open(path, 'w') as f:
f.write("1, 2 , 3 ,4\n")
res = np.fromfile(path, dtype=ctype, sep=",")
assert_equal(res, np.array([1., 2., 3., 4.]))
with temppath() as path:
with open(path, 'w') as f:
f.write("1j, -2j, 3j, 4e1j\n")
res = np.fromfile(path, dtype=ctype, sep=",")
assert_equal(res, np.array([1.j, -2.j, 3.j, 40.j]))
with temppath() as path:
with open(path, 'w') as f:
f.write("1+1j,2-2j, -3+3j, -4e1+4j\n")
res = np.fromfile(path, dtype=ctype, sep=",")
assert_equal(res, np.array([1. + 1.j, 2. - 2.j, - 3. + 3.j, - 40. + 4j]))
with temppath() as path:
with open(path, 'w') as f:
f.write("1+2 j,3\n")
with assert_warns(DeprecationWarning):
res = np.fromfile(path, dtype=ctype, sep=",")
assert_equal(res, np.array([1.]))
with temppath() as path:
with open(path, 'w') as f:
f.write("1+ 2j,3\n")
with assert_warns(DeprecationWarning):
res = np.fromfile(path, dtype=ctype, sep=",")
assert_equal(res, np.array([1.]))
with temppath() as path:
with open(path, 'w') as f:
f.write("1 +2j,3\n")
with assert_warns(DeprecationWarning):
res = np.fromfile(path, dtype=ctype, sep=",")
assert_equal(res, np.array([1.]))
with temppath() as path:
with open(path, 'w') as f:
f.write("1+j\n")
with assert_warns(DeprecationWarning):
res = np.fromfile(path, dtype=ctype, sep=",")
assert_equal(res, np.array([1.]))
with temppath() as path:
with open(path, 'w') as f:
f.write("1+\n")
with assert_warns(DeprecationWarning):
res = np.fromfile(path, dtype=ctype, sep=",")
assert_equal(res, np.array([1.]))
with temppath() as path:
with open(path, 'w') as f:
f.write("1j+1\n")
with assert_warns(DeprecationWarning):
res = np.fromfile(path, dtype=ctype, sep=",")
assert_equal(res, np.array([1.j]))
@pytest.mark.skipif(string_to_longdouble_inaccurate,
reason="Need strtold_l")
def test_fromfile(self):
with temppath() as path:
with open(path, 'w') as f:
f.write(self.out)
res = np.fromfile(path, dtype=np.longdouble, sep="\n")
assert_equal(res, self.tgt)
@pytest.mark.skipif(string_to_longdouble_inaccurate,
reason="Need strtold_l")
def test_genfromtxt(self):
with temppath() as path:
with open(path, 'w') as f:
f.write(self.out)
res = np.genfromtxt(path, dtype=np.longdouble)
assert_equal(res, self.tgt)
@pytest.mark.skipif(string_to_longdouble_inaccurate,
reason="Need strtold_l")
def test_loadtxt(self):
with temppath() as path:
with open(path, 'w') as f:
f.write(self.out)
res = np.loadtxt(path, dtype=np.longdouble)
assert_equal(res, self.tgt)
@pytest.mark.skipif(string_to_longdouble_inaccurate,
reason="Need strtold_l")
def test_tofile_roundtrip(self):
self.tgt.tofile(path, sep=" ")
res = np.fromfile(path, dtype=np.longdouble, sep=" ")
assert_equal(res, self.tgt)
def test_str_exact():
o = 1 + LD_INFO.eps
assert_(str(o) != '1')
@pytest.mark.skipif(longdouble_longer_than_double, reason="BUG #2376")
@pytest.mark.skipif(string_to_longdouble_inaccurate, reason="Need strtold_l")
def test_format():
o = 1 + LD_INFO.eps
assert_("{0:.40g}".format(o) != '1')
@pytest.mark.skipif(longdouble_longer_than_double, reason="BUG #2376")
@pytest.mark.skipif(string_to_longdouble_inaccurate, reason="Need strtold_l")
def test_percent():
o = 1 + LD_INFO.eps
assert_("%.40g" % o != '1')
@pytest.mark.skipif(longdouble_longer_than_double, reason="array repr problem")
@pytest.mark.skipif(string_to_longdouble_inaccurate, reason="Need strtold_l")
def test_array_repr():
o = 1 + LD_INFO.eps
a = np.array([o])
b = np.array([1], dtype=np.longdouble)
if not np.all(a != b):
raise ValueError("precision loss creating arrays")
assert_(repr(a) != repr(b))
class TestCommaDecimalPointLocale(CommaDecimalPointLocale):
def test_str_roundtrip_foreign(self):
o = 1.5
assert_equal(o, np.longdouble(str(o)))
def test_fromstring_foreign_repr(self):
f = 1.234
a = np.fromstring(repr(f), dtype=float, sep=" ")
assert_equal(a[0], f)
def test_fromstring_best_effort_float(self):
with assert_warns(DeprecationWarning):
assert_equal(np.fromstring("1,234", dtype=float, sep=" "),
np.array([1.]))
def test_fromstring_best_effort(self):
with assert_warns(DeprecationWarning):
assert_equal(np.fromstring("1,234", dtype=np.longdouble, sep=" "),
np.array([1.]))
def test_fromstring_foreign(self):
s = "1.234"
a = np.fromstring(s, dtype=np.longdouble, sep=" ")
assert_equal(a[0], np.longdouble(s))
def test_fromstring_foreign_sep(self):
a = np.array([1, 2, 3, 4])
b = np.fromstring("1,2,3,4,", dtype=np.longdouble, sep=",")
assert_array_equal(a, b)
def test_fromstring_foreign_value(self):
with assert_warns(DeprecationWarning):
b = np.fromstring("1,234", dtype=np.longdouble, sep=" ")
assert_array_equal(b[0], 1)
@pytest.mark.parametrize("int_val", [
2 ** 1024, 0])
def test_longdouble_from_int(int_val):
str_val = str(int_val)
with warnings.catch_warnings(record=True) as w:
warnings.filterwarnings('always', '', RuntimeWarning)
assert np.longdouble(int_val) == np.longdouble(str_val)
if np.allclose(np.finfo(np.longdouble).max,
np.finfo(np.double).max) and w:
assert w[0].category is RuntimeWarning
@pytest.mark.parametrize("bool_val", [
True, False])
def test_longdouble_from_bool(bool_val):
assert np.longdouble(bool_val) == np.longdouble(int(bool_val))
@pytest.mark.skipif(
not (IS_MUSL and platform.machine() == "x86_64"),
reason="only need to run on musllinux_x86_64"
)
def test_musllinux_x86_64_signature():
known_sigs = [b'\xcd\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xfb\xbf']
sig = (np.longdouble(-1.0) / np.longdouble(10.0))
sig = sig.view(sig.dtype.newbyteorder('<')).tobytes()[:10]
assert sig in known_sigs
def test_eps_positive():
assert np.finfo(np.longdouble).eps > 0.
.\numpy\numpy\_core\tests\test_machar.py
"""
Test machar. Given recent changes to hardcode type data, we might want to get
rid of both MachAr and this test at some point.
"""
from numpy._core._machar import MachAr
import numpy._core.numerictypes as ntypes
from numpy import errstate, array
class TestMachAr:
def _run_machar_highprec(self):
try:
hiprec = ntypes.float96
MachAr(lambda v: array(v, hiprec))
except AttributeError:
"Skipping test: no ntypes.float96 available on this platform."
def test_underlow(self):
with errstate(all='raise'):
try:
self._run_machar_highprec()
except FloatingPointError as e:
msg = "Caught %s exception, should not have been raised." % e
raise AssertionError(msg)
.\numpy\numpy\_core\tests\test_memmap.py
import sys
import os
import mmap
import pytest
from pathlib import Path
from tempfile import NamedTemporaryFile, TemporaryFile
from numpy import (
memmap, sum, average, prod, ndarray, isscalar, add, subtract, multiply)
from numpy import arange, allclose, asarray
from numpy.testing import (
assert_, assert_equal, assert_array_equal, suppress_warnings, IS_PYPY,
break_cycles
)
class TestMemmap:
def setup_method(self):
self.tmpfp = NamedTemporaryFile(prefix='mmap')
self.shape = (3, 4)
self.dtype = 'float32'
self.data = arange(12, dtype=self.dtype)
self.data.resize(self.shape)
def teardown_method(self):
self.tmpfp.close()
self.data = None
if IS_PYPY:
break_cycles()
break_cycles()
def test_roundtrip(self):
fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
shape=self.shape)
fp[:] = self.data[:]
del fp
newfp = memmap(self.tmpfp, dtype=self.dtype, mode='r',
shape=self.shape)
assert_(allclose(self.data, newfp))
assert_array_equal(self.data, newfp)
assert_equal(newfp.flags.writeable, False)
def test_open_with_filename(self, tmp_path):
tmpname = tmp_path / 'mmap'
fp = memmap(tmpname, dtype=self.dtype, mode='w+',
shape=self.shape)
fp[:] = self.data[:]
del fp
def test_unnamed_file(self):
with TemporaryFile() as f:
fp = memmap(f, dtype=self.dtype, shape=self.shape)
del fp
def test_attributes(self):
offset = 1
mode = "w+"
fp = memmap(self.tmpfp, dtype=self.dtype, mode=mode,
shape=self.shape, offset=offset)
assert_equal(offset, fp.offset)
assert_equal(mode, fp.mode)
del fp
def test_filename(self, tmp_path):
tmpname = tmp_path / "mmap"
fp = memmap(tmpname, dtype=self.dtype, mode='w+',
shape=self.shape)
abspath = Path(os.path.abspath(tmpname))
fp[:] = self.data[:]
assert_equal(abspath, fp.filename)
b = fp[:1]
assert_equal(abspath, b.filename)
del b
del fp
def test_path(self, tmp_path):
tmpname = tmp_path / "mmap"
fp = memmap(Path(tmpname), dtype=self.dtype, mode='w+',
shape=self.shape)
abspath = str(Path(tmpname).resolve())
fp[:] = self.data[:]
assert_equal(abspath, str(fp.filename.resolve()))
b = fp[:1]
assert_equal(abspath, str(b.filename.resolve()))
del b
del fp
这些注释详细解释了每行代码的作用和意图,确保每个函数和方法的功能清晰可理解。
def test_filename_fileobj(self):
fp = memmap(self.tmpfp, dtype=self.dtype, mode="w+", shape=self.shape)
assert_equal(fp.filename, self.tmpfp.name)
@pytest.mark.skipif(sys.platform == 'gnu0', reason="Known to fail on hurd")
def test_flush(self):
fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', shape=self.shape)
fp[:] = self.data[:]
assert_equal(fp[0], self.data[0])
fp.flush()
def test_del(self):
fp_base = memmap(self.tmpfp, dtype=self.dtype, mode='w+', shape=self.shape)
fp_base[0] = 5
fp_view = fp_base[0:1]
assert_equal(fp_view[0], 5)
del fp_view
assert_equal(fp_base[0], 5)
fp_base[0] = 6
assert_equal(fp_base[0], 6)
def test_arithmetic_drops_references(self):
fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', shape=self.shape)
tmp = (fp + 10)
if isinstance(tmp, memmap):
assert_(tmp._mmap is not fp._mmap)
def test_indexing_drops_references(self):
fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', shape=self.shape)
tmp = fp[(1, 2), (2, 3)]
if isinstance(tmp, memmap):
assert_(tmp._mmap is not fp._mmap)
def test_slicing_keeps_references(self):
fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', shape=self.shape)
assert_(fp[:2, :2]._mmap is fp._mmap)
def test_view(self):
fp = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape)
new1 = fp.view()
new2 = new1.view()
assert_(new1.base is fp)
assert_(new2.base is fp)
new_array = asarray(fp)
assert_(new_array.base is fp)
def test_ufunc_return_ndarray(self):
fp = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape)
fp[:] = self.data
with suppress_warnings() as sup:
sup.filter(FutureWarning, "np.average currently does not preserve")
for unary_op in [sum, average, prod]:
result = unary_op(fp)
assert_(isscalar(result))
assert_(result.__class__ is self.data[0, 0].__class__)
assert_(unary_op(fp, axis=0).__class__ is ndarray)
assert_(unary_op(fp, axis=1).__class__ is ndarray)
for binary_op in [add, subtract, multiply]:
assert_(binary_op(fp, self.data).__class__ is ndarray)
assert_(binary_op(self.data, fp).__class__ is ndarray)
assert_(binary_op(fp, fp).__class__ is ndarray)
fp += 1
assert(fp.__class__ is memmap)
add(fp, 1, out=fp)
assert(fp.__class__ is memmap)
def test_getitem(self):
fp = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape)
fp[:] = self.data
assert_(fp[1:, :-1].__class__ is memmap)
assert_(fp[[0, 1]].__class__ is ndarray)
def test_memmap_subclass(self):
class MemmapSubClass(memmap):
pass
fp = MemmapSubClass(self.tmpfp, dtype=self.dtype, shape=self.shape)
fp[:] = self.data
assert_(sum(fp, axis=0).__class__ is MemmapSubClass)
assert_(sum(fp).__class__ is MemmapSubClass)
assert_(fp[1:, :-1].__class__ is MemmapSubClass)
assert(fp[[0, 1]].__class__ is MemmapSubClass)
def test_mmap_offset_greater_than_allocation_granularity(self):
size = 5 * mmap.ALLOCATIONGRANULARITY
offset = mmap.ALLOCATIONGRANULARITY + 1
fp = memmap(self.tmpfp, shape=size, mode='w+', offset=offset)
assert_(fp.offset == offset)
def test_no_shape(self):
self.tmpfp.write(b'a'*16)
mm = memmap(self.tmpfp, dtype='float64')
assert_equal(mm.shape, (2,))
def test_empty_array(self):
with pytest.raises(ValueError, match='empty file'):
memmap(self.tmpfp, shape=(0,4), mode='w+')
self.tmpfp.write(b'\0')
memmap(self.tmpfp, shape=(0,4), mode='w+')
def test_shape_type(self):
memmap(self.tmpfp, shape=3, mode='w+')
memmap(self.tmpfp, shape=self.shape, mode='w+')
memmap(self.tmpfp, shape=list(self.shape), mode='w+')
memmap(self.tmpfp, shape=asarray(self.shape), mode='w+')
.\numpy\numpy\_core\tests\test_mem_overlap.py
import itertools
import pytest
import numpy as np
from numpy._core._multiarray_tests import solve_diophantine, internal_overlap
from numpy._core import _umath_tests
from numpy.lib.stride_tricks import as_strided
from numpy.testing import (
assert_, assert_raises, assert_equal, assert_array_equal
)
ndims = 2
size = 10
shape = tuple([size] * ndims)
MAY_SHARE_BOUNDS = 0
MAY_SHARE_EXACT = -1
def _indices_for_nelems(nelems):
"""Returns slices of length nelems, from start onwards, in direction sign."""
if nelems == 0:
return [size // 2]
res = []
for step in (1, 2):
for sign in (-1, 1):
start = size // 2 - nelems * step * sign // 2
stop = start + nelems * step * sign
res.append(slice(start, stop, step * sign))
return res
def _indices_for_axis():
"""Returns (src, dst) pairs of indices."""
res = []
for nelems in (0, 2, 3):
ind = _indices_for_nelems(nelems)
res.extend(itertools.product(ind, ind))
return res
def _indices(ndims):
"""Returns ((axis0_src, axis0_dst), (axis1_src, axis1_dst), ... ) index pairs."""
ind = _indices_for_axis()
return itertools.product(ind, repeat=ndims)
def _check_assignment(srcidx, dstidx):
"""Check assignment arr[dstidx] = arr[srcidx] works."""
arr = np.arange(np.prod(shape)).reshape(shape)
cpy = arr.copy()
cpy[dstidx] = arr[srcidx]
arr[dstidx] = arr[srcidx]
assert_(np.all(arr == cpy),
'assigning arr[%s] = arr[%s]' % (dstidx, srcidx))
def test_overlapping_assignments():
inds = _indices(ndims)
for ind in inds:
srcidx = tuple([a[0] for a in ind])
dstidx = tuple([a[1] for a in ind])
_check_assignment(srcidx, dstidx)
@pytest.mark.slow
def test_diophantine_fuzz():
rng = np.random.RandomState(1234)
max_int = np.iinfo(np.intp).max
for ndim in range(10):
feasible_count = 0
infeasible_count = 0
min_count = 500 // (ndim + 1)
while min(feasible_count, infeasible_count) < min_count:
A_max = 1 + rng.randint(0, 11, dtype=np.intp)**6
U_max = rng.randint(0, 11, dtype=np.intp)**6
A_max = min(max_int, A_max)
U_max = min(max_int - 1, U_max)
A = tuple(int(rng.randint(1, A_max + 1, dtype=np.intp))
for j in range(ndim))
U = tuple(int(rng.randint(0, U_max + 2, dtype=np.intp))
for j in range(ndim))
b_ub = min(max_int - 2, sum(a * ub for a, ub in zip(A, U)))
b = int(rng.randint(-1, b_ub + 2, dtype=np.intp))
if ndim == 0 and feasible_count < min_count:
b = 0
X = solve_diophantine(A, U, b)
if X is None:
X_simplified = solve_diophantine(A, U, b, simplify=1)
assert_(X_simplified is None, (A, U, b, X_simplified))
ranges = tuple(range(0, a * ub + 1, a) for a, ub in zip(A, U))
size = 1
for r in ranges:
size *= len(r)
if size < 100000:
assert_(not any(sum(w) == b for w in itertools.product(*ranges)))
infeasible_count += 1
else:
X_simplified = solve_diophantine(A, U, b, simplify=1)
assert_(X_simplified is not None, (A, U, b, X_simplified))
assert_(sum(a * x for a, x in zip(A, X)) == b)
assert_(all(0 <= x <= ub for x, ub in zip(X, U)))
feasible_count += 1
def test_diophantine_overflow():
max_intp = np.iinfo(np.intp).max
max_int64 = np.iinfo(np.int64).max
if max_int64 <= max_intp:
A = (max_int64//2, max_int64//2 - 10)
U = (max_int64//2, max_int64//2 - 10)
b = 2*(max_int64//2) - 10
assert_equal(solve_diophantine(A, U, b), (1, 1))
def check_may_share_memory_exact(a, b):
got = np.may_share_memory(a, b, max_work=MAY_SHARE_EXACT)
assert_equal(np.may_share_memory(a, b),
np.may_share_memory(a, b, max_work=MAY_SHARE_BOUNDS))
a.fill(0)
b.fill(0)
a.fill(1)
exact = b.any()
err_msg = ""
if got != exact:
err_msg = " " + "\n ".join([
"base_a - base_b = %r" % (a.__array_interface__['data'][0] - b.__array_interface__['data'][0],),
"shape_a = %r" % (a.shape,),
"shape_b = %r" % (b.shape,),
"strides_a = %r" % (a.strides,),
"strides_b = %r" % (b.strides,),
"size_a = %r" % (a.size,),
"size_b = %r" % (b.size,)
])
assert_equal(got, exact, err_msg=err_msg)
def test_may_share_memory_manual():
xs0 = [
np.zeros([13, 21, 23, 22], dtype=np.int8),
np.zeros([13, 21, 23*2, 22], dtype=np.int8)[:,:,::2,:]
]
xs = []
for x in xs0:
for ss in itertools.product(*(([slice(None), slice(None, None, -1)],)*4)):
xp = x[ss]
xs.append(xp)
for x in xs:
assert_(np.may_share_memory(x[:,0,:], x[:,1,:]))
assert_(np.may_share_memory(x[:,0,:], x[:,1,:], max_work=None))
check_may_share_memory_exact(x[:,0,:], x[:,1,:])
check_may_share_memory_exact(x[:,::7], x[:,3::3])
try:
xp = x.ravel()
if xp.flags.owndata:
continue
xp = xp.view(np.int16)
except ValueError:
continue
check_may_share_memory_exact(x.ravel()[6:6],
xp.reshape(13, 21, 23, 11)[:,::7])
check_may_share_memory_exact(x[:,::7],
xp.reshape(13, 21, 23, 11))
check_may_share_memory_exact(x[:,::7],
xp.reshape(13, 21, 23, 11)[:,3::3])
check_may_share_memory_exact(x.ravel()[6:7],
xp.reshape(13, 21, 23, 11)[:,::7])
x = np.zeros([1], dtype=np.int8)
check_may_share_memory_exact(x, x)
check_may_share_memory_exact(x, x.copy())
def iter_random_view_pairs(x, same_steps=True, equal_size=False):
rng = np.random.RandomState(1234)
if equal_size and same_steps:
raise ValueError()
def random_slice(n, step):
start = rng.randint(0, n+1, dtype=np.intp)
stop = rng.randint(start, n+1, dtype=np.intp)
if rng.randint(0, 2, dtype=np.intp) == 0:
stop, start = start, stop
step *= -1
return slice(start, stop, step)
def random_slice_fixed_size(n, step, size):
start = rng.randint(0, n+1 - size*step)
stop = start + (size-1)*step + 1
if rng.randint(0, 2) == 0:
stop, start = start-1, stop-1
if stop < 0:
stop = None
step *= -1
return slice(start, stop, step)
yield x, x
for j in range(1, 7, 3):
yield x[j:], x[:-j]
yield x[...,j:], x[...,:-j]
strides = list(x.strides)
strides[0] = 0
xp = as_strided(x, shape=x.shape, strides=strides)
yield x, xp
yield xp, xp
strides = list(x.strides)
if strides[0] > 1:
strides[0] = 1
xp = as_strided(x, shape=x.shape, strides=strides)
yield x, xp
yield xp, xp
while True:
steps = tuple(rng.randint(1, 11, dtype=np.intp)
if rng.randint(0, 5, dtype=np.intp) == 0 else 1
for j in range(x.ndim))
s1 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps))
t1 = np.arange(x.ndim)
rng.shuffle(t1)
if equal_size:
t2 = t1
else:
t2 = np.arange(x.ndim)
rng.shuffle(t2)
a = x[s1]
if equal_size:
if a.size == 0:
continue
steps2 = tuple(rng.randint(1, max(2, p//(1+pa)))
if rng.randint(0, 5) == 0 else 1
for p, s, pa in zip(x.shape, s1, a.shape))
s2 = tuple(random_slice_fixed_size(p, s, pa)
for p, s, pa in zip(x.shape, steps2, a.shape))
elif same_steps:
steps2 = steps
else:
steps2 = tuple(rng.randint(1, 11, dtype=np.intp)
if rng.randint(0, 5, dtype=np.intp) == 0 else 1
for j in range(x.ndim))
if not equal_size:
s2 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps2))
a = a.transpose(t1)
b = x[s2].transpose(t2)
yield a, b
def check_may_share_memory_easy_fuzz(get_max_work, same_steps, min_count):
x = np.zeros([17,34,71,97], dtype=np.int16)
feasible = 0
infeasible = 0
pair_iter = iter_random_view_pairs(x, same_steps)
while min(feasible, infeasible) < min_count:
a, b = next(pair_iter)
bounds_overlap = np.may_share_memory(a, b)
may_share_answer = np.may_share_memory(a, b)
easy_answer = np.may_share_memory(a, b, max_work=get_max_work(a, b))
exact_answer = np.may_share_memory(a, b, max_work=MAY_SHARE_EXACT)
if easy_answer != exact_answer:
assert_equal(easy_answer, exact_answer)
if may_share_answer != bounds_overlap:
assert_equal(may_share_answer, bounds_overlap)
if bounds_overlap:
if exact_answer:
feasible += 1
else:
infeasible += 1
@pytest.mark.slow
def test_may_share_memory_easy_fuzz():
check_may_share_memory_easy_fuzz(get_max_work=lambda a, b: 1,
same_steps=True,
min_count=2000)
@pytest.mark.slow
def test_may_share_memory_harder_fuzz():
check_may_share_memory_easy_fuzz(get_max_work=lambda a, b: max(a.size, b.size)//2,
same_steps=False,
min_count=2000)
def test_shares_memory_api():
x = np.zeros([4, 5, 6], dtype=np.int8)
assert_equal(np.shares_memory(x, x), True)
assert_equal(np.shares_memory(x, x.copy()), False)
a = x[:,::2,::3]
b = x[:,::3,::2]
assert_equal(np.shares_memory(a, b), True)
assert_equal(np.shares_memory(a, b, max_work=None), True)
assert_raises(
np.exceptions.TooHardError, np.shares_memory, a, b, max_work=1
)
def test_may_share_memory_bad_max_work():
x = np.zeros([1])
assert_raises(OverflowError, np.may_share_memory, x, x, max_work=10**100)
assert_raises(OverflowError, np.shares_memory, x, x, max_work=10**100)
def test_internal_overlap_diophantine():
def check(A, U, exists=None):
X = solve_diophantine(A, U, 0, require_ub_nontrivial=1)
if exists is None:
exists = (X is not None)
if X is not None:
assert_(sum(a*x for a, x in zip(A, X)) == sum(a*u//2 for a, u in zip(A, U)))
assert_(all(0 <= x <= u for x, u in zip(X, U)))
assert_(any(x != u//2 for x, u in zip(X, U)))
if exists:
assert_(X is not None, repr(X))
else:
assert_(X is None, repr(X))
check((3, 2), (2*2, 3*2), exists=True)
check((3*2, 2), (15*2, (3-1)*2), exists=False)
def test_internal_overlap_slices():
x = np.zeros([17,34,71,97], dtype=np.int16)
rng = np.random.RandomState(1234)
def random_slice(n, step):
start = rng.randint(0, n+1, dtype=np.intp)
stop = rng.randint(start, n+1, dtype=np.intp)
if rng.randint(0, 2, dtype=np.intp) == 0:
stop, start = start, stop
step *= -1
return slice(start, stop, step)
cases = 0
min_count = 5000
while cases < min_count:
steps = tuple(rng.randint(1, 11, dtype=np.intp)
if rng.randint(0, 5, dtype=np.intp) == 0 else 1
for j in range(x.ndim))
t1 = np.arange(x.ndim)
rng.shuffle(t1)
s1 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps))
a = x[s1].transpose(t1)
assert_(not internal_overlap(a))
cases += 1
def check_internal_overlap(a, manual_expected=None):
got = internal_overlap(a)
m = set()
ranges = tuple(range(n) for n in a.shape)
for v in itertools.product(*ranges):
offset = sum(s*w for s, w in zip(a.strides, v))
if offset in m:
expected = True
break
else:
m.add(offset)
else:
expected = False
if got != expected:
assert_equal(got, expected, err_msg=repr((a.strides, a.shape)))
if manual_expected is not None and expected != manual_expected:
assert_equal(expected, manual_expected)
return got
def test_internal_overlap_manual():
x = np.arange(1).astype(np.int8)
check_internal_overlap(x, False)
check_internal_overlap(x.reshape([]), False)
a = as_strided(x, strides=(3, 4), shape=(4, 4))
check_internal_overlap(a, False)
a = as_strided(x, strides=(3, 4), shape=(5, 4))
check_internal_overlap(a, True)
a = as_strided(x, strides=(0,), shape=(0,))
check_internal_overlap(a, False)
a = as_strided(x, strides=(0,), shape=(1,))
check_internal_overlap(a, False)
a = as_strided(x, strides=(0,), shape=(2,))
check_internal_overlap(a, True)
a = as_strided(x, strides=(0, -9993), shape=(87, 22))
check_internal_overlap(a, True)
a = as_strided(x, strides=(0, -9993), shape=(1, 22))
check_internal_overlap(a, False)
a = as_strided(x, strides=(0, -9993), shape=(0, 22))
check_internal_overlap(a, False)
def test_internal_overlap_fuzz():
x = np.arange(1).astype(np.int8)
overlap = 0
no_overlap = 0
min_count = 100
rng = np.random.RandomState(1234)
while min(overlap, no_overlap) < min_count:
ndim = rng.randint(1, 4, dtype=np.intp)
strides = tuple(rng.randint(-1000, 1000, dtype=np.intp)
for j in range(ndim))
shape = tuple(rng.randint(1, 30, dtype=np.intp)
for j in range(ndim))
a = as_strided(x, strides=strides, shape=shape)
result = check_internal_overlap(a)
if result:
overlap += 1
else:
no_overlap += 1
def test_non_ndarray_inputs():
class MyArray:
def __init__(self, data):
self.data = data
@property
def __array_interface__(self):
return self.data.__array_interface__
class MyArray2:
def __init__(self, data):
self.data = data
def __array__(self, dtype=None, copy=None):
return self.data
for cls in [MyArray, MyArray2]:
x = np.arange(5)
assert_(np.may_share_memory(cls(x[::2]), x[1::2]))
assert_(not np.shares_memory(cls(x[::2]), x[1::2]))
assert_(np.shares_memory(cls(x[1::3]), x[::2]))
assert_(np.may_share_memory(cls(x[1::3]), x[::2]))
def view_element_first_byte(x):
from numpy.lib._stride_tricks_impl import DummyArray
interface = dict(x.__array_interface__)
interface['typestr'] = '|b1'
interface['descr'] = [('', '|b1')]
return np.asarray(DummyArray(interface, x))
def assert_copy_equivalent(operation, args, out, **kwargs):
kwargs['out'] = out
kwargs2 = dict(kwargs)
kwargs2['out'] = out.copy()
out_orig = out.copy()
out[...] = operation(*args, **kwargs2)
expected = out.copy()
out[...] = out_orig
got = operation(*args, **kwargs).copy()
if (got != expected).any():
assert_equal(got, expected)
class TestUFunc:
"""
Test ufunc call memory overlap handling
"""
def check_unary_fuzz(self, operation, get_out_axis_size, dtype=np.int16,
count=5000):
shapes = [7, 13, 8, 21, 29, 32]
rng = np.random.RandomState(1234)
for ndim in range(1, 6):
x = rng.randint(0, 2**16, size=shapes[:ndim]).astype(dtype)
it = iter_random_view_pairs(x, same_steps=False, equal_size=True)
min_count = count // (ndim + 1)**2
overlapping = 0
while overlapping < min_count:
a, b = next(it)
a_orig = a.copy()
b_orig = b.copy()
if get_out_axis_size is None:
assert_copy_equivalent(operation, [a], out=b)
if np.shares_memory(a, b):
overlapping += 1
else:
for axis in itertools.chain(range(ndim), [None]):
a[...] = a_orig
b[...] = b_orig
outsize, scalarize = get_out_axis_size(a, b, axis)
if outsize == 'skip':
continue
sl = [slice(None)] * ndim
if axis is None:
if outsize is None:
sl = [slice(0, 1)] + [0]*(ndim - 1)
else:
sl = [slice(0, outsize)] + [0]*(ndim - 1)
else:
if outsize is None:
k = b.shape[axis]//2
if ndim == 1:
sl[axis] = slice(k, k + 1)
else:
sl[axis] = k
else:
assert b.shape[axis] >= outsize
sl[axis] = slice(0, outsize)
b_out = b[tuple(sl)]
if scalarize:
b_out = b_out.reshape([])
if np.shares_memory(a, b_out):
overlapping += 1
assert_copy_equivalent(operation, [a], out=b_out, axis=axis)
@pytest.mark.slow
def test_unary_ufunc_call_fuzz(self):
self.check_unary_fuzz(np.invert, None, np.int16)
@pytest.mark.slow
def test_unary_ufunc_call_complex_fuzz(self):
self.check_unary_fuzz(np.negative, None, np.complex128, count=500)
def test_binary_ufunc_accumulate_fuzz(self):
def get_out_axis_size(a, b, axis):
if axis is None:
if a.ndim == 1:
return a.size, False
else:
return 'skip', False
else:
return a.shape[axis], False
self.check_unary_fuzz(np.add.accumulate, get_out_axis_size,
dtype=np.int16, count=500)
def test_binary_ufunc_reduce_fuzz(self):
def get_out_axis_size(a, b, axis):
return None, (axis is None or a.ndim == 1)
self.check_unary_fuzz(np.add.reduce, get_out_axis_size,
dtype=np.int16, count=500)
def test_binary_ufunc_reduceat_fuzz(self):
def get_out_axis_size(a, b, axis):
if axis is None:
if a.ndim == 1:
return a.size, False
else:
return 'skip', False
else:
return a.shape[axis], False
def do_reduceat(a, out, axis):
if axis is None:
size = len(a)
step = size // len(out)
else:
size = a.shape[axis]
step = a.shape[axis] // out.shape[axis]
idx = np.arange(0, size, step)
return np.add.reduceat(a, idx, out=out, axis=axis)
self.check_unary_fuzz(do_reduceat, get_out_axis_size,
dtype=np.int16, count=500)
def test_binary_ufunc_reduceat_manual(self):
def check(ufunc, a, ind, out):
c1 = ufunc.reduceat(a.copy(), ind.copy(), out=out.copy())
c2 = ufunc.reduceat(a, ind, out=out)
assert_array_equal(c1, c2)
a = np.arange(10000, dtype=np.int16)
check(np.add, a, a[::-1].copy(), a)
a = np.arange(10000, dtype=np.int16)
check(np.add, a, a[::-1], a)
def test_unary_gufunc_fuzz(self):
shapes = [7, 13, 8, 21, 29, 32]
gufunc = _umath_tests.euclidean_pdist
rng = np.random.RandomState(1234)
for ndim in range(2, 6):
x = rng.rand(*shapes[:ndim])
it = iter_random_view_pairs(x, same_steps=False, equal_size=True)
min_count = 500 // (ndim + 1)**2
overlapping = 0
while overlapping < min_count:
a, b = next(it)
if min(a.shape[-2:]) < 2 or min(b.shape[-2:]) < 2 or a.shape[-1] < 2:
continue
if b.shape[-1] > b.shape[-2]:
b = b[...,0,:]
else:
b = b[...,:,0]
n = a.shape[-2]
p = n * (n - 1) // 2
if p <= b.shape[-1] and p > 0:
b = b[...,:p]
else:
n = max(2, int(np.sqrt(b.shape[-1]))//2)
p = n * (n - 1) // 2
a = a[...,:n,:]
b = b[...,:p]
if np.shares_memory(a, b):
overlapping += 1
with np.errstate(over='ignore', invalid='ignore'):
assert_copy_equivalent(gufunc, [a], out=b)
def test_ufunc_at_manual(self):
def check(ufunc, a, ind, b=None):
a0 = a.copy()
if b is None:
ufunc.at(a0, ind.copy())
c1 = a0.copy()
ufunc.at(a, ind)
c2 = a.copy()
else:
ufunc.at(a0, ind.copy(), b.copy())
c1 = a0.copy()
ufunc.at(a, ind, b)
c2 = a.copy()
assert_array_equal(c1, c2)
a = np.arange(10000, dtype=np.int16)
check(np.invert, a[::-1], a)
a = np.arange(100, dtype=np.int16)
ind = np.arange(0, 100, 2, dtype=np.int16)
check(np.add, a, ind, a[25:75])
def test_unary_ufunc_1d_manual(self):
def check(a, b):
a_orig = a.copy()
b_orig = b.copy()
b0 = b.copy()
c1 = ufunc(a, out=b0)
c2 = ufunc(a, out=b)
assert_array_equal(c1, c2)
mask = view_element_first_byte(b).view(np.bool)
a[...] = a_orig
b[...] = b_orig
c1 = ufunc(a, out=b.copy(), where=mask.copy()).copy()
a[...] = a_orig
b[...] = b_orig
c2 = ufunc(a, out=b, where=mask.copy()).copy()
a[...] = a_orig
b[...] = b_orig
c3 = ufunc(a, out=b, where=mask).copy()
assert_array_equal(c1, c2)
assert_array_equal(c1, c3)
dtypes = [np.int8, np.int16, np.int32, np.int64, np.float32,
np.float64, np.complex64, np.complex128]
dtypes = [np.dtype(x) for x in dtypes]
for dtype in dtypes:
if np.issubdtype(dtype, np.integer):
ufunc = np.invert
else:
ufunc = np.reciprocal
n = 1000
k = 10
indices = [
np.index_exp[:n],
np.index_exp[k:k+n],
np.index_exp[n-1::-1],
np.index_exp[k+n-1:k-1:-1],
np.index_exp[:2*n:2],
np.index_exp[k:k+2*n:2],
np.index_exp[2*n-1::-2],
np.index_exp[k+2*n-1:k-1:-2],
]
for xi, yi in itertools.product(indices, indices):
v = np.arange(1, 1 + n*2 + k, dtype=dtype)
x = v[xi]
y = v[yi]
with np.errstate(all='ignore'):
check(x, y)
check(x[:1], y)
check(x[-1:], y)
check(x[:1].reshape([]), y)
check(x[-1:].reshape([]), y)
def test_unary_ufunc_where_same(self):
ufunc = np.invert
def check(a, out, mask):
c1 = ufunc(a, out=out.copy(), where=mask.copy())
c2 = ufunc(a, out=out, where=mask)
assert_array_equal(c1, c2)
x = np.arange(100).astype(np.bool)
check(x, x, x)
check(x, x.copy(), x)
check(x, x, x.copy())
@pytest.mark.slow
def test_binary_ufunc_1d_manual(self):
ufunc = np.add
def check(a, b, c):
c0 = c.copy()
c1 = ufunc(a, b, out=c0)
c2 = ufunc(a, b, out=c)
assert_array_equal(c1, c2)
for dtype in [np.int8, np.int16, np.int32, np.int64,
np.float32, np.float64, np.complex64, np.complex128]:
n = 1000
k = 10
indices = []
for p in [1, 2]:
indices.extend([
np.index_exp[:p*n:p],
np.index_exp[k:k+p*n:p],
np.index_exp[p*n-1::-p],
np.index_exp[k+p*n-1:k-1:-p],
])
for x, y, z in itertools.product(indices, indices, indices):
v = np.arange(6*n).astype(dtype)
x = v[x]
y = v[y]
z = v[z]
check(x, y, z)
check(x[:1], y, z)
check(x[-1:], y, z)
check(x[:1].reshape([]), y, z)
check(x[-1:].reshape([]), y, z)
check(x, y[:1], z)
check(x, y[-1:], z)
check(x, y[:1].reshape([]), z)
check(x, y[-1:].reshape([]), z)
def test_inplace_op_simple_manual(self):
rng = np.random.RandomState(1234)
x = rng.rand(200, 200)
x += x.T
assert_array_equal(x - x.T, 0)