]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-25130: Add calls of gc.collect() in tests to support PyPy (GH-28005)
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 29 Aug 2021 11:04:40 +0000 (14:04 +0300)
committerGitHub <noreply@github.com>
Sun, 29 Aug 2021 11:04:40 +0000 (14:04 +0300)
36 files changed:
Lib/test/_test_multiprocessing.py
Lib/test/lock_tests.py
Lib/test/test_array.py [changed mode: 0644->0755]
Lib/test/test_asyncgen.py
Lib/test/test_asyncio/test_tasks.py
Lib/test/test_code.py
Lib/test/test_concurrent_futures.py
Lib/test/test_copy.py
Lib/test/test_deque.py
Lib/test/test_enum.py
Lib/test/test_exceptions.py
Lib/test/test_file.py
Lib/test/test_fileio.py
Lib/test/test_functools.py
Lib/test/test_generators.py
Lib/test/test_io.py
Lib/test/test_itertools.py
Lib/test/test_queue.py
Lib/test/test_raise.py
Lib/test/test_scope.py
Lib/test/test_set.py
Lib/test/test_socket.py
Lib/test/test_subprocess.py
Lib/test/test_tempfile.py
Lib/test/test_thread.py
Lib/test/test_threading_local.py
Lib/test/test_weakref.py
Lib/test/test_weakset.py
Lib/test/test_xml_etree.py
Lib/tkinter/test/test_tkinter/test_images.py
Lib/tkinter/test/test_tkinter/test_variables.py
Lib/tkinter/test/test_ttk/test_extensions.py
Lib/tkinter/test/test_ttk/test_widgets.py
Lib/unittest/test/test_assertions.py
Lib/unittest/test/test_case.py
Misc/NEWS.d/next/Tests/2021-08-27-22-37-19.bpo-25130.ig4oJe.rst [new file with mode: 0644]

index 4c4da24a30c371da0de957c4cd1d943fc38a1a6e..7e0b757109766226cbbad7ece3d0a03e6437e8bc 100644 (file)
@@ -611,6 +611,7 @@ class _TestProcess(BaseTestCase):
         del c
         p.start()
         p.join()
+        gc.collect()  # For PyPy or other GCs.
         self.assertIs(wr(), None)
         self.assertEqual(q.get(), 5)
         close_queue(q)
@@ -2667,6 +2668,7 @@ class _TestPool(BaseTestCase):
         self.pool.map(identity, objs)
 
         del objs
+        gc.collect()  # For PyPy or other GCs.
         time.sleep(DELTA)  # let threaded cleanup code run
         self.assertEqual(set(wr() for wr in refs), {None})
         # With a process pool, copies of the objects are returned, check
@@ -4198,6 +4200,7 @@ class _TestFinalize(BaseTestCase):
         util._finalizer_registry.clear()
 
     def tearDown(self):
+        gc.collect()  # For PyPy or other GCs.
         self.assertFalse(util._finalizer_registry)
         util._finalizer_registry.update(self.registry_backup)
 
@@ -4209,12 +4212,14 @@ class _TestFinalize(BaseTestCase):
         a = Foo()
         util.Finalize(a, conn.send, args=('a',))
         del a           # triggers callback for a
+        gc.collect()  # For PyPy or other GCs.
 
         b = Foo()
         close_b = util.Finalize(b, conn.send, args=('b',))
         close_b()       # triggers callback for b
         close_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()
         util.Finalize(c, conn.send, args=('c',))
