|
1 """Reporter foundation for Coverage.""" |
|
2 |
|
3 import os |
|
4 from codeunit import code_unit_factory |
|
5 |
|
6 class Reporter(object): |
|
7 """A base class for all reporters.""" |
|
8 |
|
9 def __init__(self, coverage, ignore_errors=False): |
|
10 """Create a reporter. |
|
11 |
|
12 `coverage` is the coverage instance. `ignore_errors` controls how |
|
13 skittish the reporter will be during file processing. |
|
14 |
|
15 """ |
|
16 self.coverage = coverage |
|
17 self.ignore_errors = ignore_errors |
|
18 |
|
19 # The code units to report on. Set by find_code_units. |
|
20 self.code_units = [] |
|
21 |
|
22 # The directory into which to place the report, used by some derived |
|
23 # classes. |
|
24 self.directory = None |
|
25 |
|
26 def find_code_units(self, morfs, omit_prefixes): |
|
27 """Find the code units we'll report on. |
|
28 |
|
29 `morfs` is a list of modules or filenames. `omit_prefixes` is a list |
|
30 of prefixes to leave out of the list. |
|
31 |
|
32 """ |
|
33 morfs = morfs or self.coverage.data.executed_files() |
|
34 self.code_units = code_unit_factory( |
|
35 morfs, self.coverage.file_locator, omit_prefixes) |
|
36 self.code_units.sort() |
|
37 |
|
38 def report_files(self, report_fn, morfs, directory=None, |
|
39 omit_prefixes=None): |
|
40 """Run a reporting function on a number of morfs. |
|
41 |
|
42 `report_fn` is called for each relative morf in `morfs`. |
|
43 |
|
44 """ |
|
45 self.find_code_units(morfs, omit_prefixes) |
|
46 |
|
47 self.directory = directory |
|
48 if self.directory and not os.path.exists(self.directory): |
|
49 os.makedirs(self.directory) |
|
50 |
|
51 for cu in self.code_units: |
|
52 try: |
|
53 if not cu.relative: |
|
54 continue |
|
55 statements, excluded, missing, _ = self.coverage._analyze(cu) |
|
56 report_fn(cu, statements, excluded, missing) |
|
57 except KeyboardInterrupt: |
|
58 raise |
|
59 except: |
|
60 if not self.ignore_errors: |
|
61 raise |