diff options
-rw-r--r-- | doc/source/reference/ufuncs.rst | 17 | ||||
-rw-r--r-- | numpy/core/include/numpy/ndarraytypes.h | 6 | ||||
-rw-r--r-- | numpy/core/src/multiarray/common.c | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarray/convert_datatype.c | 54 | ||||
-rw-r--r-- | numpy/core/tests/test_ufunc.py | 39 | ||||
-rw-r--r-- | numpy/lib/nanfunctions.py | 6 |
6 files changed, 26 insertions, 98 deletions
diff --git a/doc/source/reference/ufuncs.rst b/doc/source/reference/ufuncs.rst index 2ae794f59..3d6112058 100644 --- a/doc/source/reference/ufuncs.rst +++ b/doc/source/reference/ufuncs.rst @@ -313,16 +313,15 @@ advanced usage and will not typically be used. .. versionadded:: 1.6 + May be 'no', 'equiv', 'safe', 'same_kind', or 'unsafe'. + See :func:`can_cast` for explanations of the parameter values. + Provides a policy for what kind of casting is permitted. For compatibility - with previous versions of NumPy, this defaults to 'unsafe'. May be 'no', - 'equiv', 'safe', 'same_kind', or 'unsafe'. See :func:`can_cast` for - explanations of the parameter values. - - In a future version of numpy, this argument will default to - 'same_kind'. As part of this transition, starting in version 1.7, - ufuncs will produce a DeprecationWarning for calls which are - allowed under the 'unsafe' rules, but not under the 'same_kind' - rules. + with previous versions of NumPy, this defaults to 'unsafe' for numpy < 1.7. + In numpy 1.7 a transition to 'same_kind' was begun where ufuncs produce a + DeprecationWarning for calls which are allowed under the 'unsafe' + rules, but not under the 'same_kind' rules. In numpy 1.10 the default + will be 'same_kind'. *order* diff --git a/numpy/core/include/numpy/ndarraytypes.h b/numpy/core/include/numpy/ndarraytypes.h index 21ff8cd1a..78f79d5fe 100644 --- a/numpy/core/include/numpy/ndarraytypes.h +++ b/numpy/core/include/numpy/ndarraytypes.h @@ -203,12 +203,6 @@ typedef enum { NPY_SAME_KIND_CASTING=3, /* Allow any casts */ NPY_UNSAFE_CASTING=4, - - /* - * Temporary internal definition only, will be removed in upcoming - * release, see below - * */ - NPY_INTERNAL_UNSAFE_CASTING_BUT_WARN_UNLESS_SAME_KIND = 100, } NPY_CASTING; typedef enum { diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c index 2b3d3c3d2..f1656afd0 100644 --- a/numpy/core/src/multiarray/common.c +++ b/numpy/core/src/multiarray/common.c @@ -84,7 +84,7 @@ PyArray_GetAttrString_SuppressException(PyObject *obj, char *name) -NPY_NO_EXPORT NPY_CASTING NPY_DEFAULT_ASSIGN_CASTING = NPY_INTERNAL_UNSAFE_CASTING_BUT_WARN_UNLESS_SAME_KIND; +NPY_NO_EXPORT NPY_CASTING NPY_DEFAULT_ASSIGN_CASTING = NPY_SAME_KIND_CASTING; NPY_NO_EXPORT PyArray_Descr * diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c index 1db3bfe85..fa5fb6b67 100644 --- a/numpy/core/src/multiarray/convert_datatype.c +++ b/numpy/core/src/multiarray/convert_datatype.c @@ -624,63 +624,19 @@ type_num_unsigned_to_signed(int type_num) } } -/* - * NOTE: once the UNSAFE_CASTING -> SAME_KIND_CASTING transition is over, - * we should remove NPY_INTERNAL_UNSAFE_CASTING_BUT_WARN_UNLESS_SAME_KIND - * and PyArray_CanCastTypeTo_impl should be renamed back to - * PyArray_CanCastTypeTo. - */ -static npy_bool -PyArray_CanCastTypeTo_impl(PyArray_Descr *from, PyArray_Descr *to, - NPY_CASTING casting); - /*NUMPY_API * Returns true if data of type 'from' may be cast to data of type * 'to' according to the rule 'casting'. */ NPY_NO_EXPORT npy_bool PyArray_CanCastTypeTo(PyArray_Descr *from, PyArray_Descr *to, - NPY_CASTING casting) -{ - /* fast path for basic types */ - if (NPY_LIKELY(from->type_num < NPY_OBJECT) && - NPY_LIKELY(from->type_num == to->type_num) && - NPY_LIKELY(from->byteorder == to->byteorder)) { - return 1; - } - else if (casting == NPY_INTERNAL_UNSAFE_CASTING_BUT_WARN_UNLESS_SAME_KIND) { - npy_bool unsafe_ok, same_kind_ok; - unsafe_ok = PyArray_CanCastTypeTo_impl(from, to, NPY_UNSAFE_CASTING); - same_kind_ok = PyArray_CanCastTypeTo_impl(from, to, - NPY_SAME_KIND_CASTING); - if (unsafe_ok && !same_kind_ok) { - char * msg = "Implicitly casting between incompatible kinds. In " - "a future numpy release, this will raise an error. " - "Use casting=\"unsafe\" if this is intentional."; - if (DEPRECATE(msg) < 0) { - /* We have no way to propagate an exception :-( */ - PyErr_Clear(); - PySys_WriteStderr("Sorry, you requested this warning " - "be raised as an error, but we couldn't " - "do it. (See issue #3806 in the numpy " - "bug tracker.) So FYI, it was: " - "DeprecationWarning: %s\n", - msg); - } - } - return unsafe_ok; - } - else { - return PyArray_CanCastTypeTo_impl(from, to, casting); - } -} - -static npy_bool -PyArray_CanCastTypeTo_impl(PyArray_Descr *from, PyArray_Descr *to, NPY_CASTING casting) { - /* If unsafe casts are allowed */ - if (casting == NPY_UNSAFE_CASTING) { + /* Fast path for unsafe casts or basic types */ + if (casting == NPY_UNSAFE_CASTING || + (NPY_LIKELY(from->type_num < NPY_OBJECT) && + NPY_LIKELY(from->type_num == to->type_num) && + NPY_LIKELY(from->byteorder == to->byteorder))) { return 1; } /* Equivalent types can be cast with any value of 'casting' */ diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py index 080606dce..7b8aff72a 100644 --- a/numpy/core/tests/test_ufunc.py +++ b/numpy/core/tests/test_ufunc.py @@ -834,45 +834,20 @@ class TestUfunc(TestCase): def test_safe_casting(self): # In old versions of numpy, in-place operations used the 'unsafe' - # casting rules. In some future version, 'same_kind' will become the - # default. + # casting rules. In versions >= 1.10, 'same_kind' is the + # default and an exception is raised instead of a warning. + # when 'same_kind' is not satisfied. a = np.array([1, 2, 3], dtype=int) # Non-in-place addition is fine assert_array_equal(assert_no_warnings(np.add, a, 1.1), [2.1, 3.1, 4.1]) - assert_warns(DeprecationWarning, np.add, a, 1.1, out=a) - assert_array_equal(a, [2, 3, 4]) + assert_raises(TypeError, np.add, a, 1.1, out=a) def add_inplace(a, b): a += b - assert_warns(DeprecationWarning, add_inplace, a, 1.1) - assert_array_equal(a, [3, 4, 5]) - # Make sure that explicitly overriding the warning is allowed: + assert_raises(TypeError, add_inplace, a, 1.1) + # Make sure that explicitly overriding the exception is allowed: assert_no_warnings(np.add, a, 1.1, out=a, casting="unsafe") - assert_array_equal(a, [4, 5, 6]) - - # There's no way to propagate exceptions from the place where we issue - # this deprecation warning, so we must throw the exception away - # entirely rather than cause it to be raised at some other point, or - # trigger some other unsuspecting if (PyErr_Occurred()) { ...} at some - # other location entirely. - import warnings - import sys - if sys.version_info[0] >= 3: - from io import StringIO - else: - from StringIO import StringIO - with warnings.catch_warnings(): - warnings.simplefilter("error") - old_stderr = sys.stderr - try: - sys.stderr = StringIO() - # No error, but dumps to stderr - a += 1.1 - # No error on the next bit of code executed either - 1 + 1 - assert_("Implicitly casting" in sys.stderr.getvalue()) - finally: - sys.stderr = old_stderr + assert_array_equal(a, [2, 3, 4]) def test_ufunc_custom_out(self): # Test ufunc with built in input types and custom output type diff --git a/numpy/lib/nanfunctions.py b/numpy/lib/nanfunctions.py index 818e130a8..e6b375884 100644 --- a/numpy/lib/nanfunctions.py +++ b/numpy/lib/nanfunctions.py @@ -35,6 +35,10 @@ def _replace_nan(a, val): marking the locations where NaNs were present. If `a` is not of inexact type, do nothing and return `a` together with a mask of None. + Note that scalars will end up as array scalars, which is important + for using the result as the value of the out argument in some + operations. + Parameters ---------- a : array-like @@ -850,7 +854,7 @@ def nanvar(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False): avg = _divide_by_count(avg, cnt) # Compute squared deviation from mean. - arr -= avg + np.subtract(arr, avg, out=arr, casting='unsafe') arr = _copyto(arr, 0, mask) if issubclass(arr.dtype.type, np.complexfloating): sqr = np.multiply(arr, arr.conj(), out=arr).real |