summaryrefslogtreecommitdiff
path: root/coverage/control.py
diff options
context:
space:
mode:
Diffstat (limited to 'coverage/control.py')
-rw-r--r--coverage/control.py54
1 files changed, 30 insertions, 24 deletions
diff --git a/coverage/control.py b/coverage/control.py
index e568f643..346f655f 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -9,13 +9,13 @@ from coverage.collector import Collector
from coverage.config import CoverageConfig
from coverage.data import CoverageData
from coverage.debug import DebugControl
-from coverage.plugin import CoveragePlugin, Plugins, overrides
+from coverage.plugin import CoveragePlugin, Plugins
from coverage.files import FileLocator, TreeMatcher, FnmatchMatcher
from coverage.files import PathAliases, find_python_files, prep_patterns
from coverage.files import ModuleMatcher
from coverage.html import HtmlReporter
from coverage.misc import CoverageException, bool_or_none, join_regex
-from coverage.misc import file_be_gone
+from coverage.misc import file_be_gone, overrides
from coverage.results import Analysis, Numbers
from coverage.summary import SummaryReporter
from coverage.xmlreport import XmlReporter
@@ -24,7 +24,7 @@ from coverage.xmlreport import XmlReporter
# Pypy has some unusual stuff in the "stdlib". Consider those locations
# when deciding where the stdlib is.
try:
- import _structseq # pylint: disable=F0401
+ import _structseq
except ImportError:
_structseq = None
@@ -353,6 +353,7 @@ class Coverage(object):
"""
disp = FileDisposition(filename)
def nope(disp, reason):
+ """Simple helper to make it easy to return NO."""
disp.trace = False
disp.reason = reason
return disp
@@ -371,8 +372,6 @@ class Coverage(object):
# Empty string is pretty useless
return nope(disp, "empty string isn't a filename")
- modulename = self._name_for_module(frame.f_globals, filename)
-
if filename.startswith('memory:'):
return nope(disp, "memory isn't traceable")
@@ -398,7 +397,10 @@ class Coverage(object):
file_tracer.plugin_name = plugin.plugin_name
disp.trace = True
disp.file_tracer = file_tracer
- disp.source_filename = self.file_locator.canonical_filename(file_tracer.source_filename())
+ if file_tracer.has_dynamic_source_filename():
+ disp.has_dynamic_filename = True
+ else:
+ disp.source_filename = self.file_locator.canonical_filename(file_tracer.source_filename())
else:
disp.trace = True
disp.source_filename = canonical
@@ -406,29 +408,32 @@ class Coverage(object):
if disp.trace:
if file_tracer:
disp.file_tracer = file_tracer
- if disp.source_filename is None:
- raise CoverageException(
- "Plugin %r didn't set source_filename for %r" %
- (plugin, disp.original_filename)
- )
- if disp.check_filters:
- reason = self._check_include_omit_etc(
- disp.source_filename, modulename,
- )
- if reason:
- nope(disp, reason)
+ if not disp.has_dynamic_filename:
+ if disp.source_filename is None:
+ raise CoverageException(
+ "Plugin %r didn't set source_filename for %r" %
+ (plugin, disp.original_filename)
+ )
+ if disp.check_filters:
+ reason = self._check_include_omit_etc(
+ disp.source_filename, frame,
+ )
+ if reason:
+ nope(disp, reason)
return disp
return nope(disp, "no plugin found") # TODO: a test that causes this.
- def _check_include_omit_etc(self, filename, modulename):
+ def _check_include_omit_etc(self, filename, frame):
"""Check a filename against the include, omit, etc, rules.
Returns a string or None. String means, don't trace, and is the reason
why. None means no reason found to not trace.
"""
+ modulename = self._name_for_module(frame.f_globals, filename)
+
# If the user specified source or include, then that's authoritative
# about the outer bound of what to measure and we don't have to apply
# any canned exclusions. If they didn't, then we have to exclude the
@@ -473,13 +478,13 @@ class Coverage(object):
self.debug.write(disp.debug_message())
return disp
- def _tracing_check_include_omit_etc(self, filename):
- """Check a filename against the include, omit, etc, rules, and say so.
+ def _tracing_check_include_omit_etc(self, filename, frame):
+ """Check a filename against the include/omit/etc, rules, verbosely.
Returns a boolean: True if the file should be traced, False if not.
"""
- reason = self._check_include_omit_etc(filename)
+ reason = self._check_include_omit_etc(filename, frame)
if self.debug.should('trace'):
if not reason:
msg = "Tracing %r" % (filename,)
@@ -750,8 +755,8 @@ Unexpected third case:
return Analysis(self, it)
def report(self, morfs=None, show_missing=True, ignore_errors=None,
- file=None, # pylint: disable=W0622
- omit=None, include=None
+ file=None, # pylint: disable=redefined-builtin
+ omit=None, include=None, skip_covered=False,
):
"""Write a summary report to `file`.
@@ -768,7 +773,7 @@ Unexpected third case:
self._harvest_data()
self.config.from_args(
ignore_errors=ignore_errors, omit=omit, include=include,
- show_missing=show_missing,
+ show_missing=show_missing, skip_covered=skip_covered,
)
reporter = SummaryReporter(self, self.config)
return reporter.report(morfs, outfile=file)
@@ -921,6 +926,7 @@ class FileDisposition(object):
self.trace = False
self.reason = ""
self.file_tracer = None
+ self.has_dynamic_filename = False
def debug_message(self):
"""Produce a debugging message explaining the outcome."""