summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2018-11-03 19:29:00 -0400
committerNed Batchelder <ned@nedbatchelder.com>2018-11-03 19:29:00 -0400
commit89d529895a21c40d1e3f3913b02540f32ab9a0b9 (patch)
treedde3b370d68a0049afb1715613ca8982e0d7a4ee
parente1331826649b26465f090ad9e3100ea0870aefc3 (diff)
downloadpython-coveragepy-git-89d529895a21c40d1e3f3913b02540f32ab9a0b9.tar.gz
Debug-time environment variables can be set with set_env.py
-rw-r--r--coverage/data.py1
-rw-r--r--coverage/misc.py1
-rw-r--r--coverage/parser.py2
-rw-r--r--doc/contributing.rst2
-rw-r--r--igor.py2
-rwxr-xr-xlab/set_env.py95
-rw-r--r--tests/coveragetest.py1
7 files changed, 103 insertions, 1 deletions
diff --git a/coverage/data.py b/coverage/data.py
index 4a996e68..d6061293 100644
--- a/coverage/data.py
+++ b/coverage/data.py
@@ -640,6 +640,7 @@ class CoverageJsonData(object):
return self._arcs is not None
+# $set_env.py: COVERAGE_STORAGE - The storage implementation to use: sql (default), or json.
STORAGE = os.environ.get("COVERAGE_STORAGE", "sql")
if STORAGE == "json":
CoverageData = CoverageJsonData
diff --git a/coverage/misc.py b/coverage/misc.py
index 1782d285..c484d61e 100644
--- a/coverage/misc.py
+++ b/coverage/misc.py
@@ -49,6 +49,7 @@ def dummy_decorator_with_args(*args_unused, **kwargs_unused):
# Environment COVERAGE_NO_CONTRACTS=1 can turn off contracts while debugging
# tests to remove noise from stack traces.
+# $set_env.py: COVERAGE_NO_CONTRACTS - Disable PyContracts to simplify stack traces.
USE_CONTRACTS = env.TESTING and not bool(int(os.environ.get("COVERAGE_NO_CONTRACTS", 0)))
# Use PyContracts for assertion testing on parameters and returns, but only if
diff --git a/coverage/parser.py b/coverage/parser.py
index 6faa36e2..6ae81c19 100644
--- a/coverage/parser.py
+++ b/coverage/parser.py
@@ -491,6 +491,7 @@ new_contract('ArcStarts', lambda seq: all(isinstance(x, ArcStart) for x in seq))
# Turn on AST dumps with an environment variable.
+# $set_env.py: COVERAGE_AST_DUMP - Dump the AST nodes when parsing code.
AST_DUMP = bool(int(os.environ.get("COVERAGE_AST_DUMP", 0)))
class NodeList(object):
@@ -535,6 +536,7 @@ class AstArcAnalyzer(object):
self.missing_arc_fragments = collections.defaultdict(list)
self.block_stack = []
+ # $set_env.py: COVERAGE_TRACK_ARCS - Trace every arc added while parsing code.
self.debug = bool(int(os.environ.get("COVERAGE_TRACK_ARCS", 0)))
def analyze(self):
diff --git a/doc/contributing.rst b/doc/contributing.rst
index 90d73097..319a9d5c 100644
--- a/doc/contributing.rst
+++ b/doc/contributing.rst
@@ -137,7 +137,7 @@ these as 1 to use them:
- COVERAGE_NO_CTRACER disables the C tracer if you only want to run the
PyTracer tests.
-- COVEGE_AST_DUMP will dump the AST tree as it is being used during code
+- COVERAGE_AST_DUMP will dump the AST tree as it is being used during code
parsing.
- COVERAGE_KEEP_TMP keeps the temporary directories in which tests are run.
diff --git a/igor.py b/igor.py
index 750ea688..78de37a2 100644
--- a/igor.py
+++ b/igor.py
@@ -74,8 +74,10 @@ def label_for_tracer(tracer):
def should_skip(tracer):
"""Is there a reason to skip these tests?"""
if tracer == "py":
+ # $set_env.py: COVERAGE_NO_PYTRACER - Don't run the tests under the Python tracer.
skipper = os.environ.get("COVERAGE_NO_PYTRACER")
else:
+ # $set_env.py: COVERAGE_NO_CTRACER - Don't run the tests under the C tracer.
skipper = os.environ.get("COVERAGE_NO_CTRACER")
if skipper:
diff --git a/lab/set_env.py b/lab/set_env.py
new file mode 100755
index 00000000..184649ee
--- /dev/null
+++ b/lab/set_env.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python3
+#
+# Run this like:
+#
+# $ $(lab/set_env.py)
+#
+
+import functools
+import glob
+import itertools
+import os
+import re
+import sys
+
+pstderr = functools.partial(print, file=sys.stderr)
+
+SETTINGS = []
+
+line_pattern = r"\$set_env.py: (\w+) - (.*)"
+globs = "*/*.py *.py"
+
+filenames = itertools.chain.from_iterable(glob.glob(g) for g in globs.split())
+files = 0
+for filename in filenames:
+ files += 1
+ with open(filename) as f:
+ for line in f:
+ m = re.search(line_pattern, line)
+ if m:
+ SETTINGS.append(m.groups())
+pstderr("Read {} files".format(files))
+
+
+def read_them():
+ values = {}
+ for name, _ in SETTINGS:
+ values[name] = os.environ.get(name)
+ return values
+
+def show_them(values):
+ for i, (name, description) in enumerate(SETTINGS, start=1):
+ value = values[name]
+ if value is None:
+ eq = ' '
+ value = ''
+ else:
+ eq = '='
+ value = repr(value)
+ pstderr("{:2d}: {:>30s} {} {:12s} {}".format(i, name, eq, value, description))
+
+def set_by_num(values, n, value):
+ setting_name = SETTINGS[int(n)-1][0]
+ values[setting_name] = value
+
+def get_new_values(values):
+ show = True
+ while True:
+ if show:
+ show_them(values)
+ show = False
+ pstderr("")
+ pstderr("> ", end='')
+ sys.stderr.flush()
+ try:
+ cmd = input("").strip().split(None, 1)
+ except EOFError:
+ pstderr("\n")
+ break
+ if not cmd:
+ continue
+ if cmd[0] == 'q':
+ break
+ if cmd[0] == 'x':
+ set_by_num(values, cmd[1], None)
+ else:
+ try:
+ nsetting = int(cmd[0])
+ except ValueError:
+ pass
+ else:
+ set_by_num(values, nsetting, cmd[1])
+ show = True
+
+ return values
+
+def as_exports(values):
+ exports = []
+ for name, value in values.items():
+ if value is None:
+ exports.append("export -n {}".format(name))
+ else:
+ exports.append("export {}={!r}".format(name, value))
+ return "eval " + "; ".join(exports)
+
+print(as_exports(get_new_values(read_them())))
diff --git a/tests/coveragetest.py b/tests/coveragetest.py
index 08edd62f..d08c334e 100644
--- a/tests/coveragetest.py
+++ b/tests/coveragetest.py
@@ -84,6 +84,7 @@ class CoverageTest(
temp_dir_prefix = "coverage_test/"
# Keep the temp directories if the env says to.
+ # $set_env.py: COVERAGE_KEEP_TMP - Keep the temp directories made by tests.
keep_temp_dir = bool(int(os.getenv("COVERAGE_KEEP_TMP", 0)))
def setUp(self):