diff options
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/code_generators/generate_umath.py | 2 | ||||
-rw-r--r-- | numpy/core/numeric.py | 7 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_type_resolution.c | 46 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_type_resolution.h | 7 | ||||
-rw-r--r-- | numpy/core/tests/test_defchararray.py | 6 | ||||
-rw-r--r-- | numpy/core/tests/test_deprecations.py | 23 | ||||
-rw-r--r-- | numpy/core/tests/test_numeric.py | 7 | ||||
-rw-r--r-- | numpy/core/tests/test_regression.py | 5 |
8 files changed, 95 insertions, 8 deletions
diff --git a/numpy/core/code_generators/generate_umath.py b/numpy/core/code_generators/generate_umath.py index e02cb8709..e3c9cf28b 100644 --- a/numpy/core/code_generators/generate_umath.py +++ b/numpy/core/code_generators/generate_umath.py @@ -369,7 +369,7 @@ defdict = { 'negative': Ufunc(1, 1, None, docstrings.get('numpy.core.umath.negative'), - 'PyUFunc_SimpleUnaryOperationTypeResolver', + 'PyUFunc_NegativeTypeResolver', TD(bints+flts+timedeltaonly), TD(cmplx, f='neg'), TD(O, f='PyNumber_Negative'), diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py index 39e5a4cd5..3b8e52e71 100644 --- a/numpy/core/numeric.py +++ b/numpy/core/numeric.py @@ -2139,6 +2139,11 @@ def allclose(a, b, rtol=1.e-5, atol=1.e-8): x = array(a, copy=False, ndmin=1) y = array(b, copy=False, ndmin=1) + # make sure y is an inexact type to avoid abs(MIN_INT); will cause + # casting of x later. + dtype = multiarray.result_type(y, 1.) + y = array(y, dtype=dtype, copy=False) + xinf = isinf(x) yinf = isinf(y) if any(xinf) or any(yinf): @@ -2154,7 +2159,7 @@ def allclose(a, b, rtol=1.e-5, atol=1.e-8): # ignore invalid fpe's with errstate(invalid='ignore'): - r = all(less_equal(abs(x-y), atol + rtol * abs(y))) + r = all(less_equal(abs(x - y), atol + rtol * abs(y))) return r diff --git a/numpy/core/src/umath/ufunc_type_resolution.c b/numpy/core/src/umath/ufunc_type_resolution.c index 12d8e406b..ffdb15bbe 100644 --- a/numpy/core/src/umath/ufunc_type_resolution.c +++ b/numpy/core/src/umath/ufunc_type_resolution.c @@ -367,6 +367,34 @@ PyUFunc_SimpleUnaryOperationTypeResolver(PyUFuncObject *ufunc, return 0; } + +NPY_NO_EXPORT int +PyUFunc_NegativeTypeResolver(PyUFuncObject *ufunc, + NPY_CASTING casting, + PyArrayObject **operands, + PyObject *type_tup, + PyArray_Descr **out_dtypes) +{ + int ret; + ret = PyUFunc_SimpleUnaryOperationTypeResolver(ufunc, casting, operands, + type_tup, out_dtypes); + if (ret < 0) { + return ret; + } + + /* The type resolver would have upcast already */ + if (out_dtypes[0]->type_num == NPY_BOOL) { + if (DEPRECATE("numpy boolean negative (the unary `-` operator) is " + "deprecated, use the bitwise_xor (the `^` operator) " + "or the logical_xor function instead.") < 0) { + return -1; + } + } + + return ret; +} + + /* * The ones_like function shouldn't really be a ufunc, but while it * still is, this provides type resolution that always forces UNSAFE @@ -762,8 +790,22 @@ PyUFunc_SubtractionTypeResolver(PyUFuncObject *ufunc, /* Use the default when datetime and timedelta are not involved */ if (!PyTypeNum_ISDATETIME(type_num1) && !PyTypeNum_ISDATETIME(type_num2)) { - return PyUFunc_SimpleBinaryOperationTypeResolver(ufunc, casting, - operands, type_tup, out_dtypes); + int ret; + ret = PyUFunc_SimpleBinaryOperationTypeResolver(ufunc, casting, + operands, type_tup, out_dtypes); + if (ret < 0) { + return ret; + } + + /* The type resolver would have upcast already */ + if (out_dtypes[0]->type_num == NPY_BOOL) { + if (DEPRECATE("numpy boolean subtract (the binary `-` operator) is " + "deprecated, use the bitwise_xor (the `^` operator) " + "or the logical_xor function instead.") < 0) { + return -1; + } + } + return ret; } if (type_num1 == NPY_TIMEDELTA) { diff --git a/numpy/core/src/umath/ufunc_type_resolution.h b/numpy/core/src/umath/ufunc_type_resolution.h index a1241827e..a1e28d75b 100644 --- a/numpy/core/src/umath/ufunc_type_resolution.h +++ b/numpy/core/src/umath/ufunc_type_resolution.h @@ -16,6 +16,13 @@ PyUFunc_SimpleUnaryOperationTypeResolver(PyUFuncObject *ufunc, PyArray_Descr **out_dtypes); NPY_NO_EXPORT int +PyUFunc_NegativeTypeResolver(PyUFuncObject *ufunc, + NPY_CASTING casting, + PyArrayObject **operands, + PyObject *type_tup, + PyArray_Descr **out_dtypes); + +NPY_NO_EXPORT int PyUFunc_OnesLikeTypeResolver(PyUFuncObject *ufunc, NPY_CASTING casting, PyArrayObject **operands, diff --git a/numpy/core/tests/test_defchararray.py b/numpy/core/tests/test_defchararray.py index fe0e02a6d..2b45ba4bc 100644 --- a/numpy/core/tests/test_defchararray.py +++ b/numpy/core/tests/test_defchararray.py @@ -128,9 +128,9 @@ class TestWhitespace(TestCase): assert_(all(self.A == self.B)) assert_(all(self.A >= self.B)) assert_(all(self.A <= self.B)) - assert_(all(negative(self.A > self.B))) - assert_(all(negative(self.A < self.B))) - assert_(all(negative(self.A != self.B))) + assert_(not any(self.A > self.B)) + assert_(not any(self.A < self.B)) + assert_(not any(self.A != self.B)) class TestChar(TestCase): def setUp(self): diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py index 41f1cf744..f7fbb94e5 100644 --- a/numpy/core/tests/test_deprecations.py +++ b/numpy/core/tests/test_deprecations.py @@ -343,5 +343,28 @@ class TestMultipleEllipsisDeprecation(_DeprecationTestCase): assert_raises(IndexError, a.__getitem__, ((Ellipsis, ) * 3,)) +class TestBooleanSubtractDeprecations(_DeprecationTestCase): + """Test deprecation of boolean `-`. While + and * are well + defined, - is not and even a corrected form seems to have + no real uses. + + The deprecation process was started in NumPy 1.9. + """ + message = r"numpy boolean .* \(the .* `-` operator\) is deprecated, " \ + "use the bitwise" + + def test_operator_deprecation(self): + array = np.array([True]) + generic = np.bool_(True) + + # Minus operator/subtract ufunc: + self.assert_deprecated(operator.sub, args=(array, array)) + self.assert_deprecated(operator.sub, args=(generic, generic)) + + # Unary minus/negative ufunc: + self.assert_deprecated(operator.neg, args=(array,)) + self.assert_deprecated(operator.neg, args=(generic,)) + + if __name__ == "__main__": run_module_suite() diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py index ac341468c..12a39a522 100644 --- a/numpy/core/tests/test_numeric.py +++ b/numpy/core/tests/test_numeric.py @@ -1420,6 +1420,13 @@ class TestAllclose(object): assert_array_equal(y, array([0, inf])) + def test_min_int(self): + # Could make problems because of abs(min_int) == min_int + min_int = np.iinfo(np.int_).min + a = np.array([min_int], dtype=np.int_) + assert_(allclose(a, a)) + + class TestIsclose(object): rtol = 1e-5 atol = 1e-8 diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index 2bcb2b185..e6eb0791d 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -447,7 +447,10 @@ class TestRegression(TestCase): res1 = getattr(arr, func_meth)() res2 = getattr(np, func)(arr2) if res1 is None: - assert_(abs(arr-res2).max() < 1e-8, func) + res1 = arr + + if res1.dtype.kind in 'uib': + assert_((res1 == res2).all(), func) else: assert_(abs(res1-res2).max() < 1e-8, func) |