1616 import tomli as tomllib
1717
1818from collections .abc import Mapping , MutableMapping , Sequence
19- from typing import Any , Callable , Final , TextIO , Union
19+ from typing import Any , Callable , Final , TextIO , TypeVar , TypedDict , Union
2020from typing_extensions import Never , TypeAlias
2121
2222from mypy import defaults
2525_CONFIG_VALUE_TYPES : TypeAlias = Union [
2626 str , bool , int , float , dict [str , str ], list [str ], tuple [int , int ]
2727]
28- _INI_PARSER_CALLABLE : TypeAlias = Callable [[Any ], _CONFIG_VALUE_TYPES ]
28+ _INI_PARSER_CALLABLE : TypeAlias = Callable [[str ], _CONFIG_VALUE_TYPES ]
2929
3030
3131class VersionTypeError (argparse .ArgumentTypeError ):
@@ -246,21 +246,22 @@ def split_commas(value: str) -> list[str]:
246246
247247def _parse_individual_file (
248248 config_file : str , stderr : TextIO | None = None
249- ) -> tuple [MutableMapping [str , Any ], dict [str , _INI_PARSER_CALLABLE ], str ] | None :
249+ ) -> tuple [MutableMapping [str , _CONFIG_VALUE_TYPES ], dict [str , _INI_PARSER_CALLABLE ], str ] | None :
250250
251251 if not os .path .exists (config_file ):
252252 return None
253253
254- parser : MutableMapping [str , Any ]
254+ parser : MutableMapping [str , Mapping [ str , str ] ]
255255 try :
256256 if is_toml (config_file ):
257257 with open (config_file , "rb" ) as f :
258- toml_data = tomllib .load (f )
258+ # This type is not actually 100% comprehensive. However, load returns Any, so it doesn't complain.
259+ toml_data : dict [str , dict [str , _CONFIG_VALUE_TYPES ]] = tomllib .load (f )
259260 # Filter down to just mypy relevant toml keys
260- toml_data = toml_data .get ("tool" , {})
261- if "mypy" not in toml_data :
261+ toml_data_tool = toml_data .get ("tool" , {})
262+ if "mypy" not in toml_data_tool :
262263 return None
263- toml_data = {"mypy" : toml_data ["mypy" ]}
264+ toml_data = {"mypy" : toml_data_tool ["mypy" ]}
264265 parser = destructure_overrides (toml_data )
265266 config_types = toml_config_types
266267 else :
@@ -280,7 +281,7 @@ def _parse_individual_file(
280281
281282def _find_config_file (
282283 stderr : TextIO | None = None ,
283- ) -> tuple [MutableMapping [str , Any ], dict [str , _INI_PARSER_CALLABLE ], str ] | None :
284+ ) -> tuple [MutableMapping [str , Mapping [ str , str ] ], dict [str , _INI_PARSER_CALLABLE ], str ] | None :
284285
285286 current_dir = os .path .abspath (os .getcwd ())
286287
@@ -407,8 +408,11 @@ def get_prefix(file_read: str, name: str) -> str:
407408def is_toml (filename : str ) -> bool :
408409 return filename .lower ().endswith (".toml" )
409410
410-
411- def destructure_overrides (toml_data : dict [str , Any ]) -> dict [str , Any ]:
411+ T = TypeVar ("T" )
412+ _TypeThatDOWants = TypedDict ("_TypeThatDOWants" , {"mypy" : dict [str , dict [str , _CONFIG_VALUE_TYPES ]]})
413+ def destructure_overrides (
414+ toml_data : _TypeThatDOWants
415+ ) -> _TypeThatDOWants :
412416 """Take the new [[tool.mypy.overrides]] section array in the pyproject.toml file,
413417 and convert it back to a flatter structure that the existing config_parser can handle.
414418
0 commit comments