summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2024-10-01 10:41:59 -0700
committerJussi Pakkanen <jpakkane@gmail.com>2025-03-01 13:30:06 +0200
commitf0795e14c55dfbad2291136090ee964cce2c38ed (patch)
treee9c977aaee1b004867034a481d66206230891399
parentdfa118547247dc862310052f75fcdbc020089c24 (diff)
downloadmeson-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.py2
-rw-r--r--mesonbuild/envconfig.py15
-rw-r--r--mesonbuild/environment.py10
-rwxr-xr-xrun_mypy.py1
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',