[3.9] bpo-25130: Add calls of gc.collect() in tests to support PyPy (GH-28005). (GH-28028)

(cherry picked from commit 2a8127cafe)
This commit is contained in:
Serhiy Storchaka 2021-08-29 15:08:32 +03:00 committed by GitHub
parent dab74d68e3
commit 330aabbbbe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 143 additions and 15 deletions

View file

@ -607,6 +607,7 @@ def test_lose_target_ref(self):
del c del c
p.start() p.start()
p.join() p.join()
gc.collect() # For PyPy or other GCs.
self.assertIs(wr(), None) self.assertIs(wr(), None)
self.assertEqual(q.get(), 5) self.assertEqual(q.get(), 5)
close_queue(q) close_queue(q)
@ -2663,6 +2664,7 @@ def test_release_task_refs(self):
self.pool.map(identity, objs) self.pool.map(identity, objs)
del objs del objs
gc.collect() # For PyPy or other GCs.
time.sleep(DELTA) # let threaded cleanup code run time.sleep(DELTA) # let threaded cleanup code run
self.assertEqual(set(wr() for wr in refs), {None}) self.assertEqual(set(wr() for wr in refs), {None})
# With a process pool, copies of the objects are returned, check # With a process pool, copies of the objects are returned, check
@ -4165,6 +4167,7 @@ def setUp(self):
util._finalizer_registry.clear() util._finalizer_registry.clear()
def tearDown(self): def tearDown(self):
gc.collect() # For PyPy or other GCs.
self.assertFalse(util._finalizer_registry) self.assertFalse(util._finalizer_registry)
util._finalizer_registry.update(self.registry_backup) util._finalizer_registry.update(self.registry_backup)
@ -4176,12 +4179,14 @@ class Foo(object):
a = Foo() a = Foo()
util.Finalize(a, conn.send, args=('a',)) util.Finalize(a, conn.send, args=('a',))
del a # triggers callback for a del a # triggers callback for a
gc.collect() # For PyPy or other GCs.
b = Foo() b = Foo()
close_b = util.Finalize(b, conn.send, args=('b',)) close_b = util.Finalize(b, conn.send, args=('b',))
close_b() # triggers callback for b close_b() # triggers callback for b
close_b() # does nothing because callback has already been called close_b() # does nothing because callback has already been called
del b # does nothing because callback has already been called del b # does nothing because callback has already been called
gc.collect() # For PyPy or other GCs.
c = Foo() c = Foo()
util.Finalize(c, conn.send, args=('c',)) util.Finalize(c, conn.send, args=('c',))

View file

@ -3,6 +3,7 @@
""" """
import os import os
import gc
import sys import sys
import time import time
from _thread import start_new_thread, TIMEOUT_MAX from _thread import start_new_thread, TIMEOUT_MAX
@ -220,6 +221,7 @@ def test_weakref_deleted(self):
lock = self.locktype() lock = self.locktype()
ref = weakref.ref(lock) ref = weakref.ref(lock)
del lock del lock
gc.collect() # For PyPy or other GCs.
self.assertIsNone(ref()) self.assertIsNone(ref())

1
Lib/test/test_array.py Normal file → Executable file
View file

