Пример #1
0
    def run(self, edit):
        view = self.view
        view.erase_regions('SublimePythonCoverage')
        fname = view.file_name()
        if not fname or not fname.endswith('.py'):
            return

        cov_file = find(fname, '.coverage')
        if not cov_file:
            print('No .coverage file found near %s' % fname)
            return
        else:
            print('Reading coverage data from %s' % cov_file)

        config_file = os.path.join(os.path.dirname(cov_file), '.coveragerc')

        if find(fname, '.coverage-noisy'):
            flags = sublime.DRAW_EMPTY | sublime.DRAW_OUTLINED
        else:
            flags = sublime.HIDDEN

        # run analysis and find uncovered lines
        cov = Coverage(data_file=cov_file, config_file=config_file)
        outlines = []
        cov.load()
        if not cov.omit or not FnmatchMatcher(cov.omit).match(fname):
            f, s, excluded, missing, m = cov.analysis2(fname)
            for line in missing:
                outlines.append(view.full_line(view.text_point(line - 1, 0)))

        # update highlighted regions
        view.add_regions('SublimePythonCoverage', outlines,
                         'coverage.missing', 'bookmark', flags)
Пример #2
0
def main():
    options = parse_args()
    test_directory = os.path.dirname(os.path.abspath(__file__))
    selected_tests = get_selected_tests(options)

    if options.verbose:
        print_to_stderr('Selected tests: {}'.format(', '.join(selected_tests)))

    if options.coverage and not PYTORCH_COLLECT_COVERAGE:
        shell(['coverage', 'erase'])

    if options.jit:
        selected_tests = filter(lambda test_name: "jit" in test_name, TESTS)

    if options.determine_from is not None and os.path.exists(options.determine_from):
        with open(options.determine_from, 'r') as fh:
            touched_files = [
                os.path.normpath(name.strip()) for name in fh.read().split('\n')
                if len(name.strip()) > 0
            ]
        # HACK: Ensure the 'test' paths can be traversed by Modulefinder
        sys.path.append('test')
        selected_tests = [
            test for test in selected_tests
            if determine_target(test, touched_files, options)
        ]
        sys.path.remove('test')

    has_failed = False
    failure_messages = []
    try:
        for test in selected_tests:
            options_clone = copy.deepcopy(options)
            if test in USE_PYTEST_LIST:
                options_clone.pytest = True
            err_message = run_test_module(test, test_directory, options_clone)
            if err_message is None:
                continue
            has_failed = True
            failure_messages.append(err_message)
            if not options_clone.continue_through_error:
                raise RuntimeError(err_message)
            print_to_stderr(err_message)
    finally:
        if options.coverage:
            from coverage import Coverage
            test_dir = os.path.dirname(os.path.abspath(__file__))
            with set_cwd(test_dir):
                cov = Coverage()
                if PYTORCH_COLLECT_COVERAGE:
                    cov.load()
                cov.combine(strict=False)
                cov.save()
                if not PYTORCH_COLLECT_COVERAGE:
                    cov.html_report()

    if options.continue_through_error and has_failed:
        for err in failure_messages:
            print_to_stderr(err)
        sys.exit(1)
Пример #3
0
def read_coverage_data():
    """
    :rtype: CoverageData or None
    """
    print('Using coverage data from .coverage file')
    # noinspection PyPackageRequirements,PyUnresolvedReferences
    from coverage import Coverage
    cov = Coverage('.coverage')
    cov.load()
    return cov.get_data()
Пример #4
0
def main():
    options = parse_args()

    test_directory = str(REPO_ROOT / "test")
    selected_tests = get_selected_tests(options)

    if options.verbose:
        print_to_stderr("Selected tests:\n {}".format(
            "\n ".join(selected_tests)))

    if options.dry_run:
        return

    if options.coverage and not PYTORCH_COLLECT_COVERAGE:
        shell(["coverage", "erase"])

    if IS_CI:
        selected_tests = get_reordered_tests(selected_tests)
        # downloading test cases configuration to local environment
        get_test_case_configs(dirpath=test_directory)

    has_failed = False
    failure_messages = []
    try:
        for test in selected_tests:
            options_clone = copy.deepcopy(options)
            if test in USE_PYTEST_LIST:
                options_clone.pytest = True
            err_message = run_test_module(test, test_directory, options_clone)
            if err_message is None:
                continue
            has_failed = True
            failure_messages.append(err_message)
            if not options_clone.continue_through_error:
                raise RuntimeError(err_message)
            print_to_stderr(err_message)
    finally:
        if options.coverage:
            from coverage import Coverage

            with set_cwd(test_directory):
                cov = Coverage()
                if PYTORCH_COLLECT_COVERAGE:
                    cov.load()
                cov.combine(strict=False)
                cov.save()
                if not PYTORCH_COLLECT_COVERAGE:
                    cov.html_report()

    if options.continue_through_error and has_failed:
        for err in failure_messages:
            print_to_stderr(err)
        sys.exit(1)
Пример #5
0
def read_coverage_data():
    """
    :rtype: CoverageData or None
    """
    try:
        # noinspection PyPackageRequirements,PyUnresolvedReferences
        from coverage import Coverage
    except ImportError as e:
        raise ImportError('The --use-coverage feature requires the coverage library. Run "pip install coverage"') from e
    cov = Coverage('.coverage')
    cov.load()
    return cov.get_data()
Пример #6
0
def read_coverage_data():
    """
    :rtype: CoverageData or None
    """
    try:
        # noinspection PyPackageRequirements,PyUnresolvedReferences
        from coverage import Coverage
    except ImportError as e:
        raise ImportError('The --use-coverage feature requires the coverage library. Run "pip install --force-reinstall mutmut[coverage]"') from e
    cov = Coverage('.coverage')
    cov.load()
    data = cov.get_data()
    return {filepath: data.lines(filepath) for filepath in data.measured_files()}
Пример #7
0
def coverage_read(root):
    coverage = Coverage(".coverage")  # use pathlib
    coverage.load()
    data = coverage.get_data()
    filepaths = data.measured_files()
    out = dict()
    root = root.resolve()
    for filepath in filepaths:
        key = str(Path(filepath).relative_to(root))
        value = set(data.lines(filepath))
        print(key)
        out[key] = value
    return out
Пример #8
0
def test_py3(module):
    futurize(module)
    fix_patterns(module)
    result, elapsed = run_destral(module)
    py3 = int(result == 0)
    cov = Coverage()
    try:
        cov.load()
        cov_per = cov.report()
        cov.erase()
    except Exception:
        cov_per = 0

    update_module(module, py3, coverage=cov_per, test_time=elapsed)
Пример #9
0
    def __annotate(self):
        """
        Private slot to handle the annotate context menu action.
        
        This method produce an annotated coverage file of the
        selected file.
        """
        itm = self.resultList.currentItem()
        fn = itm.text(0)

        cover = Coverage(data_file=self.cfn)
        cover.exclude(self.excludeList[0])
        cover.load()
        cover.annotate([fn], None, True)
