summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2012-12-20 07:02:12 -0500
committerNed Batchelder <ned@nedbatchelder.com>2012-12-20 07:02:12 -0500
commit741e21203b77547906babf0f04edf7eb5dedf723 (patch)
treee6f2350497fad7c57d1aed9e4a47b7db105f0940
parent3349880afb9409cc052066a8f7688ca5e305693e (diff)
downloadpython-coveragepy-git-741e21203b77547906babf0f04edf7eb5dedf723.tar.gz
Debugging to understand why 'trace function changed' appears.
-rw-r--r--coverage/collector.py6
-rw-r--r--coverage/misc.py6
-rw-r--r--test/test_farm.py6
3 files changed, 15 insertions, 3 deletions
diff --git a/coverage/collector.py b/coverage/collector.py
index 1b807b27..bf465939 100644
--- a/coverage/collector.py
+++ b/coverage/collector.py
@@ -2,6 +2,8 @@
import os, sys, threading
+from coverage.misc import short_stack
+
try:
# Use the C extension code when we can, for speed.
from coverage.tracer import CTracer # pylint: disable=F0401,E0611
@@ -124,8 +126,8 @@ class PyTracer(object):
"""Stop this Tracer."""
if hasattr(sys, "gettrace") and self.warn:
if sys.gettrace() != self._trace:
- msg = "Trace function changed, measurement is likely wrong: %r"
- self.warn(msg % sys.gettrace())
+ msg = "Trace function changed, measurement is likely wrong: %r\n%s"
+ self.warn(msg % (sys.gettrace(), short_stack()))
sys.settrace(None)
def get_stats(self):
diff --git a/coverage/misc.py b/coverage/misc.py
index 3ed854a7..b4d1c833 100644
--- a/coverage/misc.py
+++ b/coverage/misc.py
@@ -54,6 +54,12 @@ def format_lines(statements, lines):
return ret
+def short_stack():
+ """Return a string summarizing the call stack."""
+ stack = inspect.stack()[:0:-1]
+ return "\n".join("%30s : %s @%d" % (t[3],t[1],t[2]) for t in stack)
+
+
def expensive(fn):
"""A decorator to cache the result of an expensive operation.
diff --git a/test/test_farm.py b/test/test_farm.py
index 5a2cf8a8..418a3cf5 100644
--- a/test/test_farm.py
+++ b/test/test_farm.py
@@ -7,6 +7,7 @@ sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k
from backtest import run_command, execfile # pylint: disable=W0622
from coverage.control import _TEST_NAME_FILE
+from coverage.misc import short_stack
def test_farm(clean_only=False):
@@ -93,7 +94,10 @@ class FarmTestCase(object):
self.cd(cwd)
# Remove any new modules imported during the test run. This lets us
# import the same source files for more than one test.
- for m in [m for m in sys.modules if m not in old_mods]:
+ to_del = [m for m in sys.modules if m not in old_mods]
+ with open(r"\foo\cov.txt", "a") as f:
+ print >>f, ("Deleting modules: %s, %r\n%s" % (self.description, to_del, short_stack()))
+ for m in to_del:
del sys.modules[m]
def run_fully(self): # pragma: not covered