Skip to content

Commit bed5ded

Browse files
committed
Improve CPython's gc_collect to accept optional condition for repeated GC runs; update tests to use it
Update relevant tests to use this conditional form for more reliable collection of weakly-referenced objects.
1 parent b031792 commit bed5ded

11 files changed

Lines changed: 25 additions & 17 deletions

File tree

graalpython/lib-python/3/test/_test_multiprocessing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5851,7 +5851,7 @@ def check_resource_tracker_death(self, signum, should_die):
58515851
# ensure `sem` gets collected, which triggers communication with
58525852
# the semaphore tracker
58535853
del sem
5854-
gc_collect()
5854+
gc_collect(lambda: wr())
58555855
self.assertIsNone(wr())
58565856
if should_die:
58575857
self.assertEqual(len(all_warn), 1)

graalpython/lib-python/3/test/support/__init__.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ def captured_stdin():
769769
return captured_output("stdin")
770770

771771

772-
def gc_collect():
772+
def gc_collect(until = None):
773773
"""Force as many objects as possible to be collected.
774774
775775
In non-CPython implementations of Python, this is needed because timely
@@ -784,9 +784,16 @@ def gc_collect():
784784
if is_graalpy:
785785
time.sleep(0.1)
786786
gc.collect()
787-
if is_graalpy:
788-
time.sleep(0.1)
789-
gc.collect()
787+
if until:
788+
i = 0
789+
while until():
790+
if is_graalpy:
791+
time.sleep(0.1)
792+
gc.collect()
793+
i += 1
794+
if i > 1000:
795+
print("WARNING: timeout while waiting for GC")
796+
break
790797

791798
@contextlib.contextmanager
792799
def disable_gc():

graalpython/lib-python/3/test/test_ast/test_ast.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class X:
9292
a.x.a = a
9393
ref = weakref.ref(a.x)
9494
del a
95-
support.gc_collect()
95+
support.gc_collect(lambda: ref())
9696
self.assertIsNone(ref())
9797

9898
def test_snippets(self):

graalpython/lib-python/3/test/test_concurrent_futures/executor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,5 +106,5 @@ def test_free_reference(self):
106106
for obj in self.executor.map(make_dummy_object, range(10)):
107107
wr = weakref.ref(obj)
108108
del obj
109-
support.gc_collect() # For PyPy or other GCs.
109+
support.gc_collect(wr()) # For PyPy or other GCs.
110110
self.assertIsNone(wr())

graalpython/lib-python/3/test/test_concurrent_futures/test_as_completed.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,15 @@ def test_free_reference_yielded_future(self):
8484
futures_list.remove(future)
8585
wr = weakref.ref(future)
8686
del future
87-
support.gc_collect() # For PyPy or other GCs.
87+
support.gc_collect(wr()) # For PyPy or other GCs.
8888
self.assertIsNone(wr())
8989

9090
futures_list[0].set_result("test")
9191
for future in futures.as_completed(futures_list):
9292
futures_list.remove(future)
9393
wr = weakref.ref(future)
9494
del future
95-
support.gc_collect() # For PyPy or other GCs.
95+
support.gc_collect(wr()) # For PyPy or other GCs.
9696
self.assertIsNone(wr())
9797
if futures_list:
9898
futures_list[0].set_result("test")

graalpython/lib-python/3/test/test_contextlib.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ def woohoo(a, b):
342342
a = weakref.ref(a)
343343
b = weakref.ref(b)
344344
# Allow test to work with a non-refcounted GC
345-
support.gc_collect()
345+
support.gc_collect(lambda: a() or b())
346346
self.assertIsNone(a())
347347
self.assertIsNone(b())
348348
yield

graalpython/lib-python/3/test/test_descr.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4898,7 +4898,7 @@ def __init__(self):
48984898
x.attr = 42
48994899
wr = weakref.ref(x)
49004900
del x
4901-
support.gc_collect()
4901+
support.gc_collect(lambda: wr())
49024902
self.assertIsNone(wr())
49034903
for o in gc.get_objects():
49044904
self.assertIsNot(type(o), X)

graalpython/lib-python/3/test/test_functools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1872,7 +1872,7 @@ def test_staticmethod(x):
18721872

18731873
del A
18741874
del test_function
1875-
support.gc_collect()
1875+
support.gc_collect(lambda: any([ref() for ref in refs]))
18761876

18771877
for ref in refs:
18781878
self.assertIsNone(ref())

graalpython/lib-python/3/test/test_importlib/test_locks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ def test_lock_lifetime(self):
136136
self.assertIn(name, self.bootstrap._module_locks)
137137
wr = weakref.ref(lock)
138138
del lock
139-
support.gc_collect()
139+
support.gc_collect(lambda: wr() or name in self.bootstrap._module_locks)
140140
self.assertNotIn(name, self.bootstrap._module_locks)
141141
self.assertIsNone(wr())
142142

graalpython/lib-python/3/test/test_memoryview.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import struct
1818

1919
from test.support import import_helper
20+
from test.support import gc_collect
2021

2122

2223
class MyObject:
@@ -688,7 +689,7 @@ def test_buffer_reference_loop(self):
688689
o.o = o
689690
wr = weakref.ref(o)
690691
del m, o
691-
gc.collect()
692+
gc_collect(lambda: wr())
692693
self.assertIsNone(wr())
693694

694695
def test_picklebuffer_reference_loop(self):
@@ -698,7 +699,7 @@ def test_picklebuffer_reference_loop(self):
698699
o.o = o
699700
wr = weakref.ref(o)
700701
del pb, o
701-
gc.collect()
702+
gc_collect(lambda: wr())
702703
self.assertIsNone(wr())
703704

704705

0 commit comments

Comments
 (0)