Пример #10
0
    def __erase(self):
        """
        Private slot to handle the erase context menu action.
        
        This method erases the collected coverage data that is
        stored in the .coverage file.
        """
        cover = Coverage(data_file=self.cfn)
        cover.load()
        cover.erase()

        self.reloadButton.setEnabled(False)
        self.resultList.clear()
        self.summaryList.clear()
Пример #11
0
def coverageReportHelper(config, dataPaths):
    """
    Small utility function to generate coverage reports.

    This was created to side-step the difficulties in submitting multi-line python
    commands on-the-fly.

    This combines data paths and then makes html and xml reports for the
    fully-combined result.
    """
    from coverage import Coverage
    import coverage

    try:
        cov = Coverage(config_file=config)
        if dataPaths:
            # fun fact: if you combine when there's only one file, it gets deleted.
            cov.combine(data_paths=dataPaths)
            cov.save()
        else:
            cov.load()
        cov.html_report()
        cov.xml_report()
    except PermissionError:
        # Albert has some issues with filename that start with a '.', such as the
        # .coverage files. If a permissions error is raised, it likely has something to
        # do with that. We changed the COVERAGE_RESULTS_FILE in cases.py for this reason.
        #
        # We print here, since this is used to run a one-off command, so runLog isn't
        # really appropriate.
        print(
            "There was an issue in generating coverage reports. Probably related to "
            "Albert hidden file issues."
        )
        # disabled until we figure out the problem.
        # raise
    except coverage.misc.CoverageException as e:
        # This is happening when forming the unit test coverage report. This may be
        # caused by the TestFixture coverage report gobbling up all of the coverage
        # files before the UnitTests.cov_report task gets a chance to see them. It may
        # simply be that we dont want a coverage report generated for the TestFixture.
        # Something to think about. Either way, we do not want to fail the job just
        # because of this
        print(
            "There was an issue generating coverage reports "
            "({}):\n{}".format(type(e), e.args)
        )
Пример #12
0
def initData():
    """Load data and mappings from Raw data files and mapping files"""
    Patient.load()
    VitalSigns.load()
    Lab.load()
    Procedure.load()
    Immunization.load()
    FamilyHistory.load()
    SocialHistory.load()
    Condition.load()
    Med.load()
    Refill.load()
    Document.load()
    Allergy.load()
    ClinicalNote.load()
    Practitioner.load()
    Coverage.load()
    ExplanationOfBenefit.load()
Пример #13
0
    def run_tests(self, *args, **kwargs):
        suite_result = super().run_tests(*args, **kwargs)

        cov = getattr(process_startup, "coverage")
        cov.stop()
        cov.save()

        print()
        print("Generating Coverage Report...")

        combined_cov = Coverage()
        combined_cov.load()
        combined_cov.combine()
        combined_cov.report()
        combined_cov.html_report()

        print()
        print("Linting files...")
        subprocess.call(["flake8"])

        return suite_result
Пример #14
0
def main():
    args = read_args()

    cov = Coverage()
    cov.load()

    if (args.current_branch or args.branch2) in args.full_branches:
        passed = show_coverage(cov, show_missing=args.show_missing_full, fail_under=args.fail_under)
        exit_with_status(passed)

    changed_files = get_changed_files(
        branch1=args.branch1,
        branch2=args.branch2,
        diff_filter=args.diff_filter,
        include_regexp=args.include_regexp,
        use_fork_point=args.fork_point,
    )
    if changed_files:
        passed = show_coverage(cov, changed_files, show_missing=args.show_missing, fail_under=args.fail_under)
        exit_with_status(passed)

    print('No changes.')
Пример #15
0
def json_coverage():
    COVERAGE_FILE = path.join(COVERAGE_DIR, 'coverage-final.json')
    COVERAGE_SUMMARY = path.join(COVERAGE_DIR, 'coverage-summary.json')

    coverage = Coverage(config_file=path.join(ROOT, 'pyproject.toml'))
    coverage.load()
    coverage.json_report(outfile=COVERAGE_FILE)

    report = json.load(open(COVERAGE_FILE))
    totals = report.get('totals')
    summary = {
        'lines': {
            'total':
            totals['covered_lines'] + totals['missing_lines'],
            'covered':
            totals['covered_lines'],
            'pct':
            totals['covered_lines'] /
            (totals['covered_lines'] + totals['missing_lines']) * 100
        },
        'statements': {
            'total': None,
            'covered': None,
            'pct': None,
        },
        'functions': {
            'total': None,
            'covered': None,
            'pct': None,
        },
        'branches': {
            'total': totals['num_branches'],
            'covered': totals['covered_branches'],
            'pct': totals['covered_branches'] / totals['num_branches'] * 100
        }
    }

    json.dump({'total': summary}, open(COVERAGE_SUMMARY, 'w'))
Пример #16
0
    def __annotateAll(self):
        """
        Private slot to handle the annotate all context menu action.
        
        This method produce an annotated coverage file of every
        file listed in the listview.
        """
        amount = self.resultList.topLevelItemCount()
        if amount == 0:
            return

        # get list of all filenames
        files = []
        for index in range(amount):
            itm = self.resultList.topLevelItem(index)
            files.append(itm.text(0))

        cover = Coverage(data_file=self.cfn)
        cover.exclude(self.excludeList[0])
        cover.load()

        # now process them
        progress = E5ProgressDialog(self.tr("Annotating files..."),
                                    self.tr("Abort"), 0, len(files),
                                    self.tr("%v/%m Files"), self)
        progress.setMinimumDuration(0)
        progress.setWindowTitle(self.tr("Coverage"))
        count = 0

        for file in files:
            progress.setValue(count)
            if progress.wasCanceled():
                break
            cover.annotate([file], None)  # , True)
            count += 1

        progress.setValue(len(files))
Пример #17
0
class CodeCoverage(object):
    """
        Code Coverage radish extension
    """
    OPTIONS = [
        ("--with-coverage", "enable code coverage"),
        ("--cover-packages=<cover_packages>", "specify source code package")
    ]
    LOAD_IF = staticmethod(lambda config: config.with_coverage)
    LOAD_PRIORITY = 70

    def __init__(self):
        before.all(self.coverage_start)
        after.all(self.coverage_stop)

        if world.config.cover_packages:
            cover_packages = world.config.cover_packages.split(",")
        else:
            cover_packages = []
        self.coverage = Coverage(source=cover_packages)

    def coverage_start(self, features, marker):
        """
            Start the coverage measurement
        """
        self.coverage.load()
        self.coverage.start()

    def coverage_stop(self, features, marker):
        """
            Stop the coverage measurement
            and create report
        """
        self.coverage.stop()
        self.coverage.save()
        self.coverage.report(file=sys.stdout)
