summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2016-09-25 09:47:08 -0400
committerNed Batchelder <ned@nedbatchelder.com>2016-09-25 09:47:08 -0400
commit4e40f4dcfdf4f9eed0eb396f39228b1bab56b0f9 (patch)
treec30a0eaf4a2f775d3a26971ed0fb77c6c7b26d14
parent910554531a29f73304fb3bcd29f1cd0e5efb2e4e (diff)
downloadpython-coveragepy-git-4e40f4dcfdf4f9eed0eb396f39228b1bab56b0f9.tar.gz
A better way to prevent call stacks during multi-line output
-rw-r--r--coverage/control.py25
-rw-r--r--coverage/debug.py24
2 files changed, 31 insertions, 18 deletions
diff --git a/coverage/control.py b/coverage/control.py
index 3464d66f..351992f2 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -366,18 +366,19 @@ class Coverage(object):
# The user may want to debug things, show info if desired.
wrote_any = False
- if self.debug.should('config'):
- config_info = sorted(self.config.__dict__.items())
- self.debug.write_formatted_info("config", config_info)
- wrote_any = True
-
- if self.debug.should('sys'):
- self.debug.write_formatted_info("sys", self.sys_info())
- for plugin in self.plugins:
- header = "sys: " + plugin._coverage_plugin_name
- info = plugin.sys_info()
- self.debug.write_formatted_info(header, info)
- wrote_any = True
+ with self.debug.without_callers():
+ if self.debug.should('config'):
+ config_info = sorted(self.config.__dict__.items())
+ self.debug.write_formatted_info("config", config_info)
+ wrote_any = True
+
+ if self.debug.should('sys'):
+ self.debug.write_formatted_info("sys", self.sys_info())
+ for plugin in self.plugins:
+ header = "sys: " + plugin._coverage_plugin_name
+ info = plugin.sys_info()
+ self.debug.write_formatted_info(header, info)
+ wrote_any = True
if wrote_any:
self.debug.write_formatted_info("end", ())
diff --git a/coverage/debug.py b/coverage/debug.py
index 957a6fe6..dff8beba 100644
--- a/coverage/debug.py
+++ b/coverage/debug.py
@@ -3,6 +3,7 @@
"""Control of and utilities for debugging."""
+import contextlib
import inspect
import os
import re
@@ -29,26 +30,37 @@ class DebugControl(object):
"""Configure the options and output file for debugging."""
self.options = options
self.output = output
+ self.suppress_callers = False
def __repr__(self):
return "<DebugControl options=%r output=%r>" % (self.options, self.output)
def should(self, option):
"""Decide whether to output debug information in category `option`."""
+ if option == "callers" and self.suppress_callers:
+ return False
return (option in self.options or option in FORCED_DEBUG)
- def write(self, msg, callers=True):
+ @contextlib.contextmanager
+ def without_callers(self):
+ """A context manager to prevent call stacks from being logged."""
+ old = self.suppress_callers
+ self.suppress_callers = True
+ try:
+ yield
+ finally:
+ self.suppress_callers = old
+
+ def write(self, msg):
"""Write a line of debug output.
- `msg` is the line to write. A newline will be appended. If `callers`
- is true, and the user has requested it, the call stack will be written
- also.
+ `msg` is the line to write. A newline will be appended.
"""
if self.should('pid'):
msg = "pid %5d: %s" % (os.getpid(), msg)
self.output.write(msg+"\n")
- if callers and self.should('callers'):
+ if self.should('callers'):
dump_stack_frames(out=self.output, skip=1)
self.output.flush()
@@ -56,7 +68,7 @@ class DebugControl(object):
"""Write a sequence of (label,data) pairs nicely."""
self.write(info_header(header))
for line in info_formatter(info):
- self.write(" %s" % line, callers=False)
+ self.write(" %s" % line)
def info_header(label):