summaryrefslogtreecommitdiff
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
parentbdd9842239a79d62ddf7758073c7c2d25e31b162 (diff)
downloadpython-coveragepy-3565b897757d699d558ad975bd03766e8d82f3fc.tar.gz
Built-in support for using aspectlib to debug execution.
-rw-r--r--coverage/__init__.py4
-rw-r--r--coverage/debug.py47
-rw-r--r--lab/aspectlib.diff14
3 files changed, 51 insertions, 14 deletions
diff --git a/coverage/__init__.py b/coverage/__init__.py
index 1922399..d9a1393 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 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)
diff --git a/lab/aspectlib.diff b/lab/aspectlib.diff
deleted file mode 100644
index 5e4ea6e..0000000
--- a/lab/aspectlib.diff
+++ /dev/null
@@ -1,14 +0,0 @@
-diff -r 44af4372756b coverage/__init__.py
---- a/coverage/__init__.py Sat Nov 21 14:26:51 2015 -0500
-+++ b/coverage/__init__.py Sun Nov 22 08:18:04 2015 -0500
-@@ -18,6 +18,10 @@
- # Backward compatibility.
- coverage = Coverage
-
-+if 1:
-+ import aspectlib, aspectlib.debug, sys
-+ aspectlib.weave(Coverage, aspectlib.debug.log(print_to=sys.stdout), methods=aspectlib.PUBLIC_METHODS)
-+
- # 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.