Пример #18
0
class CodeCoverage(object):
    """
        Code Coverage radish extension
    """
    OPTIONS = [
        ('--with-coverage', 'enable code coverage'),
        ('--cover-packages=<cover_packages>', 'specify source code package'),
        ('--cover-append', 'append coverage data to previous collected data'),
        ('--cover-config-file=<cover_config_file>', 'specify coverage config file [default: .coveragerc]'),
        ('--cover-branches', 'include branch coverage in report'),
        ('--cover-erase', 'erase previously collected coverage data'),
        ('--cover-min-percentage=<cover_min_percentage>', 'fail if the given minimum coverage percentage is not reached'),
        ('--cover-html=<cover_html_dir>', 'specify a directory where to store HTML coverage report'),
        ('--cover-xml=<cover_xml_file>', 'specify a file where to store XML coverage report')
    ]
    LOAD_IF = staticmethod(lambda config: config.with_coverage)
    LOAD_PRIORITY = 70

    def __init__(self):
        before.all(self.coverage_start)
        after.all(self.coverage_stop)

        if world.config.cover_packages:
            self.cover_packages = world.config.cover_packages.split(",")
        else:
            self.cover_packages = []

        self.coverage = None
        self.modules_on_init = set(sys.modules.keys())

    def coverage_start(self, features, marker):
        """
        Start the coverage measurement
        """
        # if no explicit modules are specified we just
        # use the ones loaded from radish's basedir.
        # During the plugin init the basedir modules are
        # not loaded yet, but they are during the start method.
        # Thus, we are safe to consider the difference between the
        # two for coverage measurement.
        if not self.cover_packages:
            source = list(set(sys.modules.keys()).difference(self.modules_on_init))
        else:
            source = self.cover_packages

        self.coverage = Coverage(source=source,
                                 config_file=world.config.cover_config_file,
                                 branch=world.config.cover_branches)
        if world.config.cover_erase:
            self.coverage.combine()
            self.coverage.erase()

        if world.config.cover_append:
            self.coverage.load()
        self.coverage.start()

    def coverage_stop(self, features, marker):
        """
        Stop the coverage measurement
        and create report
        """
        self.coverage.stop()
        self.coverage.combine()
        self.coverage.save()
        self.coverage.report(file=sys.stdout)

        if world.config.cover_html:
            self.coverage.html_report(directory=world.config.cover_html)

        if world.config.cover_xml:
            self.coverage.xml_report(outfile=world.config.cover_xml)

        if world.config.cover_min_percentage:
            report = StringIO()
            self.coverage.report(file=report)
            match = re.search(r'^TOTAL\s+(.*)$', report.getvalue(), re.MULTILINE)
            if not match:
                raise RadishError('Failed to find total percentage in coverage report')

            total_percentage = int(match.groups()[0].split()[-1][:-1])
            if total_percentage < int(world.config.cover_min_percentage):
                raise RadishError('Failed to reach minimum expected coverage of {0}% (reached: {1}%)'.format(
                    world.config.cover_min_percentage, total_percentage))
Пример #19
0
class CoverageScript:
    """The command-line interface to coverage.py."""
    def __init__(self):
        self.global_option = False
        self.coverage = None

    def command_line(self, argv):
        """The bulk of the command line interface to coverage.py.

        `argv` is the argument list to process.

        Returns 0 if all is well, 1 if something went wrong.

        """
        # Collect the command-line options.
        if not argv:
            show_help(topic='minimum_help')
            return OK

        # The command syntax we parse depends on the first argument.  Global
        # switch syntax always starts with an option.
        self.global_option = argv[0].startswith('-')
        if self.global_option:
            parser = GlobalOptionParser()
        else:
            parser = COMMANDS.get(argv[0])
            if not parser:
                show_help(f"Unknown command: {argv[0]!r}")
                return ERR
            argv = argv[1:]

        ok, options, args = parser.parse_args_ok(argv)
        if not ok:
            return ERR

        # Handle help and version.
        if self.do_help(options, args, parser):
            return OK

        # Listify the list options.
        source = unshell_list(options.source)
        omit = unshell_list(options.omit)
        include = unshell_list(options.include)
        debug = unshell_list(options.debug)
        contexts = unshell_list(options.contexts)

        if options.concurrency is not None:
            concurrency = options.concurrency.split(",")
        else:
            concurrency = None

        # Do something.
        self.coverage = Coverage(
            data_file=options.data_file or DEFAULT_DATAFILE,
            data_suffix=options.parallel_mode,
            cover_pylib=options.pylib,
            timid=options.timid,
            branch=options.branch,
            config_file=options.rcfile,
            source=source,
            omit=omit,
            include=include,
            debug=debug,
            concurrency=concurrency,
            check_preimported=True,
            context=options.context,
            messages=not options.quiet,
        )

        if options.action == "debug":
            return self.do_debug(args)

        elif options.action == "erase":
            self.coverage.erase()
            return OK

        elif options.action == "run":
            return self.do_run(options, args)

        elif options.action == "combine":
            if options.append:
                self.coverage.load()
            data_paths = args or None
            self.coverage.combine(data_paths,
                                  strict=True,
                                  keep=bool(options.keep))
            self.coverage.save()
            return OK

        # Remaining actions are reporting, with some common options.
        report_args = dict(
            morfs=unglob_args(args),
            ignore_errors=options.ignore_errors,
            omit=omit,
            include=include,
            contexts=contexts,
        )

        # We need to be able to import from the current directory, because
        # plugins may try to, for example, to read Django settings.
        sys.path.insert(0, '')

        self.coverage.load()

        total = None
        if options.action == "report":
            total = self.coverage.report(precision=options.precision,
                                         show_missing=options.show_missing,
                                         skip_covered=options.skip_covered,
                                         skip_empty=options.skip_empty,
                                         sort=options.sort,
                                         **report_args)
        elif options.action == "annotate":
            self.coverage.annotate(directory=options.directory, **report_args)
        elif options.action == "html":
            total = self.coverage.html_report(
                directory=options.directory,
                precision=options.precision,
                skip_covered=options.skip_covered,
                skip_empty=options.skip_empty,
                show_contexts=options.show_contexts,
                title=options.title,
                **report_args)
        elif options.action == "xml":
            total = self.coverage.xml_report(outfile=options.outfile,
                                             skip_empty=options.skip_empty,
                                             **report_args)
        elif options.action == "json":
            total = self.coverage.json_report(
                outfile=options.outfile,
                pretty_print=options.pretty_print,
                show_contexts=options.show_contexts,
                **report_args)
        elif options.action == "lcov":
            total = self.coverage.lcov_report(outfile=options.outfile,
                                              **report_args)
        else:
            # There are no other possible actions.
            raise AssertionError

        if total is not None:
            # Apply the command line fail-under options, and then use the config
            # value, so we can get fail_under from the config file.
            if options.fail_under is not None:
                self.coverage.set_option("report:fail_under",
                                         options.fail_under)
            if options.precision is not None:
                self.coverage.set_option("report:precision", options.precision)

            fail_under = self.coverage.get_option("report:fail_under")
            precision = self.coverage.get_option("report:precision")
            if should_fail_under(total, fail_under, precision):
                msg = "total of {total} is less than fail-under={fail_under:.{p}f}".format(
                    total=Numbers(precision=precision).display_covered(total),
                    fail_under=fail_under,
                    p=precision,
                )
                print("Coverage failure:", msg)
                return FAIL_UNDER

        return OK

    def do_help(self, options, args, parser):
        """Deal with help requests.

        Return True if it handled the request, False if not.

        """
        # Handle help.
        if options.help:
            if self.global_option:
                show_help(topic='help')
            else:
                show_help(parser=parser)
            return True

        if options.action == "help":
            if args:
                for a in args:
                    parser = COMMANDS.get(a)
                    if parser:
                        show_help(parser=parser)
                    else:
                        show_help(topic=a)
            else:
                show_help(topic='help')
            return True

        # Handle version.
        if options.version:
            show_help(topic='version')
            return True

        return False

    def do_run(self, options, args):
        """Implementation of 'coverage run'."""

        if not args:
            if options.module:
                # Specified -m with nothing else.
                show_help("No module specified for -m")
                return ERR
            command_line = self.coverage.get_option("run:command_line")
            if command_line is not None:
                args = shlex.split(command_line)
                if args and args[0] in {"-m", "--module"}:
                    options.module = True
                    args = args[1:]
        if not args:
            show_help("Nothing to do.")
            return ERR

        if options.append and self.coverage.get_option("run:parallel"):
            show_help("Can't append to data files in parallel mode.")
            return ERR

        if options.concurrency == "multiprocessing":
            # Can't set other run-affecting command line options with
            # multiprocessing.
            for opt_name in [
                    'branch', 'include', 'omit', 'pylib', 'source', 'timid'
            ]:
                # As it happens, all of these options have no default, meaning
                # they will be None if they have not been specified.
                if getattr(options, opt_name) is not None:
                    show_help(
                        "Options affecting multiprocessing must only be specified "
                        + "in a configuration file.\n" +
                        f"Remove --{opt_name} from the command line.")
                    return ERR

        os.environ["COVERAGE_RUN"] = "true"

        runner = PyRunner(args, as_module=bool(options.module))
        runner.prepare()

        if options.append:
            self.coverage.load()

        # Run the script.
        self.coverage.start()
        code_ran = True
        try:
            runner.run()
        except NoSource:
            code_ran = False
            raise
        finally:
            self.coverage.stop()
            if code_ran:
                self.coverage.save()

        return OK

    def do_debug(self, args):
        """Implementation of 'coverage debug'."""

        if not args:
            show_help(
                "What information would you like: config, data, sys, premain, pybehave?"
            )
            return ERR
        if args[1:]:
            show_help("Only one topic at a time, please")
            return ERR

        if args[0] == "sys":
            write_formatted_info(print, "sys", self.coverage.sys_info())
        elif args[0] == "data":
            print(info_header("data"))
            data_file = self.coverage.config.data_file
            debug_data_file(data_file)
            for filename in combinable_files(data_file):
                print("-----")
                debug_data_file(filename)
        elif args[0] == "config":
            write_formatted_info(print, "config",
                                 self.coverage.config.debug_info())
        elif args[0] == "premain":
            print(info_header("premain"))
            print(short_stack())
        elif args[0] == "pybehave":
            write_formatted_info(print, "pybehave", env.debug_info())
        else:
            show_help(f"Don't know what you mean by {args[0]!r}")
            return ERR

        return OK
