summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2016-06-10 08:07:10 -0600
committerGitHub <noreply@github.com>2016-06-10 08:07:10 -0600
commit5056c4cef5a320b2f30f5d89175e95eb4184dab1 (patch)
tree3107262825715f119c6f1d5f7351c2f3cec06453
parentd4a39b0f0e7d5b999b834b86f4beababe23e77f1 (diff)
parent5657a6cd5ed1c54986f697660c6336d2fb2b1c21 (diff)
downloadnumpy-5056c4cef5a320b2f30f5d89175e95eb4184dab1.tar.gz
Merge pull request #7719 from simongibbons/segfault_permutation
BUG: Fix segfault in np.random.shuffle for arrays of different length strings
-rw-r--r--numpy/random/mtrand/mtrand.pyx6
-rw-r--r--numpy/random/tests/test_regression.py29
2 files changed, 34 insertions, 1 deletions
diff --git a/numpy/random/mtrand/mtrand.pyx b/numpy/random/mtrand/mtrand.pyx
index f01aa6931..44ae956c8 100644
--- a/numpy/random/mtrand/mtrand.pyx
+++ b/numpy/random/mtrand/mtrand.pyx
@@ -5064,7 +5064,11 @@ cdef class RandomState:
x_ptr = <char*><size_t>x.ctypes.data
stride = x.strides[0]
itemsize = x.dtype.itemsize
- buf = np.empty_like(x[0]) # GC'd at function exit
+ # As the array x could contain python objects we use a buffer
+ # of bytes for the swaps to avoid leaving one of the objects
+ # within the buffer and erroneously decrementing it's refcount
+ # when the function exits.
+ buf = np.empty(itemsize, dtype=np.int8) # GC'd at function exit
buf_ptr = <char*><size_t>buf.ctypes.data
with self.lock:
# We trick gcc into providing a specialized implementation for
diff --git a/numpy/random/tests/test_regression.py b/numpy/random/tests/test_regression.py
index 133a1aa5a..b50b6b260 100644
--- a/numpy/random/tests/test_regression.py
+++ b/numpy/random/tests/test_regression.py
@@ -113,5 +113,34 @@ class TestRegression(TestCase):
assert_(c in a)
assert_raises(ValueError, np.random.choice, a, p=probs*0.9)
+ def test_shuffle_of_array_of_different_length_strings(self):
+ # Test that permuting an array of different length strings
+ # will not cause a segfault on garbage collection
+ # Tests gh-7710
+ np.random.seed(1234)
+
+ a = np.array(['a', 'a' * 1000])
+
+ for _ in range(100):
+ np.random.shuffle(a)
+
+ # Force Garbage Collection - should not segfault.
+ import gc
+ gc.collect()
+
+ def test_shuffle_of_array_of_objects(self):
+ # Test that permuting an array of objects will not cause
+ # a segfault on garbage collection.
+ # See gh-7719
+ np.random.seed(1234)
+ a = np.array([np.arange(1), np.arange(4)])
+
+ for _ in range(1000):
+ np.random.shuffle(a)
+
+ # Force Garbage Collection - should not segfault.
+ import gc
+ gc.collect()
+
if __name__ == "__main__":
run_module_suite()