1111from librt .internal import WriteBuffer , write_bool , write_str
1212
1313from mypy import defaults
14+ from mypy .cache import write_json
1415from mypy .errorcodes import ErrorCode , error_codes
1516from mypy .util import get_class_descriptors , replace_object_state
1617
@@ -343,7 +344,7 @@ def __init__(self) -> None:
343344 # Per-module options (raw)
344345 self .per_module_options : dict [str , dict [str , object ]] = {}
345346 self ._glob_options : list [tuple [str , Pattern [str ]]] = []
346- self .unused_configs : set [str ] = set ()
347+ self ._unused_configs : set [str ] = set ()
347348
348349 # -- development options --
349350 self .verbosity = 0 # More verbose messages (for troubleshooting)
@@ -451,6 +452,17 @@ def snapshot(self) -> dict[str, object]:
451452 d = {k : v for k , v in d .items () if not k .startswith ("_" )}
452453 return d
453454
455+ def to_bytes (self ) -> bytes :
456+ """Serialize this options object to binary data."""
457+ assert self .transform_source is None , "Source transform cannot be serialized"
458+ snapshot = self .snapshot ()
459+ # Caller will need to use process_error_codes() to re-compute these.
460+ del snapshot ["disabled_error_codes" ]
461+ del snapshot ["enabled_error_codes" ]
462+ buf = WriteBuffer ()
463+ write_json (buf , snapshot )
464+ return buf .getvalue ()
465+
454466 def __repr__ (self ) -> str :
455467 return f"Options({ pprint .pformat (self .snapshot ())} )"
456468
@@ -560,7 +572,7 @@ def build_per_module_cache(self) -> None:
560572 # sections as used if any real modules use them or if any
561573 # concrete config sections use them. This means we need to
562574 # track which get used while constructing.
563- self .unused_configs = set (unstructured_glob_keys )
575+ self ._unused_configs = set (unstructured_glob_keys )
564576
565577 for key in wildcards + concrete :
566578 # Find what the options for this key would be, just based
@@ -571,7 +583,7 @@ def build_per_module_cache(self) -> None:
571583
572584 # Add the more structured sections into unused configs, since
573585 # they only count as used if actually used by a real module.
574- self .unused_configs .update (structured_keys )
586+ self ._unused_configs .update (structured_keys )
575587
576588 def clone_for_module (self , module : str ) -> Options :
577589 """Create an Options object that incorporates per-module options.
@@ -585,7 +597,7 @@ def clone_for_module(self, module: str) -> Options:
585597
586598 # If the module just directly has a config entry, use it.
587599 if module in self ._per_module_cache :
588- self .unused_configs .discard (module )
600+ self ._unused_configs .discard (module )
589601 return self ._per_module_cache [module ]
590602
591603 # If not, search for glob paths at all the parents. So if we are looking for
@@ -598,7 +610,7 @@ def clone_for_module(self, module: str) -> Options:
598610 for i in range (len (path ), 0 , - 1 ):
599611 key = "." .join (path [:i ] + ["*" ])
600612 if key in self ._per_module_cache :
601- self .unused_configs .discard (key )
613+ self ._unused_configs .discard (key )
602614 options = self ._per_module_cache [key ]
603615 break
604616
@@ -607,7 +619,7 @@ def clone_for_module(self, module: str) -> Options:
607619 if not module .endswith (".*" ):
608620 for key , pattern in self ._glob_options :
609621 if pattern .match (module ):
610- self .unused_configs .discard (key )
622+ self ._unused_configs .discard (key )
611623 options = options .apply_changes (self .per_module_options [key ])
612624
613625 # We could update the cache to directly point to modules once
@@ -616,6 +628,9 @@ def clone_for_module(self, module: str) -> Options:
616628
617629 return options
618630
631+ def get_unused_configs (self ) -> set [str ]:
632+ return self ._unused_configs .copy ()
633+
619634 def compile_glob (self , s : str ) -> Pattern [str ]:
620635 # Compile one of the glob patterns to a regex so that '.*' can
621636 # match *zero or more* module sections. This means we compile
0 commit comments