summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattip <matti.picus@gmail.com>2019-04-17 11:33:54 +0300
committermattip <matti.picus@gmail.com>2019-04-19 13:01:04 +0300
commita641ef245a9f8d320fac5cdea5632649db5fab4a (patch)
tree371e90fb57ee3edad90f313c1cb0769a8ba730c4
parente67f8c7f78291cec03de944ed121d3e0f2a89c36 (diff)
downloadnumpy-a641ef245a9f8d320fac5cdea5632649db5fab4a.tar.gz
MAINT: move gc.collect to function (from review)
-rw-r--r--numpy/core/tests/test_multiarray.py16
-rw-r--r--numpy/testing/_private/utils.py20
-rwxr-xr-xtools/pypy-test.sh4
3 files changed, 31 insertions, 9 deletions
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 5bab992fa..b29daa675 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -36,7 +36,7 @@ from numpy.testing import (
assert_, assert_raises, assert_warns, assert_equal, assert_almost_equal,
assert_array_equal, assert_raises_regex, assert_array_almost_equal,
assert_allclose, IS_PYPY, HAS_REFCOUNT, assert_array_less, runstring,
- temppath, suppress_warnings
+ temppath, suppress_warnings, break_cycles,
)
from numpy.core.tests._locales import CommaDecimalPointLocale
@@ -3784,7 +3784,7 @@ class TestPickling(object):
a, pickle.loads(pickle.dumps(a, protocol=proto)),
err_msg="%r" % a)
del a, DATA, carray
- gc.collect(); gc.collect(); gc.collect()
+ break_cycles()
# check for reference leaks (gh-12793)
for ref in refs:
assert ref() is None
@@ -7181,7 +7181,7 @@ class TestMemEventHook(object):
# needs to be larger then limit of small memory cacher in ctors.c
a = np.zeros(1000)
del a
- gc.collect(); gc.collect(); gc.collect()
+ break_cycles()
_multiarray_tests.test_pydatamem_seteventhook_end()
class TestMapIter(object):
@@ -7753,12 +7753,12 @@ class TestCTypes(object):
# `ctypes_ptr` should hold onto `arr`
del arr
- gc.collect(); gc.collect(); gc.collect()
+ break_cycles()
assert_(arr_ref() is not None, "ctypes pointer did not hold onto a reference")
# but when the `ctypes_ptr` object dies, so should `arr`
del ctypes_ptr
- gc.collect(); gc.collect(); gc.collect()
+ break_cycles()
assert_(arr_ref() is None, "unknowable whether ctypes pointer holds a reference")
@@ -7940,15 +7940,15 @@ class TestArrayFinalize(object):
assert_(isinstance(obj_subarray, RaisesInFinalize))
# reference should still be held by obj_arr
- gc.collect(); gc.collect(); gc.collect()
+ break_cycles()
assert_(obj_ref() is not None, "object should not already be dead")
del obj_arr
- gc.collect(); gc.collect(); gc.collect()
+ break_cycles()
assert_(obj_ref() is not None, "obj_arr should not hold the last reference")
del obj_subarray
- gc.collect(); gc.collect(); gc.collect()
+ break_cycles()
assert_(obj_ref() is None, "no references should remain")
diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py
index 3ace84415..24e26d65c 100644
--- a/numpy/testing/_private/utils.py
+++ b/numpy/testing/_private/utils.py
@@ -6,6 +6,7 @@ from __future__ import division, absolute_import, print_function
import os
import sys
+import platform
import re
import gc
import operator
@@ -39,6 +40,7 @@ __all__ = [
'SkipTest', 'KnownFailureException', 'temppath', 'tempdir', 'IS_PYPY',
'HAS_REFCOUNT', 'suppress_warnings', 'assert_array_compare',
'_assert_valid_refcount', '_gen_alignment_data', 'assert_no_gc_cycles',
+ 'break_cycles',
]
@@ -50,7 +52,7 @@ class KnownFailureException(Exception):
KnownFailureTest = KnownFailureException # backwards compat
verbose = 0
-IS_PYPY = '__pypy__' in sys.modules
+IS_PYPY = platform.python_implementation() == 'PyPy'
HAS_REFCOUNT = getattr(sys, 'getrefcount', None) is not None
@@ -2324,3 +2326,19 @@ def assert_no_gc_cycles(*args, **kwargs):
args = args[1:]
with _assert_no_gc_cycles_context(name=func.__name__):
func(*args, **kwargs)
+
+def break_cycles():
+ """
+ Break reference cycles by calling gc.collect
+ Objects can call other objects' methods (for instance, another object's
+ __del__) inside their own __del__. On PyPy, the interpreter only runs
+ between calls to gc.collect, so multiple calls are needed to completely
+ release all cycles.
+ """
+
+ gc.collect()
+ if IS_PYPY:
+ # interpreter runs now, to call deleted objects' __del__ methods
+ gc.collect()
+ # one more, just to make sure
+ gc.collect()
diff --git a/tools/pypy-test.sh b/tools/pypy-test.sh
index bcadc1d6d..3dd3b439f 100755
--- a/tools/pypy-test.sh
+++ b/tools/pypy-test.sh
@@ -8,4 +8,8 @@ mkdir -p pypy3
pypy3/bin/pypy3 -mensurepip
pypy3/bin/pypy3 -m pip install --upgrade pip setuptools
pypy3/bin/pypy3 -m pip install --user cython==0.29.0 pytest pytz --no-warn-script-location
+echo
+echo pypy3 version
+pypy3/bin/pypy3 -c "import sys; print(sys.version)"
+echo
pypy3/bin/pypy3 runtests.py -- -rsx --junitxml=junit/test-results.xml --durations 10