diff options
| author | Dylan Baker <dylan@pnwbakers.com> | 2024-10-01 10:41:59 -0700 |
|---|---|---|
| committer | Jussi Pakkanen <jpakkane@gmail.com> | 2025-03-01 13:30:06 +0200 |
| commit | f0795e14c55dfbad2291136090ee964cce2c38ed (patch) | |
| tree | e9c977aaee1b004867034a481d66206230891399 | |
| parent | dfa118547247dc862310052f75fcdbc020089c24 (diff) | |
| download | meson-f0795e14c55dfbad2291136090ee964cce2c38ed.tar.gz | |
environment: make fully type safe
This as much as anything is to stop lying to envconfig about the
potential types it will be given.
| -rw-r--r-- | mesonbuild/compilers/compilers.py | 2 | ||||
| -rw-r--r-- | mesonbuild/envconfig.py | 15 | ||||
| -rw-r--r-- | mesonbuild/environment.py | 10 | ||||
| -rwxr-xr-x | run_mypy.py | 1 |
4 files changed, 20 insertions, 8 deletions
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index c927293fb..18535be42 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1424,6 +1424,8 @@ def get_global_options(lang: str, comp_options = env.options.get(comp_key, []) link_options = env.options.get(largkey, []) + assert isinstance(comp_options, (str, list)), 'for mypy' + assert isinstance(link_options, (str, list)), 'for mypy' cargs = options.UserStringArrayOption( argkey.name, diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py index 4055b2176..7cbef8928 100644 --- a/mesonbuild/envconfig.py +++ b/mesonbuild/envconfig.py @@ -13,6 +13,9 @@ from .mesonlib import EnvironmentException, HoldableObject from . import mlog from pathlib import Path +if T.TYPE_CHECKING: + from .options import ElementaryOptionValues + # These classes contains all the data pulled from configuration files (native # and cross file currently), and also assists with the reading environment @@ -153,7 +156,7 @@ class CMakeSkipCompilerTest(Enum): class Properties: def __init__( self, - properties: T.Optional[T.Dict[str, T.Optional[T.Union[str, bool, int, T.List[str]]]]] = None, + properties: T.Optional[T.Dict[str, ElementaryOptionValues]] = None, ): self.properties = properties or {} @@ -270,7 +273,13 @@ class MachineInfo(HoldableObject): return f'<MachineInfo: {self.system} {self.cpu_family} ({self.cpu})>' @classmethod - def from_literal(cls, literal: T.Dict[str, str]) -> 'MachineInfo': + def from_literal(cls, raw: T.Dict[str, ElementaryOptionValues]) -> 'MachineInfo': + # We don't have enough type information to be sure of what we loaded + # So we need to accept that this might have ElementaryOptionValues, but + # then ensure that it's actually strings, since that's what the + # [*_machine] section should have. + assert all(isinstance(v, str) for v in raw.values()), 'for mypy' + literal = T.cast('T.Dict[str, str]', raw) minimum_literal = {'cpu', 'cpu_family', 'endian', 'system'} if set(literal) < minimum_literal: raise EnvironmentException( @@ -389,7 +398,7 @@ class BinaryTable: def __init__( self, - binaries: T.Optional[T.Dict[str, T.Union[str, T.List[str]]]] = None, + binaries: T.Optional[T.Mapping[str, ElementaryOptionValues]] = None, ): self.binaries: T.Dict[str, T.List[str]] = {} if binaries: diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index d124a608b..76eb5617b 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -41,10 +41,9 @@ from functools import lru_cache from mesonbuild import envconfig if T.TYPE_CHECKING: - from configparser import ConfigParser - from .compilers import Compiler from .compilers.mixins.visualstudio import VisualStudioLikeCompiler + from .options import ElementaryOptionValues from .wrap.wrap import Resolver from . import cargo @@ -633,7 +632,7 @@ class Environment: # # Note that order matters because of 'buildtype', if it is after # 'optimization' and 'debug' keys, it override them. - self.options: T.MutableMapping[OptionKey, T.Union[str, T.List[str]]] = collections.OrderedDict() + self.options: T.MutableMapping[OptionKey, ElementaryOptionValues] = collections.OrderedDict() self.machinestore = machinefile.MachineFileStore(self.coredata.config_files, self.coredata.cross_files, self.source_dir) @@ -701,7 +700,7 @@ class Environment: # Store a global state of Cargo dependencies self.cargo: T.Optional[cargo.Interpreter] = None - def mfilestr2key(self, machine_file_string: str, section_subproject: str, machine: MachineChoice): + def mfilestr2key(self, machine_file_string: str, section_subproject: str, machine: MachineChoice) -> OptionKey: key = OptionKey.from_string(machine_file_string) assert key.machine == MachineChoice.HOST if key.subproject: @@ -712,7 +711,8 @@ class Environment: return key.evolve(machine=machine) return key - def _load_machine_file_options(self, config: 'ConfigParser', properties: Properties, machine: MachineChoice) -> None: + def _load_machine_file_options(self, config: T.Mapping[str, T.Mapping[str, ElementaryOptionValues]], + properties: Properties, machine: MachineChoice) -> None: """Read the contents of a Machine file and put it in the options store.""" # Look for any options in the deprecated paths section, warn about diff --git a/run_mypy.py b/run_mypy.py index 4f7a6317b..afa5531cd 100755 --- a/run_mypy.py +++ b/run_mypy.py @@ -36,6 +36,7 @@ modules = [ # 'mesonbuild/coredata.py', 'mesonbuild/depfile.py', 'mesonbuild/envconfig.py', + 'mesonbuild/environment.py', 'mesonbuild/interpreter/compiler.py', 'mesonbuild/interpreter/mesonmain.py', 'mesonbuild/interpreter/interpreterobjects.py', |
