diff options
-rw-r--r-- | CHANGES.txt | 17 | ||||
-rw-r--r-- | TODO.txt | 12 | ||||
-rw-r--r-- | alltests.cmd | 10 | ||||
-rw-r--r-- | covcov.ini | 2 | ||||
-rw-r--r-- | coverage/annotate.py | 8 | ||||
-rw-r--r-- | coverage/cmdline.py | 41 | ||||
-rw-r--r-- | coverage/codeunit.py | 52 | ||||
-rw-r--r-- | coverage/config.py | 12 | ||||
-rw-r--r-- | coverage/control.py | 102 | ||||
-rw-r--r-- | coverage/html.py | 8 | ||||
-rw-r--r-- | coverage/parser.py | 10 | ||||
-rw-r--r-- | coverage/report.py | 18 | ||||
-rw-r--r-- | coverage/summary.py | 6 | ||||
-rw-r--r-- | coverage/xmlreport.py | 9 | ||||
-rw-r--r-- | test/farm/html/run_omit_2.py | 2 | ||||
-rw-r--r-- | test/farm/html/run_omit_3.py | 2 | ||||
-rw-r--r-- | test/farm/html/src/omit4.ini | 2 | ||||
-rw-r--r-- | test/farm/html/src/omit5.ini | 4 | ||||
-rw-r--r-- | test/test_api.py | 8 | ||||
-rw-r--r-- | test/test_cmdline.py | 100 | ||||
-rw-r--r-- | test/test_config.py | 4 | ||||
-rw-r--r-- | test/test_summary.py | 2 |
22 files changed, 213 insertions, 218 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index d5bdce72..a6c37131 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -6,6 +6,13 @@ Change history for Coverage.py Next version ------------ +- BACKWARD INCOMPATIBILITY: the --omit and --include switches now take file + patterns rather than file prefixes, closing `issue 34`_ and `issue 36`_. + +- BACKWARD INCOMPATIBILITY: the `omit_prefixes` argument is gone throughout + coverage.py, replaced with `omit`, a list of filename patterns suitable for + `fnmatch`. A parallel argument `include` controls what files are included. + - The reporting commands (report, annotate, html, and xml) now have a --include switch to restrict reporting to modules beginning with those prefixes, similar to the existing --omit switch. Thanks, Zooko. @@ -27,8 +34,11 @@ Next version and parent processes. Use ``coverage run -p`` to get two data files that can be combined with ``coverage combine``. Fixes `issue 56`_. +- When measuring code running in a virtualenv, most of the system library was + still being measured. This is now fixed. + - Doctest text files are no longer recorded in the coverage data, since they - can't be reported anyway. Fixes `issue 61`_. + can't be reported anyway. Fixes `issue 52`_ and `issue 61`_. - Source files can have more than one dot in them (foo.test.py), and will be treated properly while reporting. Fixes `issue 46`_. @@ -39,10 +49,13 @@ Next version - Unusual code structure that confused exits from methods with exits from classes is now properly analyzed. See `issue 62`_. +.. _issue 34: http://bitbucket.org/ned/coveragepy/issue/34/enhanced-omit-globbing-handling +.. _issue 36: http://bitbucket.org/ned/coveragepy/issue/36/provide-regex-style-omit .. _issue 46: http://bitbucket.org/ned/coveragepy/issue/46 .. _issue 53: http://bitbucket.org/ned/coveragepy/issue/53 +.. _issue 52: http://bitbucket.org/ned/coveragepy/issue/52/doctesttestfile-confuses-source-detection .. _issue 56: http://bitbucket.org/ned/coveragepy/issue/56 -.. _issue 61: http://bitbucket.org/ned/coveragepy/issue/61 +.. _issue 61: http://bitbucket.org/ned/coveragepy/issue/61/annotate-i-doesnt-work .. _issue 62: http://bitbucket.org/ned/coveragepy/issue/62 @@ -1,17 +1,5 @@ Coverage TODO -* Zooko's code - -+ How do include and omit interact? - Include, then omit. -+ Test include and omit during run. -- How do coverage.__init__(omit, include) interact with coverage.report(omit, include)? - - Should cmdline pass omit and include to report/annotate/html/xml? - They've already been given to the constructor. -+ Can you use both omit and include together? - yes. -+ Fix up docstrings. How to deal well with the commonality among all the methods that take omit and include? - * 3.3 - Config file diff --git a/alltests.cmd b/alltests.cmd index 759a4f5a..8fd64d6c 100644 --- a/alltests.cmd +++ b/alltests.cmd @@ -1,11 +1,11 @@ @echo off
@rem all the Python installs have a .pth pointing to the egg file created by
@rem 2.5, so install the testdata in 2.5
-call \ned\bin\switchpy 25 quiet
+call \ned\bin\switchpy c:\vpy\coverage\25 quiet
make --quiet testdata
for %%v in (23 24 25 26 27) do (
- call \ned\bin\switchpy %%v
+ call \ned\bin\switchpy c:\vpy\coverage\%%v
python setup.py -q develop
set COVERAGE_TEST_TRACER=c
nosetests %1 %2 %3 %4 %5 %6 %7 %8 %9
@@ -14,12 +14,12 @@ for %%v in (23 24 25 26 27) do ( nosetests %1 %2 %3 %4 %5 %6 %7 %8 %9
)
-call \ned\bin\switchpy 31
+call \ned\bin\switchpy c:\vpy\coverage\31
python setup.py -q develop
set COVERAGE_TEST_TRACER=c
-python \python31\Scripts\nosetests3 %1 %2 %3 %4 %5 %6 %7 %8 %9
+python c:\vpy\coverage\31\Scripts\nosetests3 %1 %2 %3 %4 %5 %6 %7 %8 %9
del coverage\tracer.pyd
set COVERAGE_TEST_TRACER=py
-python \python31\Scripts\nosetests3 %1 %2 %3 %4 %5 %6 %7 %8 %9
+python c:\vpy\coverage\31\Scripts\nosetests3 %1 %2 %3 %4 %5 %6 %7 %8 %9
make --quiet clean
@@ -12,5 +12,5 @@ exclude_lines = if __name__ == .__main__.:
raise AssertionError
-omit = mock, ez_setup, distribute
+omit = mock.py, ez_setup.py, distribute.py
ignore_errors = true
diff --git a/coverage/annotate.py b/coverage/annotate.py index 5cbdd6a0..e6e7485d 100644 --- a/coverage/annotate.py +++ b/coverage/annotate.py @@ -33,17 +33,13 @@ class AnnotateReporter(Reporter): blank_re = re.compile(r"\s*(#|$)") else_re = re.compile(r"\s*else\s*:\s*(#|$)") - def report(self, morfs, directory=None, omit_prefixes=None, - include_prefixes=None): + def report(self, morfs, directory=None, omit=None, include=None): """Run the report. See `coverage.report()` for arguments. """ - self.report_files( - self.annotate_file, morfs, directory, omit_prefixes, - include_prefixes - ) + self.report_files(self.annotate_file, morfs, directory, omit, include) def annotate_file(self, cu, analysis): """Annotate a single file. diff --git a/coverage/cmdline.py b/coverage/cmdline.py index cb47690c..a0184af8 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -34,9 +34,9 @@ class Opts(object): ) include = optparse.Option( '', '--include', action='store', - metavar="PRE1,PRE2,...", - help="Include files only when their filename path starts with one of " - "these prefixes." + metavar="PAT1,PAT2,...", + help="Include files only when their filename path matches one of " + "these patterns. Usually needs quoting on the command line." ) pylib = optparse.Option( '-L', '--pylib', action='store_true', @@ -50,15 +50,15 @@ class Opts(object): ) old_omit = optparse.Option( '-o', '--omit', action='store', - metavar="PRE1,PRE2,...", - help="Omit files when their filename path starts with one of these " - "prefixes." + metavar="PAT1,PAT2,...", + help="Omit files when their filename matches one of these patterns. " + "Usually needs quoting on the command line." ) omit = optparse.Option( '', '--omit', action='store', - metavar="PRE1,PRE2,...", - help="Omit files when their filename path starts with one of these " - "prefixes." + metavar="PAT1,PAT2,...", + help="Omit files when their filename matches one of these patterns. " + "Usually needs quoting on the command line." ) output_xml = optparse.Option( '-o', '', action='store', dest="outfile", @@ -442,10 +442,10 @@ class CoverageScript(object): # Listify the list options. omit = None if options.omit: - omit = options.omit.split(',') + omit = self.pattern_list(options.omit) include = None if options.include: - include = options.include.split(',') + include = self.pattern_list(options.include) # Do something. self.coverage = self.covpkg.coverage( @@ -454,8 +454,8 @@ class CoverageScript(object): timid = options.timid, branch = options.branch, config_file = options.rcfile, - omit_prefixes = omit, - include_prefixes = include, + omit = omit, + include = include, ) if 'debug' in options.actions: @@ -514,8 +514,8 @@ class CoverageScript(object): 'ignore_errors': options.ignore_errors, } - report_args['omit_prefixes'] = omit - report_args['include_prefixes'] = include + report_args['omit'] = omit + report_args['include'] = include if 'report' in options.actions: self.coverage.report( @@ -532,6 +532,17 @@ class CoverageScript(object): return OK + def pattern_list(self, s): + """Turn an argument into a list of patterns.""" + if sys.platform == 'win32': + # When running coverage as coverage.exe, some of the behavior + # of the shell is emulated: wildcards are expanded into a list of + # filenames. So you have to single-quote patterns on the command + # line, but (not) helpfully, the single quotes are included in the + # argument, so we have to strip them off here. + s = s.strip("'") + return s.split(',') + HELP_TOPICS = r""" diff --git a/coverage/codeunit.py b/coverage/codeunit.py index bb680e99..96cdb022 100644 --- a/coverage/codeunit.py +++ b/coverage/codeunit.py @@ -1,23 +1,21 @@ """Code unit (module) handling for Coverage.""" -import glob, os +import fnmatch, glob, os from coverage.backward import string_class, StringIO from coverage.misc import CoverageException -def code_unit_factory( - morfs, file_locator, omit_prefixes=None, include_prefixes=None - ): +def code_unit_factory(morfs, file_locator, omit=None, include=None): """Construct a list of CodeUnits from polymorphic inputs. `morfs` is a module or a filename, or a list of same. `file_locator` is a FileLocator that can help resolve filenames. - `include_prefixes` is a list of prefixes. Only CodeUnits that match those - prefixes will be included in the list. `omit_prefixes` is a list of - prefixes to omit from the list. + `include` is a list of filename patterns. Only CodeUnits that match those + patterns will be included in the list. `omit` is a list of patterns to omit + from the list. Returns a list of CodeUnit objects. @@ -38,39 +36,31 @@ def code_unit_factory( code_units = [CodeUnit(morf, file_locator) for morf in morfs] - if include_prefixes: - assert not isinstance(include_prefixes, string_class) # common mistake - prefixes = [file_locator.abs_file(p) for p in include_prefixes] + if include: + assert not isinstance(include, string_class) # common mistake + patterns = [file_locator.abs_file(p) for p in include] filtered = [] for cu in code_units: - for prefix in prefixes: - if cu.filename.startswith(prefix): + for pattern in patterns: + if fnmatch.fnmatch(cu.filename, pattern): filtered.append(cu) break code_units = filtered - if omit_prefixes: - code_units = omit_filter(omit_prefixes, code_units, file_locator) + if omit: + assert not isinstance(omit, string_class) # common mistake + patterns = [file_locator.abs_file(p) for p in omit] + filtered = [] + for cu in code_units: + for pattern in patterns: + if fnmatch.fnmatch(cu.filename, pattern): + break + else: + filtered.append(cu) + code_units = filtered return code_units -def omit_filter(omit_prefixes, code_units, file_locator): - """ - The filtering method removing any unwanted code_units - - Refactored out so you can easily monkeypatch if needs be - """ - prefixes = [file_locator.abs_file(p) for p in omit_prefixes] - filtered = [] - for cu in code_units: - for prefix in prefixes: - if cu.filename.startswith(prefix): - break - else: - filtered.append(cu) - - return filtered - class CodeUnit(object): """Code unit: a filename or module. diff --git a/coverage/config.py b/coverage/config.py index 133444d8..9f52ecb1 100644 --- a/coverage/config.py +++ b/coverage/config.py @@ -24,8 +24,8 @@ class CoverageConfig(object): # Defaults for [report] self.exclude_list = ['(?i)# *pragma[: ]*no *cover'] self.ignore_errors = False - self.omit_prefixes = None - self.include_prefixes = None + self.omit = None + self.include = None # Defaults for [html] self.html_dir = "htmlcov" @@ -69,9 +69,9 @@ class CoverageConfig(object): if cp.has_option('run', 'timid'): self.timid = cp.getboolean('run', 'timid') if cp.has_option('run', 'omit'): - self.omit_prefixes = self.get_list(cp, 'run', 'omit') + self.omit = self.get_list(cp, 'run', 'omit') if cp.has_option('run', 'include'): - self.include_prefixes = self.get_list(cp, 'run', 'include') + self.include = self.get_list(cp, 'run', 'include') # [report] if cp.has_option('report', 'exclude_lines'): @@ -81,9 +81,9 @@ class CoverageConfig(object): if cp.has_option('report', 'ignore_errors'): self.ignore_errors = cp.getboolean('report', 'ignore_errors') if cp.has_option('report', 'omit'): - self.omit_prefixes = self.get_list(cp, 'report', 'omit') + self.omit = self.get_list(cp, 'report', 'omit') if cp.has_option('report', 'include'): - self.include_prefixes = self.get_list(cp, 'report', 'include') + self.include = self.get_list(cp, 'report', 'include') # [html] if cp.has_option('html', 'directory'): diff --git a/coverage/control.py b/coverage/control.py index d07abaf3..7936c0d0 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -1,6 +1,6 @@ """Core control stuff for Coverage.""" -import atexit, os, random, socket, sys +import atexit, fnmatch, os, random, socket, sys from coverage.annotate import AnnotateReporter from coverage.backward import string_class @@ -32,7 +32,7 @@ class coverage(object): def __init__(self, data_file=None, data_suffix=None, cover_pylib=None, auto_data=False, timid=None, branch=None, config_file=True, - omit_prefixes=None, include_prefixes=None): + omit=None, include=None): """ `data_file` is the base name of the data file to use, defaulting to ".coverage". `data_suffix` is appended (with a dot) to `data_file` to @@ -59,9 +59,8 @@ class coverage(object): standard file is read (".coveragerc"). If it is False, then no file is read. - `omit_prefixes` and `include_prefixes` are lists of filename prefixes. - Files that match `include_prefixes` will be measured, files that match - `omit_prefixes` will not. + `include` and `omit` are lists of filename patterns. Files that match + `include` will be measured, files that match `omit` will not. """ from coverage import __version__ @@ -86,8 +85,7 @@ class coverage(object): self.config.from_args( data_file=data_file, cover_pylib=cover_pylib, timid=timid, branch=branch, parallel=bool_or_none(data_suffix), - omit_prefixes=omit_prefixes, - include_prefixes=include_prefixes + omit=omit, include=include ) self.auto_data = auto_data @@ -98,8 +96,8 @@ class coverage(object): self.file_locator = FileLocator() - self.omit_prefixes = self._abs_files(self.config.omit_prefixes) - self.include_prefixes = self._abs_files(self.config.include_prefixes) + self.omit = self._abs_files(self.config.omit) + self.include = self._abs_files(self.config.include) self.collector = Collector( self._should_trace, timid=self.config.timid, @@ -127,17 +125,26 @@ class coverage(object): collector="coverage v%s" % __version__ ) - # The prefix for files considered "installed with the interpreter". + # The dirs for files considered "installed with the interpreter". 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__) - self.pylib_prefix = os.path.split(os_file)[0] + os_dir = self.canonical_dir(os.__file__) + self.pylib_dirs = [os_dir] + + # In a virtualenv, there're actually two lib directories. Find the + # other one. This is kind of ad-hoc, but it works. + random_dir = self.canonical_dir(random.__file__) + if random_dir != os_dir: + self.pylib_dirs.append(random_dir) # To avoid tracing the coverage code itself, we skip anything located # where we are. - here = self.file_locator.canonical_filename(__file__) - self.cover_prefix = os.path.split(here)[0] + self.cover_dir = self.canonical_dir(__file__) + + def canonical_dir(self, f): + """Return the canonical directory of the file `f`.""" + return os.path.split(self.file_locator.canonical_filename(f))[0] def _should_trace(self, filename, frame): """Decide whether to trace execution in `filename` @@ -170,27 +177,28 @@ class coverage(object): filename = dunder_file canonical = self.file_locator.canonical_filename(filename) + canon_dir = os.path.split(canonical)[0] # 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.config.cover_pylib: - if canonical.startswith(self.pylib_prefix): + if canon_dir in self.pylib_dirs: return False # We exclude the coverage code itself, since a little of it will be # measured otherwise. - if canonical.startswith(self.cover_prefix): + if canon_dir == self.cover_dir: return False - # Check the file against the include and omit prefixes. - if self.include_prefixes: - for prefix in self.include_prefixes: - if canonical.startswith(prefix): + # Check the file against the include and omit patterns. + if self.include: + for pattern in self.include: + if fnmatch.fnmatch(canonical, pattern): break else: return False - for prefix in self.omit_prefixes: - if canonical.startswith(prefix): + for pattern in self.omit: + if fnmatch.fnmatch(canonical, pattern): return False return canonical @@ -349,33 +357,31 @@ class coverage(object): def report(self, morfs=None, show_missing=True, ignore_errors=None, file=None, # pylint: disable-msg=W0622 - omit_prefixes=None, include_prefixes=None + omit=None, include=None ): """Write a summary report to `file`. Each module in `morfs` is listed, with counts of statements, executed statements, missing statements, and a list of lines missed. - `include_prefixes` is a list of filename prefixes. Modules that match - those prefixes will be included in the report. Modules that match - `omit_prefixes` will not be included in the report. + `include` is a list of filename patterns. Modules whose filenames + match those patterns will be included in the report. Modules matching + `omit` will not be included in the report. """ self.config.from_args( - ignore_errors=ignore_errors, - omit_prefixes=omit_prefixes, - include_prefixes=include_prefixes + ignore_errors=ignore_errors, omit=omit, include=include ) reporter = SummaryReporter( self, show_missing, self.config.ignore_errors ) reporter.report( - morfs, outfile=file, omit_prefixes=self.config.omit_prefixes, - include_prefixes=self.config.include_prefixes + morfs, outfile=file, omit=self.config.omit, + include=self.config.include ) def annotate(self, morfs=None, directory=None, ignore_errors=None, - omit_prefixes=None, include_prefixes=None): + omit=None, include=None): """Annotate a list of modules. Each module in `morfs` is annotated. The source is written to a new @@ -387,39 +393,35 @@ class coverage(object): """ self.config.from_args( - ignore_errors=ignore_errors, - omit_prefixes=omit_prefixes, - include_prefixes=include_prefixes + ignore_errors=ignore_errors, omit=omit, include=include ) reporter = AnnotateReporter(self, self.config.ignore_errors) reporter.report( morfs, directory=directory, - omit_prefixes=self.config.omit_prefixes, - include_prefixes=self.config.include_prefixes + omit=self.config.omit, + include=self.config.include ) def html_report(self, morfs=None, directory=None, ignore_errors=None, - omit_prefixes=None, include_prefixes=None): + omit=None, include=None): """Generate an HTML report. See `coverage.report()` for other arguments. """ self.config.from_args( - ignore_errors=ignore_errors, - omit_prefixes=omit_prefixes, - include_prefixes=include_prefixes, + ignore_errors=ignore_errors, omit=omit, include=include, html_dir=directory, ) reporter = HtmlReporter(self, self.config.ignore_errors) reporter.report( morfs, directory=self.config.html_dir, - omit_prefixes=self.config.omit_prefixes, - include_prefixes=self.config.include_prefixes + omit=self.config.omit, + include=self.config.include ) def xml_report(self, morfs=None, outfile=None, ignore_errors=None, - omit_prefixes=None, include_prefixes=None): + omit=None, include=None): """Generate an XML report of coverage results. The report is compatible with Cobertura reports. @@ -431,9 +433,7 @@ class coverage(object): """ self.config.from_args( - ignore_errors=ignore_errors, - omit_prefixes=omit_prefixes, - include_prefixes=include_prefixes, + ignore_errors=ignore_errors, omit=omit, include=include, xml_output=outfile, ) file_to_close = None @@ -446,8 +446,8 @@ class coverage(object): try: reporter = XmlReporter(self, self.config.ignore_errors) reporter.report( - morfs, omit_prefixes=self.config.omit_prefixes, - include_prefixes=self.config.include_prefixes, outfile=outfile + morfs, omit=self.config.omit, include=self.config.include, + outfile=outfile ) finally: if file_to_close: @@ -462,8 +462,8 @@ class coverage(object): info = [ ('version', covmod.__version__), ('coverage', covmod.__file__), - ('cover_prefix', self.cover_prefix), - ('pylib_prefix', self.pylib_prefix), + ('cover_dir', self.cover_dir), + ('pylib_dirs', self.pylib_dirs), ('tracer', self.collector.tracer_name()), ('data_path', self.data.filename), ('python', sys.version.replace('\n', '')), diff --git a/coverage/html.py b/coverage/html.py index 94ba0dea..80d3615d 100644 --- a/coverage/html.py +++ b/coverage/html.py @@ -31,9 +31,7 @@ class HtmlReporter(Reporter): self.files = [] self.arcs = coverage.data.has_arcs() - def report(self, morfs, directory, omit_prefixes=None, - include_prefixes=None - ): + def report(self, morfs, directory, omit=None, include=None): """Generate an HTML report for `morfs`. `morfs` is a list of modules or filenames. `directory` is where to put @@ -45,9 +43,7 @@ class HtmlReporter(Reporter): assert directory, "must provide a directory for html reporting" # Process all the files. - self.report_files( - self.html_file, morfs, directory, omit_prefixes, include_prefixes - ) + self.report_files(self.html_file, morfs, directory, omit, include) # Write the index file. self.index_file() diff --git a/coverage/parser.py b/coverage/parser.py index b090f02d..d883df46 100644 --- a/coverage/parser.py +++ b/coverage/parser.py @@ -306,6 +306,16 @@ class ByteParser(object): (filename, synerr.msg, synerr.lineno) ) + # Alternative Python implementations don't always provide all the + # attributes on code objects that we need to do the analysis. + for attr in ['co_lnotab', 'co_firstlineno', 'co_consts', 'co_code']: + if not hasattr(self.code, attr): + raise CoverageException( + "This implementation of Python doesn't support code " + "analysis.\n" + "Run coverage.py under CPython for this command." + ) + def child_parsers(self): """Iterate over all the code objects nested within this one. diff --git a/coverage/report.py b/coverage/report.py index a676e186..f7662a31 100644 --- a/coverage/report.py +++ b/coverage/report.py @@ -24,34 +24,32 @@ class Reporter(object): # classes. self.directory = None - def find_code_units(self, morfs, omit_prefixes, include_prefixes): + def find_code_units(self, morfs, omit, include): """Find the code units we'll report on. - `morfs` is a list of modules or filenames. `omit_prefixes` is a list - of prefixes to leave out of the list. + `morfs` is a list of modules or filenames. See `coverage.report()` for other arguments. """ morfs = morfs or self.coverage.data.executed_files() self.code_units = code_unit_factory( - morfs, self.coverage.file_locator, omit_prefixes, - include_prefixes + morfs, self.coverage.file_locator, omit, include ) self.code_units.sort() def report_files(self, report_fn, morfs, directory=None, - omit_prefixes=None, include_prefixes=None): + omit=None, include=None): """Run a reporting function on a number of morfs. `report_fn` is called for each relative morf in `morfs`. - `include_prefixes` is a list of filename prefixes. CodeUnits that match - those prefixes will be included in the list. CodeUnits that match - `omit_prefixes` will be omitted from the list. + `include` is a list of filename patterns. CodeUnits that match + those patterns will be included in the list. CodeUnits that match + `omit` will be omitted from the list. """ - self.find_code_units(morfs, omit_prefixes, include_prefixes) + self.find_code_units(morfs, omit, include) if not self.code_units: raise CoverageException("No data to report.") diff --git a/coverage/summary.py b/coverage/summary.py index 89b31020..37039bab 100644 --- a/coverage/summary.py +++ b/coverage/summary.py @@ -14,15 +14,13 @@ class SummaryReporter(Reporter): self.show_missing = show_missing self.branches = coverage.data.has_arcs() - def report(self, morfs, omit_prefixes=None, outfile=None, - include_prefixes=None - ): + def report(self, morfs, omit=None, outfile=None, include=None): """Writes a report summarizing coverage statistics per module. See `coverage.report()` for other arguments. """ - self.find_code_units(morfs, omit_prefixes, include_prefixes) + self.find_code_units(morfs, omit, include) # Prepare the formatting strings max_name = max([len(cu.name) for cu in self.code_units] + [5]) diff --git a/coverage/xmlreport.py b/coverage/xmlreport.py index 17d9fd5f..66c10a49 100644 --- a/coverage/xmlreport.py +++ b/coverage/xmlreport.py @@ -22,9 +22,7 @@ class XmlReporter(Reporter): self.xml_out = None self.arcs = coverage.data.has_arcs() - def report(self, morfs, omit_prefixes=None, include_prefixes=None, - outfile=None - ): + def report(self, morfs, omit=None, include=None, outfile=None): """Generate a Cobertura-compatible XML report for `morfs`. `morfs` is a list of modules or filenames. @@ -55,10 +53,7 @@ class XmlReporter(Reporter): # Call xml_file for each file in the data. self.packages = {} - self.report_files( - self.xml_file, morfs, omit_prefixes=omit_prefixes, - include_prefixes=include_prefixes - ) + self.report_files(self.xml_file, morfs, omit=omit, include=include) lnum_tot, lhits_tot = 0, 0 bnum_tot, bhits_tot = 0, 0 diff --git a/test/farm/html/run_omit_2.py b/test/farm/html/run_omit_2.py index 5d7e8329..53256d16 100644 --- a/test/farm/html/run_omit_2.py +++ b/test/farm/html/run_omit_2.py @@ -5,7 +5,7 @@ def html_it(): cov.start() import main cov.stop() - cov.html_report(directory="../html_omit_2", omit_prefixes=["m1"]) + cov.html_report(directory="../html_omit_2", omit=["m1.py"]) runfunc(html_it, rundir="src") compare("gold_omit_2", "html_omit_2", size_within=10, file_pattern="*.html") diff --git a/test/farm/html/run_omit_3.py b/test/farm/html/run_omit_3.py index 537ec2c7..7050cad3 100644 --- a/test/farm/html/run_omit_3.py +++ b/test/farm/html/run_omit_3.py @@ -5,7 +5,7 @@ def html_it(): cov.start() import main cov.stop() - cov.html_report(directory="../html_omit_3", omit_prefixes=["m1", "m2"]) + cov.html_report(directory="../html_omit_3", omit=["m1.py", "m2.py"]) runfunc(html_it, rundir="src") compare("gold_omit_3", "html_omit_3", size_within=10, file_pattern="*.html") diff --git a/test/farm/html/src/omit4.ini b/test/farm/html/src/omit4.ini index 95f62a13..6821ecda 100644 --- a/test/farm/html/src/omit4.ini +++ b/test/farm/html/src/omit4.ini @@ -1,2 +1,2 @@ [report] -omit = m2 +omit = m2.py diff --git a/test/farm/html/src/omit5.ini b/test/farm/html/src/omit5.ini index 70ef4917..7e32b414 100644 --- a/test/farm/html/src/omit5.ini +++ b/test/farm/html/src/omit5.ini @@ -1,8 +1,8 @@ [report] omit = fooey - gooey, m2, kablooey - m3, helloworld + gooey, m[23]*, kablooey + helloworld [html] directory = ../html_omit_5 diff --git a/test/test_api.py b/test/test_api.py index aaae89cb..eeeccfd5 100644 --- a/test/test_api.py +++ b/test/test_api.py @@ -273,7 +273,7 @@ class ApiTest(CoverageTest): cov.report() class OmitIncludeTest(CoverageTest): - """Test using omit_prefixes and include_prefixes when measuring code.""" + """Test using `omit` and `include` when measuring code.""" def test_nothing_specified(self): self.make_file("a.py", """\ @@ -301,7 +301,7 @@ class OmitIncludeTest(CoverageTest): b = 1 """) - cov = coverage.coverage(include_prefixes=["a"]) + cov = coverage.coverage(include=["a.py"]) cov.start() self.import_module("b") cov.stop() @@ -318,7 +318,7 @@ class OmitIncludeTest(CoverageTest): b = 1 """) - cov = coverage.coverage(omit_prefixes=["a"]) + cov = coverage.coverage(omit=["a*"]) cov.start() self.import_module("b") cov.stop() @@ -335,7 +335,7 @@ class OmitIncludeTest(CoverageTest): b = 1 """) - cov = coverage.coverage(include_prefixes=["a"], omit_prefixes=["aa"]) + cov = coverage.coverage(include=["a*"], omit=["aa.py"]) cov.start() self.import_module("ab") cov.stop() diff --git a/test/test_cmdline.py b/test/test_cmdline.py index 15fe1cec..cf20ba7f 100644 --- a/test/test_cmdline.py +++ b/test/test_cmdline.py @@ -16,7 +16,7 @@ class CmdLineTest(CoverageTest): run_in_temp_dir = False INIT_LOAD = """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=None) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=None) .load()\n""" def model_object(self): @@ -96,7 +96,7 @@ class ClassicCmdLineTest(CmdLineTest): def testErase(self): # coverage -e self.cmd_executes("-e", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=None) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=None) .erase() """) self.cmd_executes_same("-e", "--erase") @@ -106,7 +106,7 @@ class ClassicCmdLineTest(CmdLineTest): # -x calls coverage.load first. self.cmd_executes("-x foo.py", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=None) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=None) .load() .start() .run_python_file('foo.py', ['foo.py']) @@ -115,7 +115,7 @@ class ClassicCmdLineTest(CmdLineTest): """) # -e -x calls coverage.erase first. self.cmd_executes("-e -x foo.py", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=None) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=None) .erase() .start() .run_python_file('foo.py', ['foo.py']) @@ -124,7 +124,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=None, timid=True, branch=None, config_file=True, include_prefixes=None, omit_prefixes=None) + .coverage(cover_pylib=None, data_suffix=None, timid=True, branch=None, config_file=True, include=None, omit=None) .load() .start() .run_python_file('foo.py', ['foo.py', 'abc', '123']) @@ -133,7 +133,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, branch=None, config_file=True, include_prefixes=None, omit_prefixes=None) + .coverage(cover_pylib=True, data_suffix=True, timid=None, branch=None, config_file=True, include=None, omit=None) .load() .start() .run_python_file('foo.py', ['foo.py', '-a', '-b']) @@ -150,7 +150,7 @@ class ClassicCmdLineTest(CmdLineTest): def testCombine(self): # coverage -c self.cmd_executes("-c", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=None) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=None) .load() .combine() .save() @@ -160,35 +160,35 @@ class ClassicCmdLineTest(CmdLineTest): def testReport(self): # coverage -r [-m] [-i] [-o DIR,...] [FILE1 FILE2 ...] self.cmd_executes("-r", self.INIT_LOAD + """\ - .report(ignore_errors=None, omit_prefixes=None, include_prefixes=None, morfs=[], + .report(ignore_errors=None, omit=None, include=None, morfs=[], show_missing=None) """) self.cmd_executes("-r -i", self.INIT_LOAD + """\ - .report(ignore_errors=True, omit_prefixes=None, include_prefixes=None, morfs=[], + .report(ignore_errors=True, omit=None, include=None, morfs=[], show_missing=None) """) self.cmd_executes("-r -m", self.INIT_LOAD + """\ - .report(ignore_errors=None, omit_prefixes=None, include_prefixes=None, morfs=[], + .report(ignore_errors=None, omit=None, include=None, morfs=[], show_missing=True) """) self.cmd_executes("-r -o fooey", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=["fooey"]) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=["fooey"]) .load() - .report(ignore_errors=None, omit_prefixes=["fooey"], include_prefixes=None, + .report(ignore_errors=None, omit=["fooey"], include=None, morfs=[], show_missing=None) """) self.cmd_executes("-r -o fooey,booey", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=["fooey", "booey"]) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=["fooey", "booey"]) .load() - .report(ignore_errors=None, omit_prefixes=["fooey", "booey"], include_prefixes=None, + .report(ignore_errors=None, omit=["fooey", "booey"], include=None, morfs=[], show_missing=None) """) self.cmd_executes("-r mod1", self.INIT_LOAD + """\ - .report(ignore_errors=None, omit_prefixes=None, include_prefixes=None, + .report(ignore_errors=None, omit=None, include=None, morfs=["mod1"], show_missing=None) """) self.cmd_executes("-r mod1 mod2 mod3", self.INIT_LOAD + """\ - .report(ignore_errors=None, omit_prefixes=None, include_prefixes=None, + .report(ignore_errors=None, omit=None, include=None, morfs=["mod1", "mod2", "mod3"], show_missing=None) """) @@ -206,35 +206,35 @@ class ClassicCmdLineTest(CmdLineTest): # coverage -a [-d DIR] [-i] [-o DIR,...] [FILE1 FILE2 ...] self.cmd_executes("-a", self.INIT_LOAD + """\ .annotate(directory=None, ignore_errors=None, - omit_prefixes=None, include_prefixes=None, morfs=[]) + omit=None, include=None, morfs=[]) """) self.cmd_executes("-a -d dir1", self.INIT_LOAD + """\ .annotate(directory="dir1", ignore_errors=None, - omit_prefixes=None, include_prefixes=None, morfs=[]) + omit=None, include=None, morfs=[]) """) self.cmd_executes("-a -i", self.INIT_LOAD + """\ .annotate(directory=None, ignore_errors=True, - omit_prefixes=None, include_prefixes=None, morfs=[]) + omit=None, include=None, morfs=[]) """) self.cmd_executes("-a -o fooey", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=["fooey"]) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=["fooey"]) .load() .annotate(directory=None, ignore_errors=None, - omit_prefixes=["fooey"], include_prefixes=None, morfs=[]) + omit=["fooey"], include=None, morfs=[]) """) self.cmd_executes("-a -o fooey,booey", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=["fooey", "booey"]) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=["fooey", "booey"]) .load() .annotate(directory=None, ignore_errors=None, - omit_prefixes=["fooey", "booey"], include_prefixes=None, morfs=[]) + omit=["fooey", "booey"], include=None, morfs=[]) """) self.cmd_executes("-a mod1", self.INIT_LOAD + """\ .annotate(directory=None, ignore_errors=None, - omit_prefixes=None, include_prefixes=None, morfs=["mod1"]) + omit=None, include=None, morfs=["mod1"]) """) self.cmd_executes("-a mod1 mod2 mod3", self.INIT_LOAD + """\ .annotate(directory=None, ignore_errors=None, - omit_prefixes=None, include_prefixes=None, morfs=["mod1", "mod2", "mod3"]) + omit=None, include=None, morfs=["mod1", "mod2", "mod3"]) """) self.cmd_executes_same("-a", "--annotate") @@ -251,35 +251,35 @@ class ClassicCmdLineTest(CmdLineTest): # coverage -b -d DIR [-i] [-o DIR,...] [FILE1 FILE2 ...] self.cmd_executes("-b", self.INIT_LOAD + """\ .html_report(directory=None, ignore_errors=None, - omit_prefixes=None, include_prefixes=None, morfs=[]) + omit=None, include=None, morfs=[]) """) self.cmd_executes("-b -d dir1", self.INIT_LOAD + """\ .html_report(directory="dir1", ignore_errors=None, - omit_prefixes=None, include_prefixes=None, morfs=[]) + omit=None, include=None, morfs=[]) """) self.cmd_executes("-b -i", self.INIT_LOAD + """\ .html_report(directory=None, ignore_errors=True, - omit_prefixes=None, include_prefixes=None, morfs=[]) + omit=None, include=None, morfs=[]) """) self.cmd_executes("-b -o fooey", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=["fooey"]) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=["fooey"]) .load() .html_report(directory=None, ignore_errors=None, - omit_prefixes=["fooey"], include_prefixes=None, morfs=[]) + omit=["fooey"], include=None, morfs=[]) """) self.cmd_executes("-b -o fooey,booey", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=["fooey", "booey"]) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=["fooey", "booey"]) .load() .html_report(directory=None, ignore_errors=None, - omit_prefixes=["fooey", "booey"], include_prefixes=None, morfs=[]) + omit=["fooey", "booey"], include=None, morfs=[]) """) self.cmd_executes("-b mod1", self.INIT_LOAD + """\ .html_report(directory=None, ignore_errors=None, - omit_prefixes=None, include_prefixes=None, morfs=["mod1"]) + omit=None, include=None, morfs=["mod1"]) """) self.cmd_executes("-b mod1 mod2 mod3", self.INIT_LOAD + """\ .html_report(directory=None, ignore_errors=None, - omit_prefixes=None, include_prefixes=None, morfs=["mod1", "mod2", "mod3"]) + omit=None, include=None, morfs=["mod1", "mod2", "mod3"]) """) self.cmd_executes_same("-b", "--html") @@ -465,7 +465,7 @@ class NewCmdLineTest(CmdLineTest): self.cmd_executes_same("run --timid f.py", "-e -x --timid f.py") self.cmd_executes_same("run", "-x") self.cmd_executes("run --branch foo.py", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=True, config_file=True, include_prefixes=None, omit_prefixes=None) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=True, config_file=True, include=None, omit=None) .erase() .start() .run_python_file('foo.py', ['foo.py']) @@ -473,7 +473,7 @@ class NewCmdLineTest(CmdLineTest): .save() """) self.cmd_executes("run --rcfile=myrc.rc foo.py", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file="myrc.rc", include_prefixes=None, omit_prefixes=None) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file="myrc.rc", include=None, omit=None) .erase() .start() .run_python_file('foo.py', ['foo.py']) @@ -481,7 +481,7 @@ class NewCmdLineTest(CmdLineTest): .save() """) self.cmd_executes("run --include=pre1,pre2 foo.py", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=["pre1", "pre2"], omit_prefixes=None) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=["pre1", "pre2"], omit=None) .erase() .start() .run_python_file('foo.py', ['foo.py']) @@ -489,7 +489,7 @@ class NewCmdLineTest(CmdLineTest): .save() """) self.cmd_executes("run --omit=opre1,opre2 foo.py", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=["opre1", "opre2"]) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=["opre1", "opre2"]) .erase() .start() .run_python_file('foo.py', ['foo.py']) @@ -500,8 +500,8 @@ class NewCmdLineTest(CmdLineTest): """\ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, - include_prefixes=["pre1", "pre2"], - omit_prefixes=["opre1", "opre2"]) + include=["pre1", "pre2"], + omit=["opre1", "opre2"]) .erase() .start() .run_python_file('foo.py', ['foo.py']) @@ -512,39 +512,39 @@ class NewCmdLineTest(CmdLineTest): def testXml(self): # coverage xml [-i] [--omit DIR,...] [FILE1 FILE2 ...] self.cmd_executes("xml", self.INIT_LOAD + """\ - .xml_report(ignore_errors=None, omit_prefixes=None, include_prefixes=None, morfs=[], + .xml_report(ignore_errors=None, omit=None, include=None, morfs=[], outfile="coverage.xml") """) self.cmd_executes("xml -i", self.INIT_LOAD + """\ - .xml_report(ignore_errors=True, omit_prefixes=None, include_prefixes=None, morfs=[], + .xml_report(ignore_errors=True, omit=None, include=None, morfs=[], outfile="coverage.xml") """) self.cmd_executes("xml -o myxml.foo", self.INIT_LOAD + """\ - .xml_report(ignore_errors=None, omit_prefixes=None, include_prefixes=None, morfs=[], + .xml_report(ignore_errors=None, omit=None, include=None, morfs=[], outfile="myxml.foo") """) self.cmd_executes("xml -o -", self.INIT_LOAD + """\ - .xml_report(ignore_errors=None, omit_prefixes=None, include_prefixes=None, morfs=[], + .xml_report(ignore_errors=None, omit=None, include=None, morfs=[], outfile="-") """) self.cmd_executes("xml --omit fooey", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=["fooey"]) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=["fooey"]) .load() - .xml_report(ignore_errors=None, omit_prefixes=["fooey"], include_prefixes=None, morfs=[], + .xml_report(ignore_errors=None, omit=["fooey"], include=None, morfs=[], outfile="coverage.xml") """) self.cmd_executes("xml --omit fooey,booey", """\ - .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include_prefixes=None, omit_prefixes=["fooey", "booey"]) + .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, include=None, omit=["fooey", "booey"]) .load() - .xml_report(ignore_errors=None, omit_prefixes=["fooey", "booey"], include_prefixes=None, + .xml_report(ignore_errors=None, omit=["fooey", "booey"], include=None, morfs=[], outfile="coverage.xml") """) self.cmd_executes("xml mod1", self.INIT_LOAD + """\ - .xml_report(ignore_errors=None, omit_prefixes=None, include_prefixes=None, morfs=["mod1"], + .xml_report(ignore_errors=None, omit=None, include=None, morfs=["mod1"], outfile="coverage.xml") """) self.cmd_executes("xml mod1 mod2 mod3", self.INIT_LOAD + """\ - .xml_report(ignore_errors=None, omit_prefixes=None, include_prefixes=None, + .xml_report(ignore_errors=None, omit=None, include=None, morfs=["mod1", "mod2", "mod3"], outfile="coverage.xml") """) diff --git a/test/test_config.py b/test/test_config.py index d29ab3d7..96b87650 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -137,8 +137,8 @@ class ConfigFileTest(CoverageTest): ["if 0:", "pragma:?\s+no cover", "another_tab"] ) self.assertTrue(cov.config.ignore_errors) - self.assertEqual(cov.config.include_prefixes, ["a/", "b/"]) - self.assertEqual(cov.config.omit_prefixes, + self.assertEqual(cov.config.include, ["a/", "b/"]) + self.assertEqual(cov.config.omit, ["one", "another", "some_more", "yet_more"] ) diff --git a/test/test_summary.py b/test/test_summary.py index b41a3e7d..d797cc50 100644 --- a/test/test_summary.py +++ b/test/test_summary.py @@ -72,7 +72,7 @@ class SummaryTest(CoverageTest): # Try reporting while omitting some modules prefix = os.path.split(__file__)[0] self.run_command("coverage -x mycode.py") - report = self.report_from_command("coverage -r -o %s" % prefix) + report = self.report_from_command("coverage -r -o '%s/*'" % prefix) # Name Stmts Miss Cover # ---------------------------- |