]> granicus.if.org Git - python/commitdiff
Add missing DECREF to PyErr_WriteUnraisable(). That function reports
authorThomas Wouters <thomas@python.org>
Sat, 15 Apr 2006 23:27:28 +0000 (23:27 +0000)
committerThomas Wouters <thomas@python.org>
Sat, 15 Apr 2006 23:27:28 +0000 (23:27 +0000)
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?

Lib/test/leakers/test_gen1.py [deleted file]
Lib/test/test_generators.py
Python/errors.c

diff --git a/Lib/test/leakers/test_gen1.py b/Lib/test/leakers/test_gen1.py
deleted file mode 100644 (file)
index 72f644d..0000000
+++ /dev/null
@@ -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()
index 67781c981c4940ca607f0da321c4eb2e5fc5789e..a60a768be18cd75617c459c860b4e0ada16c05b7 100644 (file)
@@ -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.
 
 """
 
index 25deaa691973c442d60d187a14dea173e792a2dc..275a0656f6b8583c211eeaafe6c2765296a706b7 100644 (file)
@@ -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);