19 from coverage.config import read_coverage_config |
19 from coverage.config import read_coverage_config |
20 from coverage.context import should_start_context_test_function, combine_context_switchers |
20 from coverage.context import should_start_context_test_function, combine_context_switchers |
21 from coverage.data import CoverageData, combine_parallel_data |
21 from coverage.data import CoverageData, combine_parallel_data |
22 from coverage.debug import DebugControl, short_stack, write_formatted_info |
22 from coverage.debug import DebugControl, short_stack, write_formatted_info |
23 from coverage.disposition import disposition_debug_msg |
23 from coverage.disposition import disposition_debug_msg |
24 from coverage.exceptions import CoverageException, CoverageWarning |
24 from coverage.exceptions import ConfigError, CoverageException, CoverageWarning, PluginError |
25 from coverage.files import PathAliases, abs_file, relative_filename, set_relative_directory |
25 from coverage.files import PathAliases, abs_file, relative_filename, set_relative_directory |
26 from coverage.html import HtmlReporter |
26 from coverage.html import HtmlReporter |
27 from coverage.inorout import InOrOut |
27 from coverage.inorout import InOrOut |
28 from coverage.jsonreport import JsonReporter |
28 from coverage.jsonreport import JsonReporter |
29 from coverage.misc import bool_or_none, join_regex, human_sorted, human_sorted_items |
29 from coverage.misc import bool_or_none, join_regex, human_sorted, human_sorted_items |
77 |
77 |
78 Note: in keeping with Python custom, names starting with underscore are |
78 Note: in keeping with Python custom, names starting with underscore are |
79 not part of the public API. They might stop working at any point. Please |
79 not part of the public API. They might stop working at any point. Please |
80 limit yourself to documented methods to avoid problems. |
80 limit yourself to documented methods to avoid problems. |
81 |
81 |
|
82 Methods can raise any of the exceptions described in :ref:`api_exceptions`. |
|
83 |
82 """ |
84 """ |
83 |
85 |
84 # The stack of started Coverage instances. |
86 # The stack of started Coverage instances. |
85 _instances = [] |
87 _instances = [] |
86 |
88 |
444 self._data.read() |
446 self._data.read() |
445 |
447 |
446 def _init_for_start(self): |
448 def _init_for_start(self): |
447 """Initialization for start()""" |
449 """Initialization for start()""" |
448 # Construct the collector. |
450 # Construct the collector. |
449 concurrency = self.config.concurrency or () |
451 concurrency = self.config.concurrency or [] |
450 if "multiprocessing" in concurrency: |
452 if "multiprocessing" in concurrency: |
451 if not patch_multiprocessing: |
453 if not patch_multiprocessing: |
452 raise CoverageException( # pragma: only jython |
454 raise ConfigError( # pragma: only jython |
453 "multiprocessing is not supported on this Python" |
455 "multiprocessing is not supported on this Python" |
454 ) |
456 ) |
455 patch_multiprocessing(rcfile=self.config.config_file) |
457 patch_multiprocessing(rcfile=self.config.config_file) |
456 |
458 |
457 dycon = self.config.dynamic_context |
459 dycon = self.config.dynamic_context |
458 if not dycon or dycon == "none": |
460 if not dycon or dycon == "none": |
459 context_switchers = [] |
461 context_switchers = [] |
460 elif dycon == "test_function": |
462 elif dycon == "test_function": |
461 context_switchers = [should_start_context_test_function] |
463 context_switchers = [should_start_context_test_function] |
462 else: |
464 else: |
463 raise CoverageException(f"Don't understand dynamic_context setting: {dycon!r}") |
465 raise ConfigError(f"Don't understand dynamic_context setting: {dycon!r}") |
464 |
466 |
465 context_switchers.extend( |
467 context_switchers.extend( |
466 plugin.dynamic_context for plugin in self._plugins.context_switchers |
468 plugin.dynamic_context for plugin in self._plugins.context_switchers |
467 ) |
469 ) |
468 |
470 |
478 warn=self._warn, |
480 warn=self._warn, |
479 concurrency=concurrency, |
481 concurrency=concurrency, |
480 ) |
482 ) |
481 |
483 |
482 suffix = self._data_suffix_specified |
484 suffix = self._data_suffix_specified |
483 if suffix or self.config.parallel: |
485 if suffix: |
484 if not isinstance(suffix, str): |
486 if not isinstance(suffix, str): |
485 # if data_suffix=True, use .machinename.pid.random |
487 # if data_suffix=True, use .machinename.pid.random |
486 suffix = True |
488 suffix = True |
|
489 elif self.config.parallel: |
|
490 if suffix is None: |
|
491 suffix = True |
|
492 elif not isinstance(suffix, str): |
|
493 suffix = bool(suffix) |
487 else: |
494 else: |
488 suffix = None |
495 suffix = None |
489 |
496 |
490 self._init_data(suffix) |
497 self._init_data(suffix) |
491 |
498 |
833 plugin = self._plugins.get(plugin_name) |
840 plugin = self._plugins.get(plugin_name) |
834 |
841 |
835 if plugin: |
842 if plugin: |
836 file_reporter = plugin.file_reporter(mapped_morf) |
843 file_reporter = plugin.file_reporter(mapped_morf) |
837 if file_reporter is None: |
844 if file_reporter is None: |
838 raise CoverageException( |
845 raise PluginError( |
839 "Plugin {!r} did not provide a file reporter for {!r}.".format( |
846 "Plugin {!r} did not provide a file reporter for {!r}.".format( |
840 plugin._coverage_plugin_name, morf |
847 plugin._coverage_plugin_name, morf |
841 ) |
848 ) |
842 ) |
849 ) |
843 |
850 |
931 omit=None, include=None, contexts=None, |
938 omit=None, include=None, contexts=None, |
932 ): |
939 ): |
933 """Annotate a list of modules. |
940 """Annotate a list of modules. |
934 |
941 |
935 .. note:: |
942 .. note:: |
936 This method has been obsoleted by more modern reporting tools, |
943 |
937 including the :meth:`html_report` method. It will be removed in a |
944 This method has been obsoleted by more modern reporting tools, |
938 future version. |
945 including the :meth:`html_report` method. It will be removed in a |
|
946 future version. |
939 |
947 |
940 Each module in `morfs` is annotated. The source is written to a new |
948 Each module in `morfs` is annotated. The source is written to a new |
941 file, named with a ",cover" suffix, with each line prefixed with a |
949 file, named with a ",cover" suffix, with each line prefixed with a |
942 marker to indicate the coverage of the line. Covered lines have ">", |
950 marker to indicate the coverage of the line. Covered lines have ">", |
943 excluded lines have "-", and missing lines have "!". |
951 excluded lines have "-", and missing lines have "!". |
976 See :meth:`report` for other arguments. |
984 See :meth:`report` for other arguments. |
977 |
985 |
978 Returns a float, the total percentage covered. |
986 Returns a float, the total percentage covered. |
979 |
987 |
980 .. note:: |
988 .. note:: |
|
989 |
981 The HTML report files are generated incrementally based on the |
990 The HTML report files are generated incrementally based on the |
982 source files and coverage results. If you modify the report files, |
991 source files and coverage results. If you modify the report files, |
983 the changes will not be considered. You should be careful about |
992 the changes will not be considered. You should be careful about |
984 changing the files in the report folder. |
993 changing the files in the report folder. |
985 |
994 |