summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2018-10-29 15:05:55 -0500
committerGitHub <noreply@github.com>2018-10-29 15:05:55 -0500
commite726c045c72833d5c826e8a13f889746ee0bfdf4 (patch)
treedc337946b0785d365ba23f4c7b7b22060b51d8be
parentb2b532081b4b7fc15f97ffedb30a975aef835137 (diff)
parent00640218fcbc5d71f22550a9368da92358c8de96 (diff)
downloadnumpy-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.py26
-rw-r--r--numpy/core/tests/test_shape_base.py21
-rw-r--r--numpy/lib/shape_base.py5
-rw-r--r--numpy/lib/tests/test_shape_base.py9
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