From f38d10b66263393f0e85e4e9f7b8699860ca850b Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Mon, 14 Sep 2026 12:26:24 -0400 Subject: [PATCH 01/14] added num workers parser --- mypy/config_parser.py | 15 +++++++++++++++ mypy/defaults.py | 2 ++ 2 files changed, 17 insertions(+) diff --git a/mypy/config_parser.py b/mypy/config_parser.py index 97fa01b8dd21..14e85d8dcef2 100644 --- a/mypy/config_parser.py +++ b/mypy/config_parser.py @@ -19,6 +19,7 @@ from mypy import defaults from mypy.options import PER_MODULE_OPTIONS, Options +from mypy.util import get_available_threads _CONFIG_VALUE_TYPES: TypeAlias = ( str | bool | int | float | dict[str, str] | list[str] | tuple[int, int] @@ -58,6 +59,19 @@ def parse_version(v: str | float) -> tuple[int, int]: return major, minor +def parse_num_workers(v: str | int) -> int: + value = v.strip() if isinstance(v, str) else v + if value == "auto": + return min(defaults.MAX_AUTO_WORKERS, get_available_threads()) + + try: + return int(value) + except (TypeError, ValueError) as err: + raise argparse.ArgumentTypeError( + f"Invalid number of workers '{v}' (expected an integer or 'auto')" + ) from err + + def try_split(v: str | Sequence[str] | object, split_regex: str = ",") -> list[str]: """Split and trim a str or sequence (eg: list) of str into a list of str. If an element of the input is not str, a type error will be raised.""" @@ -207,6 +221,7 @@ def split_commas(value: str) -> list[str]: "exclude": lambda s: [s.strip()], "packages": try_split, "modules": try_split, + "num_workers": parse_num_workers, } # Reuse the ini_config_types and overwrite the diff diff --git a/mypy/defaults.py b/mypy/defaults.py index d8197e4db00d..2301e6979d10 100644 --- a/mypy/defaults.py +++ b/mypy/defaults.py @@ -47,6 +47,8 @@ RECURSION_LIMIT: Final = 2**14 +MAX_AUTO_WORKERS: Final = 8 + # It looks like Windows is slow with processes, causing test flakiness even # with our generous timeouts, so we set them higher. WORKER_START_INTERVAL: Final = 0.01 if sys.platform != "win32" else 0.03 From b72b92b45a477e4781a27ad73dde52dbe6f5aa0b Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Mon, 14 Sep 2026 12:34:48 -0400 Subject: [PATCH 02/14] add constant documentation --- mypy/defaults.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mypy/defaults.py b/mypy/defaults.py index 2301e6979d10..3eb61526f056 100644 --- a/mypy/defaults.py +++ b/mypy/defaults.py @@ -47,6 +47,8 @@ RECURSION_LIMIT: Final = 2**14 +# Cap the automatic selection of workers since each worker adds roughly 10% of memory overhead. +# Users can specify an explicit --num-workers value which can exceed this limit. MAX_AUTO_WORKERS: Final = 8 # It looks like Windows is slow with processes, causing test flakiness even From d343293c9f5bb51a73c085fb50d1c318126f7d55 Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Mon, 14 Sep 2026 12:41:23 -0400 Subject: [PATCH 03/14] use num_workers parser --- mypy/main.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/mypy/main.py b/mypy/main.py index 9d6d3d5c5f7a..0f9d02f20068 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -23,7 +23,12 @@ sys.exit(2) from mypy import build, defaults, state, util -from mypy.config_parser import parse_config_file, parse_version, validate_package_allow_list +from mypy.config_parser import ( + parse_config_file, + parse_num_workers, + parse_version, + validate_package_allow_list, +) from mypy.defaults import RECURSION_LIMIT from mypy.error_formatter import OUTPUT_CHOICES from mypy.errors import CompileError @@ -1189,9 +1194,10 @@ def add_invertible_flag( internals_group.add_argument( "-n", "--num-workers", - type=int, + type=parse_num_workers, + metavar="VALUE", default=0, - help="Number of separate mypy worker processes (experimental)", + help="Number of separate mypy worker processes, or 'auto' (experimental)", ) report_group = parser.add_argument_group( @@ -1477,9 +1483,9 @@ def set_strict_flags() -> None: environ_num_workers = os.getenv("MYPY_NUM_WORKERS", "") if environ_num_workers.strip(): try: - options.num_workers = int(environ_num_workers) - except ValueError: - parser.error(f"MYPY_NUM_WORKERS must be an integer, got {environ_num_workers!r}") + options.num_workers = parse_num_workers(environ_num_workers) + except argparse.ArgumentTypeError as error: + parser.error(f"MYPY_NUM_WORKERS: {error}") # Parse command line for real, using a split namespace. special_opts = argparse.Namespace() From 53e4150e50aceb5773d46634726678014892209b Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Mon, 14 Sep 2026 12:42:01 -0400 Subject: [PATCH 04/14] force enable incremental --- mypy/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mypy/main.py b/mypy/main.py index 0f9d02f20068..33fe140d803b 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -105,6 +105,7 @@ def main( if options.num_workers: # Supporting both parsers would be really tricky, so just support the new one. options.native_parser = True + options.incremental = True if options.num_workers < 0: fail("error: Number of workers cannot be negative", stderr, options) if options.cache_dir == os.devnull: From 90760998625f87873e787ec9d6ccd4d5b8cc1e6f Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Tue, 15 Sep 2026 02:11:49 -0400 Subject: [PATCH 05/14] add tests --- mypy/test/testargs.py | 112 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/mypy/test/testargs.py b/mypy/test/testargs.py index 767b36fbedd7..f29ab4588c40 100644 --- a/mypy/test/testargs.py +++ b/mypy/test/testargs.py @@ -8,15 +8,125 @@ from __future__ import annotations import argparse +import os import sys +import tempfile +from io import StringIO +from pathlib import Path from typing import Any, cast +from unittest import mock -from mypy.main import infer_python_executable, process_options +from mypy.config_parser import parse_num_workers +from mypy.main import infer_python_executable, main, process_options from mypy.options import Options from mypy.test.helpers import Suite class ArgSuite(Suite): + def test_parse_num_workers(self) -> None: + with mock.patch("mypy.config_parser.get_available_threads", return_value=4): + assert parse_num_workers("auto") == 4 + with mock.patch("mypy.config_parser.get_available_threads", return_value=32): + assert parse_num_workers("auto") == 8 + + assert parse_num_workers(12) == 12 + assert parse_num_workers("12") == 12 + + assert parse_num_workers("0") == 0 + assert parse_num_workers("1") == 1 + + assert parse_num_workers("-1") == -1 + with self.assertRaises(argparse.ArgumentTypeError): + parse_num_workers("automatic") + + def test_num_workers_auto_from_command_line_and_environment(self) -> None: + with mock.patch("mypy.config_parser.get_available_threads", return_value=6): + with mock.patch.dict(os.environ, {"MYPY_NUM_WORKERS": ""}): + _, cli_options = process_options( + ["--config-file=", "--num-workers=auto"], require_targets=False + ) + with mock.patch.dict(os.environ, {"MYPY_NUM_WORKERS": "auto"}): + _, env_options = process_options(["--config-file="], require_targets=False) + + assert cli_options.num_workers == 6 + assert env_options.num_workers == 6 + + def test_invalid_num_workers_environment(self) -> None: + stderr = StringIO() + with mock.patch.dict(os.environ, {"MYPY_NUM_WORKERS": "automatic"}): + with self.assertRaises(SystemExit) as context: + process_options( + ["--config-file="], require_targets=False, stdout=StringIO(), stderr=stderr + ) + + assert context.exception.code == 2 + assert "MYPY_NUM_WORKERS: Invalid number of workers 'automatic'" in stderr.getvalue() + + def test_num_workers_auto_from_config(self) -> None: + configs = ( + ("mypy.ini", "[mypy]\nnum_workers = auto\n"), + ("pyproject.toml", '[tool.mypy]\nnum_workers = "auto"\n'), + ) + with tempfile.TemporaryDirectory() as temp_dir: + with mock.patch("mypy.config_parser.get_available_threads", return_value=6): + for filename, contents in configs: + config = Path(temp_dir) / filename + config.write_text(contents, encoding="utf-8") + with mock.patch.dict(os.environ, {"MYPY_NUM_WORKERS": ""}): + _, options = process_options( + ["--config-file", str(config)], require_targets=False + ) + assert options.num_workers == 6, filename + + def test_num_workers_precedence(self) -> None: + with tempfile.TemporaryDirectory() as temp_dir: + config = Path(temp_dir) / "mypy.ini" + config.write_text("[mypy]\nnum_workers = 2\n", encoding="utf-8") + + with mock.patch("mypy.config_parser.get_available_threads", return_value=4): + with mock.patch.dict(os.environ, {"MYPY_NUM_WORKERS": ""}): + _, config_options = process_options( + ["--config-file", str(config)], require_targets=False + ) + + with mock.patch.dict(os.environ, {"MYPY_NUM_WORKERS": "7"}): + _, env_options = process_options( + ["--config-file", str(config)], require_targets=False + ) + + _, cli_options = process_options( + ["--config-file", str(config), "--num-workers=auto"], + require_targets=False, + ) + + assert config_options.num_workers == 2 + assert env_options.num_workers == 7 + assert cli_options.num_workers == 4 + + def test_parallel_mode_forces_incremental(self) -> None: + def incremental_with_workers(num_workers: int) -> bool: + with mock.patch("mypy.main.run_build", return_value=(None, [], False)) as run_build: + main( + args=[ + "--config-file=", + f"--num-workers={num_workers}", + "--no-incremental", + "--no-site-packages", + "--no-error-summary", + "-c", + "pass", + ], + stdout=StringIO(), + stderr=StringIO(), + clean_exit=True, + ) + + options = cast(Options, run_build.call_args.args[1]) + return options.incremental + + assert incremental_with_workers(1) + assert not incremental_with_workers(0) + def test_coherence(self) -> None: options = Options() _, parsed_options = process_options([], require_targets=False) From cedfd220fe668e272a35019c740060a1793728cc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 15 Sep 2026 06:13:36 +0000 Subject: [PATCH 06/14] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/test/testargs.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mypy/test/testargs.py b/mypy/test/testargs.py index f29ab4588c40..821244235b98 100644 --- a/mypy/test/testargs.py +++ b/mypy/test/testargs.py @@ -31,10 +31,10 @@ def test_parse_num_workers(self) -> None: assert parse_num_workers(12) == 12 assert parse_num_workers("12") == 12 - + assert parse_num_workers("0") == 0 assert parse_num_workers("1") == 1 - + assert parse_num_workers("-1") == -1 with self.assertRaises(argparse.ArgumentTypeError): parse_num_workers("automatic") @@ -95,8 +95,7 @@ def test_num_workers_precedence(self) -> None: ) _, cli_options = process_options( - ["--config-file", str(config), "--num-workers=auto"], - require_targets=False, + ["--config-file", str(config), "--num-workers=auto"], require_targets=False ) assert config_options.num_workers == 2 @@ -126,7 +125,7 @@ def incremental_with_workers(num_workers: int) -> bool: assert incremental_with_workers(1) assert not incremental_with_workers(0) - + def test_coherence(self) -> None: options = Options() _, parsed_options = process_options([], require_targets=False) From 7aa572939d6dccee409c5f8cb8f1fb5b6c481d90 Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Tue, 15 Sep 2026 02:16:58 -0400 Subject: [PATCH 07/14] add command line doc --- docs/source/command_line.rst | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index b371062e8bff..2c660a2af9bb 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -1044,15 +1044,18 @@ used to manage most of the shared state. Parallel type-checking also requires :option:`--local-partial-types `, which is enabled by default starting from mypy 2.0. -.. option:: -n NUMBER, --num-workers NUMBER +.. option:: -n VALUE, --num-workers VALUE - Use ``NUMBER`` parallel worker processes (in addition to the coordinator - process) to perform type-checking. Specifying ``--num-workers 0`` (default) - disables parallel checking. Automatic detection of the optimal number - of workers is not supported yet. + Use the specified amount of parallel worker processes (in addition to the + coordinator process) to perform type-checking. Specifying ``--num-workers 0`` + (default) disables parallel checking. Specifying ``--num-workers auto`` + selects the number based on the physical CPU cores available to mypy. - This setting will override the ``MYPY_NUM_WORKERS`` environment - variable if it is set. + Automatic selection uses at most 8 workers because each worker adds roughly + 10% memory overhead. This cap does not apply when an explicit value is specified. + + The ``MYPY_NUM_WORKERS`` environment variable also accepts ``auto``. This + setting will override the environment variable if it is set. Notes: @@ -1065,7 +1068,9 @@ Notes: tune the number of workers on a given machine is to start from 3-4 workers and increase the number while you see a performance improvement. -* Parallel mode requires and automatically enables :option:`--native-parser`. +* Parallel mode requires and automatically enables :option:`--native-parser` + and :ref:`incremental mode `. Specifying + :option:`--no-incremental` has no effect in parallel mode. Advanced options From dabc51b243571f5d23a46f6323dfc173db7c8c90 Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Tue, 15 Sep 2026 02:23:24 -0400 Subject: [PATCH 08/14] added config file documentation --- docs/source/config_file.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index adb6c9f21a72..61ec382795f2 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -1013,13 +1013,14 @@ These options may only be set in the global section (``[mypy]``). .. confval:: num_workers - :type: integer + :type: integer or string :default: 0 - Use specific number of parallel worker processes for type-checking, see - :ref:`parallel type-checking ` for more details. - This setting will be overridden by the ``MYPY_NUM_WORKERS`` environment - variable. + Use a specific number of parallel worker processes for type-checking or + the value ``auto`` to select the number based on the CPUs available to mypy. + See :ref:`parallel type-checking ` for more details. + The ``MYPY_NUM_WORKERS`` environment variable accepts the same values and + overrides this setting. Advanced options From 03ca7fffccdc81e7d43153e91d0ce95d9da61988 Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Tue, 15 Sep 2026 03:06:51 -0400 Subject: [PATCH 09/14] update wording --- docs/source/command_line.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index 2c660a2af9bb..4ebfdfb4046e 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -1049,7 +1049,7 @@ enabled by default starting from mypy 2.0. Use the specified amount of parallel worker processes (in addition to the coordinator process) to perform type-checking. Specifying ``--num-workers 0`` (default) disables parallel checking. Specifying ``--num-workers auto`` - selects the number based on the physical CPU cores available to mypy. + selects the number based on the CPU resources available to mypy. Automatic selection uses at most 8 workers because each worker adds roughly 10% memory overhead. This cap does not apply when an explicit value is specified. From bf91acb097573ed979a7a9e64426e48087eaad9e Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Wed, 16 Sep 2026 02:26:48 -0400 Subject: [PATCH 10/14] Update docs/source/command_line.rst Co-authored-by: Ivan Levkivskyi --- docs/source/command_line.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index 4ebfdfb4046e..fc03077f8fb1 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -1054,8 +1054,8 @@ enabled by default starting from mypy 2.0. Automatic selection uses at most 8 workers because each worker adds roughly 10% memory overhead. This cap does not apply when an explicit value is specified. - The ``MYPY_NUM_WORKERS`` environment variable also accepts ``auto``. This - setting will override the environment variable if it is set. + This setting will override the ``MYPY_NUM_WORKERS`` environment + variable if it is set. Notes: From d73e581f929cda33ed765fc5a413a498995de199 Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Wed, 16 Sep 2026 02:27:29 -0400 Subject: [PATCH 11/14] fix tests to work with mypyc --- mypy/test/testargs.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/mypy/test/testargs.py b/mypy/test/testargs.py index 821244235b98..7ea69f04ea89 100644 --- a/mypy/test/testargs.py +++ b/mypy/test/testargs.py @@ -8,25 +8,38 @@ from __future__ import annotations import argparse +import contextlib import os import sys import tempfile +from collections.abc import Iterator from io import StringIO from pathlib import Path from typing import Any, cast from unittest import mock +from mypy import util from mypy.config_parser import parse_num_workers from mypy.main import infer_python_executable, main, process_options from mypy.options import Options from mypy.test.helpers import Suite +@contextlib.contextmanager +def _available_threads(value: int) -> Iterator[None]: + previous = util._AVAILABLE_THREADS + util._AVAILABLE_THREADS = value + try: + yield + finally: + util._AVAILABLE_THREADS = previous + + class ArgSuite(Suite): def test_parse_num_workers(self) -> None: - with mock.patch("mypy.config_parser.get_available_threads", return_value=4): + with _available_threads(4): assert parse_num_workers("auto") == 4 - with mock.patch("mypy.config_parser.get_available_threads", return_value=32): + with _available_threads(32): assert parse_num_workers("auto") == 8 assert parse_num_workers(12) == 12 @@ -40,7 +53,7 @@ def test_parse_num_workers(self) -> None: parse_num_workers("automatic") def test_num_workers_auto_from_command_line_and_environment(self) -> None: - with mock.patch("mypy.config_parser.get_available_threads", return_value=6): + with _available_threads(6): with mock.patch.dict(os.environ, {"MYPY_NUM_WORKERS": ""}): _, cli_options = process_options( ["--config-file=", "--num-workers=auto"], require_targets=False @@ -68,7 +81,7 @@ def test_num_workers_auto_from_config(self) -> None: ("pyproject.toml", '[tool.mypy]\nnum_workers = "auto"\n'), ) with tempfile.TemporaryDirectory() as temp_dir: - with mock.patch("mypy.config_parser.get_available_threads", return_value=6): + with _available_threads(6): for filename, contents in configs: config = Path(temp_dir) / filename config.write_text(contents, encoding="utf-8") @@ -83,7 +96,7 @@ def test_num_workers_precedence(self) -> None: config = Path(temp_dir) / "mypy.ini" config.write_text("[mypy]\nnum_workers = 2\n", encoding="utf-8") - with mock.patch("mypy.config_parser.get_available_threads", return_value=4): + with _available_threads(4): with mock.patch.dict(os.environ, {"MYPY_NUM_WORKERS": ""}): _, config_options = process_options( ["--config-file", str(config)], require_targets=False From f88e7799b214078c6bf32696d471f931f646e168 Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Wed, 16 Sep 2026 02:47:56 -0400 Subject: [PATCH 12/14] warn when incremental isn't enabled and remove experimental wording --- mypy/main.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mypy/main.py b/mypy/main.py index 33fe140d803b..034bc6d39043 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -105,7 +105,9 @@ def main( if options.num_workers: # Supporting both parsers would be really tricky, so just support the new one. options.native_parser = True - options.incremental = True + if not options.incremental and os.path.isdir(options.cache_dir): + print("Warning: disabling incremental mode may severely reduce performance") + print(f"If this is intentional, delete '{options.cache_dir}' to suppress this warning") if options.num_workers < 0: fail("error: Number of workers cannot be negative", stderr, options) if options.cache_dir == os.devnull: @@ -1191,14 +1193,14 @@ def add_invertible_flag( # This undocumented feature exports limited line-level dependency information. internals_group.add_argument("--export-ref-info", action="store_true", help=argparse.SUPPRESS) - # Experimental parallel type-checking support. + # Parallel type-checking support. internals_group.add_argument( "-n", "--num-workers", type=parse_num_workers, metavar="VALUE", default=0, - help="Number of separate mypy worker processes, or 'auto' (experimental)", + help="Number of separate mypy worker processes, or 'auto'", ) report_group = parser.add_argument_group( From 2158d1c07d1139d2329ca695c960dfe0cae607c3 Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Wed, 16 Sep 2026 03:19:02 -0400 Subject: [PATCH 13/14] test to validate new warning --- mypy/main.py | 9 ++++++-- mypy/test/testargs.py | 48 ++++++++++++++++++++++--------------------- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/mypy/main.py b/mypy/main.py index 034bc6d39043..4eaa802f21c5 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -106,8 +106,13 @@ def main( # Supporting both parsers would be really tricky, so just support the new one. options.native_parser = True if not options.incremental and os.path.isdir(options.cache_dir): - print("Warning: disabling incremental mode may severely reduce performance") - print(f"If this is intentional, delete '{options.cache_dir}' to suppress this warning") + print( + "Warning: disabling incremental mode may severely reduce performance", file=stdout + ) + print( + f"If this is intentional, delete '{options.cache_dir}' to suppress this warning", + file=stdout, + ) if options.num_workers < 0: fail("error: Number of workers cannot be negative", stderr, options) if options.cache_dir == os.devnull: diff --git a/mypy/test/testargs.py b/mypy/test/testargs.py index 7ea69f04ea89..e233d5a42a1a 100644 --- a/mypy/test/testargs.py +++ b/mypy/test/testargs.py @@ -115,29 +115,31 @@ def test_num_workers_precedence(self) -> None: assert env_options.num_workers == 7 assert cli_options.num_workers == 4 - def test_parallel_mode_forces_incremental(self) -> None: - def incremental_with_workers(num_workers: int) -> bool: - with mock.patch("mypy.main.run_build", return_value=(None, [], False)) as run_build: - main( - args=[ - "--config-file=", - f"--num-workers={num_workers}", - "--no-incremental", - "--no-site-packages", - "--no-error-summary", - "-c", - "pass", - ], - stdout=StringIO(), - stderr=StringIO(), - clean_exit=True, - ) - - options = cast(Options, run_build.call_args.args[1]) - return options.incremental - - assert incremental_with_workers(1) - assert not incremental_with_workers(0) + def test_parallel_mode_warns_when_incremental_disabled(self) -> None: + with tempfile.TemporaryDirectory() as cache_dir: + stdout = StringIO() + stderr = StringIO() + main( + args=[ + "--config-file=", + "--num-workers=1", + "--no-incremental", + "--no-site-packages", + "--no-error-summary", + f"--cache-dir={cache_dir}", + "-c", + "pass", + ], + stdout=stdout, + stderr=stderr, + clean_exit=True, + ) + + assert stdout.getvalue() == ( + "Warning: disabling incremental mode may severely reduce performance\n" + f"If this is intentional, delete '{cache_dir}' to suppress this warning\n" + ) + assert stderr.getvalue() == "" def test_coherence(self) -> None: options = Options() From 13be468e7751f10f81a00fce25edfc23bf3f7408 Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Wed, 16 Sep 2026 03:21:06 -0400 Subject: [PATCH 14/14] updated command line doc --- docs/source/command_line.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index fc03077f8fb1..cbd72a217d29 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -1037,7 +1037,7 @@ Parallel type-checking ********************** By default, mypy checks all modules in the same Python process. This can be slow -for large code bases. Mypy offers experimental parallel type-checking mode using +for large code bases. Mypy offers parallel type-checking mode using multiple worker processes. In parallel mode, modules that do not depend om each other are type-checked in parallel. :ref:`Incremental cache ` is used to manage most of the shared state. Parallel type-checking also requires @@ -1068,9 +1068,7 @@ Notes: tune the number of workers on a given machine is to start from 3-4 workers and increase the number while you see a performance improvement. -* Parallel mode requires and automatically enables :option:`--native-parser` - and :ref:`incremental mode `. Specifying - :option:`--no-incremental` has no effect in parallel mode. +* Parallel mode requires and automatically enables :option:`--native-parser`. Advanced options