summaryrefslogtreecommitdiff
path: root/coverage/debug.py
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2016-08-06 13:25:31 -0400
committerNed Batchelder <ned@nedbatchelder.com>2016-08-06 13:25:31 -0400
commit3565b897757d699d558ad975bd03766e8d82f3fc (patch)
tree4ed0551102793e477e34b1b376e400b1a9c3ec76 /coverage/debug.py
parentbdd9842239a79d62ddf7758073c7c2d25e31b162 (diff)
downloadpython-coveragepy-3565b897757d699d558ad975bd03766e8d82f3fc.tar.gz
Built-in support for using aspectlib to debug execution.
Diffstat (limited to 'coverage/debug.py')
-rw-r--r--coverage/debug.py47
1 files changed, 47 insertions, 0 deletions
diff --git a/coverage/debug.py b/coverage/debug.py
index 8ed664c..96e5792 100644
--- a/coverage/debug.py
+++ b/coverage/debug.py
@@ -5,6 +5,7 @@
import inspect
import os
+import re
import sys
from coverage.misc import isolate_module
@@ -112,3 +113,49 @@ def log(msg, stack=False): # pragma: debugging
f.write("{pid}: {msg}\n".format(pid=os.getpid(), msg=msg))
if stack:
dump_stack_frames(out=f)
+
+
+def enable_aspectlib_maybe():
+ """For debugging, we can use aspectlib to trace execution.
+
+ Define COVERAGE_ASPECTLIB to enable and configure aspectlib to trace
+ execution::
+
+ COVERAGE_ASPECTLIB=covaspect.txt:coverage.Coverage:coverage.data.CoverageData program...
+
+ This will trace all the public methods on Coverage and CoverageData,
+ writing the information to covaspect.txt.
+
+ """
+ aspects = os.environ.get("COVERAGE_ASPECTLIB", "")
+ if not aspects:
+ return
+
+ import aspectlib # pylint: disable=import-error
+ import aspectlib.debug # pylint: disable=import-error
+
+ class AspectlibOutputFile(object):
+ """A file-like object that includes pid and cwd information."""
+ def __init__(self, outfile):
+ self.outfile = outfile
+ self.cwd = None
+
+ def write(self, text):
+ """Just like file.write"""
+ cwd = os.getcwd()
+ if cwd != self.cwd:
+ self._write("cwd is now {0!r}\n".format(cwd))
+ self.cwd = cwd
+ self._write(text)
+
+ def _write(self, text):
+ """The raw text-writer, so that we can use it ourselves."""
+ self.outfile.write("{0:5d}: {1}".format(os.getpid(), text))
+
+ aspects = aspects.split(':')
+ aspects_file = AspectlibOutputFile(open(aspects[0], "a"))
+ aspect_log = aspectlib.debug.log(print_to=aspects_file, use_logging=False)
+ aspects = aspects[1:]
+ public_methods = re.compile(r'^(__init__|[a-zA-Z].*)$')
+ for aspect in aspects:
+ aspectlib.weave(aspect, aspect_log, methods=public_methods)