summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2009-11-28 17:06:20 -0500
committerNed Batchelder <ned@nedbatchelder.com>2009-11-28 17:06:20 -0500
commite1de04194e03a28cd54a5a19ae34ea8615774ed7 (patch)
treefc60d0f1872328250a411060db09a1c2b7cd88b8
parentd0c093b8e80972bf5097d6d210b2cc8af0598696 (diff)
parent9936dd6b9fbeca3179dd554f5c9a8523478868c3 (diff)
downloadpython-coveragepy-e1de04194e03a28cd54a5a19ae34ea8615774ed7.tar.gz
Merged change from default branch
-rw-r--r--coverage/__init__.py2
-rw-r--r--coverage/config.py40
-rw-r--r--coverage/control.py54
-rw-r--r--test/test_api.py2
4 files changed, 76 insertions, 22 deletions
diff --git a/coverage/__init__.py b/coverage/__init__.py
index a41dafd..9dea800 100644
--- a/coverage/__init__.py
+++ b/coverage/__init__.py
@@ -5,7 +5,7 @@ http://nedbatchelder.com/code/coverage
"""
-__version__ = "3.2b4" # see detailed history in CHANGES.txt
+__version__ = "3.3-config" # see detailed history in CHANGES.txt
__url__ = "http://nedbatchelder.com/code/coverage"
diff --git a/coverage/config.py b/coverage/config.py
new file mode 100644
index 0000000..0596cc0
--- /dev/null
+++ b/coverage/config.py
@@ -0,0 +1,40 @@
+"""Config file for coverage.py"""
+
+import ConfigParser, os
+
+
+class CoverageConfig(object):
+ def __init__(self):
+ # Defaults.
+ self.cover_pylib = False
+ self.timid = False
+ self.branch = False
+ self.exclude_list = ['# *pragma[: ]*[nN][oO] *[cC][oO][vV][eE][rR]']
+
+ def from_environment(self, env_var):
+ # Timidity: for nose users, read an environment variable. This is a
+ # cheap hack, since the rest of the command line arguments aren't
+ # recognized, but it solves some users' problems.
+ env = os.environ.get(env_var, '')
+ if env:
+ self.timid = ('--timid' in env)
+
+ def from_args(self, **kwargs):
+ for k, v in kwargs.items():
+ if v is not None:
+ setattr(self, k, v)
+
+ def from_file(self, *files):
+ cp = ConfigParser.RawConfigParser()
+ cp.read(files)
+
+ if cp.has_option('run', 'timid'):
+ self.timid = cp.getboolean('run', 'timid')
+ if cp.has_option('run', 'cover_pylib'):
+ self.cover_pylib = cp.getboolean('run', 'cover_pylib')
+ if cp.has_option('run', 'branch'):
+ self.branch = cp.getboolean('run', 'branch')
+ if cp.has_option('report', 'exclude'):
+ # Exclude is a list of lines, leave out the blank ones.
+ exclude_list = cp.get('report', 'exclude')
+ self.exclude_list = filter(None, exclude_list.split('\n'))
diff --git a/coverage/control.py b/coverage/control.py
index 674bb15..f947816 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -6,6 +6,7 @@ from coverage.annotate import AnnotateReporter
from coverage.backward import string_class # pylint: disable-msg=W0622
from coverage.codeunit import code_unit_factory, CodeUnit
from coverage.collector import Collector
+from coverage.config import CoverageConfig
from coverage.data import CoverageData
from coverage.files import FileLocator
from coverage.html import HtmlReporter
@@ -28,8 +29,8 @@ class coverage(object):
"""
- def __init__(self, data_file=None, data_suffix=False, cover_pylib=False,
- auto_data=False, timid=False, branch=False):
+ def __init__(self, data_file=None, data_suffix=False, cover_pylib=None,
+ auto_data=False, timid=None, branch=None, config_file=True):
"""
`data_file` is the base name of the data file to use, defaulting to
".coverage". `data_suffix` is appended to `data_file` to create the
@@ -50,24 +51,36 @@ class coverage(object):
If `branch` is true, then branch coverage will be measured in addition
to the usual statement coverage.
+
+ `config_file` determines what config file to read. If it is a string,
+ it is the name of the config file to read. If it is True, then a
+ standard file is read (".coveragerc"). If it is False, then no file is
+ read.
"""
from coverage import __version__
-
- self.cover_pylib = cover_pylib
+
+ # Build our configuration from a number of sources.
+ self.config = CoverageConfig()
+ if config_file:
+ if config_file is True:
+ config_file = ".coveragerc"
+ self.config.from_file(config_file)
+ self.config.from_environment('COVERAGE_OPTIONS')
+ self.config.from_args(
+ cover_pylib=cover_pylib, timid=timid, branch=branch
+ )
+
self.auto_data = auto_data
self.exclude_re = ""
- self.exclude_list = []
-
+ self._compile_exclude()
+
self.file_locator = FileLocator()
- # Timidity: for nose users, read an environment variable. This is a
- # 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, branch=branch
+ self._should_trace, timid=self.config.timid,
+ branch=self.config.branch
)
# Create the data file.
@@ -83,11 +96,8 @@ class coverage(object):
collector="coverage v%s" % __version__
)
- # The default exclude pattern.
- self.exclude('# *pragma[: ]*[nN][oO] *[cC][oO][vV][eE][rR]')
-
# The prefix for files considered "installed with the interpreter".
- if not self.cover_pylib:
+ if not self.config.cover_pylib:
# Look at where the "os" module is located. That's the indication
# for "installed with the interpreter".
os_file = self.file_locator.canonical_filename(os.__file__)
@@ -130,7 +140,7 @@ class coverage(object):
# If we aren't supposed to trace installed code, then check if this is
# near the Python standard library and skip it if so.
- if not self.cover_pylib:
+ if not self.config.cover_pylib:
if canonical.startswith(self.pylib_prefix):
return False
@@ -189,7 +199,7 @@ class coverage(object):
def clear_exclude(self):
"""Clear the exclude list."""
- self.exclude_list = []
+ self.config.exclude_list = []
self.exclude_re = ""
def exclude(self, regex):
@@ -201,12 +211,16 @@ class coverage(object):
Matching any of the regexes excludes a source line.
"""
- self.exclude_list.append(regex)
- self.exclude_re = "(" + ")|(".join(self.exclude_list) + ")"
+ self.config.exclude_list.append(regex)
+ self._compile_exclude()
+
+ def _compile_exclude(self):
+ """Build the internal usable form of the exclude list."""
+ self.exclude_re = "(" + ")|(".join(self.config.exclude_list) + ")"
def get_exclude_list(self):
"""Return the list of excluded regex patterns."""
- return self.exclude_list
+ return self.config.exclude_list
def save(self):
"""Save the collected coverage data to the data file."""
diff --git a/test/test_api.py b/test/test_api.py
index 932606f..270c723 100644
--- a/test/test_api.py
+++ b/test/test_api.py
@@ -161,7 +161,7 @@ class ApiTest(CoverageTest):
# Measure without the stdlib.
cov1 = coverage.coverage()
- self.assertEqual(cov1.cover_pylib, False)
+ self.assertEqual(cov1.config.cover_pylib, False)
cov1.start()
self.import_module("mymain")
cov1.stop()