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

(cherry picked from commit 2a8127cafe)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
Serhiy Storchaka 2021-09-08 18:08:57 +03:00 committed by GitHub
parent c081649e6d
commit 462c1f0403
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 139 additions and 13 deletions

View file

@ -611,6 +611,7 @@ class _TestProcess(BaseTestCase):
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)
@ -2667,6 +2668,7 @@ class _TestPool(BaseTestCase):
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
@ -4197,6 +4199,7 @@ class _TestFinalize(BaseTestCase):
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)
@ -4208,12 +4211,14 @@ class _TestFinalize(BaseTestCase):
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 @@ Various tests for synchronization primitives.
""" """
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
@ -221,6 +222,7 @@ class BaseLockTests(BaseTestCase):
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

@ -1097,6 +1097,7 @@ class BaseTest:
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

@ -1044,6 +1044,7 @@ class AsyncGenAsyncioTest(unittest.TestCase):
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

@ -2690,6 +2690,7 @@ class BaseTaskTests:
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 @@ try:
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):
@ -343,6 +343,7 @@ class CodeWeakRefTest(unittest.TestCase):
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

@ -463,6 +463,7 @@ class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase
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]$')
@ -473,6 +474,7 @@ class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase
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
@ -535,6 +537,7 @@ class ProcessPoolShutdownTest(ExecutorShutdownTest):
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
@ -759,6 +762,7 @@ class AsCompletedTests:
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")
@ -766,6 +770,7 @@ class AsCompletedTests:
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")
@ -865,6 +870,7 @@ class ExecutorTest:
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 @@ import abc
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
@ -805,6 +806,7 @@ class TestCopy(unittest.TestCase):
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
@ -834,6 +836,7 @@ class TestCopy(unittest.TestCase):
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):
@ -857,6 +860,7 @@ class TestCopy(unittest.TestCase):
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

@ -869,6 +869,7 @@ class TestSubclass(unittest.TestCase):
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

@ -656,6 +656,7 @@ class ExceptionTests(unittest.TestCase):
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)
@ -667,6 +668,7 @@ class ExceptionTests(unittest.TestCase):
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)
@ -678,6 +680,7 @@ class ExceptionTests(unittest.TestCase):
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)
@ -690,6 +693,7 @@ class ExceptionTests(unittest.TestCase):
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)
@ -708,6 +712,7 @@ class ExceptionTests(unittest.TestCase):
# 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):
@ -898,6 +903,7 @@ class ExceptionTests(unittest.TestCase):
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)
@ -951,6 +957,7 @@ class ExceptionTests(unittest.TestCase):
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):
@ -1413,6 +1420,7 @@ class ExceptionTests(unittest.TestCase):
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
@ -1433,6 +1441,7 @@ class ExceptionTests(unittest.TestCase):
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):
@ -1453,6 +1462,7 @@ class ExceptionTests(unittest.TestCase):
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,6 +7,7 @@ from weakref import proxy
import io import io
import _pyio as pyio import _pyio as pyio
from test.support import gc_collect
from test.support.os_helper import TESTFN from test.support.os_helper import TESTFN
from test.support import os_helper from test.support import os_helper
from test.support import warnings_helper from test.support import warnings_helper
@ -30,6 +31,7 @@ class AutoFileTests:
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

@ -9,7 +9,7 @@ from array import array
from weakref import proxy from weakref import proxy
from functools import wraps from functools import wraps
from test.support import (run_unittest, cpython_only, swap_attr) from test.support import run_unittest, cpython_only, swap_attr, gc_collect
from test.support.os_helper import (TESTFN, TESTFN_UNICODE, make_bad_fd) from test.support.os_helper import (TESTFN, TESTFN_UNICODE, make_bad_fd)
from test.support.warnings_helper import check_warnings from test.support.warnings_helper import check_warnings
from collections import UserList from collections import UserList
@ -36,6 +36,7 @@ class AutoFileTests:
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

@ -167,6 +167,7 @@ class TestPartial:
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 @@ True
""" """
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 @@ And finalization:
>>> 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 @@ GeneratorExit is not caught by except Exception:
>>> g = f() >>> g = f()
>>> next(g) >>> next(g)
>>> del g >>> del g; gc_collect() # For PyPy or other GCs.
finally finally