Пример #20
0
    def start(self, cfn, fn):
        """
        Public slot to start the coverage data evaluation.
        
        @param cfn basename of the coverage file (string)
        @param fn file or list of files or directory to be checked
                (string or list of strings)
        """
        self.__cfn = cfn
        self.__fn = fn

        self.basename = os.path.splitext(cfn)[0]

        self.cfn = "{0}.coverage".format(self.basename)

        if isinstance(fn, list):
            files = fn
            self.path = os.path.dirname(cfn)
        elif os.path.isdir(fn):
            files = Utilities.direntries(fn, True, '*.py', False)
            self.path = fn
        else:
            files = [fn]
            self.path = os.path.dirname(cfn)
        files.sort()

        cover = Coverage(data_file=self.cfn)
        cover.load()

        # set the exclude pattern
        self.excludeCombo.clear()
        self.excludeCombo.addItems(self.excludeList)

        self.checkProgress.setMaximum(len(files))
        QApplication.processEvents()

        total_statements = 0
        total_executed = 0
        total_exceptions = 0

        cover.exclude(self.excludeList[0])
        progress = 0

        try:
            # disable updates of the list for speed
            self.resultList.setUpdatesEnabled(False)
            self.resultList.setSortingEnabled(False)

            # now go through all the files
            for file in files:
                if self.cancelled:
                    return

                try:
                    statements, excluded, missing, readable = (
                        cover.analysis2(file)[1:])
                    readableEx = (excluded and self.__format_lines(excluded)
                                  or '')
                    n = len(statements)
                    m = n - len(missing)
                    if n > 0:
                        pc = 100.0 * m / n
                    else:
                        pc = 100.0
                    self.__createResultItem(file, str(n), str(m), pc,
                                            readableEx, readable)

                    total_statements = total_statements + n
                    total_executed = total_executed + m
                except CoverageException:
                    total_exceptions += 1

                progress += 1
                self.checkProgress.setValue(progress)
                QApplication.processEvents()
        finally:
            # reenable updates of the list
            self.resultList.setSortingEnabled(True)
            self.resultList.setUpdatesEnabled(True)
            self.checkProgress.reset()

        # show summary info
        if len(files) > 1:
            if total_statements > 0:
                pc = 100.0 * total_executed / total_statements
            else:
                pc = 100.0
            itm = QTreeWidgetItem(self.summaryList, [
                str(total_statements),
                str(total_executed), "{0:.0f}%".format(pc)
            ])
            for col in range(0, 3):
                itm.setTextAlignment(col, Qt.AlignRight)
        else:
            self.summaryGroup.hide()

        if total_exceptions:
            E5MessageBox.warning(
                self, self.tr("Parse Error"),
                self.tr(
                    """%n file(s) could not be parsed. Coverage"""
                    """ info for these is not available.""", "",
                    total_exceptions))

        self.__finish()
Пример #21
0
# usage:
#   run_tests.py [PYTEST_ARGS]

import os
import subprocess
import sys

from coverage import Coverage


SHELL = sys.platform == 'win32'