@ -1006,6 +1006,7 @@ def test_weakref(self):
p = weakref.proxy(s) p = weakref.proxy(s)
self.assertEqual(p.tobytes(), s.tobytes()) self.assertEqual(p.tobytes(), s.tobytes())
s = None s = None
support.gc_collect() # For PyPy or other GCs.
self.assertRaises(ReferenceError, len, p) self.assertRaises(ReferenceError, len, p)
@unittest.skipUnless(hasattr(sys, 'getrefcount'), @unittest.skipUnless(hasattr(sys, 'getrefcount'),

View file

@ -3,6 +3,7 @@
import unittest import unittest
from test.support import import_module from test.support import import_module
from test.support import gc_collect
asyncio = import_module("asyncio") asyncio = import_module("asyncio")
@ -659,6 +660,7 @@ async def run():
await g.__anext__() await g.__anext__()
await g.__anext__() await g.__anext__()
del g del g
gc_collect() # For PyPy or other GCs.
await asyncio.sleep(0.1) await asyncio.sleep(0.1)

View file

@ -2611,6 +2611,7 @@ def coro():
self.new_task(self.loop, gen) self.new_task(self.loop, gen)
finally: finally:
gen.close() gen.close()
gc.collect() # For PyPy or other GCs.
self.assertTrue(m_log.error.called) self.assertTrue(m_log.error.called)
message = m_log.error.call_args[0][0] message = m_log.error.call_args[0][0]

View file

@ -135,7 +135,7 @@
except ImportError: except ImportError:
ctypes = None ctypes = None
from test.support import (run_doctest, run_unittest, cpython_only, from test.support import (run_doctest, run_unittest, cpython_only,
check_impl_detail) check_impl_detail, gc_collect)
def consts(t): def consts(t):
@ -337,6 +337,7 @@ def callback(code):
coderef = weakref.ref(f.__code__, callback) coderef = weakref.ref(f.__code__, callback)
self.assertTrue(bool(coderef())) self.assertTrue(bool(coderef()))
del f del f
gc_collect() # For PyPy or other GCs.
self.assertFalse(bool(coderef())) self.assertFalse(bool(coderef()))
self.assertTrue(self.called) self.assertTrue(self.called)

View file

@ -448,6 +448,7 @@ def test_thread_names_assigned(self):
executor.map(abs, range(-5, 5)) executor.map(abs, range(-5, 5))
threads = executor._threads threads = executor._threads
del executor del executor
support.gc_collect() # For PyPy or other GCs.
for t in threads: for t in threads:
self.assertRegex(t.name, r'^SpecialPool_[0-4]$') self.assertRegex(t.name, r'^SpecialPool_[0-4]$')
@ -458,6 +459,7 @@ def test_thread_names_default(self):
executor.map(abs, range(-5, 5)) executor.map(abs, range(-5, 5))
threads = executor._threads threads = executor._threads
del executor del executor
support.gc_collect() # For PyPy or other GCs.
for t in threads: for t in threads:
# Ensure that our default name is reasonably sane and unique when # Ensure that our default name is reasonably sane and unique when
@ -520,6 +522,7 @@ def test_del_shutdown(self):
call_queue = executor._call_queue call_queue = executor._call_queue
executor_manager_thread = executor._executor_manager_thread executor_manager_thread = executor._executor_manager_thread
del executor del executor
support.gc_collect() # For PyPy or other GCs.
# Make sure that all the executor resources were properly cleaned by # Make sure that all the executor resources were properly cleaned by
# the shutdown process # the shutdown process
@ -744,6 +747,7 @@ def test_free_reference_yielded_future(self):
futures_list.remove(future) futures_list.remove(future)
wr = weakref.ref(future) wr = weakref.ref(future)
del future del future
support.gc_collect() # For PyPy or other GCs.
self.assertIsNone(wr()) self.assertIsNone(wr())
futures_list[0].set_result("test") futures_list[0].set_result("test")
@ -751,6 +755,7 @@ def test_free_reference_yielded_future(self):
futures_list.remove(future) futures_list.remove(future)
wr = weakref.ref(future) wr = weakref.ref(future)
del future del future
support.gc_collect() # For PyPy or other GCs.
self.assertIsNone(wr()) self.assertIsNone(wr())
if futures_list: if futures_list:
futures_list[0].set_result("test") futures_list[0].set_result("test")
@ -850,6 +855,7 @@ def test_free_reference(self):
for obj in self.executor.map(make_dummy_object, range(10)): for obj in self.executor.map(make_dummy_object, range(10)):
wr = weakref.ref(obj) wr = weakref.ref(obj)
del obj del obj
support.gc_collect() # For PyPy or other GCs.
self.assertIsNone(wr()) self.assertIsNone(wr())

View file

@ -7,6 +7,7 @@
from operator import le, lt, ge, gt, eq, ne from operator import le, lt, ge, gt, eq, ne
import unittest import unittest
from test import support
order_comparisons = le, lt, ge, gt order_comparisons = le, lt, ge, gt
equality_comparisons = eq, ne equality_comparisons = eq, ne
@ -816,6 +817,7 @@ class C(object):
self.assertEqual(v[c], d) self.assertEqual(v[c], d)
self.assertEqual(len(v), 2) self.assertEqual(len(v), 2)
del c, d del c, d
support.gc_collect() # For PyPy or other GCs.
self.assertEqual(len(v), 1) self.assertEqual(len(v), 1)
x, y = C(), C() x, y = C(), C()
# The underlying containers are decoupled # The underlying containers are decoupled
@ -845,6 +847,7 @@ def __init__(self, i):
self.assertEqual(v[a].i, b.i) self.assertEqual(v[a].i, b.i)
self.assertEqual(v[c].i, d.i) self.assertEqual(v[c].i, d.i)
del c del c
support.gc_collect() # For PyPy or other GCs.
self.assertEqual(len(v), 1) self.assertEqual(len(v), 1)
def test_deepcopy_weakvaluedict(self): def test_deepcopy_weakvaluedict(self):
@ -868,6 +871,7 @@ def __init__(self, i):
self.assertIs(t, d) self.assertIs(t, d)
del x, y, z, t del x, y, z, t
del d del d
support.gc_collect() # For PyPy or other GCs.
self.assertEqual(len(v), 1) self.assertEqual(len(v), 1)
def test_deepcopy_bound_method(self): def test_deepcopy_bound_method(self):

View file

@ -902,6 +902,7 @@ def test_weakref(self):
p = weakref.proxy(d) p = weakref.proxy(d)
self.assertEqual(str(p), str(d)) self.assertEqual(str(p), str(d))
d = None d = None
support.gc_collect() # For PyPy or other GCs.
self.assertRaises(ReferenceError, str, p) self.assertRaises(ReferenceError, str, p)
def test_strange_subclass(self): def test_strange_subclass(self):

View file

@ -1934,6 +1934,7 @@ def _missing_(cls, item):
raise Exception('Exception not raised.') raise Exception('Exception not raised.')
def test_missing_exceptions_reset(self): def test_missing_exceptions_reset(self):
import gc
import weakref import weakref
# #
class TestEnum(enum.Enum): class TestEnum(enum.Enum):
@ -1960,8 +1961,9 @@ def __init__(self):
class_2_ref = weakref.ref(Class2()) class_2_ref = weakref.ref(Class2())
# #
# The exception raised by Enum creates a reference loop and thus # The exception raised by Enum creates a reference loop and thus
# Class2 instances will stick around until the next gargage collection # Class2 instances will stick around until the next garbage collection
# cycle, unlike Class1. # cycle, unlike Class1.
gc.collect() # For PyPy or other GCs.
self.assertIs(class_1_ref(), None) self.assertIs(class_1_ref(), None)
self.assertIs(class_2_ref(), None) self.assertIs(class_2_ref(), None)

View file

@ -627,6 +627,7 @@ def inner_raising_func():
except MyException as e: except MyException as e:
pass pass
obj = None obj = None
gc_collect() # For PyPy or other GCs.
obj = wr() obj = wr()
self.assertIsNone(obj) self.assertIsNone(obj)
@ -638,6 +639,7 @@ def inner_raising_func():
except MyException: except MyException:
pass pass
obj = None obj = None
gc_collect() # For PyPy or other GCs.
obj = wr() obj = wr()
self.assertIsNone(obj) self.assertIsNone(obj)
@ -649,6 +651,7 @@ def inner_raising_func():
except: except:
pass pass
obj = None obj = None
gc_collect() # For PyPy or other GCs.
obj = wr() obj = wr()
self.assertIsNone(obj) self.assertIsNone(obj)
@ -661,6 +664,7 @@ def inner_raising_func():
except: except:
break break
obj = None obj = None
gc_collect() # For PyPy or other GCs.
obj = wr() obj = wr()
self.assertIsNone(obj) self.assertIsNone(obj)
@ -679,6 +683,7 @@ def inner_raising_func():
# must clear the latter manually for our test to succeed. # must clear the latter manually for our test to succeed.
e.__context__ = None e.__context__ = None
obj = None obj = None
gc_collect() # For PyPy or other GCs.
obj = wr() obj = wr()
# guarantee no ref cycles on CPython (don't gc_collect) # guarantee no ref cycles on CPython (don't gc_collect)
if check_impl_detail(cpython=False): if check_impl_detail(cpython=False):
@ -869,6 +874,7 @@ def raising_gen():
next(g) next(g)
testfunc(g) testfunc(g)
g = obj = None g = obj = None
gc_collect() # For PyPy or other GCs.
obj = wr() obj = wr()
self.assertIsNone(obj) self.assertIsNone(obj)
@ -922,6 +928,7 @@ def __del__(self):
raise Exception(MyObject()) raise Exception(MyObject())
except: except:
pass pass
gc_collect() # For PyPy or other GCs.
self.assertEqual(e, (None, None, None)) self.assertEqual(e, (None, None, None))
def test_raise_does_not_create_context_chain_cycle(self): def test_raise_does_not_create_context_chain_cycle(self):
@ -1335,6 +1342,7 @@ def inner():
self.assertNotEqual(wr(), None) self.assertNotEqual(wr(), None)
else: else:
self.fail("MemoryError not raised") self.fail("MemoryError not raised")
gc_collect() # For PyPy or other GCs.
self.assertEqual(wr(), None) self.assertEqual(wr(), None)
@no_tracing @no_tracing
@ -1355,6 +1363,7 @@ def inner():
self.assertNotEqual(wr(), None) self.assertNotEqual(wr(), None)
else: else:
self.fail("RecursionError not raised") self.fail("RecursionError not raised")
gc_collect() # For PyPy or other GCs.
self.assertEqual(wr(), None) self.assertEqual(wr(), None)
def test_errno_ENOTDIR(self): def test_errno_ENOTDIR(self):
@ -1375,6 +1384,7 @@ def __del__(self):
with support.catch_unraisable_exception() as cm: with support.catch_unraisable_exception() as cm:
del obj del obj
gc_collect() # For PyPy or other GCs.
self.assertEqual(cm.unraisable.object, BrokenDel.__del__) self.assertEqual(cm.unraisable.object, BrokenDel.__del__)
self.assertIsNotNone(cm.unraisable.exc_traceback) self.assertIsNotNone(cm.unraisable.exc_traceback)

View file

@ -7,7 +7,7 @@
import io import io
import _pyio as pyio import _pyio as pyio
from test.support import TESTFN from test.support import TESTFN, gc_collect
from test import support from test import support
from collections import UserList from collections import UserList
@ -29,6 +29,7 @@ def testWeakRefs(self):
self.assertEqual(self.f.tell(), p.tell()) self.assertEqual(self.f.tell(), p.tell())
self.f.close() self.f.close()
self.f = None self.f = None
gc_collect() # For PyPy or other GCs.
self.assertRaises(ReferenceError, getattr, p, 'tell') self.assertRaises(ReferenceError, getattr, p, 'tell')
def testAttributes(self): def testAttributes(self):

View file

@ -10,7 +10,7 @@
from functools import wraps from functools import wraps
from test.support import (TESTFN, TESTFN_UNICODE, check_warnings, run_unittest, from test.support import (TESTFN, TESTFN_UNICODE, check_warnings, run_unittest,
make_bad_fd, cpython_only, swap_attr) make_bad_fd, cpython_only, swap_attr, gc_collect)
from collections import UserList from collections import UserList
import _io # C implementation of io import _io # C implementation of io
@ -35,6 +35,7 @@ def testWeakRefs(self):
self.assertEqual(self.f.tell(), p.tell()) self.assertEqual(self.f.tell(), p.tell())
self.f.close() self.f.close()
self.f = None self.f = None
gc_collect() # For PyPy or other GCs.
self.assertRaises(ReferenceError, getattr, p, 'tell') self.assertRaises(ReferenceError, getattr, p, 'tell')
def testSeekTell(self): def testSeekTell(self):

View file

@ -164,6 +164,7 @@ def test_weakref(self):
p = proxy(f) p = proxy(f)
self.assertEqual(f.func, p.func) self.assertEqual(f.func, p.func)
f = None f = None
support.gc_collect() # For PyPy or other GCs.
self.assertRaises(ReferenceError, getattr, p, 'func') self.assertRaises(ReferenceError, getattr, p, 'func')
def test_with_bound_and_unbound_methods(self): def test_with_bound_and_unbound_methods(self):

View file

@ -1966,6 +1966,8 @@ def printsolution(self, x):
""" """
coroutine_tests = """\ coroutine_tests = """\
>>> from test.support import gc_collect
Sending a value into a started generator: Sending a value into a started generator:
>>> def f(): >>> def f():
@ -2189,7 +2191,7 @@ def printsolution(self, x):
>>> g = f() >>> g = f()
>>> next(g) >>> next(g)
>>> del g >>> del g; gc_collect() # For PyPy or other GCs.
exiting exiting
@ -2204,7 +2206,7 @@ def printsolution(self, x):
>>> g = f() >>> g = f()
>>> next(g) >>> next(g)
>>> del g >>> del g; gc_collect() # For PyPy or other GCs.
finally finally

View file

@ -4310,6 +4310,31 @@ def check_interrupted_write(self, item, bytes, **fdopen_kwargs):
"""Check that a partial write, when it gets interrupted, properly """Check that a partial write, when it gets interrupted, properly
invokes the signal handler, and bubbles up the exception raised invokes the signal handler, and bubbles up the exception raised
in the latter.""" in the latter."""
# XXX This test has three flaws that appear when objects are
# XXX not reference counted.
# - if wio.write() happens to trigger a garbage collection,
# the signal exception may be raised when some __del__
# method is running; it will not reach the assertRaises()
# call.
# - more subtle, if the wio object is not destroyed at once
# and survives this function, the next opened file is likely
# to have the same fileno (since the file descriptor was
# actively closed). When wio.__del__ is finally called, it
# will close the other's test file... To trigger this with
# CPython, try adding "global wio" in this function.
# - This happens only for streams created by the _pyio module,
# because a wio.close() that fails still consider that the
# file needs to be closed again. You can try adding an
# "assert wio.closed" at the end of the function.
# Fortunately, a little gc.collect() seems to be enough to
# work around all these issues.
support.gc_collect() # For PyPy or other GCs.
read_results = [] read_results = []
def _read(): def _read():
s = os.read(r, 1) s = os.read(r, 1)

View file

@ -1423,6 +1423,7 @@ def test_tee(self):
p = weakref.proxy(a) p = weakref.proxy(a)
self.assertEqual(getattr(p, '__class__'), type(b)) self.assertEqual(getattr(p, '__class__'), type(b))
del a del a
support.gc_collect() # For PyPy or other GCs.
self.assertRaises(ReferenceError, getattr, p, '__class__') self.assertRaises(ReferenceError, getattr, p, '__class__')
ans = list('abc') ans = list('abc')

View file

@ -7,6 +7,7 @@
import unittest import unittest
import weakref import weakref
from test import support from test import support
from test.support import gc_collect
py_queue = support.import_fresh_module('queue', blocked=['_queue']) py_queue = support.import_fresh_module('queue', blocked=['_queue'])
c_queue = support.import_fresh_module('queue', fresh=['_queue']) c_queue = support.import_fresh_module('queue', fresh=['_queue'])
@ -588,6 +589,7 @@ class C:
q.put(C()) q.put(C())
for i in range(N): for i in range(N):
wr = weakref.ref(q.get()) wr = weakref.ref(q.get())
gc_collect() # For PyPy or other GCs.
self.assertIsNone(wr()) self.assertIsNone(wr())

View file

@ -438,6 +438,7 @@ def f():
f() f()
def test_3611(self): def test_3611(self):
import gc
# A re-raised exception in a __del__ caused the __context__ # A re-raised exception in a __del__ caused the __context__
# to be cleared # to be cleared
class C: class C:
@ -451,9 +452,11 @@ def f():
x = C() x = C()
try: try:
try: try:
x.x f.x
except AttributeError: except AttributeError:
# make x.__del__ trigger
del x del x
gc.collect() # For PyPy or other GCs.
raise TypeError raise TypeError
except Exception as e: except Exception as e:
self.assertNotEqual(e.__context__, None) self.assertNotEqual(e.__context__, None)

View file

@ -2,6 +2,7 @@
import weakref import weakref
from test.support import check_syntax_error, cpython_only from test.support import check_syntax_error, cpython_only
from test.support import gc_collect
class ScopeTests(unittest.TestCase): class ScopeTests(unittest.TestCase):
@ -422,6 +423,7 @@ def f2():
for i in range(100): for i in range(100):
f1() f1()
gc_collect() # For PyPy or other GCs.
self.assertEqual(Foo.count, 0) self.assertEqual(Foo.count, 0)
def testClassAndGlobal(self): def testClassAndGlobal(self):
@ -754,6 +756,7 @@ def dig(self):
tester.dig() tester.dig()
ref = weakref.ref(tester) ref = weakref.ref(tester)
del tester del tester
gc_collect() # For PyPy or other GCs.
self.assertIsNone(ref()) self.assertIsNone(ref())

View file

@ -606,6 +606,7 @@ def test_weakref(self):
p = weakref.proxy(s) p = weakref.proxy(s)
self.assertEqual(str(p), str(s)) self.assertEqual(str(p), str(s))
s = None s = None
support.gc_collect() # For PyPy or other GCs.
self.assertRaises(ReferenceError, str, p) self.assertRaises(ReferenceError, str, p)
def test_rich_compare(self): def test_rich_compare(self):

View file

@ -868,6 +868,7 @@ def test_weakref(self):
p = proxy(s) p = proxy(s)
self.assertEqual(p.fileno(), s.fileno()) self.assertEqual(p.fileno(), s.fileno())
s = None s = None
support.gc_collect() # For PyPy or other GCs.
try: try:
p.fileno() p.fileno()
except ReferenceError: except ReferenceError:

View file

@ -2969,6 +2969,7 @@ def test_leak_fast_process_del_killed(self):
pid = p.pid pid = p.pid
with support.check_warnings(('', ResourceWarning)): with support.check_warnings(('', ResourceWarning)):
p = None p = None
support.gc_collect() # For PyPy or other GCs.
os.kill(pid, signal.SIGKILL) os.kill(pid, signal.SIGKILL)
if mswindows: if mswindows:

View file

@ -428,6 +428,7 @@ def test_choose_directory(self):
self.do_create(dir=dir).write(b"blat") self.do_create(dir=dir).write(b"blat")
self.do_create(dir=pathlib.Path(dir)).write(b"blat") self.do_create(dir=pathlib.Path(dir)).write(b"blat")
finally: finally:
support.gc_collect() # For PyPy or other GCs.
os.rmdir(dir) os.rmdir(dir)
def test_file_mode(self): def test_file_mode(self):
@ -821,6 +822,8 @@ def test_many(self):
extant = list(range(TEST_FILES)) extant = list(range(TEST_FILES))
for i in extant: for i in extant:
extant[i] = self.do_create(pre="aa") extant[i] = self.do_create(pre="aa")
del extant
support.gc_collect() # For PyPy or other GCs.
## def test_warning(self): ## def test_warning(self):
## # mktemp issues a warning when used ## # mktemp issues a warning when used

View file

@ -131,6 +131,7 @@ def task():
del task del task
while not done: while not done:
time.sleep(POLL_SLEEP) time.sleep(POLL_SLEEP)
support.gc_collect() # For PyPy or other GCs.
self.assertEqual(thread._count(), orig) self.assertEqual(thread._count(), orig)
def test_unraisable_exception(self): def test_unraisable_exception(self):

View file

@ -36,7 +36,7 @@ def _local_refs(self, n):
t.join() t.join()
del t del t
gc.collect() support.gc_collect() # For PyPy or other GCs.
self.assertEqual(len(weaklist), n) self.assertEqual(len(weaklist), n)
# XXX _threading_local keeps the local of the last stopped thread alive. # XXX _threading_local keeps the local of the last stopped thread alive.
@ -45,7 +45,7 @@ def _local_refs(self, n):
# Assignment to the same thread local frees it sometimes (!) # Assignment to the same thread local frees it sometimes (!)
local.someothervar = None local.someothervar = None
gc.collect() support.gc_collect() # For PyPy or other GCs.
deadlist = [weak for weak in weaklist if weak() is None] deadlist = [weak for weak in weaklist if weak() is None]
self.assertIn(len(deadlist), (n-1, n), (n, len(deadlist))) self.assertIn(len(deadlist), (n-1, n), (n, len(deadlist)))
@ -88,7 +88,7 @@ def f():
# 2) GC the cycle (triggers threadmodule.c::local_clear # 2) GC the cycle (triggers threadmodule.c::local_clear
# before local_dealloc) # before local_dealloc)
del cycle del cycle
gc.collect() support.gc_collect() # For PyPy or other GCs.
e1.set() e1.set()
e2.wait() e2.wait()
@ -189,7 +189,7 @@ class X:
x.local.x = x x.local.x = x
wr = weakref.ref(x) wr = weakref.ref(x)
del x del x
gc.collect() support.gc_collect() # For PyPy or other GCs.
self.assertIsNone(wr()) self.assertIsNone(wr())

View file

@ -12,6 +12,7 @@
from test import support from test import support
from test.support import script_helper, ALWAYS_EQ from test.support import script_helper, ALWAYS_EQ
from test.support import gc_collect
# Used in ReferencesTestCase.test_ref_created_during_del() . # Used in ReferencesTestCase.test_ref_created_during_del() .
ref_from_del = None ref_from_del = None
@ -135,6 +136,7 @@ def test_multiple_callbacks(self):
ref1 = weakref.ref(o, self.callback) ref1 = weakref.ref(o, self.callback)
ref2 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback)
del o del o
gc_collect() # For PyPy or other GCs.
self.assertIsNone(ref1(), "expected reference to be invalidated") self.assertIsNone(ref1(), "expected reference to be invalidated")
self.assertIsNone(ref2(), "expected reference to be invalidated") self.assertIsNone(ref2(), "expected reference to be invalidated")
self.assertEqual(self.cbcalled, 2, self.assertEqual(self.cbcalled, 2,
@ -168,13 +170,16 @@ def test_proxy_ref(self):
ref1 = weakref.proxy(o, self.callback) ref1 = weakref.proxy(o, self.callback)
ref2 = weakref.proxy(o, self.callback) ref2 = weakref.proxy(o, self.callback)
del o del o
gc_collect() # For PyPy or other GCs.
def check(proxy): def check(proxy):
proxy.bar proxy.bar
self.assertRaises(ReferenceError, check, ref1) self.assertRaises(ReferenceError, check, ref1)
self.assertRaises(ReferenceError, check, ref2) self.assertRaises(ReferenceError, check, ref2)
self.assertRaises(ReferenceError, bool, weakref.proxy(C())) ref3 = weakref.proxy(C())
gc_collect() # For PyPy or other GCs.
self.assertRaises(ReferenceError, bool, ref3)
self.assertEqual(self.cbcalled, 2) self.assertEqual(self.cbcalled, 2)
def check_basic_ref(self, factory): def check_basic_ref(self, factory):
@ -191,6 +196,7 @@ def check_basic_callback(self, factory):
o = factory() o = factory()
ref = weakref.ref(o, self.callback) ref = weakref.ref(o, self.callback)
del o del o
gc_collect() # For PyPy or other GCs.
self.assertEqual(self.cbcalled, 1, self.assertEqual(self.cbcalled, 1,
"callback did not properly set 'cbcalled'") "callback did not properly set 'cbcalled'")
self.assertIsNone(ref(), self.assertIsNone(ref(),
@ -215,6 +221,7 @@ def test_ref_reuse(self):
self.assertEqual(weakref.getweakrefcount(o), 2, self.assertEqual(weakref.getweakrefcount(o), 2,
"wrong weak ref count for object") "wrong weak ref count for object")
del proxy del proxy
gc_collect() # For PyPy or other GCs.
self.assertEqual(weakref.getweakrefcount(o), 1, self.assertEqual(weakref.getweakrefcount(o), 1,
"wrong weak ref count for object after deleting proxy") "wrong weak ref count for object after deleting proxy")
@ -480,6 +487,7 @@ def test_getweakrefcount(self):
"got wrong number of weak reference objects") "got wrong number of weak reference objects")
del ref1, ref2, proxy1, proxy2 del ref1, ref2, proxy1, proxy2
gc_collect() # For PyPy or other GCs.
self.assertEqual(weakref.getweakrefcount(o), 0, self.assertEqual(weakref.getweakrefcount(o), 0,
"weak reference objects not unlinked from" "weak reference objects not unlinked from"
" referent when discarded.") " referent when discarded.")
@ -493,6 +501,7 @@ def test_getweakrefs(self):
ref1 = weakref.ref(o, self.callback) ref1 = weakref.ref(o, self.callback)
ref2 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback)
del ref1 del ref1
gc_collect() # For PyPy or other GCs.
self.assertEqual(weakref.getweakrefs(o), [ref2], self.assertEqual(weakref.getweakrefs(o), [ref2],
"list of refs does not match") "list of refs does not match")
@ -500,10 +509,12 @@ def test_getweakrefs(self):
ref1 = weakref.ref(o, self.callback) ref1 = weakref.ref(o, self.callback)
ref2 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback)
del ref2 del ref2
gc_collect() # For PyPy or other GCs.
self.assertEqual(weakref.getweakrefs(o), [ref1], self.assertEqual(weakref.getweakrefs(o), [ref1],
"list of refs does not match") "list of refs does not match")
del ref1 del ref1
gc_collect() # For PyPy or other GCs.
self.assertEqual(weakref.getweakrefs(o), [], self.assertEqual(weakref.getweakrefs(o), [],
"list of refs not cleared") "list of refs not cleared")
@ -989,6 +1000,7 @@ def __call__(self):
self.assertTrue(mr.called) self.assertTrue(mr.called)
self.assertEqual(mr.value, 24) self.assertEqual(mr.value, 24)
del o del o
gc_collect() # For PyPy or other GCs.
self.assertIsNone(mr()) self.assertIsNone(mr())
self.assertTrue(mr.called) self.assertTrue(mr.called)
@ -1291,15 +1303,18 @@ def test_weak_values(self):
del items1, items2 del items1, items2
self.assertEqual(len(dict), self.COUNT) self.assertEqual(len(dict), self.COUNT)
del objects[0] del objects[0]
gc_collect() # For PyPy or other GCs.
self.assertEqual(len(dict), self.COUNT - 1, self.assertEqual(len(dict), self.COUNT - 1,
"deleting object did not cause dictionary update") "deleting object did not cause dictionary update")
del objects, o del objects, o
gc_collect() # For PyPy or other GCs.
self.assertEqual(len(dict), 0, self.assertEqual(len(dict), 0,
"deleting the values did not clear the dictionary") "deleting the values did not clear the dictionary")
# regression on SF bug #447152: # regression on SF bug #447152:
dict = weakref.WeakValueDictionary() dict = weakref.WeakValueDictionary()
self.assertRaises(KeyError, dict.__getitem__, 1) self.assertRaises(KeyError, dict.__getitem__, 1)
dict[2] = C() dict[2] = C()
gc_collect() # For PyPy or other GCs.
self.assertRaises(KeyError, dict.__getitem__, 2) self.assertRaises(KeyError, dict.__getitem__, 2)
def test_weak_keys(self): def test_weak_keys(self):
@ -1320,9 +1335,11 @@ def test_weak_keys(self):
del items1, items2 del items1, items2
self.assertEqual(len(dict), self.COUNT) self.assertEqual(len(dict), self.COUNT)
del objects[0] del objects[0]
gc_collect() # For PyPy or other GCs.
self.assertEqual(len(dict), (self.COUNT - 1), self.assertEqual(len(dict), (self.COUNT - 1),
"deleting object did not cause dictionary update") "deleting object did not cause dictionary update")
del objects, o del objects, o
gc_collect() # For PyPy or other GCs.
self.assertEqual(len(dict), 0, self.assertEqual(len(dict), 0,
"deleting the keys did not clear the dictionary") "deleting the keys did not clear the dictionary")
o = Object(42) o = Object(42)
@ -1821,6 +1838,7 @@ def __eq__(self, other):
for o in objs: for o in objs:
count += 1 count += 1
del d[o] del d[o]
gc_collect() # For PyPy or other GCs.
self.assertEqual(len(d), 0) self.assertEqual(len(d), 0)
self.assertEqual(count, 2) self.assertEqual(count, 2)
@ -2129,6 +2147,7 @@ def test_atexit(self):
libreftest = """ Doctest for examples in the library reference: weakref.rst libreftest = """ Doctest for examples in the library reference: weakref.rst
>>> from test.support import gc_collect
>>> import weakref >>> import weakref
>>> class Dict(dict): >>> class Dict(dict):
... pass ... pass
@ -2148,6 +2167,7 @@ def test_atexit(self):
>>> o is o2 >>> o is o2
True True
>>> del o, o2 >>> del o, o2
>>> gc_collect() # For PyPy or other GCs.
>>> print(r()) >>> print(r())
None None
@ -2200,6 +2220,7 @@ def test_atexit(self):
>>> id2obj(a_id) is a >>> id2obj(a_id) is a
True True
>>> del a >>> del a
>>> gc_collect() # For PyPy or other GCs.
>>> try: >>> try:
... id2obj(a_id) ... id2obj(a_id)
... except KeyError: ... except KeyError:

View file

@ -5,6 +5,7 @@
from collections.abc import Set, MutableSet from collections.abc import Set, MutableSet
import gc import gc
import contextlib import contextlib
from test import support
class Foo: class Foo:
@ -48,6 +49,7 @@ def test_len(self):
self.assertEqual(len(self.s), len(self.d)) self.assertEqual(len(self.s), len(self.d))
self.assertEqual(len(self.fs), 1) self.assertEqual(len(self.fs), 1)
del self.obj del self.obj
support.gc_collect() # For PyPy or other GCs.
self.assertEqual(len(self.fs), 0) self.assertEqual(len(self.fs), 0)
def test_contains(self): def test_contains(self):
@ -57,6 +59,7 @@ def test_contains(self):
self.assertNotIn(1, self.s) self.assertNotIn(1, self.s)
self.assertIn(self.obj, self.fs) self.assertIn(self.obj, self.fs)
del self.obj del self.obj
support.gc_collect() # For PyPy or other GCs.
self.assertNotIn(ustr('F'), self.fs) self.assertNotIn(ustr('F'), self.fs)
def test_union(self): def test_union(self):
@ -215,6 +218,7 @@ def test_add(self):
self.assertEqual(self.s, dup) self.assertEqual(self.s, dup)
self.assertRaises(TypeError, self.s.add, []) self.assertRaises(TypeError, self.s.add, [])
self.fs.add(Foo()) self.fs.add(Foo())
support.gc_collect() # For PyPy or other GCs.
self.assertTrue(len(self.fs) == 1) self.assertTrue(len(self.fs) == 1)
self.fs.add(self.obj) self.fs.add(self.obj)
self.assertTrue(len(self.fs) == 1) self.assertTrue(len(self.fs) == 1)
@ -406,6 +410,7 @@ def test_len_cycles(self):
n1 = len(s) n1 = len(s)
del it del it
gc.collect() gc.collect()
gc.collect() # For PyPy or other GCs.
n2 = len(s) n2 = len(s)
# one item may be kept alive inside the iterator # one item may be kept alive inside the iterator
self.assertIn(n1, (0, 1)) self.assertIn(n1, (0, 1))

View file

@ -2456,6 +2456,7 @@ def wref_cb(w):
wref = weakref.ref(e, wref_cb) wref = weakref.ref(e, wref_cb)
self.assertEqual(wref().tag, 'e') self.assertEqual(wref().tag, 'e')
del e del e
gc_collect() # For PyPy or other GCs.
self.assertEqual(flag, True) self.assertEqual(flag, True)
self.assertEqual(wref(), None) self.assertEqual(wref(), None)

View file

@ -77,6 +77,7 @@ def test_create_from_file(self):
self.assertEqual(image.height(), 16) self.assertEqual(image.height(), 16)
self.assertIn('::img::test', self.root.image_names()) self.assertIn('::img::test', self.root.image_names())
del image del image
support.gc_collect() # For PyPy or other GCs.
self.assertNotIn('::img::test', self.root.image_names()) self.assertNotIn('::img::test', self.root.image_names())
def test_create_from_data(self): def test_create_from_data(self):
@ -91,6 +92,7 @@ def test_create_from_data(self):
self.assertEqual(image.height(), 16) self.assertEqual(image.height(), 16)
self.assertIn('::img::test', self.root.image_names()) self.assertIn('::img::test', self.root.image_names())
del image del image
support.gc_collect() # For PyPy or other GCs.
self.assertNotIn('::img::test', self.root.image_names()) self.assertNotIn('::img::test', self.root.image_names())
def assertEqualStrList(self, actual, expected): def assertEqualStrList(self, actual, expected):
@ -171,6 +173,7 @@ def check_create_from_file(self, ext):
self.assertEqual(image['file'], testfile) self.assertEqual(image['file'], testfile)
self.assertIn('::img::test', self.root.image_names()) self.assertIn('::img::test', self.root.image_names())
del image del image
support.gc_collect() # For PyPy or other GCs.
self.assertNotIn('::img::test', self.root.image_names()) self.assertNotIn('::img::test', self.root.image_names())
def check_create_from_data(self, ext): def check_create_from_data(self, ext):
@ -188,6 +191,7 @@ def check_create_from_data(self, ext):
self.assertEqual(image['file'], '') self.assertEqual(image['file'], '')
self.assertIn('::img::test', self.root.image_names()) self.assertIn('::img::test', self.root.image_names())
del image del image
support.gc_collect() # For PyPy or other GCs.
self.assertNotIn('::img::test', self.root.image_names()) self.assertNotIn('::img::test', self.root.image_names())
def test_create_from_ppm_file(self): def test_create_from_ppm_file(self):

View file

@ -1,4 +1,6 @@
import unittest import unittest
from test import support
import gc import gc
import tkinter import tkinter
from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl, from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
@ -46,6 +48,7 @@ def test___del__(self):
v = Variable(self.root, "sample string", "varname") v = Variable(self.root, "sample string", "varname")
self.assertTrue(self.info_exists("varname")) self.assertTrue(self.info_exists("varname"))
del v del v
support.gc_collect() # For PyPy or other GCs.
self.assertFalse(self.info_exists("varname")) self.assertFalse(self.info_exists("varname"))
def test_dont_unset_not_existing(self): def test_dont_unset_not_existing(self):
@ -53,9 +56,11 @@ def test_dont_unset_not_existing(self):
v1 = Variable(self.root, name="name") v1 = Variable(self.root, name="name")
v2 = Variable(self.root, name="name") v2 = Variable(self.root, name="name")
del v1 del v1
support.gc_collect() # For PyPy or other GCs.
self.assertFalse(self.info_exists("name")) self.assertFalse(self.info_exists("name"))
# shouldn't raise exception # shouldn't raise exception
del v2 del v2
support.gc_collect() # For PyPy or other GCs.
self.assertFalse(self.info_exists("name")) self.assertFalse(self.info_exists("name"))
def test_equality(self): def test_equality(self):

View file

@ -2,7 +2,7 @@
import unittest import unittest
import tkinter import tkinter
from tkinter import ttk from tkinter import ttk
from test.support import requires, run_unittest from test.support import requires, run_unittest, gc_collect
from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest
requires('gui') requires('gui')
@ -18,6 +18,7 @@ def test_widget_destroy(self):
x = ttk.LabeledScale(self.root) x = ttk.LabeledScale(self.root)
var = x._variable._name var = x._variable._name
x.destroy() x.destroy()
gc_collect() # For PyPy or other GCs.
self.assertRaises(tkinter.TclError, x.tk.globalgetvar, var) self.assertRaises(tkinter.TclError, x.tk.globalgetvar, var)
# manually created variable # manually created variable
@ -30,6 +31,7 @@ def test_widget_destroy(self):
else: else:
self.assertEqual(float(x.tk.globalgetvar(name)), myvar.get()) self.assertEqual(float(x.tk.globalgetvar(name)), myvar.get())
del myvar del myvar
gc_collect() # For PyPy or other GCs.
self.assertRaises(tkinter.TclError, x.tk.globalgetvar, name) self.assertRaises(tkinter.TclError, x.tk.globalgetvar, name)
# checking that the tracing callback is properly removed # checking that the tracing callback is properly removed
@ -171,6 +173,7 @@ def test_variable_change(self):
def test_resize(self): def test_resize(self):
x = ttk.LabeledScale(self.root) x = ttk.LabeledScale(self.root)
x.pack(expand=True, fill='both') x.pack(expand=True, fill='both')
gc_collect() # For PyPy or other GCs.
x.update() x.update()
width, height = x.master.winfo_width(), x.master.winfo_height() width, height = x.master.winfo_width(), x.master.winfo_height()
@ -206,6 +209,7 @@ def test_widget_destroy(self):
optmenu.destroy() optmenu.destroy()
self.assertEqual(optmenu.tk.globalgetvar(name), var.get()) self.assertEqual(optmenu.tk.globalgetvar(name), var.get())
del var del var
gc_collect() # For PyPy or other GCs.
self.assertRaises(tkinter.TclError, optmenu.tk.globalgetvar, name) self.assertRaises(tkinter.TclError, optmenu.tk.globalgetvar, name)
@ -251,6 +255,7 @@ def test_menu(self):
# check that variable is updated correctly # check that variable is updated correctly
optmenu.pack() optmenu.pack()
gc_collect() # For PyPy or other GCs.
optmenu['menu'].invoke(0) optmenu['menu'].invoke(0)
self.assertEqual(optmenu._variable.get(), items[0]) self.assertEqual(optmenu._variable.get(), items[0])

View file

@ -1,7 +1,7 @@
import unittest import unittest
import tkinter import tkinter
from tkinter import ttk, TclError from tkinter import ttk, TclError
from test.support import requires from test.support import requires, gc_collect
import sys import sys
from tkinter.test.test_ttk.test_functions import MockTclObj from tkinter.test.test_ttk.test_functions import MockTclObj
@ -839,6 +839,7 @@ def test_set(self):
self.assertEqual(conv(self.scale.get()), var.get()) self.assertEqual(conv(self.scale.get()), var.get())
self.assertEqual(conv(self.scale.get()), max + 5) self.assertEqual(conv(self.scale.get()), max + 5)
del var del var
gc_collect() # For PyPy or other GCs.
# the same happens with the value option # the same happens with the value option
self.scale['value'] = max + 10 self.scale['value'] = max + 10

View file

@ -2,6 +2,7 @@
import warnings import warnings
import weakref import weakref
import unittest import unittest
from test.support import gc_collect
from itertools import product from itertools import product
@ -124,8 +125,10 @@ def test_with(self):
self.foo() self.foo()
Foo("test_functional").run() Foo("test_functional").run()
gc_collect() # For PyPy or other GCs.
self.assertIsNone(wr()) self.assertIsNone(wr())
Foo("test_with").run() Foo("test_with").run()
gc_collect() # For PyPy or other GCs.
self.assertIsNone(wr()) self.assertIsNone(wr())
def testAssertNotRegex(self): def testAssertNotRegex(self):

View file

@ -18,7 +18,7 @@
TestEquality, TestHashing, LoggingResult, LegacyLoggingResult, TestEquality, TestHashing, LoggingResult, LegacyLoggingResult,
ResultWithNoStartTestRunStopTestRun ResultWithNoStartTestRunStopTestRun
) )
from test.support import captured_stderr from test.support import captured_stderr, gc_collect
log_foo = logging.getLogger('foo') log_foo = logging.getLogger('foo')
@ -1845,6 +1845,7 @@ def test2(self):
for method_name in ('test1', 'test2'): for method_name in ('test1', 'test2'):
testcase = TestCase(method_name) testcase = TestCase(method_name)
testcase.run() testcase.run()
gc_collect() # For PyPy or other GCs.
self.assertEqual(MyException.ninstance, 0) self.assertEqual(MyException.ninstance, 0)

View file

@ -0,0 +1 @@
Add calls of :func:`gc.collect` in tests to support PyPy.