index d69bcc9496843f372ca6078c0e6601cc59677643..dffb7d4418dfe656a8c87f1e4329b8e0ea9432e3 100644 (file)
@@ -3,6 +3,7 @@ Various tests for synchronization primitives.
 """
 
 import os
+import gc
 import sys
 import time
 from _thread import start_new_thread, TIMEOUT_MAX
@@ -221,6 +222,7 @@ class BaseLockTests(BaseTestCase):
         lock = self.locktype()
         ref = weakref.ref(lock)
         del lock
+        gc.collect()  # For PyPy or other GCs.
         self.assertIsNone(ref())
 
 
old mode 100644 (file)
new mode 100755 (executable)
index 18f78d5..6a48c1c
@@ -1097,6 +1097,7 @@ class BaseTest:
         p = weakref.proxy(s)
         self.assertEqual(p.tobytes(), s.tobytes())
         s = None
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertRaises(ReferenceError, len, p)
 
     @unittest.skipUnless(hasattr(sys, 'getrefcount'),
index 77c15c02bc8914fb36ea9c7a622990c4b5938155..a557cb570514dae6ef5b1dd95e8ead93425325d9 100644 (file)
@@ -3,6 +3,7 @@ import types
 import unittest
 
 from test.support.import_helper import import_module
+from test.support import gc_collect
 asyncio = import_module("asyncio")
 
 
@@ -871,6 +872,7 @@ class AsyncGenAsyncioTest(unittest.TestCase):
             await g.__anext__()
             await g.__anext__()
             del g
+            gc_collect()  # For PyPy or other GCs.
 
             await asyncio.sleep(0.1)
 
index de003737f906ef9b3e4d1548cb6414f49bd5dc86..92b1a43500311d1ad9f54d6189f08cbb279746f7 100644 (file)
@@ -2307,6 +2307,7 @@ class BaseTaskTests:
                 self.new_task(self.loop, gen)
             finally:
                 gen.close()
+        gc.collect()  # For PyPy or other GCs.
 
         self.assertTrue(m_log.error.called)
         message = m_log.error.call_args[0][0]
index 66c84a953cb3d2c2122b77d212a40925ebd48cda..64fd10da1ef2146aed8a75db925ad39e2b97efce 100644 (file)
@@ -137,7 +137,8 @@ try:
 except ImportError:
     ctypes = None
 from test.support import (run_doctest, run_unittest, cpython_only,
-                          check_impl_detail, requires_debug_ranges)
+                          check_impl_detail, requires_debug_ranges,
+                          gc_collect)
 from test.support.script_helper import assert_python_ok
 
 
@@ -510,6 +511,7 @@ class CodeWeakRefTest(unittest.TestCase):
         coderef = weakref.ref(f.__code__, callback)
         self.assertTrue(bool(coderef()))
         del f
+        gc_collect()  # For PyPy or other GCs.
         self.assertFalse(bool(coderef()))
         self.assertTrue(self.called)
 
index 99651f5f4ed4da37a93f5aeb2a80084c75d71182..eae98d690bd975003a6782de801c0595592061c6 100644 (file)
@@ -463,6 +463,7 @@ class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase
         executor.map(abs, range(-5, 5))
         threads = executor._threads
         del executor
+        support.gc_collect()  # For PyPy or other GCs.
 
         for t in threads:
             self.assertRegex(t.name, r'^SpecialPool_[0-4]$')
@@ -473,6 +474,7 @@ class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase
         executor.map(abs, range(-5, 5))
         threads = executor._threads
         del executor
+        support.gc_collect()  # For PyPy or other GCs.
 
         for t in threads:
             # Ensure that our default name is reasonably sane and unique when
@@ -535,6 +537,7 @@ class ProcessPoolShutdownTest(ExecutorShutdownTest):
         call_queue = executor._call_queue
         executor_manager_thread = executor._executor_manager_thread
         del executor
+        support.gc_collect()  # For PyPy or other GCs.
 
         # Make sure that all the executor resources were properly cleaned by
         # the shutdown process
@@ -759,6 +762,7 @@ class AsCompletedTests:
                 futures_list.remove(future)
                 wr = weakref.ref(future)
                 del future
+                support.gc_collect()  # For PyPy or other GCs.
                 self.assertIsNone(wr())
 
         futures_list[0].set_result("test")
@@ -766,6 +770,7 @@ class AsCompletedTests:
             futures_list.remove(future)
             wr = weakref.ref(future)
             del future
+            support.gc_collect()  # For PyPy or other GCs.
             self.assertIsNone(wr())
             if futures_list:
                 futures_list[0].set_result("test")
@@ -865,6 +870,7 @@ class ExecutorTest:
         for obj in self.executor.map(make_dummy_object, range(10)):
             wr = weakref.ref(obj)
             del obj
+            support.gc_collect()  # For PyPy or other GCs.
             self.assertIsNone(wr())
 
 
index ba3d233f63d1c1c944d80bb683e4cdbb1fffc34d..f1ca8cb254d1887f166d6d9a2081f1ee878b5589 100644 (file)
@@ -7,6 +7,7 @@ import abc
 from operator import le, lt, ge, gt, eq, ne
 
 import unittest
+from test import support
 
 order_comparisons = le, lt, ge, gt
 equality_comparisons = eq, ne
@@ -805,6 +806,7 @@ class TestCopy(unittest.TestCase):
         self.assertEqual(v[c], d)
         self.assertEqual(len(v), 2)
         del c, d
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertEqual(len(v), 1)
         x, y = C(), C()
         # The underlying containers are decoupled
@@ -834,6 +836,7 @@ class TestCopy(unittest.TestCase):
         self.assertEqual(v[a].i, b.i)
         self.assertEqual(v[c].i, d.i)
         del c
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertEqual(len(v), 1)
 
     def test_deepcopy_weakvaluedict(self):
@@ -857,6 +860,7 @@ class TestCopy(unittest.TestCase):
         self.assertIs(t, d)
         del x, y, z, t
         del d
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertEqual(len(v), 1)
 
     def test_deepcopy_bound_method(self):
index ffe0e204a0e8c0fb8ddcf63dd1f5ff44ad44d272..20cfc88b160318ae23427f3723cf4abd04b12e85 100644 (file)
@@ -870,6 +870,7 @@ class TestSubclass(unittest.TestCase):
         p = weakref.proxy(d)
         self.assertEqual(str(p), str(d))
         d = None
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertRaises(ReferenceError, str, p)
 
     def test_strange_subclass(self):
index 52d7756da98bd8859773636c1fdcd6cb3963fc8d..7d220871a35ccb2d8d33fc656493d97c9484ed76 100644 (file)
@@ -2044,6 +2044,7 @@ class TestEnum(unittest.TestCase):
             raise Exception('Exception not raised.')
 
     def test_missing_exceptions_reset(self):
+        import gc
         import weakref
         #
         class TestEnum(enum.Enum):
@@ -2070,8 +2071,9 @@ class TestEnum(unittest.TestCase):
         class_2_ref = weakref.ref(Class2())
         #
         # 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.
+        gc.collect()  # For PyPy or other GCs.
         self.assertIs(class_1_ref(), None)
         self.assertIs(class_2_ref(), None)
 
index ce7b86880e69f70e65a2e8dbd930432331495cc5..6141f2e8f62b0c56468316a12333a9915ab17b36 100644 (file)
@@ -656,6 +656,7 @@ class ExceptionTests(unittest.TestCase):
         except MyException as e:
             pass
         obj = None
+        gc_collect()  # For PyPy or other GCs.
         obj = wr()
         self.assertIsNone(obj)
 
@@ -667,6 +668,7 @@ class ExceptionTests(unittest.TestCase):
         except MyException:
             pass
         obj = None
+        gc_collect()  # For PyPy or other GCs.
         obj = wr()
         self.assertIsNone(obj)
 
@@ -678,6 +680,7 @@ class ExceptionTests(unittest.TestCase):
         except:
             pass
         obj = None
+        gc_collect()  # For PyPy or other GCs.
         obj = wr()
         self.assertIsNone(obj)
 
@@ -690,6 +693,7 @@ class ExceptionTests(unittest.TestCase):
             except:
                 break
         obj = None
+        gc_collect()  # For PyPy or other GCs.
         obj = wr()
         self.assertIsNone(obj)
 
@@ -708,6 +712,7 @@ class ExceptionTests(unittest.TestCase):
             # must clear the latter manually for our test to succeed.
             e.__context__ = None
             obj = None
+            gc_collect()  # For PyPy or other GCs.
             obj = wr()
             # guarantee no ref cycles on CPython (don't gc_collect)
             if check_impl_detail(cpython=False):
@@ -898,6 +903,7 @@ class ExceptionTests(unittest.TestCase):
         next(g)
         testfunc(g)
         g = obj = None
+        gc_collect()  # For PyPy or other GCs.
         obj = wr()
         self.assertIsNone(obj)
 
@@ -951,6 +957,7 @@ class ExceptionTests(unittest.TestCase):
             raise Exception(MyObject())
         except:
             pass
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(e, (None, None, None))
 
     def test_raise_does_not_create_context_chain_cycle(self):
@@ -1413,6 +1420,7 @@ class ExceptionTests(unittest.TestCase):
             self.assertNotEqual(wr(), None)
         else:
             self.fail("MemoryError not raised")
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(wr(), None)
 
     @no_tracing
@@ -1433,6 +1441,7 @@ class ExceptionTests(unittest.TestCase):
             self.assertNotEqual(wr(), None)
         else:
             self.fail("RecursionError not raised")
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(wr(), None)
 
     def test_errno_ENOTDIR(self):
@@ -1453,6 +1462,7 @@ class ExceptionTests(unittest.TestCase):
         with support.catch_unraisable_exception() as cm:
             del obj
 
+            gc_collect()  # For PyPy or other GCs.
             self.assertEqual(cm.unraisable.object, BrokenDel.__del__)
             self.assertIsNotNone(cm.unraisable.exc_traceback)
 
index 1ec756f334d28f784beb993f9554e763d5477b8d..1146a37323c9bfe229ce973f67450faae82cf4bc 100644 (file)
@@ -7,6 +7,7 @@ from weakref import proxy
 import io
 import _pyio as pyio
 
+from test.support import gc_collect
 from test.support.os_helper import TESTFN
 from test.support import os_helper
 from test.support import warnings_helper
@@ -30,6 +31,7 @@ class AutoFileTests:
         self.assertEqual(self.f.tell(), p.tell())
         self.f.close()
         self.f = None
+        gc_collect()  # For PyPy or other GCs.
         self.assertRaises(ReferenceError, getattr, p, 'tell')
 
     def testAttributes(self):
index ff611a90eede3bd2babe1be9fd9ad695d15dc1a9..cdca5a8599655be99f57cc15a983f55feaed10ed 100644 (file)
@@ -9,7 +9,7 @@ from array import array
 from weakref import proxy
 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.warnings_helper import check_warnings
 from collections import UserList
@@ -36,6 +36,7 @@ class AutoFileTests:
         self.assertEqual(self.f.tell(), p.tell())
         self.f.close()
         self.f = None
+        gc_collect()  # For PyPy or other GCs.
         self.assertRaises(ReferenceError, getattr, p, 'tell')
 
     def testSeekTell(self):
index fbf5578872e6b0519f2be5aa7646ea89d6e39fef..fece8256a3e2619f485799b2a4ac42a7f3f81f97 100644 (file)
@@ -167,6 +167,7 @@ class TestPartial:
         p = proxy(f)
         self.assertEqual(f.func, p.func)
         f = None
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertRaises(ReferenceError, getattr, p, 'func')
 
     def test_with_bound_and_unbound_methods(self):
index 53d579e723c470f4463660b014dc3652dc6fcc21..d14c757c7b6e435aa1c300a1ea91f72ab2b1cd7f 100644 (file)
@@ -1966,6 +1966,8 @@ True
 """
 
 coroutine_tests = """\
+>>> from test.support import gc_collect
+
 Sending a value into a started generator:
 
 >>> def f():
@@ -2189,7 +2191,7 @@ And finalization:
 
 >>> g = f()
 >>> next(g)
->>> del g
+>>> del g; gc_collect()  # For PyPy or other GCs.
 exiting
 
 
@@ -2204,7 +2206,7 @@ GeneratorExit is not caught by except Exception:
 
 >>> g = f()
 >>> next(g)
->>> del g
+>>> del g; gc_collect()  # For PyPy or other GCs.
 finally
 
 
index 32c29ea5dc4a76ee2ce1982d2adb7a4626d0a3b4..273545a2a2cbb8f2b697e31db4da01877ed0a909 100644 (file)
@@ -4372,6 +4372,31 @@ class SignalsTest(unittest.TestCase):
         """Check that a partial write, when it gets interrupted, properly
         invokes the signal handler, and bubbles up the exception raised
         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 = []
         def _read():
             s = os.read(r, 1)