if __name__ == '__main__':
    command = ['py.test']
    if os.environ.get('WITH_COVERAGE') == '1':
        command.extend(['--cov=rinoh', '--cov-report='])
    if os.environ.get('BASETEMP'):
        command.append('--basetemp={}'.format(os.environ['BASETEMP']))
    command.extend(sys.argv[1:])
    rc = subprocess.call(command, shell=SHELL)
    if os.environ.get('WITH_COVERAGE') == '1':
        cov = Coverage()
        cov.load()
        cov.combine()
        cov.report(skip_covered=True)
        cov.xml_report()
    raise SystemExit(rc)
Пример #22
0
 def _validate_coverage(self):
     """Make sure there 100% coverage between the two test groups"""
     coverage = Coverage(config_file='coverage_tests/.coveragerc', )
     coverage.load()
     coverage.combine(strict=True)
     self.__assert(coverage.report() == 100.0, '100% coverage not achieved')
Пример #23
0
def get_cov(input_file):
    cov = Coverage(data_file=input_file)
    cov.load()
    return cov
Пример #24
0
# usage:
#   run_tests.py [PYTEST_ARGS]

import os
import subprocess
import sys

from coverage import Coverage

SHELL = sys.platform == 'win32'

if __name__ == '__main__':
    command = ['py.test', '-n', 'auto']
    if os.environ.get('WITH_COVERAGE') == '1':
        command.extend(['--cov=rinoh', '--cov-report='])
    if os.environ.get('BASETEMP'):
        command.append('--basetemp={}'.format(os.environ['BASETEMP']))
    command.extend(sys.argv[1:])
    rc = subprocess.call(command, shell=SHELL)
    if os.environ.get('WITH_COVERAGE') == '1':
        cov = Coverage()
        cov.load()
        cov.combine()
        cov.report(skip_covered=True)
        cov.xml_report()
    raise SystemExit(rc)
Пример #25
0
class Coverage:
    """
    Extension for Python Code Coverage
    """

    OPTIONS = [
        click.Option(
            param_decls=("--with-coverage", "with_coverage"),
            is_flag=True,
            help="Enable Code Coverage",
        ),
        click.Option(
            param_decls=("--cover-package", "cover_packages"),
            multiple=True,
            help=
            "Python Package name for which the coverage is measured and reported",
        ),
        click.Option(
            param_decls=("--cover-append", "cover_append"),
            is_flag=True,
            help="Append measured coverage data to previous collected data",
        ),
        click.Option(
            param_decls=("--cover-config-file", "cover_config_file"),
            default=".coveragerc",
            help="Path to a custom coverage configuration file",
        ),
        click.Option(
            param_decls=("--cover-branches", "cover_branches"),
            is_flag=True,
            help="Include branch coverage in the report",
        ),
        click.Option(
            param_decls=("--cover-erase", "cover_erase"),
            is_flag=True,
            help="Erase previously collected data",
        ),
        click.Option(
            param_decls=("--cover-min-percentage", "cover_min_percentage"),
            type=click.IntRange(0, 100),
            help=
            "Fail if the provided minimum coverage percentage is not reached",
        ),
        click.Option(
            param_decls=("--cover-html", "cover_html"),
            help=
            "Path to the directory where to store the HTML coverage report",
        ),
        click.Option(
            param_decls=("--cover-xml", "cover_xml"),
            help="Path to the directory where to store the XML coverage report",
        ),
    ]

    @classmethod
    def load(cls, config):
        if config.with_coverage:
            return cls(
                config.cover_packages,
                config.cover_append,
                config.cover_config_file,
                config.cover_branches,
                config.cover_erase,
                config.cover_min_percentage,
                config.cover_html,
                config.cover_xml,
            )
        else:
            return None

    def __init__(
        self,
        cover_packages,
        cover_append,
        cover_config_file,
        cover_branches,
        cover_erase,
        cover_min_percentage,
        cover_html,
        cover_xml,
    ):
        try:
            from coverage import Coverage  # noqa
        except ImportError:
            raise RadishError(
                "if you want to use the code coverage extension you have to "
                "'pip install radish-bdd[coverage]'")

        self.cover_packages = cover_packages
        self.cover_append = cover_append
        self.cover_config_file = cover_config_file
        self.cover_branches = cover_branches
        self.cover_erase = cover_erase
        self.cover_min_percentage = cover_min_percentage
        self.cover_html = cover_html
        self.cover_xml = cover_xml

        before.all()(self.coverage_start)
        after.all()(self.coverage_stop)

        self.coverage = None
        self.modules_on_init = set(sys.modules.keys())

    def coverage_start(self, features):
        """
        Hook to start the coverage measurement
        """
        from coverage import Coverage

        # if no explicit modules are specified we just
        # use the ones loaded from radish's basedir.
        # During the plugin init the basedir modules are
        # not loaded yet, but they are during the start method.
        # Thus, we are safe to consider the difference between the
        # two for coverage measurement.
        if not self.cover_packages:
            source = list(
                set(sys.modules.keys()).difference(self.modules_on_init))
        else:
            source = self.cover_packages

        self.coverage = Coverage(
            source=source,
            config_file=self.cover_config_file,
            branch=self.cover_branches,
        )
        if self.cover_erase:
            self.coverage.combine()
            self.coverage.erase()

        if self.cover_append:
            self.coverage.load()
        self.coverage.start()

    def coverage_stop(self, features):
        """
        Stop the coverage measurement
        and create report
        """
        self.coverage.stop()
        self.coverage.combine()
        self.coverage.save()
        self.coverage.report(file=sys.stdout)

        if self.cover_html:
            self.coverage.html_report(directory=self.cover_html)

        if self.cover_xml:
            self.coverage.xml_report(outfile=self.cover_xml)

        if self.cover_min_percentage:
            report = StringIO()
            self.coverage.report(file=report)
            match = re.search(r"^TOTAL\s+(.*)$", report.getvalue(),
                              re.MULTILINE)
            if not match:
                raise RadishError(
                    "Failed to find total percentage in coverage report")

            total_percentage = int(match.groups()[0].split()[-1][:-1])
            if total_percentage < int(self.cover_min_percentage):
                raise RadishError(
                    "Failed to reach minimum expected coverage of {0}% (reached: {1}%)"
                    .format(self.cover_min_percentage, total_percentage))