View file

@ -4372,6 +4372,31 @@ class SignalsTest(unittest.TestCase):
"""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

@ -1442,6 +1442,7 @@ class TestBasicOps(unittest.TestCase):
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

@ -6,6 +6,7 @@ import threading
import time import time
import unittest import unittest
import weakref import weakref
from test.support import gc_collect
from test.support import import_helper from test.support import import_helper
from test.support import threading_helper from test.support import threading_helper
@ -590,6 +591,7 @@ class BaseSimpleQueueTest:
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 @@ class TestContext(unittest.TestCase):
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 @@ class TestContext(unittest.TestCase):
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 unittest
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 @@ class ScopeTests(unittest.TestCase):
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 @@ class ScopeTests(unittest.TestCase):
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

@ -593,6 +593,7 @@ class TestSet(TestJointOps, unittest.TestCase):
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

@ -870,6 +870,7 @@ class GeneralModuleTests(unittest.TestCase):
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

@ -3022,6 +3022,7 @@ class POSIXProcessTestCase(BaseTestCase):
pid = p.pid pid = p.pid
with warnings_helper.check_warnings(('', ResourceWarning)): with warnings_helper.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

@ -430,6 +430,7 @@ class TestMkstempInner(TestBadTempdir, BaseTestCase):
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):
@ -880,6 +881,8 @@ class TestMktemp(BaseTestCase):
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

@ -132,6 +132,7 @@ class ThreadRunningTests(BasicThreadTest):
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

@ -37,7 +37,7 @@ class BaseLocalTest:
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.
@ -46,7 +46,7 @@ class BaseLocalTest:
# 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)))
@ -89,7 +89,7 @@ class BaseLocalTest:
# 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()
@ -190,7 +190,7 @@ class BaseLocalTest:
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 @@ import random
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 @@ class ReferencesTestCase(TestBase):
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 @@ class ReferencesTestCase(TestBase):
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 @@ class ReferencesTestCase(TestBase):
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 @@ class ReferencesTestCase(TestBase):
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 @@ class ReferencesTestCase(TestBase):
"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 @@ class ReferencesTestCase(TestBase):
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 @@ class ReferencesTestCase(TestBase):
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 @@ class SubclassableWeakrefTestCase(TestBase):
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 @@ class MappingTestCase(TestBase):
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 @@ class MappingTestCase(TestBase):
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 @@ class MappingTestCase(TestBase):
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 @@ class FinalizeTestCase(unittest.TestCase):
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 @@ True
>>> 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 @@ True
>>> 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 import UserString as ustr
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 @@ class TestWeakSet(unittest.TestCase):
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 @@ class TestWeakSet(unittest.TestCase):
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 @@ class TestWeakSet(unittest.TestCase):
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 @@ class TestWeakSet(unittest.TestCase):
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

@ -2480,6 +2480,7 @@ class BasicElementTest(ElementTestCase, unittest.TestCase):
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

@ -78,6 +78,7 @@ class BitmapImageTest(AbstractTkTest, unittest.TestCase):
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):
@ -92,6 +93,7 @@ class BitmapImageTest(AbstractTkTest, unittest.TestCase):
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):
@ -172,6 +174,7 @@ class PhotoImageTest(AbstractTkTest, unittest.TestCase):
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):
@ -189,6 +192,7 @@ class PhotoImageTest(AbstractTkTest, unittest.TestCase):
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 @@ class TestVariable(TestBase):
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 @@ class TestVariable(TestBase):
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 sys
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 @@ class LabeledScaleTest(AbstractTkTest, unittest.TestCase):
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 @@ class LabeledScaleTest(AbstractTkTest, unittest.TestCase):
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 @@ class LabeledScaleTest(AbstractTkTest, unittest.TestCase):
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 @@ class OptionMenuTest(AbstractTkTest, unittest.TestCase):
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 @@ class OptionMenuTest(AbstractTkTest, unittest.TestCase):
# 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 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase):
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 datetime
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 @@ class Test_Assertions(unittest.TestCase):
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

@ -19,7 +19,7 @@ from unittest.test.support import (
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')
@ -1947,6 +1947,7 @@ test case
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.