From 59ebfbbe32bcac4a278c39a9a24b80a42d47a8f6 Mon Sep 17 00:00:00 2001 From: Matti Picus Date: Fri, 28 Jun 2019 18:27:42 -0700 Subject: ENH: Deprecate writeable broadcast_array (#12609) When the base is not an array (or generally when the flag of the base array was toggled), it is OK to allow setting the writeable flag to True, as long as any ancestor (especially the last one) is writeable. This commit also slightly change the behaviour of the base attribute. --- * ENH: Deprecate writeable broadcast_array * ENH: Make writeable flag enabling more reliable for non-array bases When the base is not an array (or generally when the flag of the base array was toggled), it is OK to allow setting the writeable flag to True, as long as any ancestor (especially the last one) is writeable. * Update doc/release/1.17.0-notes.rst Co-Authored-By: Sebastian Berg * Update doc/release/1.17.0-notes.rst Co-Authored-By: Sebastian Berg * Update numpy/lib/tests/test_stride_tricks.py Co-Authored-By: Sebastian Berg * Update numpy/core/tests/test_multiarray.py Co-Authored-By: Sebastian Berg * DOC: improve warning (from review) --- numpy/lib/tests/test_stride_tricks.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'numpy/lib/tests/test_stride_tricks.py') diff --git a/numpy/lib/tests/test_stride_tricks.py b/numpy/lib/tests/test_stride_tricks.py index b2bd7da3e..955fb914c 100644 --- a/numpy/lib/tests/test_stride_tricks.py +++ b/numpy/lib/tests/test_stride_tricks.py @@ -4,7 +4,7 @@ import numpy as np from numpy.core._rational_tests import rational from numpy.testing import ( assert_equal, assert_array_equal, assert_raises, assert_, - assert_raises_regex + assert_raises_regex, assert_warns, ) from numpy.lib.stride_tricks import ( as_strided, broadcast_arrays, _broadcast_shape, broadcast_to @@ -415,12 +415,28 @@ def test_writeable(): assert_equal(result.flags.writeable, False) assert_raises(ValueError, result.__setitem__, slice(None), 0) - # but the result of broadcast_arrays needs to be writeable (for now), to + # but the result of broadcast_arrays needs to be writeable, to # preserve backwards compatibility for results in [broadcast_arrays(original), broadcast_arrays(0, original)]: for result in results: + # This will change to False in a future version + if any([s == 0 for s in result.strides]): + with assert_warns(FutureWarning): + assert_equal(result.flags.writeable, True) + with assert_warns(DeprecationWarning): + result[:] = 0 + # Warning not emitted, writing to the array resets it + assert_equal(result.flags.writeable, True) + for results in [broadcast_arrays(original), + broadcast_arrays(0, original)]: + for result in results: + # resets the warn_on_write DeprecationWarning + result.flags.writeable = True + # check: no warning emitted assert_equal(result.flags.writeable, True) + result[:] = 0 + # keep readonly input readonly original.flags.writeable = False _, result = broadcast_arrays(0, original) -- cgit v1.2.1 From 81cfd4726c2d441406b3f7bd78716d664377fee2 Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Mon, 8 Jul 2019 13:18:44 -0700 Subject: DEP: Speed up WarnOnWrite deprecation in buffer interface When a buffer interface does not request a writeable buffer, simply pass a read-only one when the warn on write flag is set. This is to give an easier way forward with avoiding the deprecation warnings: Simply do not ask for a writeable buffer. It will break code that expects writeable buffers but does not ask for them specifically a bit harder than would be nice. But since such code probably should ask for it specifically, this is likely fine (an RC release has to find out). The main reason for this is, that this way it plays very will with cython, which requests writeable buffers explicitly and if declared `const` is happy about read-only (so that using `const` is the best way to avoid the warning and makes code cleaner). Closes gh-13929, gh-13974 --- numpy/lib/tests/test_stride_tricks.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'numpy/lib/tests/test_stride_tricks.py') diff --git a/numpy/lib/tests/test_stride_tricks.py b/numpy/lib/tests/test_stride_tricks.py index 955fb914c..85fcceedc 100644 --- a/numpy/lib/tests/test_stride_tricks.py +++ b/numpy/lib/tests/test_stride_tricks.py @@ -417,17 +417,21 @@ def test_writeable(): # but the result of broadcast_arrays needs to be writeable, to # preserve backwards compatibility - for results in [broadcast_arrays(original), - broadcast_arrays(0, original)]: + for is_broadcast, results in [(False, broadcast_arrays(original,)), + (True, broadcast_arrays(0, original))]: for result in results: # This will change to False in a future version - if any([s == 0 for s in result.strides]): + if is_broadcast: with assert_warns(FutureWarning): assert_equal(result.flags.writeable, True) with assert_warns(DeprecationWarning): result[:] = 0 # Warning not emitted, writing to the array resets it assert_equal(result.flags.writeable, True) + else: + # No warning: + assert_equal(result.flags.writeable, True) + for results in [broadcast_arrays(original), broadcast_arrays(0, original)]: for result in results: @@ -451,6 +455,25 @@ def test_writeable(): assert_(first.shape == second.shape) +def test_writeable_memoryview(): + # The result of broadcast_arrays exports as a non-writeable memoryview + # because otherwise there is no good way to opt in to the new behaviour + # (i.e. you would need to set writeable to False explicitly). + # See gh-13929. + original = np.array([1, 2, 3]) + + for is_broadcast, results in [(False, broadcast_arrays(original,)), + (True, broadcast_arrays(0, original))]: + for result in results: + # This will change to False in a future version + if is_broadcast: + # memoryview(result, writable=True) will give warning but cannot + # be tested using the python API. + assert memoryview(result).readonly + else: + assert not memoryview(result).readonly + + def test_reference_types(): input_array = np.array('a', dtype=object) expected = np.array(['a'] * 3, dtype=object) -- cgit v1.2.1