Пример #26
0
class CoverageScript(object):
    """The command-line interface to coverage.py."""
    def __init__(self):
        self.global_option = False
        self.coverage = None

    def command_line(self, argv):
        """The bulk of the command line interface to coverage.py.

        `argv` is the argument list to process.

        Returns 0 if all is well, 1 if something went wrong.

        """
        # Collect the command-line options.
        if not argv:
            show_help(topic='minimum_help')
            return OK

        # The command syntax we parse depends on the first argument.  Global
        # switch syntax always starts with an option.
        self.global_option = argv[0].startswith('-')
        if self.global_option:
            parser = GlobalOptionParser()
        else:
            parser = CMDS.get(argv[0])
            if not parser:
                show_help("Unknown command: '%s'" % argv[0])
                return ERR
            argv = argv[1:]

        ok, options, args = parser.parse_args_ok(argv)
        if not ok:
            return ERR

        # Handle help and version.
        if self.do_help(options, args, parser):
            return OK

        # Listify the list options.
        source = unshell_list(options.source)
        omit = unshell_list(options.omit)
        include = unshell_list(options.include)
        debug = unshell_list(options.debug)
        contexts = unshell_list(options.contexts)

        # Do something.
        self.coverage = Coverage(
            data_suffix=options.parallel_mode,
            cover_pylib=options.pylib,
            timid=options.timid,
            branch=options.branch,
            config_file=options.rcfile,
            source=source,
            omit=omit,
            include=include,
            debug=debug,
            concurrency=options.concurrency,
            check_preimported=True,
            context=options.context,
        )

        if options.action == "debug":
            return self.do_debug(args)

        elif options.action == "erase":
            self.coverage.erase()
            return OK

        elif options.action == "run":
            return self.do_run(options, args)

        elif options.action == "combine":
            if options.append:
                self.coverage.load()
            data_dirs = args or None
            self.coverage.combine(data_dirs, strict=True)
            self.coverage.save()
            return OK

        # Remaining actions are reporting, with some common options.
        report_args = dict(
            morfs=unglob_args(args),
            ignore_errors=options.ignore_errors,
            omit=omit,
            include=include,
            contexts=contexts,
        )

        # We need to be able to import from the current directory, because
        # plugins may try to, for example, to read Django settings.
        sys.path.insert(0, '')

        self.coverage.load()

        total = None
        if options.action == "report":
            total = self.coverage.report(show_missing=options.show_missing,
                                         skip_covered=options.skip_covered,
                                         **report_args)
        elif options.action == "annotate":
            self.coverage.annotate(directory=options.directory, **report_args)
        elif options.action == "html":
            total = self.coverage.html_report(
                directory=options.directory,
                title=options.title,
                skip_covered=options.skip_covered,
                show_contexts=options.show_contexts,
                **report_args)
        elif options.action == "xml":
            outfile = options.outfile
            total = self.coverage.xml_report(outfile=outfile, **report_args)

        if total is not None:
            # Apply the command line fail-under options, and then use the config
            # value, so we can get fail_under from the config file.
            if options.fail_under is not None:
                self.coverage.set_option("report:fail_under",
                                         options.fail_under)

            fail_under = self.coverage.get_option("report:fail_under")
            precision = self.coverage.get_option("report:precision")
            if should_fail_under(total, fail_under, precision):
                return FAIL_UNDER

        return OK

    def do_help(self, options, args, parser):
        """Deal with help requests.

        Return True if it handled the request, False if not.

        """
        # Handle help.
        if options.help:
            if self.global_option:
                show_help(topic='help')
            else:
                show_help(parser=parser)
            return True

        if options.action == "help":
            if args:
                for a in args:
                    parser = CMDS.get(a)
                    if parser:
                        show_help(parser=parser)
                    else:
                        show_help(topic=a)
            else:
                show_help(topic='help')
            return True

        # Handle version.
        if options.version:
            show_help(topic='version')
            return True

        return False

    def do_run(self, options, args):
        """Implementation of 'coverage run'."""

        if not args:
            if options.module:
                # Specified -m with nothing else.
                show_help("No module specified for -m")
                return ERR
            command_line = self.coverage.get_option("run:command_line")
            if command_line is not None:
                args = shlex.split(command_line)
                if args and args[0] == "-m":
                    options.module = True
                    args = args[1:]
        if not args:
            show_help("Nothing to do.")
            return ERR

        if options.append and self.coverage.get_option("run:parallel"):
            show_help("Can't append to data files in parallel mode.")
            return ERR

        if options.concurrency == "multiprocessing":
            # Can't set other run-affecting command line options with
            # multiprocessing.
            for opt_name in [
                    'branch', 'include', 'omit', 'pylib', 'source', 'timid'
            ]:
                # As it happens, all of these options have no default, meaning
                # they will be None if they have not been specified.
                if getattr(options, opt_name) is not None:
                    show_help(
                        "Options affecting multiprocessing must only be specified "
                        "in a configuration file.\n"
                        "Remove --{} from the command line.".format(opt_name))
                    return ERR

        runner = PyRunner(args, as_module=bool(options.module))
        runner.prepare()

        if options.append:
            self.coverage.load()

        # Run the script.
        self.coverage.start()
        code_ran = True
        try:
            runner.run()
        except NoSource:
            code_ran = False
            raise
        finally:
            self.coverage.stop()
            if code_ran:
                self.coverage.save()

        return OK

    def do_debug(self, args):
        """Implementation of 'coverage debug'."""

        if not args:
            show_help("What information would you like: config, data, sys?")
            return ERR

        for info in args:
            if info == 'sys':
                sys_info = self.coverage.sys_info()
                print(info_header("sys"))
                for line in info_formatter(sys_info):
                    print(" %s" % line)
            elif info == 'data':
                self.coverage.load()
                data = self.coverage.get_data()
                print(info_header("data"))
                print("path: %s" % self.coverage.get_data().data_filename())
                if data:
                    print("has_arcs: %r" % data.has_arcs())
                    summary = line_counts(data, fullpath=True)
                    filenames = sorted(summary.keys())
                    print("\n%d files:" % len(filenames))
                    for f in filenames:
                        line = "%s: %d lines" % (f, summary[f])
                        plugin = data.file_tracer(f)
                        if plugin:
                            line += " [%s]" % plugin
                        print(line)
                else:
                    print("No data collected")
            elif info == 'config':
                print(info_header("config"))
                config_info = self.coverage.config.__dict__.items()
                for line in info_formatter(config_info):
                    print(" %s" % line)
            else:
                show_help("Don't know what you mean by %r" % info)
                return ERR

        return OK
def coverage_json(cov_file, json_file):
    # this method will be removed when merge to sdk
    from coverage import Coverage
    cov = Coverage(data_file=cov_file, auto_data=False)
    cov.load()
    cov.json_report(outfile=json_file)
