diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index b5081f113f917..a01c9c85515ac 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -937,6 +937,7 @@ in error messages. Use visually nicer output in error messages: use soft word wrap, show source code snippets, and show error location markers. + This is enabled by default. Use ``--no-pretty`` to disable. .. option:: --no-color-output diff --git a/mypy/options.py b/mypy/options.py index 0a7ddb112e273..46f26b7722d08 100644 --- a/mypy/options.py +++ b/mypy/options.py @@ -365,7 +365,7 @@ def __init__(self) -> None: self.hide_error_codes = False self.show_error_code_links = False # Use soft word wrap and show trimmed source snippets with error location markers. - self.pretty = False + self.pretty = True self.dump_graph = False self.dump_deps = False self.logical_deps = False diff --git a/mypy/stubtest.py b/mypy/stubtest.py index a6780984c1f54..2ae21a3777885 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -2286,6 +2286,7 @@ def test_stubs(args: _Arguments, use_builtins_fixtures: bool = False) -> int: options = Options() options.incremental = False + options.pretty = False options.custom_typeshed_dir = args.custom_typeshed_dir if options.custom_typeshed_dir: options.abs_custom_typeshed_dir = os.path.abspath(options.custom_typeshed_dir) diff --git a/mypy/test/helpers.py b/mypy/test/helpers.py index fbd3b8f2aac32..0b49498b1ff3f 100644 --- a/mypy/test/helpers.py +++ b/mypy/test/helpers.py @@ -352,11 +352,14 @@ def parse_options( raise RuntimeError("Specifying targets via the flags pragma is not supported.") if "--show-error-codes" not in flag_list: options.hide_error_codes = True + if "--pretty" not in flag_list: + options.pretty = False else: flag_list = [] options = Options() options.error_summary = False options.hide_error_codes = True + options.pretty = False # Allow custom python version to override testfile_pyversion. if all(flag.split("=")[0] != "--python-version" for flag in flag_list): diff --git a/mypy/test/testcmdline.py b/mypy/test/testcmdline.py index 450f5abc14c34..39b736f409093 100644 --- a/mypy/test/testcmdline.py +++ b/mypy/test/testcmdline.py @@ -66,6 +66,8 @@ def test_python_cmdline(testcase: DataDrivenTestCase, step: int) -> None: args.append("--hide-error-codes") if "--disallow-empty-bodies" not in args: args.append("--allow-empty-bodies") + if "--pretty" not in args: + args.append("--no-pretty") # Type check the program. fixed = [python3_path, "-m", "mypy"] env = os.environ.copy() diff --git a/mypy/test/testdaemon.py b/mypy/test/testdaemon.py index 7115e682e60da..acac3ee8338c5 100644 --- a/mypy/test/testdaemon.py +++ b/mypy/test/testdaemon.py @@ -8,6 +8,7 @@ from __future__ import annotations import os +import re import subprocess import sys import tempfile @@ -76,9 +77,78 @@ def parse_script(input: list[str]) -> list[list[str]]: return steps +def _add_no_pretty_to_dmypy(input: str) -> str: + """Add --no-pretty to a dmypy run/start command that has no -- separator. + + For dmypy run/start, mypy flags are passed as positional args after --. + When the command has no --, we need to insert -- before the positional args + and append --no-pretty. We must keep any dmypy-specific named flags + (like --export-types, --log-file FILE) before the -- separator. + """ + # Match: "dmypy run" or "dmypy start", then the rest of the args + m = re.match(r"(dmypy (?:run|start))\s*(.*)", input) + if not m: + return input + prefix = m.group(1) + rest = m.group(2) + + # Known dmypy run/start flags that take no value + no_value_flags = {"--export-types", "--verbose", "-v"} + # Known dmypy run/start flags that take a value + value_flags = {"--log-file", "--timeout", "--junit-xml", "--perf-stats-file"} + + parts = rest.split() + dmypy_flags: list[str] = [] + positional: list[str] = [] + i = 0 + while i < len(parts): + if parts[i] in no_value_flags: + dmypy_flags.append(parts[i]) + i += 1 + elif parts[i] in value_flags: + dmypy_flags.append(parts[i]) + if i + 1 < len(parts): + dmypy_flags.append(parts[i + 1]) + i += 2 + elif parts[i].startswith("-") and "=" in parts[i]: + # Handle --flag=value style for known flags + flag_name = parts[i].split("=")[0] + if flag_name in value_flags: + dmypy_flags.append(parts[i]) + else: + positional.append(parts[i]) + i += 1 + else: + positional.append(parts[i]) + i += 1 + + dmypy_part = " ".join(dmypy_flags) + positional_part = " ".join(positional) + result = prefix + if dmypy_part: + result += " " + dmypy_part + result += " -- " + if positional_part: + result += positional_part + " " + result += "--no-pretty" + return result + + def run_cmd(input: str) -> tuple[int, str]: if input[1:].startswith("mypy run --") and "--show-error-codes" not in input: input += " --hide-error-codes" + if "--pretty" not in input: + if input.startswith(("dmypy run ", "dmypy start")) and " -- " in input: + # For dmypy run/start, mypy flags come after --, so append at end + input += " --no-pretty" + elif input.startswith("mypy ") and " -- " in input: + # For mypy commands, options come before --, so insert before -- + input = input.replace(" -- ", " --no-pretty -- ", 1) + elif input.startswith(("dmypy run ", "dmypy start")): + # dmypy run/start without -- need the separator added + input = _add_no_pretty_to_dmypy(input) + elif input.startswith("mypy "): + input += " --no-pretty" if input.startswith("dmypy "): input = sys.executable + " -m mypy." + input if input.startswith("mypy "): diff --git a/mypy/test/testerrorstream.py b/mypy/test/testerrorstream.py index a54a3495ddb2f..6cca7860526fe 100644 --- a/mypy/test/testerrorstream.py +++ b/mypy/test/testerrorstream.py @@ -27,6 +27,7 @@ def test_error_stream(testcase: DataDrivenTestCase) -> None: options = Options() options.show_traceback = True options.hide_error_codes = True + options.pretty = False logged_messages: list[str] = [] diff --git a/mypy/test/testpep561.py b/mypy/test/testpep561.py index 0afb69bc0c998..fdad87463af55 100644 --- a/mypy/test/testpep561.py +++ b/mypy/test/testpep561.py @@ -124,7 +124,7 @@ def test_pep561(testcase: DataDrivenTestCase) -> None: f.write(f"{s}\n") cmd_line.append(program) - cmd_line.extend(["--no-error-summary", "--hide-error-codes"]) + cmd_line.extend(["--no-error-summary", "--hide-error-codes", "--no-pretty"]) if python_executable != sys.executable: cmd_line.append(f"--python-executable={python_executable}") diff --git a/mypy/test/testpythoneval.py b/mypy/test/testpythoneval.py index 6d22aca07da7f..b7088e5f93a71 100644 --- a/mypy/test/testpythoneval.py +++ b/mypy/test/testpythoneval.py @@ -52,6 +52,7 @@ def test_python_evaluation(testcase: DataDrivenTestCase, cache_dir: str) -> None "--no-error-summary", "--hide-error-codes", "--allow-empty-bodies", + "--no-pretty", "--test-env", # Speeds up some checks ] interpreter = python3_path diff --git a/mypyc/test/test_commandline.py b/mypyc/test/test_commandline.py index f66ca2ec8ff02..0b94121b108a8 100644 --- a/mypyc/test/test_commandline.py +++ b/mypyc/test/test_commandline.py @@ -50,7 +50,7 @@ def run_case(self, testcase: DataDrivenTestCase) -> None: try: # Compile program cmd = subprocess.run( - [sys.executable, "-m", "mypyc", *args], + [sys.executable, "-m", "mypyc", "--no-pretty", *args], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd="tmp",