summaryrefslogtreecommitdiff
path: root/numpy/core/tests/test_scalarmath.py
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core/tests/test_scalarmath.py')
-rw-r--r--numpy/core/tests/test_scalarmath.py82
1 files changed, 60 insertions, 22 deletions
diff --git a/numpy/core/tests/test_scalarmath.py b/numpy/core/tests/test_scalarmath.py
index e3dc52c48..c737099c1 100644
--- a/numpy/core/tests/test_scalarmath.py
+++ b/numpy/core/tests/test_scalarmath.py
@@ -4,7 +4,7 @@ import warnings
import itertools
import operator
import platform
-from numpy.compat import _pep440
+from numpy._utils import _pep440
import pytest
from hypothesis import given, settings
from hypothesis.strategies import sampled_from
@@ -14,7 +14,7 @@ import numpy as np
from numpy.testing import (
assert_, assert_equal, assert_raises, assert_almost_equal,
assert_array_equal, IS_PYPY, suppress_warnings, _gen_alignment_data,
- assert_warns,
+ assert_warns, _SUPPORTS_SVE,
)
types = [np.bool_, np.byte, np.ubyte, np.short, np.ushort, np.intc, np.uintc,
@@ -75,17 +75,7 @@ class TestTypes:
np.add(1, 1)
-@pytest.mark.slow
-@settings(max_examples=10000, deadline=2000)
-@given(sampled_from(reasonable_operators_for_scalars),
- hynp.arrays(dtype=hynp.scalar_dtypes(), shape=()),
- hynp.arrays(dtype=hynp.scalar_dtypes(), shape=()))
-def test_array_scalar_ufunc_equivalence(op, arr1, arr2):
- """
- This is a thorough test attempting to cover important promotion paths
- and ensuring that arrays and scalars stay as aligned as possible.
- However, if it creates troubles, it should maybe just be removed.
- """
+def check_ufunc_scalar_equivalence(op, arr1, arr2):
scalar1 = arr1[()]
scalar2 = arr2[()]
assert isinstance(scalar1, np.generic)
@@ -95,6 +85,11 @@ def test_array_scalar_ufunc_equivalence(op, arr1, arr2):
comp_ops = {operator.ge, operator.gt, operator.le, operator.lt}
if op in comp_ops and (np.isnan(scalar1) or np.isnan(scalar2)):
pytest.xfail("complex comp ufuncs use sort-order, scalars do not.")
+ if op == operator.pow and arr2.item() in [-1, 0, 0.5, 1, 2]:
+ # array**scalar special case can have different result dtype
+ # (Other powers may have issues also, but are not hit here.)
+ # TODO: It would be nice to resolve this issue.
+ pytest.skip("array**2 can have incorrect/weird result dtype")
# ignore fpe's since they may just mismatch for integers anyway.
with warnings.catch_warnings(), np.errstate(all="ignore"):
@@ -107,10 +102,51 @@ def test_array_scalar_ufunc_equivalence(op, arr1, arr2):
op(scalar1, scalar2)
else:
scalar_res = op(scalar1, scalar2)
- assert_array_equal(scalar_res, res)
+ assert_array_equal(scalar_res, res, strict=True)
+
+
+@pytest.mark.slow
+@settings(max_examples=10000, deadline=2000)
+@given(sampled_from(reasonable_operators_for_scalars),
+ hynp.arrays(dtype=hynp.scalar_dtypes(), shape=()),
+ hynp.arrays(dtype=hynp.scalar_dtypes(), shape=()))
+def test_array_scalar_ufunc_equivalence(op, arr1, arr2):
+ """
+ This is a thorough test attempting to cover important promotion paths
+ and ensuring that arrays and scalars stay as aligned as possible.
+ However, if it creates troubles, it should maybe just be removed.
+ """
+ check_ufunc_scalar_equivalence(op, arr1, arr2)
+
+
+@pytest.mark.slow
+@given(sampled_from(reasonable_operators_for_scalars),
+ hynp.scalar_dtypes(), hynp.scalar_dtypes())
+def test_array_scalar_ufunc_dtypes(op, dt1, dt2):
+ # Same as above, but don't worry about sampling weird values so that we
+ # do not have to sample as much
+ arr1 = np.array(2, dtype=dt1)
+ arr2 = np.array(3, dtype=dt2) # some power do weird things.
+
+ check_ufunc_scalar_equivalence(op, arr1, arr2)
+
+
+@pytest.mark.parametrize("fscalar", [np.float16, np.float32])
+def test_int_float_promotion_truediv(fscalar):
+ # Promotion for mixed int and float32/float16 must not go to float64
+ i = np.int8(1)
+ f = fscalar(1)
+ expected = np.result_type(i, f)
+ assert (i / f).dtype == expected
+ assert (f / i).dtype == expected
+ # But normal int / int true division goes to float64:
+ assert (i / i).dtype == np.dtype("float64")
+ # For int16, result has to be ast least float32 (takes ufunc path):
+ assert (np.int16(1) / f).dtype == np.dtype("float32")
class TestBaseMath:
+ @pytest.mark.xfail(_SUPPORTS_SVE, reason="gh-22982")
def test_blocked(self):
# test alignments offsets for simd instructions
# alignments for vz + 2 * (vs - 1) + 1
@@ -860,27 +896,29 @@ def test_operator_scalars(op, type1, type2):
@pytest.mark.parametrize("op", reasonable_operators_for_scalars)
-def test_longdouble_inf_loop(op):
+@pytest.mark.parametrize("val", [None, 2**64])
+def test_longdouble_inf_loop(op, val):
+ # Note: The 2**64 value will pass once NEP 50 is adopted.
try:
- op(np.longdouble(3), None)
+ op(np.longdouble(3), val)
except TypeError:
pass
try:
- op(None, np.longdouble(3))
+ op(val, np.longdouble(3))
except TypeError:
pass
@pytest.mark.parametrize("op", reasonable_operators_for_scalars)
-def test_clongdouble_inf_loop(op):
- if op in {operator.mod} and False:
- pytest.xfail("The modulo operator is known to be broken")
+@pytest.mark.parametrize("val", [None, 2**64])
+def test_clongdouble_inf_loop(op, val):
+ # Note: The 2**64 value will pass once NEP 50 is adopted.
try:
- op(np.clongdouble(3), None)
+ op(np.clongdouble(3), val)
except TypeError:
pass
try:
- op(None, np.longdouble(3))
+ op(val, np.longdouble(3))
except TypeError:
pass