Skip to content

Commit

Permalink
Switch WARN_ON_WRITE to issuing FutureWarnings instead of Deprecation…
Browse files Browse the repository at this point in the history
…Warnings

FutureWarnings are displayed by default, so they should be used
whenever a future change will change the semantics of existing code
(as opposed to making existing code simply stop working).

List discussion:
  http://www.mail-archive.com/numpy-discussion@scipy.org/msg37500.html
  • Loading branch information
njsmith committed Jul 17, 2012
1 parent 1234d1c commit b798f12
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 15 deletions.
4 changes: 2 additions & 2 deletions doc/release/1.7.0-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ the diagonal method of ndarrays will return a view onto the original
array, instead of producing a copy as they do now. This makes a
difference if you write to the array returned by any of these
functions. To facilitate this transition, numpy 1.7 produces a
DeprecationWarning if it detects that you may be attempting to write
to such an array. See the documentation for np.diagonal for details.
FutureWarning if it detects that you may be attempting to write to
such an array. See the documentation for np.diagonal for details.

The default casting rule for UFunc out= parameters has been changed from
'unsafe' to 'same_kind'. Most usages which violate the 'same_kind'
Expand Down
2 changes: 1 addition & 1 deletion numpy/core/fromnumeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ def diagonal(a, offset=0, axis1=0, axis2=1):
In NumPy 1.7, it continues to return a copy of the diagonal, but depending
on this fact is deprecated. Writing to the resulting array continues to
work as it used to, but a DeprecationWarning will be issued.
work as it used to, but a FutureWarning will be issued.
In NumPy 1.8, it will switch to returning a read-only view on the original
array. Attempting to write to the resulting array will produce an error.
Expand Down
2 changes: 2 additions & 0 deletions numpy/core/include/numpy/ndarrayobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,10 @@ PyArray_XDECREF_ERR(PyArrayObject *arr)

#if PY_VERSION_HEX >= 0x02050000
#define DEPRECATE(msg) PyErr_WarnEx(PyExc_DeprecationWarning,msg,1)
#define DEPRECATE_FUTUREWARNING(msg) PyErr_WarnEx(PyExc_FutureWarning,msg,1)
#else
#define DEPRECATE(msg) PyErr_Warn(PyExc_DeprecationWarning,msg)
#define DEPRECATE_FUTUREWARNING(msg) PyErr_Warn(PyExc_FutureWarning,msg)
#endif


Expand Down
2 changes: 1 addition & 1 deletion numpy/core/src/multiarray/arrayobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ array_might_be_written(PyArrayObject *obj)
"release -- see numpy.diagonal docs for details. The quick fix is\n"
"to make an explicit copy (e.g., do arr.diagonal().copy()).";
if (PyArray_FLAGS(obj) & NPY_ARRAY_WARN_ON_WRITE) {
if (DEPRECATE(msg) < 0) {
if (DEPRECATE_FUTUREWARNING(msg) < 0) {
return -1;
}
/* Only warn once per array */
Expand Down
22 changes: 11 additions & 11 deletions numpy/core/tests/test_multiarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -913,19 +913,19 @@ def collect_warning_types(f, *args, **kwargs):
# All the different functions raise a warning, but not an error, and
# 'a' is not modified:
assert_equal(collect_warning_types(a.diagonal().__setitem__, 0, 10),
[DeprecationWarning])
[FutureWarning])
assert_equal(a, np.arange(9).reshape(3, 3))
assert_equal(collect_warning_types(np.diagonal(a).__setitem__, 0, 10),
[DeprecationWarning])
[FutureWarning])
assert_equal(a, np.arange(9).reshape(3, 3))
assert_equal(collect_warning_types(np.diag(a).__setitem__, 0, 10),
[DeprecationWarning])
[FutureWarning])
assert_equal(a, np.arange(9).reshape(3, 3))
# Views also warn
d = np.diagonal(a)
d_view = d.view()
assert_equal(collect_warning_types(d_view.__setitem__, 0, 10),
[DeprecationWarning])
[FutureWarning])
# But the write goes through:
assert_equal(d[0], 10)
# Only one warning per call to diagonal, though (even if there are
Expand All @@ -947,21 +947,21 @@ def get_data_and_write(getter):
buf_or_memoryview[0] = "x"
assert_equal(collect_warning_types(get_data_and_write,
lambda d: d.data),
[DeprecationWarning])
[FutureWarning])
if hasattr(np, "getbuffer"):
assert_equal(collect_warning_types(get_data_and_write,
np.getbuffer),
[DeprecationWarning])
[FutureWarning])
# PEP 3118:
if have_memoryview:
assert_equal(collect_warning_types(get_data_and_write, memoryview),
[DeprecationWarning])
[FutureWarning])
# Void dtypes can give us a read-write buffer, but only in Python 2:
import sys
if sys.version_info[0] < 3:
aV = np.empty((3, 3), dtype="V10")
assert_equal(collect_warning_types(aV.diagonal().item, 0),
[DeprecationWarning])
[FutureWarning])
# XX it seems that direct indexing of a void object returns a void
# scalar, which ignores not just WARN_ON_WRITE but even WRITEABLE.
# i.e. in this:
Expand All @@ -973,7 +973,7 @@ def get_data_and_write(getter):
# __array_interface also lets a data pointer get away from us
log = collect_warning_types(getattr, a.diagonal(),
"__array_interface__")
assert_equal(log, [DeprecationWarning])
assert_equal(log, [FutureWarning])
# ctypeslib goes via __array_interface__:
try:
# may not exist in python 2.4:
Expand All @@ -982,10 +982,10 @@ def get_data_and_write(getter):
pass
else:
log = collect_warning_types(np.ctypeslib.as_ctypes, a.diagonal())
assert_equal(log, [DeprecationWarning])
assert_equal(log, [FutureWarning])
# __array_struct__
log = collect_warning_types(getattr, a.diagonal(), "__array_struct__")
assert_equal(log, [DeprecationWarning])
assert_equal(log, [FutureWarning])

# Make sure that our recommendation to silence the warning by copying
# the array actually works:
Expand Down

0 comments on commit b798f12

Please sign in to comment.