summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Berg <sebastianb@nvidia.com>2022-10-27 12:58:59 +0200
committerCharles Harris <charlesr.harris@gmail.com>2022-10-28 06:52:40 -0600
commite3eb14a14a31cc3bafd4994d3e48ff283ca390e4 (patch)
tree5743fda3402af35d1432ad183f13b33d76523bdc
parente55d2d097940cec3a8172c4f8a5e007d0ee98b74 (diff)
downloadnumpy-e3eb14a14a31cc3bafd4994d3e48ff283ca390e4.tar.gz
TST: Make test_partial_iteration_cleanup robust but require leak checker
This makes sure the test is not flaky, but the test now requires a leak checker (both valgrind or reference count based should work in CPython at least). Closes gh-21169
-rw-r--r--numpy/core/tests/test_nditer.py22
1 files changed, 9 insertions, 13 deletions
diff --git a/numpy/core/tests/test_nditer.py b/numpy/core/tests/test_nditer.py
index b43bc50e9..a1ed3ab93 100644
--- a/numpy/core/tests/test_nditer.py
+++ b/numpy/core/tests/test_nditer.py
@@ -3130,7 +3130,6 @@ def test_warn_noclose():
@pytest.mark.skipif(sys.version_info[:2] == (3, 9) and sys.platform == "win32",
reason="Errors with Python 3.9 on Windows")
-@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
@pytest.mark.parametrize(["in_dtype", "buf_dtype"],
[("i", "O"), ("O", "i"), # most simple cases
("i,O", "O,O"), # structured partially only copying O
@@ -3138,9 +3137,14 @@ def test_warn_noclose():
])
@pytest.mark.parametrize("steps", [1, 2, 3])
def test_partial_iteration_cleanup(in_dtype, buf_dtype, steps):
- value = 123 # relies on python cache (leak-check will still find it)
+ """
+ Checks for reference counting leaks during cleanup. Using explicit
+ reference counts lead to occasional false positives (at least in parallel
+ test setups). This test now should still test leaks correctly when
+ run e.g. with pytest-valgrind or pytest-leaks
+ """
+ value = 2**30 + 1 # just a random value that Python won't intern
arr = np.full(int(np.BUFSIZE * 2.5), value).astype(in_dtype)
- count = sys.getrefcount(value)
it = np.nditer(arr, op_dtypes=[np.dtype(buf_dtype)],
flags=["buffered", "external_loop", "refs_ok"], casting="unsafe")
@@ -3148,11 +3152,7 @@ def test_partial_iteration_cleanup(in_dtype, buf_dtype, steps):
# The iteration finishes in 3 steps, the first two are partial
next(it)
- # Note that resetting does not free references
- del it
- break_cycles()
- break_cycles()
- assert count == sys.getrefcount(value)
+ del it # not necessary, but we test the cleanup
# Repeat the test with `iternext`
it = np.nditer(arr, op_dtypes=[np.dtype(buf_dtype)],
@@ -3160,11 +3160,7 @@ def test_partial_iteration_cleanup(in_dtype, buf_dtype, steps):
for step in range(steps):
it.iternext()
- del it # should ensure cleanup
- break_cycles()
- break_cycles()
- assert count == sys.getrefcount(value)
-
+ del it # not necessary, but we test the cleanup
@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
@pytest.mark.parametrize(["in_dtype", "buf_dtype"],