• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pyta-uoft / pyta / 29351058596

14 Jul 2026 04:46PM UTC coverage: 90.889% (-0.04%) from 90.931%
29351058596

Pull #1367

github

web-flow
Merge 13cf5f3c4 into 728645ffa
Pull Request #1367: Fix PyTA CLI output format behaviour

13 of 16 new or added lines in 1 file covered. (81.25%)

3701 of 4072 relevant lines covered (90.89%)

17.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.75
/packages/python-ta/src/python_ta/__main__.py
1
from __future__ import annotations
20✔
2

3
import configparser
20✔
4
import sys
20✔
5
from os import path
20✔
6
from typing import Optional
20✔
7

8
import click
20✔
9
import toml
20✔
10

11
from python_ta import __version__, check_all, check_errors
20✔
12
from python_ta.config import DEFAULT_CONFIG_LOCATION, flatten
20✔
13

14
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
20✔
15

16

17
def _load_config_as_dict(config_path: str) -> dict[str, str]:
20✔
18
    """Load a config file and return it as a dictionary of option: value pairs."""
19
    if config_path.endswith(".toml"):
20✔
20
        return flatten(toml.load(config_path).get("tool", {}).get("python-ta", {}))
20✔
21
    else:
NEW
22
        parser = configparser.ConfigParser()
×
NEW
23
        parser.read(config_path)
×
NEW
24
        return {
×
25
            option: value
26
            for section in parser.sections()
27
            for option, value in parser.items(section)
28
        }
29

30

31
@click.command(context_settings=CONTEXT_SETTINGS)
20✔
32
@click.option(
20✔
33
    "-v", "--version", is_flag=True, help="Print current version of PythonTA.", default=False
34
)
35
@click.option(
20✔
36
    "-c",
37
    "--config",
38
    type=click.Path(exists=True, dir_okay=False, resolve_path=True),
39
    help="python_ta configuration file",
40
)
41
@click.option("-E", "--errors-only", is_flag=True, help="Displays errors only", default=False)
20✔
42
@click.argument(
20✔
43
    "filenames", nargs=-1, type=click.Path(exists=True, dir_okay=True, resolve_path=True)
44
)
45
@click.option("--exit-zero", is_flag=True, help="Always return with status code 0", default=False)
20✔
46
@click.option(
20✔
47
    "-g",
48
    "--generate-config",
49
    is_flag=True,
50
    help="Print out default PythonTA configuration file",
51
    default=False,
52
)
53
@click.option(
20✔
54
    "--output-format",
55
    help="Specify the format of output report. This option overrides the output format specified in the config file.",
56
    default=None,
57
)
58
def main(
20✔
59
    version: bool,
60
    config: Optional[str],
61
    errors_only: bool,
62
    filenames: list[str],
63
    exit_zero: bool,
64
    generate_config: bool,
65
    output_format: Optional[str],
66
) -> None:
67
    """A code checking tool for teaching Python.
68
    FILENAMES can be a string of a directory, or file to check (`.py` extension optional) or
69
    a list of strings of directories or files.
70
    """
71
    if version:
20✔
72
        print(__version__)
20✔
73
        return
20✔
74

75
    # `config` is None if `-c` flag is not set
76
    if generate_config:
20✔
77
        config_location = path.join(path.dirname(__file__), DEFAULT_CONFIG_LOCATION)
20✔
78
        with open(config_location, "r") as f:
20✔
79
            contents = f.read()
20✔
80
            print(contents)
20✔
81
            sys.exit(0)
20✔
82

83
    checker = check_errors if errors_only else check_all
20✔
84
    paths = [click.format_filename(fn) for fn in filenames]
20✔
85

86
    if output_format and config:
20✔
87
        # If both specified, use the config file and override the output format
88
        config_data = _load_config_as_dict(config)
20✔
89
        config_data["output-format"] = output_format
20✔
90
        reporter = checker(module_name=paths, config=config_data)
20✔
91
    elif output_format:
20✔
92
        reporter = checker(module_name=paths, config={"output-format": output_format})
20✔
93
    elif config:
20✔
94
        reporter = checker(module_name=paths, config=config)
20✔
95
    else:
96
        reporter = checker(module_name=paths)
20✔
97

98
    if not exit_zero and reporter.has_messages():
20✔
99
        sys.exit(1)
20✔
100
    else:
101
        sys.exit(0)
20✔
102

103

104
if __name__ == "__main__":  # pragma: no cover
105
    main()
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc