From 435b7131cb63fd304d2b3fea9d1705e069665c7f Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Thu, 30 Apr 2026 23:58:36 +0100 Subject: [PATCH 1/3] Expose --num-workers and --native-parser --- docs/source/command_line.rst | 36 ++++++++++++++++++++++++++++++++++++ docs/source/config_file.rst | 22 ++++++++++++++++++++++ mypy/main.py | 16 ++++++++++++++-- 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index 72caf65845ff3..a8d63c9ceb5fc 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -1032,6 +1032,37 @@ beyond what incremental mode can offer, try running mypy in Skip cache internal consistency checks based on mtime. +.. _parallel: + +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 +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 +:option:`--local-partial-types `, which is +enabled by default starting from mypy 2.0. + +.. option:: -n NUMBER, --num-workers NUMBER + + 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. + +Notes: +* An import cycle is always processed as a whole by a worker process. Thus, + avoiding large import cycles in your code will *significantly* improve + type-checking speed. +* Specifying a number of workers that is larger than the number of *physical* + CPU cores is not beneficial, since mypy is usually CPU bound. Best way to + tune the number of workers on a given machine is to start from 2-3 workers + and increase the number while you see a performance improvement. +* Parallel mode requires and automatically enables :option:`--native-parser`. + + Advanced options **************** @@ -1105,6 +1136,11 @@ in developing or debugging mypy internals. cause mypy to type check the contents of ``temp.py`` instead of ``original.py``, but error messages will still reference ``original.py``. +.. option:: --native-parser + + This enables fast Rust-based parser that parses directly to mypy AST. + It will become the default parser in one of the next mypy releases. + Report generation ***************** diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index 05520e97908ef..4f2fddaeba8cd 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -1006,6 +1006,20 @@ These options may only be set in the global section (``[mypy]``). Skip cache internal consistency checks based on mtime. +Parallel type-checking configuration +************************************ + +These options may only be set in the global section (``[mypy]``). + +.. confval:: num_workers + + :type: integer + :default: 0 + + Use specific number of parallel worker processes for type-checking, see + :ref:`parallel type-checking ` for more details. + + Advanced options **************** @@ -1067,6 +1081,14 @@ These options may only be set in the global section (``[mypy]``). Warns about missing type annotations in typeshed. This is only relevant in combination with :confval:`disallow_untyped_defs` or :confval:`disallow_incomplete_defs`. +.. confval:: native_parser + + :type: boolean + :default: False + + This enables fast Rust-based parser that parses directly to mypy AST. + It will become the default parser in one of the next mypy releases. + Report generation ***************** diff --git a/mypy/main.py b/mypy/main.py index 223efc9e1af86..040275984fb63 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -100,8 +100,12 @@ def main( if options.num_workers: # Supporting both parsers would be really tricky, so just support the new one. options.native_parser = True + if options.num_workers < 0: + fail("error: Number of workers cannot be negative", stderr, options) if options.cache_dir == os.devnull: fail("error: Cache must be enabled in parallel mode", stderr, options) + if not options.local_partial_types: + fail("error: --local-partial-types must be enabled in parallel mode", stderr, options) if options.report_dirs: fail( "error: Reports are not supported in parallel mode yet\n" @@ -1175,7 +1179,11 @@ def add_invertible_flag( # Experimental parallel type-checking support. internals_group.add_argument( - "-n", "--num-workers", type=int, default=0, help=argparse.SUPPRESS + "-n", + "--num-workers", + type=int, + default=0, + help="Number of separate mypy worker processes (experimental)", ) report_group = parser.add_argument_group( @@ -1288,7 +1296,11 @@ def add_invertible_flag( help=argparse.SUPPRESS, ) # --native-parser enables the native parser (experimental) - add_invertible_flag("--native-parser", default=False, help=argparse.SUPPRESS) + add_invertible_flag( + "--native-parser", + default=False, + help="Enable faster parser that parses directly to mypy AST", + ) # --logical-deps adds some more dependencies that are not semantically needed, but # may be helpful to determine relative importance of classes and functions for overall # type precision in a code base. It also _removes_ some deps, so this flag should be never From 963198d6281da45b64326ea36c75acf637ff281d Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Fri, 1 May 2026 00:09:47 +0100 Subject: [PATCH 2/3] Try fixing docs --- docs/source/command_line.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index a8d63c9ceb5fc..e386a265b90cc 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -1053,13 +1053,16 @@ enabled by default starting from mypy 2.0. of workers is not supported yet. Notes: + * An import cycle is always processed as a whole by a worker process. Thus, avoiding large import cycles in your code will *significantly* improve type-checking speed. + * Specifying a number of workers that is larger than the number of *physical* CPU cores is not beneficial, since mypy is usually CPU bound. Best way to tune the number of workers on a given machine is to start from 2-3 workers and increase the number while you see a performance improvement. + * Parallel mode requires and automatically enables :option:`--native-parser`. From 6169d4644ec1bab9b9c6a8664b9c65f87133757e Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Fri, 1 May 2026 11:30:05 +0100 Subject: [PATCH 3/3] Some CR --- 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 e386a265b90cc..7d6280f2ff0ff 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -1037,7 +1037,7 @@ beyond what incremental mode can offer, try running mypy in Parallel type-checking ********************** -By default, mypy checks all modules in the same Python process, this can be slow +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 multiple worker processes. In parallel mode, modules that do not depend om each other are type-checked in parallel. :ref:`Incremental cache ` is @@ -1060,7 +1060,7 @@ Notes: * Specifying a number of workers that is larger than the number of *physical* CPU cores is not beneficial, since mypy is usually CPU bound. Best way to - tune the number of workers on a given machine is to start from 2-3 workers + 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`.