index a99b5e2bb71db9b2d8cf39da1078cdefc5246f07..4019af05e028ce3e6f146938580782c9e37829cb 100644 (file)
@@ -1442,6 +1442,7 @@ class TestBasicOps(unittest.TestCase):
         p = weakref.proxy(a)
         self.assertEqual(getattr(p, '__class__'), type(b))
         del a
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertRaises(ReferenceError, getattr, p, '__class__')
 
         ans = list('abc')
index 508b739019593d6084a19ebf88a631afc36aaa7a..9bb5181377698c7ac3d90af37ab11ec8ce6363fc 100644 (file)
@@ -6,6 +6,7 @@ import threading
 import time
 import unittest
 import weakref
+from test.support import gc_collect
 from test.support import import_helper
 from test.support import threading_helper
 
@@ -590,6 +591,7 @@ class BaseSimpleQueueTest:
             q.put(C())
         for i in range(N):
             wr = weakref.ref(q.get())
+            gc_collect()  # For PyPy or other GCs.
             self.assertIsNone(wr())
 
 
index 57da0e15a756b60cc050ec704302ebb7762f01a2..8dc62a933e872e73c378c5c3222f11a131182ca2 100644 (file)
@@ -438,6 +438,7 @@ class TestContext(unittest.TestCase):
         f()
 
     def test_3611(self):
