mirror of https://github.com/python/cpython
Add missing DECREF to PyErr_WriteUnraisable(). That function reports
exceptions that can't be raised any further, because (for instance) they occur in __del__ methods. The coroutine tests in test_generators was triggering this leak. Remove the leakers' testcase, and add a simpler testcase that explicitly tests this leak to test_generators. test_generators now no longer leaks at all, on my machine. This fix may also solve other leaks, but my full refleakhunting run is still busy, so who knows?
This commit is contained in:
parent
81b092d0e6
commit
b8f81d4863
|
@ -1,19 +0,0 @@
|
|||
import gc
|
||||
|
||||
# Taken from test_generators
|
||||
|
||||
def f():
|
||||
try:
|
||||
yield
|
||||
except GeneratorExit:
|
||||
yield "foo!"
|
||||
|
||||
def inner_leak():
|
||||
g = f()
|
||||
g.next()
|
||||
|
||||
def leak():
|
||||
inner_leak()
|
||||
gc.collect()
|
||||
gc.collect()
|
||||
gc.collect()
|
|
@ -1745,8 +1745,40 @@ was removed.
|
|||
>>> leak()
|
||||
|
||||
|
||||
There should be more test_generator-induced refleaks here, after they get
|
||||
fixed.
|
||||
|
||||
This test isn't really generator related, but rather exception-in-cleanup
|
||||
related. The coroutine tests (above) just happen to cause an exception in
|
||||
the generator's __del__ (tp_del) method. We can also test for this
|
||||
explicitly, without generators. We do have to redirect stderr to avoid
|
||||
printing warnings and to doublecheck that we actually tested what we wanted
|
||||
to test.
|
||||
|
||||
>>> import sys, StringIO
|
||||
>>> old = sys.stderr
|
||||
>>> try:
|
||||
... sys.stderr = StringIO.StringIO()
|
||||
... class Leaker:
|
||||
... def __del__(self):
|
||||
... raise RuntimeError
|
||||
...
|
||||
... l = Leaker()
|
||||
... del l
|
||||
... err = sys.stderr.getvalue().strip()
|
||||
... err.startswith(
|
||||
... "Exception exceptions.RuntimeError: RuntimeError() in <"
|
||||
... )
|
||||
... err.endswith("> ignored")
|
||||
... len(err.splitlines())
|
||||
... finally:
|
||||
... sys.stderr = old
|
||||
True
|
||||
True
|
||||
1
|
||||
|
||||
|
||||
|
||||
These refleak tests should perhaps be in a testfile of their own,
|
||||
test_generators just happened to be the test that drew these out.
|
||||
|
||||
"""
|
||||
|
||||
|
|
|
@ -604,6 +604,7 @@ PyErr_WriteUnraisable(PyObject *obj)
|
|||
PyFile_WriteString(": ", f);
|
||||
PyFile_WriteObject(v, f, 0);
|
||||
}
|
||||
Py_DECREF(moduleName);
|
||||
}
|
||||
PyFile_WriteString(" in ", f);
|
||||
PyFile_WriteObject(obj, f, 0);
|
||||
|
|
Loading…
Reference in New Issue