DebugClients/Python/coverage/report.py

changeset 4489
d0d6e4ad31bd
parent 3499
f2d4b02c7e88
child 4491
0d8612e24fef
equal deleted inserted replaced
4481:456c58fc64b0 4489:d0d6e4ad31bd
1 """Reporter foundation for Coverage.""" 1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
2 # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
2 3
3 import fnmatch, os 4 """Reporter foundation for coverage.py."""
4 from .codeunit import code_unit_factory 5
5 from .files import prep_patterns 6 import os
6 from .misc import CoverageException, NoSource, NotPython 7
8 from coverage.files import prep_patterns, FnmatchMatcher
9 from coverage.misc import CoverageException, NoSource, NotPython
10
7 11
8 class Reporter(object): 12 class Reporter(object):
9 """A base class for all reporters.""" 13 """A base class for all reporters."""
10 14
11 def __init__(self, coverage, config): 15 def __init__(self, coverage, config):
16 20
17 """ 21 """
18 self.coverage = coverage 22 self.coverage = coverage
19 self.config = config 23 self.config = config
20 24
21 # The code units to report on. Set by find_code_units. 25 # The FileReporters to report on. Set by find_file_reporters.
22 self.code_units = [] 26 self.file_reporters = []
23 27
24 # The directory into which to place the report, used by some derived 28 # The directory into which to place the report, used by some derived
25 # classes. 29 # classes.
26 self.directory = None 30 self.directory = None
27 31
28 def find_code_units(self, morfs): 32 def find_file_reporters(self, morfs):
29 """Find the code units we'll report on. 33 """Find the FileReporters we'll report on.
30 34
31 `morfs` is a list of modules or filenames. 35 `morfs` is a list of modules or file names.
32 36
33 """ 37 """
34 morfs = morfs or self.coverage.data.measured_files() 38 self.file_reporters = self.coverage._get_file_reporters(morfs)
35 file_locator = self.coverage.file_locator
36 self.code_units = code_unit_factory(morfs, file_locator)
37 39
38 if self.config.include: 40 if self.config.include:
39 patterns = prep_patterns(self.config.include) 41 patterns = prep_patterns(self.config.include)
42 matcher = FnmatchMatcher(patterns)
40 filtered = [] 43 filtered = []
41 for cu in self.code_units: 44 for fr in self.file_reporters:
42 for pattern in patterns: 45 if matcher.match(fr.filename):
43 if fnmatch.fnmatch(cu.filename, pattern): 46 filtered.append(fr)
44 filtered.append(cu) 47 self.file_reporters = filtered
45 break
46 self.code_units = filtered
47 48
48 if self.config.omit: 49 if self.config.omit:
49 patterns = prep_patterns(self.config.omit) 50 patterns = prep_patterns(self.config.omit)
51 matcher = FnmatchMatcher(patterns)
50 filtered = [] 52 filtered = []
51 for cu in self.code_units: 53 for fr in self.file_reporters:
52 for pattern in patterns: 54 if not matcher.match(fr.filename):
53 if fnmatch.fnmatch(cu.filename, pattern): 55 filtered.append(fr)
54 break 56 self.file_reporters = filtered
55 else:
56 filtered.append(cu)
57 self.code_units = filtered
58 57
59 self.code_units.sort() 58 self.file_reporters.sort()
60 59
61 def report_files(self, report_fn, morfs, directory=None): 60 def report_files(self, report_fn, morfs, directory=None):
62 """Run a reporting function on a number of morfs. 61 """Run a reporting function on a number of morfs.
63 62
64 `report_fn` is called for each relative morf in `morfs`. It is called 63 `report_fn` is called for each relative morf in `morfs`. It is called
65 as:: 64 as::
66 65
67 report_fn(code_unit, analysis) 66 report_fn(file_reporter, analysis)
68 67
69 where `code_unit` is the `CodeUnit` for the morf, and `analysis` is 68 where `file_reporter` is the `FileReporter` for the morf, and
70 the `Analysis` for the morf. 69 `analysis` is the `Analysis` for the morf.
71 70
72 """ 71 """
73 self.find_code_units(morfs) 72 self.find_file_reporters(morfs)
74 73
75 if not self.code_units: 74 if not self.file_reporters:
76 raise CoverageException("No data to report.") 75 raise CoverageException("No data to report.")
77 76
78 self.directory = directory 77 self.directory = directory
79 if self.directory and not os.path.exists(self.directory): 78 if self.directory and not os.path.exists(self.directory):
80 os.makedirs(self.directory) 79 os.makedirs(self.directory)
81 80
82 for cu in self.code_units: 81 for fr in self.file_reporters:
83 try: 82 try:
84 report_fn(cu, self.coverage._analyze(cu)) 83 report_fn(fr, self.coverage._analyze(fr))
85 except NoSource: 84 except NoSource:
86 if not self.config.ignore_errors: 85 if not self.config.ignore_errors:
87 raise 86 raise
88 except NotPython: 87 except NotPython:
89 # Only report errors for .py files, and only if we didn't 88 # Only report errors for .py files, and only if we didn't
90 # explicitly suppress those errors. 89 # explicitly suppress those errors.
91 if cu.should_be_python() and not self.config.ignore_errors: 90 # NotPython is only raised by PythonFileReporter, which has a
91 # should_be_python() method.
92 if fr.should_be_python() and not self.config.ignore_errors:
92 raise 93 raise
93
94 #
95 # eflag: FileType = Python2

eric ide

mercurial