+        import gc
         # A re-raised exception in a __del__ caused the __context__
         # to be cleared
         class C:
@@ -451,9 +452,11 @@ class TestContext(unittest.TestCase):
             x = C()
             try:
                 try:
-                    x.x
+                    f.x
                 except AttributeError:
+                    # make x.__del__ trigger
                     del x
+                    gc.collect()  # For PyPy or other GCs.
                     raise TypeError
             except Exception as e:
                 self.assertNotEqual(e.__context__, None)
index 29d60ffe53f036403387004362942a1f6e7f872e..6e46dfa96a664f20a9f50153123ee1bad958d0b3 100644 (file)
@@ -2,6 +2,7 @@ import unittest
 import weakref
 
 from test.support import check_syntax_error, cpython_only
+from test.support import gc_collect
 
 
 class ScopeTests(unittest.TestCase):
@@ -473,6 +474,7 @@ class ScopeTests(unittest.TestCase):
         for i in range(100):
             f1()
 
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(Foo.count, 0)
 
     def testClassAndGlobal(self):
@@ -805,6 +807,7 @@ class ScopeTests(unittest.TestCase):
         tester.dig()
         ref = weakref.ref(tester)
         del tester
+        gc_collect()  # For PyPy or other GCs.
         self.assertIsNone(ref())
 
 