Пример #28
0
def main():
    options = parse_args()

    # TODO: move this export & download function in tools/ folder
    test_times_filename = options.export_past_test_times
    if test_times_filename:
        print(
            f"Exporting past test times from S3 to {test_times_filename}, no tests will be run."
        )
        export_S3_test_times(test_times_filename)
        return

    specified_test_cases_filename = options.run_specified_test_cases
    if specified_test_cases_filename:
        print(
            f"Loading specified test cases to run from {specified_test_cases_filename}."
        )
        global SPECIFIED_TEST_CASES_DICT
        SPECIFIED_TEST_CASES_DICT = get_specified_test_cases(
            specified_test_cases_filename, TESTS
        )

    test_directory = str(REPO_ROOT / "test")
    selected_tests = get_selected_tests(options)

    if options.verbose:
        print_to_stderr("Selected tests:\n {}".format("\n ".join(selected_tests)))

    if options.dry_run:
        return

    if options.coverage and not PYTORCH_COLLECT_COVERAGE:
        shell(["coverage", "erase"])

    # NS: Disable target determination until it can be made more reliable
    # if options.determine_from is not None and os.path.exists(options.determine_from):
    #     slow_tests = get_slow_tests_based_on_S3(
    #         TESTS, TARGET_DET_LIST, SLOW_TEST_THRESHOLD
    #     )
    #     print_to_stderr(
    #         "Added the following tests to target_det tests as calculated based on S3:"
    #     )
    #     print_to_stderr(slow_tests)
    #     with open(options.determine_from, "r") as fh:
    #         touched_files = [
    #             os.path.normpath(name.strip())
    #             for name in fh.read().split("\n")
    #             if len(name.strip()) > 0
    #         ]
    #     # HACK: Ensure the 'test' paths can be traversed by Modulefinder
    #     sys.path.append(test_directory)
    #     selected_tests = [
    #         test
    #         for test in selected_tests
    #         if should_run_test(
    #             TARGET_DET_LIST + slow_tests, test, touched_files, options
    #         )
    #     ]
    #     sys.path.remove(test_directory)

    if IS_IN_CI:
        selected_tests = get_reordered_tests(
            selected_tests, ENABLE_PR_HISTORY_REORDERING
        )
        # downloading test cases configuration to local environment
        get_test_case_configs(dirpath=test_directory)

    has_failed = False
    failure_messages = []
    try:
        for test in selected_tests:
            options_clone = copy.deepcopy(options)
            if test in USE_PYTEST_LIST:
                options_clone.pytest = True
            err_message = run_test_module(test, test_directory, options_clone)
            if err_message is None:
                continue
            has_failed = True
            failure_messages.append(err_message)
            if not options_clone.continue_through_error:
                raise RuntimeError(err_message)
            print_to_stderr(err_message)
    finally:
        if options.coverage:
            from coverage import Coverage

            with set_cwd(test_directory):
                cov = Coverage()
                if PYTORCH_COLLECT_COVERAGE:
                    cov.load()
                cov.combine(strict=False)
                cov.save()
                if not PYTORCH_COLLECT_COVERAGE:
                    cov.html_report()

    if options.continue_through_error and has_failed:
        for err in failure_messages:
            print_to_stderr(err)
        sys.exit(1)
Пример #29
0
        raise Exception()
    mode = sys.argv[1]
    if mode == "test":
        pass  # TODO: python -m pytest (...)
    elif mode == "build:grpc":
        pass  # TODO: python -m grpc_tools.protoc -I protos/ --python_out=konlpy_grpc/_generated/ --grpc_python_out=konlpy_grpc/_generated/ protos/*.proto
    elif mode == "coverage":
        pass  # TODO: (REQUIRED: test)
        # python -m pytest --cov=konlpy_grpc --cov-report=xml --konlpy-repo=../konlpy
        # python -m pytest --cov=konlpy_grpc --cov-report=xml --cov-append --konlpy-repo=../konlpy --grpc-fake-server
        # python -m pytest --cov=konlpy_grpc --cov-report=xml --cov-append --konlpy-repo=../konlpy --grpc-real-server=[::]:50051
    elif mode == "coverage:html":
        from coverage import Coverage

        c = Coverage()
        c.load()
        c.html_report(directory="covhtml", omit="konlpy_grpc/_generated/*")
    elif mode == "git:cleanup":
        pass  # TODO
    elif mode == "bumpversion":
        pass  # TODO: bump2version --allow-dirty --dry-run --verbose patch
    elif mode in (
            "requirements.txt", "poetry:requirements.txt"
    ):  # XXX: https://github.com/sdispater/poetry/issues/100#issuecomment-409807277
        import tomlkit

        with open("poetry.lock") as t:
            lock = tomlkit.parse(t.read())
            for p in lock["package"]:
                if not p["category"] == "dev":
                    print(f"{p['name']}=={p['version']}")
Пример #30
0
def main():
    options = parse_args()

    # TODO: move this export & download function in tools/ folder
    test_times_filename = options.export_past_test_times
    if test_times_filename:
        print(
            f'Exporting past test times from S3 to {test_times_filename}, no tests will be run.'
        )
        export_S3_test_times(test_times_filename)
        return

    specified_test_cases_filename = options.run_specified_test_cases
    if specified_test_cases_filename:
        print(
            f'Loading specified test cases to run from {specified_test_cases_filename}.'
        )
        global SPECIFIED_TEST_CASES_DICT
        SPECIFIED_TEST_CASES_DICT = get_specified_test_cases(
            specified_test_cases_filename, TESTS)

    test_directory = os.path.dirname(os.path.abspath(__file__))
    selected_tests = get_selected_tests(options)

    if options.verbose:
        print_to_stderr('Selected tests: {}'.format(', '.join(selected_tests)))

    if options.coverage and not PYTORCH_COLLECT_COVERAGE:
        shell(['coverage', 'erase'])

    if options.jit:
        selected_tests = filter(lambda test_name: "jit" in test_name, TESTS)

    if options.determine_from is not None and os.path.exists(
            options.determine_from):
        slow_tests = get_slow_tests_based_on_S3(TESTS, TARGET_DET_LIST,
                                                SLOW_TEST_THRESHOLD)
        print(
            'Added the following tests to target_det tests as calculated based on S3:'
        )
        print(slow_tests)
        with open(options.determine_from, 'r') as fh:
            touched_files = [
                os.path.normpath(name.strip())
                for name in fh.read().split('\n') if len(name.strip()) > 0
            ]
        # HACK: Ensure the 'test' paths can be traversed by Modulefinder
        sys.path.append('test')
        selected_tests = [
            test for test in selected_tests
            if determine_target(TARGET_DET_LIST +
                                slow_tests, test, touched_files, options)
        ]
        sys.path.remove('test')

    if IS_IN_CI:
        selected_tests = get_reordered_tests(selected_tests,
                                             ENABLE_PR_HISTORY_REORDERING)
        # downloading test cases configuration to local environment
        get_test_case_configs(
            dirpath=os.path.dirname(os.path.abspath(__file__)))

    has_failed = False
    failure_messages = []
    try:
        for test in selected_tests:
            options_clone = copy.deepcopy(options)
            if test in USE_PYTEST_LIST:
                options_clone.pytest = True
            err_message = run_test_module(test, test_directory, options_clone)
            if err_message is None:
                continue
            has_failed = True
            failure_messages.append(err_message)
            if not options_clone.continue_through_error:
                raise RuntimeError(err_message)
            print_to_stderr(err_message)
    finally:
        if options.coverage:
            from coverage import Coverage
            test_dir = os.path.dirname(os.path.abspath(__file__))
            with set_cwd(test_dir):
                cov = Coverage()
                if PYTORCH_COLLECT_COVERAGE:
                    cov.load()
                cov.combine(strict=False)
                cov.save()
                if not PYTORCH_COLLECT_COVERAGE:
                    cov.html_report()

    if options.continue_through_error and has_failed:
        for err in failure_messages:
            print_to_stderr(err)
        sys.exit(1)
