diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2016-08-06 13:25:31 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2016-08-06 13:25:31 -0400 |
commit | a23ab8eb5b1d1522120970e1f72fbf629b4d77e2 (patch) | |
tree | e2da20d903d4069cafd0cadb1b182b7432889ae5 /coverage | |
parent | 90ecf09e3fc3f9c8950deba71fca699c7623edbf (diff) | |
download | python-coveragepy-git-a23ab8eb5b1d1522120970e1f72fbf629b4d77e2.tar.gz |
Built-in support for using aspectlib to debug execution.
Diffstat (limited to 'coverage')
-rw-r--r-- | coverage/__init__.py | 4 | ||||
-rw-r--r-- | coverage/debug.py | 47 |
2 files changed, 51 insertions, 0 deletions
diff --git a/coverage/__init__.py b/coverage/__init__.py index 19223992..d9a13936 100644 --- a/coverage/__init__.py +++ b/coverage/__init__.py @@ -12,6 +12,7 @@ from coverage.version import __version__, __url__, version_info from coverage.control import Coverage, process_startup from coverage.data import CoverageData +from coverage.debug import enable_aspectlib_maybe from coverage.misc import CoverageException from coverage.plugin import CoveragePlugin, FileTracer, FileReporter from coverage.pytracer import PyTracer @@ -19,6 +20,9 @@ from coverage.pytracer import PyTracer # Backward compatibility. coverage = Coverage +# Possibly enable aspectlib to debug our execution. +enable_aspectlib_maybe() + # On Windows, we encode and decode deep enough that something goes wrong and # the encodings.utf_8 module is loaded and then unloaded, I don't know why. # Adding a reference here prevents it from being unloaded. Yuk. 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) |