index b1fab0f6207f40d9746cac90cc0a67b60c6c7d54..29bb39df76c8a56929bae7960bd8e76b613cdf7f 100644 (file)
@@ -593,6 +593,7 @@ class TestSet(TestJointOps, unittest.TestCase):
         p = weakref.proxy(s)
         self.assertEqual(str(p), str(s))
         s = None
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertRaises(ReferenceError, str, p)
 
     def test_rich_compare(self):
index c09f11e0f000fe86b141ebfb7133b2f5d2add268..7ac92608f7ce8005f16a83b147cc8bbd92a5a41d 100755 (executable)
@@ -870,6 +870,7 @@ class GeneralModuleTests(unittest.TestCase):
             p = proxy(s)
             self.assertEqual(p.fileno(), s.fileno())
         s = None
+        support.gc_collect()  # For PyPy or other GCs.
         try:
             p.fileno()
         except ReferenceError:
index 94a95c7a00bf20e316bed7a15e4b47e0352c6d6f..87967ca7f3c93df15eba4da3d7e7da553670cb26 100644 (file)
@@ -3026,6 +3026,7 @@ class POSIXProcessTestCase(BaseTestCase):
         pid = p.pid
         with warnings_helper.check_warnings(('', ResourceWarning)):
             p = None
+            support.gc_collect()  # For PyPy or other GCs.
 
         os.kill(pid, signal.SIGKILL)
         if mswindows:
index 3a3f6a999ce0af132c8b7103b95dbd7d41d3817e..f1d483733e26755f1597ff477739e7779f9cd519 100644 (file)
@@ -430,6 +430,7 @@ class TestMkstempInner(TestBadTempdir, BaseTestCase):
             self.do_create(dir=dir).write(b"blat")
             self.do_create(dir=pathlib.Path(dir)).write(b"blat")
         finally:
+            support.gc_collect()  # For PyPy or other GCs.
             os.rmdir(dir)
 
     def test_file_mode(self):
@@ -880,6 +881,8 @@ class TestMktemp(BaseTestCase):
         extant = list(range(TEST_FILES))
         for i in extant:
             extant[i] = self.do_create(pre="aa")
+        del extant
+        support.gc_collect()  # For PyPy or other GCs.
 
 ##     def test_warning(self):
 ##         # mktemp issues a warning when used
index 62b57fa3388376bf618f0adabd1791c3b1e30e36..4ae8a833b990d78f4acb5f18df440e42b6a6f596 100644 (file)
@@ -132,6 +132,7 @@ class ThreadRunningTests(BasicThreadTest):
             del task
             while not done:
                 time.sleep(POLL_SLEEP)
+                support.gc_collect()  # For PyPy or other GCs.
             self.assertEqual(thread._count(), orig)
 
     def test_unraisable_exception(self):
index 9862094eaccd810a42fb3f8e933afd7e6681ca0e..13facb513367a42a12ada3e0458a109a239afe39 100644 (file)
@@ -37,7 +37,7 @@ class BaseLocalTest:
             t.join()
         del t
 
-        gc.collect()
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertEqual(len(weaklist), n)
 
         # 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 (!)
         local.someothervar = None
-        gc.collect()
+        support.gc_collect()  # For PyPy or other GCs.
         deadlist = [weak for weak in weaklist if weak() is None]
         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
             # before local_dealloc)
             del cycle
-            gc.collect()
+            support.gc_collect()  # For PyPy or other GCs.
             e1.set()
             e2.wait()
 
@@ -190,7 +190,7 @@ class BaseLocalTest:
         x.local.x = x
         wr = weakref.ref(x)
         del x
-        gc.collect()
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertIsNone(wr())
 
 
index 1a5314ccff315a4d216658fdd80cab1eb0d57392..5a3e59c3e9ef1599cb4ee3fcb5606152abbc742d 100644 (file)
@@ -12,6 +12,7 @@ import random
 
 from test import support
 from test.support import script_helper, ALWAYS_EQ
+from test.support import gc_collect
 
 # Used in ReferencesTestCase.test_ref_created_during_del() .
 ref_from_del = None
