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
commita23ab8eb5b1d1522120970e1f72fbf629b4d77e2 (patch)
treee2da20d903d4069cafd0cadb1b182b7432889ae5 /coverage/debug.py
parent90ecf09e3fc3f9c8950deba71fca699c7623edbf (diff)
downloadpython-coveragepy-git-a23ab8eb5b1d1522120970e1f72fbf629b4d77e2.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 8ed664ce..96e57920 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)