summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2009-10-07 05:31:03 -0400
committerNed Batchelder <ned@nedbatchelder.com>2009-10-07 05:31:03 -0400
commita7072c02bd2f9f4f5de97be0e85db32265756109 (patch)
tree1229b0de791af41013f66babd0b8ec42d2c463fe
parenta3f706683ec93cb8082f4495c6cdaae207950799 (diff)
downloadpython-coveragepy-git-a7072c02bd2f9f4f5de97be0e85db32265756109.tar.gz
Basic plumbing for a --branch option.
-rw-r--r--coverage/cmdline.py7
-rw-r--r--coverage/collector.py10
-rw-r--r--coverage/control.py4
-rw-r--r--coverage/tracer.c4
-rw-r--r--test/test_cmdline.py14
5 files changed, 28 insertions, 11 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index b34c4b1d..c9b8a7fb 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -8,6 +8,10 @@ from coverage.execfile import run_python_file
class Opts:
"""A namespace class for individual options we'll build parsers from."""
+ branch = optparse.Option(
+ '', '--branch', action='store_true',
+ help="Measure branch execution. HIGHLY EXPERIMENTAL!"
+ )
directory = optparse.Option(
'-d', '--directory', action='store',
metavar="DIR",
@@ -78,6 +82,7 @@ class CoverageOptionParser(optparse.OptionParser, object):
)
self.set_defaults(
actions=[],
+ branch=None,
directory=None,
help=None,
ignore_errors=None,
@@ -251,6 +256,7 @@ CMDS = {
'run': CmdOptionParser("execute",
[
Opts.append,
+ Opts.branch,
Opts.pylib,
Opts.parallel_mode,
Opts.timid,
@@ -401,6 +407,7 @@ class CoverageScript:
data_suffix = bool(options.parallel_mode),
cover_pylib = options.pylib,
timid = options.timid,
+ branch = options.branch,
)
if 'debug' in options.actions:
diff --git a/coverage/collector.py b/coverage/collector.py
index 3b56d241..8e304c1f 100644
--- a/coverage/collector.py
+++ b/coverage/collector.py
@@ -35,6 +35,7 @@ class PyTracer:
self.cur_filename = None
self.filename_stack = []
self.last_exc_back = None
+ self.branch = False
def _trace(self, frame, event, arg_unused):
"""The trace function passed to sys.settrace."""
@@ -68,6 +69,7 @@ class PyTracer:
def start(self):
"""Start this Tracer."""
+ assert not self.branch
sys.settrace(self._trace)
def stop(self):
@@ -95,7 +97,7 @@ class Collector:
# the top, and resumed when they become the top again.
_collectors = []
- def __init__(self, should_trace, timid=False):
+ def __init__(self, should_trace, timid=False, branch=False):
"""Create a collector.
`should_trace` is a function, taking a filename, and returning a
@@ -107,10 +109,13 @@ class Collector:
tracing functions make the faster more sophisticated trace function not
operate properly.
+ TODO: `branch`
+
"""
self.should_trace = should_trace
+ self.branch = branch
self.reset()
- if timid:
+ if timid or branch:
# Being timid: use the simple Python trace function.
self._trace_class = PyTracer
else:
@@ -142,6 +147,7 @@ class Collector:
tracer.data = self.data
tracer.should_trace = self.should_trace
tracer.should_trace_cache = self.should_trace_cache
+ tracer.branch = self.branch
tracer.start()
self.tracers.append(tracer)
diff --git a/coverage/control.py b/coverage/control.py
index ba642e44..8f54a641 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -29,7 +29,7 @@ class coverage:
"""
def __init__(self, data_file=None, data_suffix=False, cover_pylib=False,
- auto_data=False, timid=False):
+ auto_data=False, timid=False, branch=False):
"""Create a new coverage measurement context.
`data_file` is the base name of the data file to use, defaulting to
@@ -65,7 +65,7 @@ class coverage:
# cheap hack, since the rest of the command line arguments aren't
# recognized, but it solves some users' problems.
timid = timid or ('--timid' in os.environ.get('COVERAGE_OPTIONS', ''))
- self.collector = Collector(self._should_trace, timid=timid)
+ self.collector = Collector(self._should_trace, timid=timid, branch=branch)
# Create the data file.
if data_suffix:
diff --git a/coverage/tracer.c b/coverage/tracer.c
index b2389228..c318e9ed 100644
--- a/coverage/tracer.c
+++ b/coverage/tracer.c
@@ -41,6 +41,7 @@ typedef struct {
PyObject * should_trace;
PyObject * data;
PyObject * should_trace_cache;
+ PyObject * branch;
int started;
/* The index of the last-used entry in tracenames. */
int depth;
@@ -301,6 +302,9 @@ Tracer_members[] = {
{ "should_trace_cache", T_OBJECT, offsetof(Tracer, should_trace_cache), 0,
PyDoc_STR("Dictionary caching should_trace results.") },
+ { "branch", T_OBJECT, offsetof(Tracer, branch), 0,
+ PyDoc_STR("Should we trace branches?") },
+
{ NULL }
};
diff --git a/test/test_cmdline.py b/test/test_cmdline.py
index db3c3896..26bb295b 100644
--- a/test/test_cmdline.py
+++ b/test/test_cmdline.py
@@ -14,7 +14,7 @@ class CmdLineTest(CoverageTest):
"""Tests of execution paths through the command line interpreter."""
INIT_LOAD = """\
- .coverage(cover_pylib=None, data_suffix=False, timid=None)
+ .coverage(cover_pylib=None, data_suffix=False, timid=None, branch=None)
.load()\n"""
def command_line(self, args, ret=OK):
@@ -92,7 +92,7 @@ class ClassicCmdLineTest(CmdLineTest):
def testErase(self):
# coverage -e
self.cmd_executes("-e", """\
- .coverage(cover_pylib=None, data_suffix=False, timid=None)
+ .coverage(cover_pylib=None, data_suffix=False, timid=None, branch=None)
.erase()
""")
self.cmd_executes_same("-e", "--erase")
@@ -102,7 +102,7 @@ class ClassicCmdLineTest(CmdLineTest):
# -x calls coverage.load first.
self.cmd_executes("-x foo.py", """\
- .coverage(cover_pylib=None, data_suffix=False, timid=None)
+ .coverage(cover_pylib=None, data_suffix=False, timid=None, branch=None)
.load()
.start()
.run_python_file('foo.py', ['foo.py'])
@@ -111,7 +111,7 @@ class ClassicCmdLineTest(CmdLineTest):
""")
# -e -x calls coverage.erase first.
self.cmd_executes("-e -x foo.py", """\
- .coverage(cover_pylib=None, data_suffix=False, timid=None)
+ .coverage(cover_pylib=None, data_suffix=False, timid=None, branch=None)
.erase()
.start()
.run_python_file('foo.py', ['foo.py'])
@@ -120,7 +120,7 @@ class ClassicCmdLineTest(CmdLineTest):
""")
# --timid sets a flag, and program arguments get passed through.
self.cmd_executes("-x --timid foo.py abc 123", """\
- .coverage(cover_pylib=None, data_suffix=False, timid=True)
+ .coverage(cover_pylib=None, data_suffix=False, timid=True, branch=None)
.load()
.start()
.run_python_file('foo.py', ['foo.py', 'abc', '123'])
@@ -129,7 +129,7 @@ class ClassicCmdLineTest(CmdLineTest):
""")
# -L sets a flag, and flags for the program don't confuse us.
self.cmd_executes("-x -p -L foo.py -a -b", """\
- .coverage(cover_pylib=True, data_suffix=True, timid=None)
+ .coverage(cover_pylib=True, data_suffix=True, timid=None, branch=None)
.load()
.start()
.run_python_file('foo.py', ['foo.py', '-a', '-b'])
@@ -146,7 +146,7 @@ class ClassicCmdLineTest(CmdLineTest):
def testCombine(self):
# coverage -c
self.cmd_executes("-c", """\
- .coverage(cover_pylib=None, data_suffix=False, timid=None)
+ .coverage(cover_pylib=None, data_suffix=False, timid=None, branch=None)
.load()
.combine()
.save()