summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxwell Aladago <maxwell.aladago@gmail.com>2019-08-22 13:45:59 -0400
committerCharles Harris <charlesr.harris@gmail.com>2019-08-22 11:45:59 -0600
commit965ea2ff417bcb285beca5c36cd02a8790a3d8f6 (patch)
tree3d4622d6e96b834b10e0ff362b4725362912172d
parent99b7afc519ff4708ed3b66f288125a404efced2e (diff)
downloadnumpy-965ea2ff417bcb285beca5c36cd02a8790a3d8f6.tar.gz
BUG: Fix segfault in `random.permutation(x)` when x is a string. (#14241)
* fixing segfault error in np.random.permutation(x) where x is str * removed whitespace * changing error type to ValueError * changing error type to ValueError * changing error type to ValueError * tests * changed error to IndexError for backward compatibility with numpy 1.16 * fixes numpy.randomstate.permutation segfault too * Rolled back to ValueError for Generator.permutation() for all 0-dimensional * fixes refuige erro and rolls backs to AxisError
-rw-r--r--numpy/random/generator.pyx10
-rw-r--r--numpy/random/mtrand.pyx4
-rw-r--r--numpy/random/tests/test_generator_mt19937.py13
-rw-r--r--numpy/random/tests/test_randomstate.py15
4 files changed, 40 insertions, 2 deletions
diff --git a/numpy/random/generator.pyx b/numpy/random/generator.pyx
index c7432d8c1..26fd95129 100644
--- a/numpy/random/generator.pyx
+++ b/numpy/random/generator.pyx
@@ -3919,9 +3919,8 @@ cdef class Generator:
permutation(x)
Randomly permute a sequence, or return a permuted range.
-
If `x` is a multi-dimensional array, it is only shuffled along its
- first index.
+ first index.
Parameters
----------
@@ -3950,13 +3949,20 @@ cdef class Generator:
[0, 1, 2],
[3, 4, 5]])
+ >>> rng.permutation("abc")
+ Traceback (most recent call last):
+ ...
+ numpy.AxisError: x must be an integer or at least 1-dimensional
"""
+
if isinstance(x, (int, np.integer)):
arr = np.arange(x)
self.shuffle(arr)
return arr
arr = np.asarray(x)
+ if arr.ndim < 1:
+ raise np.AxisError("x must be an integer or at least 1-dimensional")
# shuffle has fast-path for 1-d
if arr.ndim == 1:
diff --git a/numpy/random/mtrand.pyx b/numpy/random/mtrand.pyx
index 46b6b3388..eb263cd2d 100644
--- a/numpy/random/mtrand.pyx
+++ b/numpy/random/mtrand.pyx
@@ -4134,6 +4134,7 @@ cdef class RandomState:
out : ndarray
Permuted sequence or array range.
+
Examples
--------
>>> np.random.permutation(10)
@@ -4149,12 +4150,15 @@ cdef class RandomState:
[3, 4, 5]])
"""
+
if isinstance(x, (int, np.integer)):
arr = np.arange(x)
self.shuffle(arr)
return arr
arr = np.asarray(x)
+ if arr.ndim < 1:
+ raise IndexError("x must be an integer or at least 1-dimensional")
# shuffle has fast-path for 1-d
if arr.ndim == 1:
diff --git a/numpy/random/tests/test_generator_mt19937.py b/numpy/random/tests/test_generator_mt19937.py
index a962fe84e..853d86fba 100644
--- a/numpy/random/tests/test_generator_mt19937.py
+++ b/numpy/random/tests/test_generator_mt19937.py
@@ -757,6 +757,19 @@ class TestRandomDist(object):
arr_2d = np.atleast_2d([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]).T
actual = random.permutation(arr_2d)
assert_array_equal(actual, np.atleast_2d(desired).T)
+
+ bad_x_str = "abcd"
+ assert_raises(np.AxisError, random.permutation, bad_x_str)
+
+ bad_x_float = 1.2
+ assert_raises(np.AxisError, random.permutation, bad_x_float)
+
+ random = Generator(MT19937(self.seed))
+ integer_val = 10
+ desired = [3, 0, 8, 7, 9, 4, 2, 5, 1, 6]
+
+ actual = random.permutation(integer_val)
+ assert_array_equal(actual, desired)
def test_beta(self):
random = Generator(MT19937(self.seed))
diff --git a/numpy/random/tests/test_randomstate.py b/numpy/random/tests/test_randomstate.py
index 3b5a279a3..a0edc5c23 100644
--- a/numpy/random/tests/test_randomstate.py
+++ b/numpy/random/tests/test_randomstate.py
@@ -686,6 +686,21 @@ class TestRandomDist(object):
actual = random.permutation(arr_2d)
assert_array_equal(actual, np.atleast_2d(desired).T)
+ random.seed(self.seed)
+ bad_x_str = "abcd"
+ assert_raises(IndexError, random.permutation, bad_x_str)
+
+ random.seed(self.seed)
+ bad_x_float = 1.2
+ assert_raises(IndexError, random.permutation, bad_x_float)
+
+ integer_val = 10
+ desired = [9, 0, 8, 5, 1, 3, 4, 7, 6, 2]
+
+ random.seed(self.seed)
+ actual = random.permutation(integer_val)
+ assert_array_equal(actual, desired)
+
def test_beta(self):
random.seed(self.seed)
actual = random.beta(.1, .9, size=(3, 2))