@@ -135,6 +136,7 @@ class ReferencesTestCase(TestBase):
         ref1 = weakref.ref(o, self.callback)
         ref2 = weakref.ref(o, self.callback)
         del o
+        gc_collect()  # For PyPy or other GCs.
         self.assertIsNone(ref1(), "expected reference to be invalidated")
         self.assertIsNone(ref2(), "expected reference to be invalidated")
         self.assertEqual(self.cbcalled, 2,
@@ -168,13 +170,16 @@ class ReferencesTestCase(TestBase):
         ref1 = weakref.proxy(o, self.callback)
         ref2 = weakref.proxy(o, self.callback)
         del o
+        gc_collect()  # For PyPy or other GCs.
 
         def check(proxy):
             proxy.bar
 
         self.assertRaises(ReferenceError, check, ref1)
         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)
 
     def check_basic_ref(self, factory):
@@ -191,6 +196,7 @@ class ReferencesTestCase(TestBase):
         o = factory()
         ref = weakref.ref(o, self.callback)
         del o
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(self.cbcalled, 1,
                      "callback did not properly set 'cbcalled'")
         self.assertIsNone(ref(),
@@ -215,6 +221,7 @@ class ReferencesTestCase(TestBase):
         self.assertEqual(weakref.getweakrefcount(o), 2,
                      "wrong weak ref count for object")
         del proxy
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(weakref.getweakrefcount(o), 1,
                      "wrong weak ref count for object after deleting proxy")
 
@@ -480,6 +487,7 @@ class ReferencesTestCase(TestBase):
                      "got wrong number of weak reference objects")
 
         del ref1, ref2, proxy1, proxy2
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(weakref.getweakrefcount(o), 0,
                      "weak reference objects not unlinked from"
                      " referent when discarded.")
@@ -493,6 +501,7 @@ class ReferencesTestCase(TestBase):
         ref1 = weakref.ref(o, self.callback)
         ref2 = weakref.ref(o, self.callback)
         del ref1
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(weakref.getweakrefs(o), [ref2],
                      "list of refs does not match")
 
@@ -500,10 +509,12 @@ class ReferencesTestCase(TestBase):
         ref1 = weakref.ref(o, self.callback)
         ref2 = weakref.ref(o, self.callback)
         del ref2
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(weakref.getweakrefs(o), [ref1],
                      "list of refs does not match")
 
         del ref1
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(weakref.getweakrefs(o), [],
                      "list of refs not cleared")
 
@@ -989,6 +1000,7 @@ class SubclassableWeakrefTestCase(TestBase):
         self.assertTrue(mr.called)
         self.assertEqual(mr.value, 24)
         del o
+        gc_collect()  # For PyPy or other GCs.
         self.assertIsNone(mr())
         self.assertTrue(mr.called)
 
@@ -1291,15 +1303,18 @@ class MappingTestCase(TestBase):
         del items1, items2
         self.assertEqual(len(dict), self.COUNT)
         del objects[0]
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(len(dict), self.COUNT - 1,
                      "deleting object did not cause dictionary update")
         del objects, o
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(len(dict), 0,
                      "deleting the values did not clear the dictionary")
         # regression on SF bug #447152:
         dict = weakref.WeakValueDictionary()
         self.assertRaises(KeyError, dict.__getitem__, 1)
         dict[2] = C()
+        gc_collect()  # For PyPy or other GCs.
         self.assertRaises(KeyError, dict.__getitem__, 2)
 
     def test_weak_keys(self):
@@ -1320,9 +1335,11 @@ class MappingTestCase(TestBase):
         del items1, items2
         self.assertEqual(len(dict), self.COUNT)
         del objects[0]
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(len(dict), (self.COUNT - 1),
                      "deleting object did not cause dictionary update")
         del objects, o
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(len(dict), 0,
                      "deleting the keys did not clear the dictionary")
         o = Object(42)
@@ -1821,6 +1838,7 @@ class MappingTestCase(TestBase):
         for o in objs:
             count += 1
             del d[o]
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(len(d), 0)
         self.assertEqual(count, 2)
 