Пример #31
0
class CoverageScript(object):
    """The command-line interface to coverage.py."""

    def __init__(self):
        self.global_option = False
        self.coverage = None

    def command_line(self, argv):
        """The bulk of the command line interface to coverage.py.

        `argv` is the argument list to process.

        Returns 0 if all is well, 1 if something went wrong.

        """
        # Collect the command-line options.
        if not argv:
            show_help(topic='minimum_help')
            return OK

        # The command syntax we parse depends on the first argument.  Global
        # switch syntax always starts with an option.
        self.global_option = argv[0].startswith('-')
        if self.global_option:
            parser = GlobalOptionParser()
        else:
            parser = CMDS.get(argv[0])
            if not parser:
                show_help("Unknown command: '%s'" % argv[0])
                return ERR
            argv = argv[1:]

        ok, options, args = parser.parse_args_ok(argv)
        if not ok:
            return ERR

        # Handle help and version.
        if self.do_help(options, args, parser):
            return OK

        # Listify the list options.
        source = unshell_list(options.source)
        omit = unshell_list(options.omit)
        include = unshell_list(options.include)
        debug = unshell_list(options.debug)

        # Do something.
        self.coverage = Coverage(
            data_suffix=options.parallel_mode,
            cover_pylib=options.pylib,
            timid=options.timid,
            branch=options.branch,
            config_file=options.rcfile,
            source=source,
            omit=omit,
            include=include,
            debug=debug,
            concurrency=options.concurrency,
            check_preimported=True,
            context=options.context,
            )

        if options.action == "debug":
            return self.do_debug(args)

        elif options.action == "erase":
            self.coverage.erase()
            return OK

        elif options.action == "run":
            return self.do_run(options, args)

        elif options.action == "combine":
            if options.append:
                self.coverage.load()
            data_dirs = args or None
            self.coverage.combine(data_dirs, strict=True)
            self.coverage.save()
            return OK

        # Remaining actions are reporting, with some common options.
        report_args = dict(
            morfs=unglob_args(args),
            ignore_errors=options.ignore_errors,
            omit=omit,
            include=include,
            )

        # We need to be able to import from the current directory, because
        # plugins may try to, for example, to read Django settings.
        sys.path.insert(0, '')

        self.coverage.load()

        total = None
        if options.action == "report":
            total = self.coverage.report(
                show_missing=options.show_missing,
                skip_covered=options.skip_covered,
                **report_args
                )
        elif options.action == "annotate":
            self.coverage.annotate(directory=options.directory, **report_args)
        elif options.action == "html":
            total = self.coverage.html_report(
                directory=options.directory,
                title=options.title,
                skip_covered=options.skip_covered,
                **report_args
                )
        elif options.action == "xml":
            outfile = options.outfile
            total = self.coverage.xml_report(outfile=outfile, **report_args)

        if total is not None:
            # Apply the command line fail-under options, and then use the config
            # value, so we can get fail_under from the config file.
            if options.fail_under is not None:
                self.coverage.set_option("report:fail_under", options.fail_under)

            fail_under = self.coverage.get_option("report:fail_under")
            precision = self.coverage.get_option("report:precision")
            if should_fail_under(total, fail_under, precision):
                return FAIL_UNDER

        return OK

    def do_help(self, options, args, parser):
        """Deal with help requests.

        Return True if it handled the request, False if not.

        """
        # Handle help.
        if options.help:
            if self.global_option:
                show_help(topic='help')
            else:
                show_help(parser=parser)
            return True

        if options.action == "help":
            if args:
                for a in args:
                    parser = CMDS.get(a)
                    if parser:
                        show_help(parser=parser)
                    else:
                        show_help(topic=a)
            else:
                show_help(topic='help')
            return True

        # Handle version.
        if options.version:
            show_help(topic='version')
            return True

        return False

    def do_run(self, options, args):
        """Implementation of 'coverage run'."""

        if not args:
            if options.module:
                # Specified -m with nothing else.
                show_help("No module specified for -m")
                return ERR
            command_line = self.coverage.get_option("run:command_line")
            if command_line is not None:
                args = shlex.split(command_line)
                if args and args[0] == "-m":
                    options.module = True
                    args = args[1:]
        if not args:
            show_help("Nothing to do.")
            return ERR

        if options.append and self.coverage.get_option("run:parallel"):
            show_help("Can't append to data files in parallel mode.")
            return ERR

        if options.concurrency == "multiprocessing":
            # Can't set other run-affecting command line options with
            # multiprocessing.
            for opt_name in ['branch', 'include', 'omit', 'pylib', 'source', 'timid']:
                # As it happens, all of these options have no default, meaning
                # they will be None if they have not been specified.
                if getattr(options, opt_name) is not None:
                    show_help(
                        "Options affecting multiprocessing must only be specified "
                        "in a configuration file.\n"
                        "Remove --{} from the command line.".format(opt_name)
                    )
                    return ERR

        runner = PyRunner(args, as_module=bool(options.module))
        runner.prepare()

        if options.append:
            self.coverage.load()

        # Run the script.
        self.coverage.start()
        code_ran = True
        try:
            runner.run()
        except NoSource:
            code_ran = False
            raise
        finally:
            self.coverage.stop()
            if code_ran:
                self.coverage.save()

        return OK

    def do_debug(self, args):
        """Implementation of 'coverage debug'."""

        if not args:
            show_help("What information would you like: config, data, sys?")
            return ERR

        for info in args:
            if info == 'sys':
                sys_info = self.coverage.sys_info()
                print(info_header("sys"))
                for line in info_formatter(sys_info):
                    print(" %s" % line)
            elif info == 'data':
                self.coverage.load()
                data = self.coverage.get_data()
                print(info_header("data"))
                print("path: %s" % self.coverage.get_data().data_filename())
                if data:
                    print("has_arcs: %r" % data.has_arcs())
                    summary = line_counts(data, fullpath=True)
                    filenames = sorted(summary.keys())
                    print("\n%d files:" % len(filenames))
                    for f in filenames:
                        line = "%s: %d lines" % (f, summary[f])
                        plugin = data.file_tracer(f)
                        if plugin:
                            line += " [%s]" % plugin
                        print(line)
                else:
                    print("No data collected")
            elif info == 'config':
                print(info_header("config"))
                config_info = self.coverage.config.__dict__.items()
                for line in info_formatter(config_info):
                    print(" %s" % line)
            else:
                show_help("Don't know what you mean by %r" % info)
                return ERR

        return OK