@@ -898,7 +898,6 @@ def __init__(
898898 self .errors ,
899899 self .plugin ,
900900 self .import_map ,
901- parallel_worker ,
902901 )
903902 self .all_types : dict [Expression , Type ] = {} # Enabled by export_types
904903 self .indirection_detector = TypeIndirectionVisitor ()
@@ -2056,14 +2055,26 @@ def find_cache_meta(
20562055
20572056 # Ignore cache if (relevant) options aren't the same.
20582057 # Note that it's fine to mutilate cached_options since it's only used here.
2059- cached_options = m .options
2058+ cached_options = m .options . copy ()
20602059 current_options = options_snapshot (id , manager )
20612060 if manager .options .skip_version_check :
20622061 # When we're lax about version we're also lax about platform.
20632062 cached_options ["platform" ] = current_options ["platform" ]
20642063 if "debug_cache" in cached_options :
20652064 # Older versions included debug_cache, but it's silly to compare it.
20662065 del cached_options ["debug_cache" ]
2066+ if "local_partial_types" in cached_options :
2067+ local_partial_types = cached_options ["local_partial_types" ]
2068+ del cached_options ["local_partial_types" ]
2069+ is_parallel = manager .options .num_workers > 0
2070+ if not local_partial_types and cached_options ["is_parallel" ] != is_parallel :
2071+ # If local partial types are disabled, behavior is too different for
2072+ # parallel and sequential runs, see write_cache for details.
2073+ return None
2074+ del cached_options ["is_parallel" ]
2075+ else :
2076+ # Cache from an old mypy version.
2077+ return None
20672078 if cached_options != current_options :
20682079 manager .log (f"Metadata abandoned for { id } : options differ" )
20692080 if manager .options .verbosity >= 2 :
@@ -2227,7 +2238,6 @@ def validate_meta(
22272238 meta .mtime = mtime
22282239 meta .path = path
22292240 meta .size = size
2230- meta .options = options_snapshot (id , manager )
22312241 meta_file , _ , _ = get_cache_names (id , path , manager .options )
22322242 if manager .logging_enabled :
22332243 manager .log (
@@ -2272,6 +2282,8 @@ def write_cache(
22722282 trans_dep_hash : bytes ,
22732283 source_hash : str ,
22742284 ignore_all : bool ,
2285+ local_partial_types : bool ,
2286+ is_parallel : bool ,
22752287 manager : BuildManager ,
22762288) -> tuple [bytes , tuple [CacheMeta , str ] | None ]:
22772289 """Write cache files for a module.
@@ -2371,6 +2383,16 @@ def write_cache(
23712383 # important, or otherwise the options would never match when
23722384 # verifying the cache.
23732385 assert source_hash is not None
2386+ # Local partial types need special handling as they behave differently
2387+ # in sequential and parallel runs:
2388+ # * In sequential run we respected the option, but use different SCC
2389+ # processing logic depending on whether they are enabled or disabled.
2390+ # * In parallel run they are always on, and we give an error if a user
2391+ # tries to disable them.
2392+ extra_options = {
2393+ "local_partial_types" : local_partial_types ,
2394+ "is_parallel" : is_parallel ,
2395+ }
23742396 meta = CacheMeta (
23752397 id = id ,
23762398 path = path ,
@@ -2382,7 +2404,7 @@ def write_cache(
23822404 data_file = data_file ,
23832405 suppressed = suppressed ,
23842406 imports_ignored = imports_ignored ,
2385- options = options_snapshot (id , manager ),
2407+ options = options_snapshot (id , manager ) | extra_options ,
23862408 suppressed_deps_opts = suppressed_deps_opts ,
23872409 dep_prios = dep_prios ,
23882410 dep_lines = dep_lines ,
@@ -2727,6 +2749,11 @@ def new_state(
27272749 meta , meta_ex = meta_pair
27282750 interface_hash = meta .interface_hash
27292751 meta_source_hash = meta .hash
2752+ # Update the local partial types in case they were set by an inline config.
2753+ # So we can select the correct SCC processing logic without reading the file.
2754+ local_partial_types = meta .options ["local_partial_types" ]
2755+ if options .local_partial_types != local_partial_types :
2756+ options = options .apply_changes ({"local_partial_types" : local_partial_types })
27302757 if path and source is None and manager .fscache .isdir (path ):
27312758 source = ""
27322759
@@ -3637,6 +3664,8 @@ def write_cache(self) -> tuple[CacheMeta, str] | None:
36373664 self .trans_dep_hash ,
36383665 self .source_hash ,
36393666 self .ignore_all ,
3667+ self .options .local_partial_types ,
3668+ self .options .num_workers > 0 ,
36403669 self .manager ,
36413670 )
36423671 if new_interface_hash == self .interface_hash :
0 commit comments