diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2018-10-29 15:05:55 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-29 15:05:55 -0500 |
commit | e726c045c72833d5c826e8a13f889746ee0bfdf4 (patch) | |
tree | dc337946b0785d365ba23f4c7b7b22060b51d8be | |
parent | b2b532081b4b7fc15f97ffedb30a975aef835137 (diff) | |
parent | 00640218fcbc5d71f22550a9368da92358c8de96 (diff) | |
download | numpy-e726c045c72833d5c826e8a13f889746ee0bfdf4.tar.gz |
Merge pull request #12280 from shoyer/stack-generator-warning
DEP: deprecate passing a generator to stack functions
-rw-r--r-- | numpy/core/shape_base.py | 26 | ||||
-rw-r--r-- | numpy/core/tests/test_shape_base.py | 21 | ||||
-rw-r--r-- | numpy/lib/shape_base.py | 5 | ||||
-rw-r--r-- | numpy/lib/tests/test_shape_base.py | 9 |
4 files changed, 49 insertions, 12 deletions
diff --git a/numpy/core/shape_base.py b/numpy/core/shape_base.py index 71a23f438..3edf0824e 100644 --- a/numpy/core/shape_base.py +++ b/numpy/core/shape_base.py @@ -5,6 +5,8 @@ __all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'block', 'hstack', import functools import operator +import types +import warnings from . import numeric as _nx from . import overrides @@ -204,11 +206,22 @@ def atleast_3d(*arys): return res -def _vstack_dispatcher(tup): - return tup +def _arrays_for_stack_dispatcher(arrays, stacklevel=4): + if not hasattr(arrays, '__getitem__') and hasattr(arrays, '__iter__'): + warnings.warn('arrays to stack must be passed as a "sequence" type ' + 'such as list or tuple. Support for non-sequence ' + 'iterables such as generators is deprecated as of ' + 'NumPy 1.16 and will raise an error in the future.', + FutureWarning, stacklevel=stacklevel) + return () + return arrays -@array_function_dispatch(_vstack_dispatcher) +def _vhstack_dispatcher(tup): + return _arrays_for_stack_dispatcher(tup) + + +@array_function_dispatch(_vhstack_dispatcher) def vstack(tup): """ Stack arrays in sequence vertically (row wise). @@ -264,11 +277,7 @@ def vstack(tup): return _nx.concatenate([atleast_2d(_m) for _m in tup], 0) -def _hstack_dispatcher(tup): - return tup - - -@array_function_dispatch(_hstack_dispatcher) +@array_function_dispatch(_vhstack_dispatcher) def hstack(tup): """ Stack arrays in sequence horizontally (column wise). @@ -325,6 +334,7 @@ def hstack(tup): def _stack_dispatcher(arrays, axis=None, out=None): + arrays = _arrays_for_stack_dispatcher(arrays, stacklevel=6) for a in arrays: yield a if out is not None: diff --git a/numpy/core/tests/test_shape_base.py b/numpy/core/tests/test_shape_base.py index 9bedd8670..b2c610da6 100644 --- a/numpy/core/tests/test_shape_base.py +++ b/numpy/core/tests/test_shape_base.py @@ -1,6 +1,7 @@ from __future__ import division, absolute_import, print_function import warnings +import sys import numpy as np from numpy.core import ( array, arange, atleast_1d, atleast_2d, atleast_3d, block, vstack, hstack, @@ -10,7 +11,7 @@ from numpy.core.shape_base import (_block_dispatcher, _block_setup, _block_concatenate, _block_slicing) from numpy.testing import ( assert_, assert_raises, assert_array_equal, assert_equal, - assert_raises_regex, assert_almost_equal + assert_raises_regex, assert_warns, assert_almost_equal ) from numpy.compat import long @@ -155,6 +156,14 @@ class TestHstack(object): desired = array([[1, 1], [2, 2]]) assert_array_equal(res, desired) + def test_generator(self): + with assert_warns(FutureWarning): + hstack((np.arange(3) for _ in range(2))) + if sys.version_info.major > 2: + # map returns a list on Python 2 + with assert_warns(FutureWarning): + hstack(map(lambda x: x, np.ones((3, 2)))) + class TestVstack(object): def test_non_iterable(self): @@ -191,6 +200,10 @@ class TestVstack(object): desired = array([[1, 2], [1, 2]]) assert_array_equal(res, desired) + def test_generator(self): + with assert_warns(FutureWarning): + vstack((np.arange(3) for _ in range(2))) + class TestConcatenate(object): def test_returns_copy(self): @@ -354,7 +367,7 @@ def test_stack(): arrays = [np.random.randn(3, 4) for _ in range(10)] axes = [0, 1, 2, -1, -2, -3] expected_shapes = [(10, 3, 4), (3, 10, 4), (3, 4, 10), - (3, 4, 10), (3, 10, 4), (10, 3, 4)] + (3, 4, 10), (3, 10, 4), (10, 3, 4)] for axis, expected_shape in zip(axes, expected_shapes): assert_equal(np.stack(arrays, axis).shape, expected_shape) # empty arrays @@ -372,6 +385,10 @@ def test_stack(): stack, [np.zeros((3, 3)), np.zeros(3)], axis=1) assert_raises_regex(ValueError, 'must have the same shape', stack, [np.arange(2), np.arange(3)]) + # generator is deprecated + with assert_warns(FutureWarning): + result = stack((x for x in range(3))) + assert_array_equal(result, np.array([0, 1, 2])) # See for more information on how to parametrize a whole class diff --git a/numpy/lib/shape_base.py b/numpy/lib/shape_base.py index 00424d55d..6e7cab3fa 100644 --- a/numpy/lib/shape_base.py +++ b/numpy/lib/shape_base.py @@ -11,6 +11,7 @@ from numpy.core.fromnumeric import product, reshape, transpose from numpy.core.multiarray import normalize_axis_index from numpy.core import overrides from numpy.core import vstack, atleast_3d +from numpy.core.shape_base import _arrays_for_stack_dispatcher from numpy.lib.index_tricks import ndindex from numpy.matrixlib.defmatrix import matrix # this raises all the right alarm bells @@ -591,7 +592,7 @@ row_stack = vstack def _column_stack_dispatcher(tup): - return tup + return _arrays_for_stack_dispatcher(tup) @array_function_dispatch(_column_stack_dispatcher) @@ -638,7 +639,7 @@ def column_stack(tup): def _dstack_dispatcher(tup): - return tup + return _arrays_for_stack_dispatcher(tup) @array_function_dispatch(_dstack_dispatcher) diff --git a/numpy/lib/tests/test_shape_base.py b/numpy/lib/tests/test_shape_base.py index a7f5ca7db..e338467f9 100644 --- a/numpy/lib/tests/test_shape_base.py +++ b/numpy/lib/tests/test_shape_base.py @@ -457,6 +457,7 @@ class TestSplit(object): a = np.arange(10) assert_raises(ValueError, split, a, 3) + class TestColumnStack(object): def test_non_iterable(self): assert_raises(TypeError, column_stack, 1) @@ -481,6 +482,10 @@ class TestColumnStack(object): actual = np.column_stack((a, b)) assert_equal(actual, expected) + def test_generator(self): + with assert_warns(FutureWarning): + column_stack((np.arange(3) for _ in range(2))) + class TestDstack(object): def test_non_iterable(self): @@ -514,6 +519,10 @@ class TestDstack(object): desired = np.array([[[1, 1], [2, 2]]]) assert_array_equal(res, desired) + def test_generator(self): + with assert_warns(FutureWarning): + dstack((np.arange(3) for _ in range(2))) + # array_split has more comprehensive test of splitting. # only do simple test on hsplit, vsplit, and dsplit |