@@ -2129,6 +2147,7 @@ class FinalizeTestCase(unittest.TestCase):
 
 libreftest = """ Doctest for examples in the library reference: weakref.rst
 
+>>> from test.support import gc_collect
 >>> import weakref
 >>> class Dict(dict):
 ...     pass
@@ -2148,6 +2167,7 @@ True
 >>> o is o2
 True
 >>> del o, o2
+>>> gc_collect()  # For PyPy or other GCs.
 >>> print(r())
 None
 
@@ -2200,6 +2220,7 @@ True
 >>> id2obj(a_id) is a
 True
 >>> del a
+>>> gc_collect()  # For PyPy or other GCs.
 >>> try:
 ...     id2obj(a_id)
 ... except KeyError:
index 49a9b5c3c658a89afb1dc490ea61c147d197ccbc..9b31d5fce3472f693350278ea64aaeee2af8a5d7 100644 (file)
@@ -5,6 +5,7 @@ from collections import UserString as ustr
 from collections.abc import Set, MutableSet
 import gc
 import contextlib
+from test import support
 
 
 class Foo:
@@ -48,6 +49,7 @@ class TestWeakSet(unittest.TestCase):
         self.assertEqual(len(self.s), len(self.d))
         self.assertEqual(len(self.fs), 1)
         del self.obj
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertEqual(len(self.fs), 0)
 
     def test_contains(self):
@@ -57,6 +59,7 @@ class TestWeakSet(unittest.TestCase):
         self.assertNotIn(1, self.s)
         self.assertIn(self.obj, self.fs)
         del self.obj
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertNotIn(ustr('F'), self.fs)
 
     def test_union(self):
@@ -215,6 +218,7 @@ class TestWeakSet(unittest.TestCase):
         self.assertEqual(self.s, dup)
         self.assertRaises(TypeError, self.s.add, [])
         self.fs.add(Foo())
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertTrue(len(self.fs) == 1)
         self.fs.add(self.obj)
         self.assertTrue(len(self.fs) == 1)
@@ -406,6 +410,7 @@ class TestWeakSet(unittest.TestCase):
         n1 = len(s)
         del it
         gc.collect()
+        gc.collect()  # For PyPy or other GCs.
         n2 = len(s)
         # one item may be kept alive inside the iterator
         self.assertIn(n1, (0, 1))
index 553529a30017027336b9202f30bacffc06cfe954..c79b5462b931df16dda1a42d6bde941944983300 100644 (file)
@@ -2480,6 +2480,7 @@ class BasicElementTest(ElementTestCase, unittest.TestCase):
         wref = weakref.ref(e, wref_cb)
         self.assertEqual(wref().tag, 'e')
         del e
+        gc_collect()  # For PyPy or other GCs.
         self.assertEqual(flag, True)
         self.assertEqual(wref(), None)
 
index 2526e92200d9029b1d08329fd4886191da8e4e81..c7b468044d55eb8fa74ee2f37343d4c26e7ad050 100644 (file)
@@ -78,6 +78,7 @@ class BitmapImageTest(AbstractTkTest, unittest.TestCase):
         self.assertEqual(image.height(), 16)
         self.assertIn('::img::test', self.root.image_names())
         del image
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertNotIn('::img::test', self.root.image_names())
 
     def test_create_from_data(self):
@@ -92,6 +93,7 @@ class BitmapImageTest(AbstractTkTest, unittest.TestCase):
         self.assertEqual(image.height(), 16)
         self.assertIn('::img::test', self.root.image_names())
         del image
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertNotIn('::img::test', self.root.image_names())
 
     def assertEqualStrList(self, actual, expected):
@@ -172,6 +174,7 @@ class PhotoImageTest(AbstractTkTest, unittest.TestCase):
         self.assertEqual(image['file'], testfile)
         self.assertIn('::img::test', self.root.image_names())
         del image
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertNotIn('::img::test', self.root.image_names())
 
     def check_create_from_data(self, ext):
@@ -189,6 +192,7 @@ class PhotoImageTest(AbstractTkTest, unittest.TestCase):
         self.assertEqual(image['file'], '')
         self.assertIn('::img::test', self.root.image_names())
         del image
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertNotIn('::img::test', self.root.image_names())
 
     def test_create_from_ppm_file(self):
index 6aebe8d16d556b66ca243ddf3e9464572a46c742..0be5282a3a3b30a1ad72cb03af06d0c9d3268804 100644 (file)
@@ -1,4 +1,6 @@
 import unittest
+from test import support
+
 import gc
 import tkinter
 from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
@@ -46,6 +48,7 @@ class TestVariable(TestBase):
         v = Variable(self.root, "sample string", "varname")
         self.assertTrue(self.info_exists("varname"))
         del v
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertFalse(self.info_exists("varname"))
 
     def test_dont_unset_not_existing(self):
@@ -53,9 +56,11 @@ class TestVariable(TestBase):
         v1 = Variable(self.root, name="name")
         v2 = Variable(self.root, name="name")
         del v1
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertFalse(self.info_exists("name"))
         # shouldn't raise exception
         del v2
+        support.gc_collect()  # For PyPy or other GCs.
         self.assertFalse(self.info_exists("name"))
 
     def test_equality(self):
index 1a70e0befe6234b519989849b18620dbec19df6e..e6b3eccf7afb8a0cbfcd282a08ad96da871a7253 100644 (file)
@@ -2,7 +2,7 @@ import sys
 import unittest
 import tkinter
 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
 
 requires('gui')
@@ -18,6 +18,7 @@ class LabeledScaleTest(AbstractTkTest, unittest.TestCase):
         x = ttk.LabeledScale(self.root)
         var = x._variable._name
         x.destroy()
+        gc_collect()  # For PyPy or other GCs.
         self.assertRaises(tkinter.TclError, x.tk.globalgetvar, var)
 
         # manually created variable
@@ -30,6 +31,7 @@ class LabeledScaleTest(AbstractTkTest, unittest.TestCase):
         else:
             self.assertEqual(float(x.tk.globalgetvar(name)), myvar.get())
         del myvar
+        gc_collect()  # For PyPy or other GCs.
         self.assertRaises(tkinter.TclError, x.tk.globalgetvar, name)
 
         # checking that the tracing callback is properly removed
@@ -171,6 +173,7 @@ class LabeledScaleTest(AbstractTkTest, unittest.TestCase):
     def test_resize(self):
         x = ttk.LabeledScale(self.root)
         x.pack(expand=True, fill='both')
+        gc_collect()  # For PyPy or other GCs.
         x.update()
 
         width, height = x.master.winfo_width(), x.master.winfo_height()
@@ -206,6 +209,7 @@ class OptionMenuTest(AbstractTkTest, unittest.TestCase):
         optmenu.destroy()
         self.assertEqual(optmenu.tk.globalgetvar(name), var.get())
         del var
+        gc_collect()  # For PyPy or other GCs.
         self.assertRaises(tkinter.TclError, optmenu.tk.globalgetvar, name)
 
 
@@ -251,6 +255,7 @@ class OptionMenuTest(AbstractTkTest, unittest.TestCase):
 
         # check that variable is updated correctly
         optmenu.pack()
+        gc_collect()  # For PyPy or other GCs.
         optmenu['menu'].invoke(0)
         self.assertEqual(optmenu._variable.get(), items[0])
 
index 1fac83a004a6d0e441c289dcec070120237bb5dd..ee5af82fd1b4482fa17c95d80bc9ad2e08235d7d 100644 (file)
@@ -1,7 +1,7 @@
 import unittest
 import tkinter
 from tkinter import ttk, TclError
-from test.support import requires
+from test.support import requires, gc_collect
 import sys
 
 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()), max + 5)
         del var
+        gc_collect()  # For PyPy or other GCs.
 
         # the same happens with the value option
         self.scale['value'] = max + 10
index f5e64d68e7b1014529432f45718736efd172e279..a0db3423b868aa8463ffadcb284d586442435c32 100644 (file)
@@ -2,6 +2,7 @@ import datetime
 import warnings
 import weakref
 import unittest
+from test.support import gc_collect
 from itertools import product
 
 
@@ -124,8 +125,10 @@ class Test_Assertions(unittest.TestCase):
                     self.foo()
 
         Foo("test_functional").run()
+        gc_collect()  # For PyPy or other GCs.
         self.assertIsNone(wr())
         Foo("test_with").run()
+        gc_collect()  # For PyPy or other GCs.
         self.assertIsNone(wr())
 
     def testAssertNotRegex(self):
index f3cabe44d1c88ea54f311e2e84f47192c1955b07..9b32da1a9f536a2b323bfe8e864ea0a180a2f8d2 100644 (file)
@@ -19,7 +19,7 @@ from unittest.test.support import (
     TestEquality, TestHashing, LoggingResult, LegacyLoggingResult,
     ResultWithNoStartTestRunStopTestRun
 )
-from test.support import captured_stderr
+from test.support import captured_stderr, gc_collect
 
 
 log_foo = logging.getLogger('foo')
@@ -1967,6 +1967,7 @@ test case
         for method_name in ('test1', 'test2'):
             testcase = TestCase(method_name)
             testcase.run()
+            gc_collect()  # For PyPy or other GCs.
             self.assertEqual(MyException.ninstance, 0)
 
 
diff --git a/Misc/NEWS.d/next/Tests/2021-08-27-22-37-19.bpo-25130.ig4oJe.rst b/Misc/NEWS.d/next/Tests/2021-08-27-22-37-19.bpo-25130.ig4oJe.rst
new file mode 100644 (file)
index 0000000..43ce68b
--- /dev/null
@@ -0,0 +1 @@
+Add calls of :func:`gc.collect` in tests to support PyPy.