Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Lib/test/_test_multiprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ def test_lose_target_ref(self):
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)
Expand Down Expand Up @@ -2663,6 +2664,7 @@ def test_release_task_refs(self):
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
Expand Down Expand Up @@ -4165,6 +4167,7 @@ def setUp(self):
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)

Expand All @@ -4176,12 +4179,14 @@ class Foo(object):
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',))
Expand Down
2 changes: 2 additions & 0 deletions Lib/test/lock_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

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


Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_array.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,7 @@ def test_weakref(self):
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'),
Expand Down
2 changes: 2 additions & 0 deletions Lib/test/test_asyncgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import unittest

from test.support import import_module
from test.support import gc_collect
asyncio = import_module("asyncio")


Expand Down Expand Up @@ -659,6 +660,7 @@ async def run():
await g.__anext__()
await g.__anext__()
del g
gc_collect() # For PyPy or other GCs.

await asyncio.sleep(0.1)

Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_asyncio/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2611,6 +2611,7 @@ def coro():
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]
Expand Down
3 changes: 2 additions & 1 deletion Lib/test/test_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
except ImportError:
ctypes = None
from test.support import (run_doctest, run_unittest, cpython_only,
check_impl_detail)
check_impl_detail, gc_collect)


def consts(t):
Expand Down Expand Up @@ -337,6 +337,7 @@ def callback(code):
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)

Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_concurrent_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ def test_thread_names_assigned(self):
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]$')
Expand All @@ -458,6 +459,7 @@ def test_thread_names_default(self):
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
Expand Down Expand Up @@ -520,6 +522,7 @@ def test_del_shutdown(self):
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
Expand Down Expand Up @@ -744,13 +747,15 @@ def test_free_reference_yielded_future(self):
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")
for future in futures.as_completed(futures_list):
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")
Expand Down Expand Up @@ -850,6 +855,7 @@ def test_free_reference(self):
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())


Expand Down
4 changes: 4 additions & 0 deletions Lib/test/test_copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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
Expand Down Expand Up @@ -816,6 +817,7 @@ class C(object):
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
Expand Down Expand Up @@ -845,6 +847,7 @@ def __init__(self, i):
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):
Expand All @@ -868,6 +871,7 @@ def __init__(self, i):
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):
Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_deque.py
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,7 @@ def test_weakref(self):
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):
Expand Down
4 changes: 3 additions & 1 deletion Lib/test/test_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -1934,6 +1934,7 @@ def _missing_(cls, item):
raise Exception('Exception not raised.')

def test_missing_exceptions_reset(self):
import gc
import weakref
#
class TestEnum(enum.Enum):
Expand All @@ -1960,8 +1961,9 @@ def __init__(self):
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)

Expand Down
10 changes: 10 additions & 0 deletions Lib/test/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,7 @@ def inner_raising_func():
except MyException as e:
pass
obj = None
gc_collect() # For PyPy or other GCs.
obj = wr()
self.assertIsNone(obj)

Expand All @@ -638,6 +639,7 @@ def inner_raising_func():
except MyException:
pass
obj = None
gc_collect() # For PyPy or other GCs.
obj = wr()
self.assertIsNone(obj)

Expand All @@ -649,6 +651,7 @@ def inner_raising_func():
except:
pass
obj = None
gc_collect() # For PyPy or other GCs.
obj = wr()
self.assertIsNone(obj)

Expand All @@ -661,6 +664,7 @@ def inner_raising_func():
except:
break
obj = None
gc_collect() # For PyPy or other GCs.
obj = wr()
self.assertIsNone(obj)

Expand All @@ -679,6 +683,7 @@ def inner_raising_func():
# 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):
Expand Down Expand Up @@ -869,6 +874,7 @@ def raising_gen():
next(g)
testfunc(g)
g = obj = None
gc_collect() # For PyPy or other GCs.
obj = wr()
self.assertIsNone(obj)

Expand Down Expand Up @@ -922,6 +928,7 @@ def __del__(self):
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):
Expand Down Expand Up @@ -1335,6 +1342,7 @@ def inner():
self.assertNotEqual(wr(), None)
else:
self.fail("MemoryError not raised")
gc_collect() # For PyPy or other GCs.
self.assertEqual(wr(), None)

@no_tracing
Expand All @@ -1355,6 +1363,7 @@ def inner():
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):
Expand All @@ -1375,6 +1384,7 @@ def __del__(self):
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)

Expand Down
3 changes: 2 additions & 1 deletion Lib/test/test_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import io
import _pyio as pyio

from test.support import TESTFN
from test.support import TESTFN, gc_collect
from test import support
from collections import UserList

Expand All @@ -29,6 +29,7 @@ def testWeakRefs(self):
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):
Expand Down
3 changes: 2 additions & 1 deletion Lib/test/test_fileio.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from functools import wraps

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

import _io # C implementation of io
Expand All @@ -35,6 +35,7 @@ def testWeakRefs(self):
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):
Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_functools.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ def test_weakref(self):
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):
Expand Down
6 changes: 4 additions & 2 deletions Lib/test/test_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -1966,6 +1966,8 @@ def printsolution(self, x):
"""

coroutine_tests = """\
>>> from test.support import gc_collect

Sending a value into a started generator:

>>> def f():
Expand Down Expand Up @@ -2189,7 +2191,7 @@ def printsolution(self, x):

>>> g = f()
>>> next(g)
>>> del g
>>> del g; gc_collect() # For PyPy or other GCs.
exiting


Expand All @@ -2204,7 +2206,7 @@ def printsolution(self, x):

>>> g = f()
>>> next(g)
>>> del g
>>> del g; gc_collect() # For PyPy or other GCs.
finally


Expand Down
25 changes: 25 additions & 0 deletions Lib/test/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -4310,6 +4310,31 @@ def check_interrupted_write(self, item, bytes, **fdopen_kwargs):
"""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)
Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_itertools.py
Original file line number Diff line number Diff line change
Expand Up @@ -1423,6 +1423,7 @@ def test_tee(self):
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')
Expand Down
Loading