aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/ast/introspection.py3
-rw-r--r--mesonbuild/backend/backends.py18
-rw-r--r--mesonbuild/backend/ninjabackend.py2
-rw-r--r--mesonbuild/backend/vs2010backend.py4
-rw-r--r--mesonbuild/build.py51
-rw-r--r--mesonbuild/coredata.py81
-rw-r--r--mesonbuild/dependencies/boost.py4
-rw-r--r--mesonbuild/environment.py25
-rw-r--r--mesonbuild/interpreter.py42
-rw-r--r--mesonbuild/mcompile.py6
-rw-r--r--mesonbuild/mconf.py8
-rw-r--r--mesonbuild/mintro.py19
-rw-r--r--mesonbuild/modules/__init__.py12
-rw-r--r--mesonbuild/msetup.py18
-rw-r--r--mesonbuild/mtest.py67
-rw-r--r--mesonbuild/optinterpreter.py11
-rw-r--r--mesonbuild/scripts/depfixer.py2
-rw-r--r--mesonbuild/scripts/meson_exe.py2
-rwxr-xr-xrun_mypy.py1
19 files changed, 215 insertions, 161 deletions
diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py
index 73cd422..19fedbf 100644
--- a/mesonbuild/ast/introspection.py
+++ b/mesonbuild/ast/introspection.py
@@ -25,10 +25,11 @@ from ..build import BuildTarget, Executable, Jar, SharedLibrary, SharedModule, S
from ..mparser import BaseNode, ArithmeticNode, ArrayNode, ElementaryNode, IdNode, FunctionNode, StringNode
import typing as T
import os
+import argparse
build_target_functions = ['executable', 'jar', 'library', 'shared_library', 'shared_module', 'static_library', 'both_libraries']
-class IntrospectionHelper:
+class IntrospectionHelper(argparse.Namespace):
# mimic an argparse namespace
def __init__(self, cross_file: str):
self.cross_file = cross_file # type: str
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index e0bab7c..b12932a 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -36,7 +36,7 @@ from ..mesonlib import (
)
if T.TYPE_CHECKING:
- from ..interpreter import Interpreter
+ from ..interpreter import Interpreter, Test
class TestProtocol(enum.Enum):
@@ -104,7 +104,7 @@ class TargetInstallData:
class ExecutableSerialisation:
def __init__(self, cmd_args, env=None, exe_wrapper=None,
- workdir=None, extra_paths=None, capture=None):
+ workdir=None, extra_paths=None, capture=None) -> None:
self.cmd_args = cmd_args
self.env = env or {}
if exe_wrapper is not None:
@@ -182,11 +182,15 @@ class Backend:
self.interpreter = interpreter
self.environment = build.environment
self.processed_targets = {}
+ self.name = '<UNKNOWN>'
self.build_dir = self.environment.get_build_dir()
self.source_dir = self.environment.get_source_dir()
self.build_to_src = mesonlib.relpath(self.environment.get_source_dir(),
self.environment.get_build_dir())
+ def generate(self) -> None:
+ raise RuntimeError('generate is not implemented in {}'.format(type(self).__name__))
+
def get_target_filename(self, t, *, warn_multi_output: bool = True):
if isinstance(t, build.CustomTarget):
if warn_multi_output and len(t.get_outputs()) != 1:
@@ -794,7 +798,7 @@ class Backend:
def write_test_file(self, datafile):
self.write_test_serialisation(self.build.get_tests(), datafile)
- def create_test_serialisation(self, tests):
+ def create_test_serialisation(self, tests: T.List['Test']) -> T.List[TestSerialisation]:
arr = []
for t in sorted(tests, key=lambda tst: -1 * tst.priority):
exe = t.get_exe()
@@ -864,7 +868,7 @@ class Backend:
arr.append(ts)
return arr
- def write_test_serialisation(self, tests, datafile):
+ def write_test_serialisation(self, tests: T.List['Test'], datafile: str):
pickle.dump(self.create_test_serialisation(tests), datafile)
def construct_target_rel_path(self, a, workdir):
@@ -1128,7 +1132,7 @@ class Backend:
cmd = [i.replace('\\', '/') for i in cmd]
return inputs, outputs, cmd
- def run_postconf_scripts(self):
+ def run_postconf_scripts(self) -> None:
env = {'MESON_SOURCE_ROOT': self.environment.get_source_dir(),
'MESON_BUILD_ROOT': self.environment.get_build_dir(),
'MESONINTROSPECT': ' '.join([shlex.quote(x) for x in self.environment.get_build_command() + ['introspect']]),
@@ -1140,7 +1144,7 @@ class Backend:
cmd = s['exe'] + s['args']
subprocess.check_call(cmd, env=child_env)
- def create_install_data(self):
+ def create_install_data(self) -> InstallData:
strip_bin = self.environment.lookup_binary_entry(MachineChoice.HOST, 'strip')
if strip_bin is None:
if self.environment.is_cross_build():
@@ -1338,7 +1342,7 @@ class Backend:
d.install_subdirs.append([src_dir, dst_dir, sd.install_mode,
sd.exclude])
- def get_introspection_data(self, target_id, target):
+ def get_introspection_data(self, target_id: str, target: build.Target) -> T.List[T.Dict[str, T.Union[bool, str, T.List[T.Union[str, T.Dict[str, T.Union[str, T.List[str], bool]]]]]]]:
'''
Returns a list of source dicts with the following format for a given target:
[
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 9004165..0cf1d54 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -2997,7 +2997,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
elem = NinjaBuildElement(self.all_outputs, deps, 'phony', '')
self.add_build(elem)
- def get_introspection_data(self, target_id, target):
+ def get_introspection_data(self, target_id: str, target: build.Target) -> T.List[T.Dict[str, T.Union[bool, str, T.List[T.Union[str, T.Dict[str, T.Union[str, T.List[str], bool]]]]]]]:
if target_id not in self.introspection_data or len(self.introspection_data[target_id]) == 0:
return super().get_introspection_data(target_id, target)
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index f282d02..4fc3d5c 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -192,11 +192,11 @@ class Vs2010Backend(backends.Backend):
Vs2010Backend.touch_regen_timestamp(self.environment.get_build_dir())
@staticmethod
- def get_regen_stampfile(build_dir):
+ def get_regen_stampfile(build_dir: str) -> None:
return os.path.join(os.path.join(build_dir, Environment.private_dir), 'regen.stamp')
@staticmethod
- def touch_regen_timestamp(build_dir):
+ def touch_regen_timestamp(build_dir: str) -> None:
with open(Vs2010Backend.get_regen_stampfile(build_dir), 'w'):
pass
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index edd1506..bf325b0 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -37,6 +37,9 @@ from .compilers import (
from .linkers import StaticLinker
from .interpreterbase import FeatureNew
+if T.TYPE_CHECKING:
+ from .interpreter import Test
+
pch_kwargs = set(['c_pch', 'cpp_pch'])
lang_arg_kwargs = set([
@@ -128,14 +131,14 @@ class Build:
self.project_version = None
self.environment = environment
self.projects = {}
- self.targets = OrderedDict()
+ self.targets = OrderedDict() # type: T.Dict[str, 'Target']
self.run_target_names = set() # type: T.Set[T.Tuple[str, str]]
self.global_args = PerMachine({}, {}) # type: PerMachine[T.Dict[str, T.List[str]]]
self.projects_args = PerMachine({}, {}) # type: PerMachine[T.Dict[str, T.List[str]]]
self.global_link_args = PerMachine({}, {}) # type: PerMachine[T.Dict[str, T.List[str]]]
self.projects_link_args = PerMachine({}, {}) # type: PerMachine[T.Dict[str, T.List[str]]]
- self.tests = []
- self.benchmarks = []
+ self.tests = [] # type: T.List['Test']
+ self.benchmarks = [] # type: T.List['Test']
self.headers = []
self.man = []
self.data = []
@@ -178,13 +181,13 @@ class Build:
def get_subproject_dir(self):
return self.subproject_dir
- def get_targets(self):
+ def get_targets(self) -> T.Dict[str, 'Target']:
return self.targets
- def get_tests(self):
+ def get_tests(self) -> T.List['Test']:
return self.tests
- def get_benchmarks(self):
+ def get_benchmarks(self) -> T.List['Test']:
return self.benchmarks
def get_headers(self):
@@ -403,13 +406,13 @@ a hard error in the future.'''.format(name))
outdirs[0] = default_install_dir
return outdirs, custom_install_dir
- def get_basename(self):
+ def get_basename(self) -> str:
return self.name
- def get_subdir(self):
+ def get_subdir(self) -> str:
return self.subdir
- def get_typename(self):
+ def get_typename(self) -> str:
return self.typename
@staticmethod
@@ -423,7 +426,7 @@ a hard error in the future.'''.format(name))
return h.hexdigest()[:7]
@staticmethod
- def construct_id_from_path(subdir, name, type_suffix):
+ def construct_id_from_path(subdir: str, name: str, type_suffix: str) -> str:
"""Construct target ID from subdir, name and type suffix.
This helper function is made public mostly for tests."""
@@ -441,7 +444,7 @@ a hard error in the future.'''.format(name))
return subdir_part + '@@' + my_id
return my_id
- def get_id(self):
+ def get_id(self) -> str:
return self.construct_id_from_path(
self.subdir, self.name, self.type_suffix())
@@ -480,6 +483,12 @@ a hard error in the future.'''.format(name))
def is_linkable_target(self) -> bool:
return False
+ def get_outputs(self) -> T.List[str]:
+ return []
+
+ def should_install(self) -> bool:
+ return False
+
class BuildTarget(Target):
known_kwargs = known_build_target_kwargs
@@ -1006,7 +1015,7 @@ This will become a hard error in a future Meson release.''')
def get_filename(self):
return self.filename
- def get_outputs(self):
+ def get_outputs(self) -> T.List[str]:
return self.outputs
def get_extra_args(self, language):
@@ -1036,7 +1045,7 @@ This will become a hard error in a future Meson release.''')
def get_generated_sources(self):
return self.generated
- def should_install(self):
+ def should_install(self) -> bool:
return self.need_install
def has_pch(self):
@@ -1474,7 +1483,7 @@ class GeneratedList:
def get_inputs(self):
return self.infilelist
- def get_outputs(self):
+ def get_outputs(self) -> T.List[str]:
return self.outfilelist
def get_outputs_for(self, filename):
@@ -2192,7 +2201,7 @@ class CustomTarget(Target):
def get_dependencies(self):
return self.dependencies
- def should_install(self):
+ def should_install(self) -> bool:
return self.install
def get_custom_install_dir(self):
@@ -2201,7 +2210,7 @@ class CustomTarget(Target):
def get_custom_install_mode(self):
return self.install_mode
- def get_outputs(self):
+ def get_outputs(self) -> T.List[str]:
return self.outputs
def get_filename(self):
@@ -2289,13 +2298,13 @@ class RunTarget(Target):
def get_sources(self):
return []
- def should_install(self):
+ def should_install(self) -> bool:
return False
- def get_filename(self):
+ def get_filename(self) -> str:
return self.name
- def get_outputs(self):
+ def get_outputs(self) -> T.List[str]:
if isinstance(self.name, str):
return [self.name]
elif isinstance(self.name, list):
@@ -2367,7 +2376,7 @@ class CustomTargetIndex:
return '<CustomTargetIndex: {!r}[{}]>'.format(
self.target, self.target.get_outputs().index(self.output))
- def get_outputs(self):
+ def get_outputs(self) -> T.List[str]:
return [self.output]
def get_subdir(self):
@@ -2509,6 +2518,6 @@ def load(build_dir: str) -> Build:
raise MesonException(load_fail_msg)
return obj
-def save(obj, filename):
+def save(obj: Build, filename: str) -> None:
with open(filename, 'wb') as f:
pickle.dump(obj, f)
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index ce03fbc..4fc4999 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -47,7 +47,7 @@ _T = T.TypeVar('_T')
class MesonVersionMismatchException(MesonException):
'''Build directory generated with Meson version incompatible with current version'''
- def __init__(self, old_version, current_version):
+ def __init__(self, old_version: str, current_version: str) -> None:
super().__init__('Build directory has been generated with Meson version {}, '
'which is incompatible with current version {}.'
.format(old_version, current_version))
@@ -56,7 +56,7 @@ class MesonVersionMismatchException(MesonException):
class UserOption(T.Generic[_T]):
- def __init__(self, description, choices, yielding):
+ def __init__(self, description: str, choices: T.Optional[T.Union[str, T.List[_T]]], yielding: T.Optional[bool]):
super().__init__()
self.choices = choices
self.description = description
@@ -66,7 +66,8 @@ class UserOption(T.Generic[_T]):
raise MesonException('Value of "yielding" must be a boolean.')
self.yielding = yielding
- def printable_value(self):
+ def printable_value(self) -> T.Union[str, int, bool, T.List[T.Union[str, int, bool]]]:
+ assert isinstance(self.value, (str, int, bool, list))
return self.value
# Check that the input is a valid value and return the
@@ -75,30 +76,32 @@ class UserOption(T.Generic[_T]):
def validate_value(self, value: T.Any) -> _T:
raise RuntimeError('Derived option class did not override validate_value.')
- def set_value(self, newvalue):
+ def set_value(self, newvalue: T.Any) -> None:
self.value = self.validate_value(newvalue)
class UserStringOption(UserOption[str]):
- def __init__(self, description, value, choices=None, yielding=None):
- super().__init__(description, choices, yielding)
+ def __init__(self, description: str, value: T.Any, yielding: T.Optional[bool] = None):
+ super().__init__(description, None, yielding)
self.set_value(value)
- def validate_value(self, value):
+ def validate_value(self, value: T.Any) -> str:
if not isinstance(value, str):
raise MesonException('Value "%s" for string option is not a string.' % str(value))
return value
class UserBooleanOption(UserOption[bool]):
- def __init__(self, description, value, yielding=None):
+ def __init__(self, description: str, value, yielding: T.Optional[bool] = None) -> None:
super().__init__(description, [True, False], yielding)
self.set_value(value)
def __bool__(self) -> bool:
return self.value
- def validate_value(self, value) -> bool:
+ def validate_value(self, value: T.Any) -> bool:
if isinstance(value, bool):
return value
+ if not isinstance(value, str):
+ raise MesonException('Value {} cannot be converted to a boolean'.format(value))
if value.lower() == 'true':
return True
if value.lower() == 'false':
@@ -106,7 +109,7 @@ class UserBooleanOption(UserOption[bool]):
raise MesonException('Value %s is not boolean (true or false).' % value)
class UserIntegerOption(UserOption[int]):
- def __init__(self, description, value, yielding=None):
+ def __init__(self, description: str, value: T.Any, yielding: T.Optional[bool] = None):
min_value, max_value, default_value = value
self.min_value = min_value
self.max_value = max_value
@@ -119,7 +122,7 @@ class UserIntegerOption(UserOption[int]):
super().__init__(description, choices, yielding)
self.set_value(default_value)
- def validate_value(self, value) -> int:
+ def validate_value(self, value: T.Any) -> int:
if isinstance(value, str):
value = self.toint(value)
if not isinstance(value, int):
@@ -130,35 +133,35 @@ class UserIntegerOption(UserOption[int]):
raise MesonException('New value %d is more than maximum value %d.' % (value, self.max_value))
return value
- def toint(self, valuestring) -> int:
+ def toint(self, valuestring: str) -> int:
try:
return int(valuestring)
except ValueError:
raise MesonException('Value string "%s" is not convertible to an integer.' % valuestring)
class UserUmaskOption(UserIntegerOption, UserOption[T.Union[str, int]]):
- def __init__(self, description, value, yielding=None):
+ def __init__(self, description: str, value: T.Any, yielding: T.Optional[bool] = None):
super().__init__(description, (0, 0o777, value), yielding)
self.choices = ['preserve', '0000-0777']
- def printable_value(self):
+ def printable_value(self) -> str:
if self.value == 'preserve':
return self.value
return format(self.value, '04o')
- def validate_value(self, value):
+ def validate_value(self, value: T.Any) -> T.Union[str, int]:
if value is None or value == 'preserve':
return 'preserve'
return super().validate_value(value)
- def toint(self, valuestring):
+ def toint(self, valuestring: T.Union[str, int]) -> int:
try:
return int(valuestring, 8)
except ValueError as e:
raise MesonException('Invalid mode: {}'.format(e))
class UserComboOption(UserOption[str]):
- def __init__(self, description, choices: T.List[str], value, yielding=None):
+ def __init__(self, description: str, choices: T.List[str], value: T.Any, yielding: T.Optional[bool] = None):
super().__init__(description, choices, yielding)
if not isinstance(self.choices, list):
raise MesonException('Combo choices must be an array.')
@@ -167,7 +170,7 @@ class UserComboOption(UserOption[str]):
raise MesonException('Combo choice elements must be strings.')
self.set_value(value)
- def validate_value(self, value):
+ def validate_value(self, value: T.Any) -> str:
if value not in self.choices:
if isinstance(value, bool):
_type = 'boolean'
@@ -182,13 +185,13 @@ class UserComboOption(UserOption[str]):
return value
class UserArrayOption(UserOption[T.List[str]]):
- def __init__(self, description, value, split_args=False, user_input=False, allow_dups=False, **kwargs):
+ def __init__(self, description: str, value: T.Union[str, T.List[str]], split_args: bool = False, user_input: bool = False, allow_dups: bool = False, **kwargs: T.Any) -> None:
super().__init__(description, kwargs.get('choices', []), yielding=kwargs.get('yielding', None))
self.split_args = split_args
self.allow_dups = allow_dups
self.value = self.validate_value(value, user_input=user_input)
- def validate_value(self, value, user_input: bool = True) -> T.List[str]:
+ def validate_value(self, value: T.Union[str, T.List[str]], user_input: bool = True) -> T.List[str]:
# User input is for options defined on the command line (via -D
# options). Users can put their input in as a comma separated
# string, but for defining options in meson_options.txt the format
@@ -232,16 +235,16 @@ class UserArrayOption(UserOption[T.List[str]]):
class UserFeatureOption(UserComboOption):
static_choices = ['enabled', 'disabled', 'auto']
- def __init__(self, description, value, yielding=None):
+ def __init__(self, description: str, value: T.Any, yielding: T.Optional[bool] = None):
super().__init__(description, self.static_choices, value, yielding)
- def is_enabled(self):
+ def is_enabled(self) -> bool:
return self.value == 'enabled'
- def is_disabled(self):
+ def is_disabled(self) -> bool:
return self.value == 'disabled'
- def is_auto(self):
+ def is_auto(self) -> bool:
return self.value == 'auto'
if T.TYPE_CHECKING:
@@ -534,7 +537,7 @@ class CoreData:
value = None
opts_map[optname] = opt.init_option(key, value, default_prefix())
- def init_backend_options(self, backend_name):
+ def init_backend_options(self, backend_name: str) -> None:
if backend_name == 'ninja':
self.backend_options['backend_max_links'] = \
UserIntegerOption(
@@ -547,7 +550,7 @@ class CoreData:
'Default project to execute in Visual Studio',
'')
- def get_builtin_option(self, optname, subproject=''):
+ def get_builtin_option(self, optname: str, subproject: str = '') -> T.Union[str, int, bool]:
raw_optname = optname
if subproject:
optname = subproject + ':' + optname
@@ -683,7 +686,7 @@ class CoreData:
def get_external_link_args(self, for_machine: MachineChoice, lang):
return self.compiler_options[for_machine][lang]['link_args'].value
- def merge_user_options(self, options):
+ def merge_user_options(self, options: T.Dict[str, T.Union[str, bool, int]]) -> None:
for (name, value) in options.items():
if name not in self.user_options:
self.user_options[name] = value
@@ -715,7 +718,7 @@ class CoreData:
if k in build_opts:
build_opts[k].set_value(o.value)
- def set_options(self, options, *, subproject='', warn_unknown=True):
+ def set_options(self, options: T.Dict[str, T.Any], subproject: str = '', warn_unknown: bool = True) -> None:
if not self.is_cross_build():
options = self.strip_build_option_names(options)
# Set prefix first because it's needed to sanitize other options
@@ -912,10 +915,10 @@ def parse_machine_files(filenames):
parser = MachineFileParser(filenames)
return parser.sections
-def get_cmd_line_file(build_dir):
+def get_cmd_line_file(build_dir: str) -> str:
return os.path.join(build_dir, 'meson-private', 'cmd_line.txt')
-def read_cmd_line_file(build_dir, options):
+def read_cmd_line_file(build_dir: str, options: argparse.Namespace) -> None:
filename = get_cmd_line_file(build_dir)
if not os.path.isfile(filename):
return
@@ -937,10 +940,10 @@ def read_cmd_line_file(build_dir, options):
# literal_eval to get it into the list of strings.
options.native_file = ast.literal_eval(properties.get('native_file', '[]'))
-def cmd_line_options_to_string(options):
+def cmd_line_options_to_string(options: argparse.Namespace) -> T.Dict[str, str]:
return {k: str(v) for k, v in options.cmd_line_options.items()}
-def write_cmd_line_file(build_dir, options):
+def write_cmd_line_file(build_dir: str, options: argparse.Namespace) -> None:
filename = get_cmd_line_file(build_dir)
config = CmdLineFileParser()
@@ -955,7 +958,7 @@ def write_cmd_line_file(build_dir, options):
with open(filename, 'w') as f:
config.write(f)
-def update_cmd_line_file(build_dir, options):
+def update_cmd_line_file(build_dir: str, options: argparse.Namespace):
filename = get_cmd_line_file(build_dir)
config = CmdLineFileParser()
config.read(filename)
@@ -963,7 +966,7 @@ def update_cmd_line_file(build_dir, options):
with open(filename, 'w') as f:
config.write(f)
-def get_cmd_line_options(build_dir, options):
+def get_cmd_line_options(build_dir: str, options: argparse.Namespace) -> str:
copy = argparse.Namespace(**vars(options))
read_cmd_line_file(build_dir, copy)
cmdline = ['-D{}={}'.format(k, v) for k, v in copy.cmd_line_options.items()]
@@ -976,7 +979,7 @@ def get_cmd_line_options(build_dir, options):
def major_versions_differ(v1, v2):
return v1.split('.')[0:2] != v2.split('.')[0:2]
-def load(build_dir):
+def load(build_dir: str) -> CoreData:
filename = os.path.join(build_dir, 'meson-private', 'coredata.dat')
load_fail_msg = 'Coredata file {!r} is corrupted. Try with a fresh build tree.'.format(filename)
try:
@@ -995,7 +998,7 @@ def load(build_dir):
raise MesonVersionMismatchException(obj.version, version)
return obj
-def save(obj, build_dir):
+def save(obj: CoreData, build_dir: str) -> str:
filename = os.path.join(build_dir, 'meson-private', 'coredata.dat')
prev_filename = filename + '.prev'
tempfilename = filename + '~'
@@ -1012,7 +1015,7 @@ def save(obj, build_dir):
return filename
-def register_builtin_arguments(parser):
+def register_builtin_arguments(parser: argparse.ArgumentParser) -> None:
for n, b in BUILTIN_OPTIONS.items():
b.add_to_argparse(n, parser, '', '')
for n, b in BUILTIN_OPTIONS_PER_MACHINE.items():
@@ -1021,7 +1024,7 @@ def register_builtin_arguments(parser):
parser.add_argument('-D', action='append', dest='projectoptions', default=[], metavar="option",
help='Set the value of an option, can be used several times to set multiple options.')
-def create_options_dict(options):
+def create_options_dict(options: T.List[str]) -> T.Dict[str, str]:
result = OrderedDict()
for o in options:
try:
@@ -1031,7 +1034,7 @@ def create_options_dict(options):
result[key] = value
return result
-def parse_cmd_line_options(args):
+def parse_cmd_line_options(args: argparse.Namespace) -> None:
args.cmd_line_options = create_options_dict(args.projectoptions)
# Merge builtin options set with --option into the dict.
diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py
index 8497d2c..6e95860 100644
--- a/mesonbuild/dependencies/boost.py
+++ b/mesonbuild/dependencies/boost.py
@@ -341,7 +341,9 @@ class BoostLibraryFile():
class BoostDependency(ExternalDependency):
def __init__(self, environment: Environment, kwargs: T.Dict[str, T.Any]) -> None:
super().__init__('boost', environment, kwargs, language='cpp')
- self.debug = environment.coredata.get_builtin_option('buildtype').startswith('debug')
+ buildtype = environment.coredata.get_builtin_option('buildtype')
+ assert isinstance(buildtype, str)
+ self.debug = buildtype.startswith('debug')
self.multithreading = kwargs.get('threading', 'multi') == 'multi'
self.boost_root = None # type: Path
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index f8282c0..5cd6069 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -132,6 +132,9 @@ build_filename = 'meson.build'
CompilersDict = T.Dict[str, Compiler]
+if T.TYPE_CHECKING:
+ import argparse
+
def detect_gcovr(min_version='3.3', new_rootdir_version='4.2', log=False):
gcovr_exe = 'gcovr'
try:
@@ -153,7 +156,7 @@ def detect_llvm_cov():
return tool
return None
-def find_coverage_tools():
+def find_coverage_tools() -> T.Tuple[T.Optional[str], T.Optional[str], T.Optional[str], T.Optional[str], T.Optional[str]]:
gcovr_exe, gcovr_new_rootdir = detect_gcovr()
llvm_cov_exe = detect_llvm_cov()
@@ -522,7 +525,7 @@ class Environment:
log_dir = 'meson-logs'
info_dir = 'meson-info'
- def __init__(self, source_dir, build_dir, options):
+ def __init__(self, source_dir: T.Optional[str], build_dir: T.Optional[str], options: 'argparse.Namespace') -> None:
self.source_dir = source_dir
self.build_dir = build_dir
# Do not try to create build directories when build_dir is none.
@@ -535,7 +538,7 @@ class Environment:
os.makedirs(self.log_dir, exist_ok=True)
os.makedirs(self.info_dir, exist_ok=True)
try:
- self.coredata = coredata.load(self.get_build_dir())
+ self.coredata = coredata.load(self.get_build_dir()) # type: coredata.CoreData
self.first_invocation = False
except FileNotFoundError:
self.create_new_coredata(options)
@@ -807,7 +810,7 @@ class Environment:
self.default_pkgconfig = ['pkg-config']
self.wrap_resolver = None
- def create_new_coredata(self, options):
+ def create_new_coredata(self, options: 'argparse.Namespace') -> None:
# WARNING: Don't use any values from coredata in __init__. It gets
# re-initialized with project options by the interpreter during
# build file parsing.
@@ -819,17 +822,17 @@ class Environment:
def is_cross_build(self, when_building_for: MachineChoice = MachineChoice.HOST) -> bool:
return self.coredata.is_cross_build(when_building_for)
- def dump_coredata(self):
+ def dump_coredata(self) -> str:
return coredata.save(self.coredata, self.get_build_dir())
- def get_script_dir(self):
+ def get_script_dir(self) -> str:
import mesonbuild.scripts
return os.path.dirname(mesonbuild.scripts.__file__)
- def get_log_dir(self):
+ def get_log_dir(self) -> str:
return self.log_dir
- def get_coredata(self):
+ def get_coredata(self) -> coredata.CoreData:
return self.coredata
def get_build_command(self, unbuffered=False):
@@ -1535,7 +1538,7 @@ class Environment:
self._handle_exceptions(popen_exceptions, compilers)
- def get_scratch_dir(self):
+ def get_scratch_dir(self) -> str:
return self.scratch_dir
def detect_objc_compiler(self, for_machine: MachineInfo) -> 'Compiler':
@@ -1974,10 +1977,10 @@ class Environment:
self._handle_exceptions(popen_exceptions, linkers, 'linker')
raise EnvironmentException('Unknown static linker "{}"'.format(' '.join(linkers)))
- def get_source_dir(self):
+ def get_source_dir(self) -> str:
return self.source_dir
- def get_build_dir(self):
+ def get_build_dir(self) -> str:
return self.build_dir
def get_import_lib_dir(self) -> str:
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 322cc26..031bed0 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -31,9 +31,10 @@ from .interpreterbase import InterpreterException, InvalidArguments, InvalidCode
from .interpreterbase import InterpreterObject, MutableInterpreterObject, Disabler, disablerIfNotFound
from .interpreterbase import FeatureNew, FeatureDeprecated, FeatureNewKwargs, FeatureDeprecatedKwargs
from .interpreterbase import ObjectHolder, MesonVersionString
-from .modules import ModuleReturnValue
+from .interpreterbase import TYPE_var, TYPE_nkwargs
+from .modules import ModuleReturnValue, ExtensionModule
from .cmake import CMakeInterpreter
-from .backend.backends import TestProtocol
+from .backend.backends import TestProtocol, Backend
from pathlib import Path, PurePath
import os
@@ -673,22 +674,22 @@ class MachineHolder(InterpreterObject, ObjectHolder):
@noPosargs
@permittedKwargs({})
- def cpu_family_method(self, args, kwargs):
+ def cpu_family_method(self, args: T.List[TYPE_var], kwargs: TYPE_nkwargs) -> str:
return self.held_object.cpu_family
@noPosargs
@permittedKwargs({})
- def cpu_method(self, args, kwargs):
+ def cpu_method(self, args: T.List[TYPE_var], kwargs: TYPE_nkwargs) -> str:
return self.held_object.cpu
@noPosargs
@permittedKwargs({})
- def system_method(self, args, kwargs):
+ def system_method(self, args: T.List[TYPE_var], kwargs: TYPE_nkwargs) -> str:
return self.held_object.system
@noPosargs
@permittedKwargs({})
- def endian_method(self, args, kwargs):
+ def endian_method(self, args: T.List[TYPE_var], kwargs: TYPE_nkwargs) -> str:
return self.held_object.endian
class IncludeDirsHolder(InterpreterObject, ObjectHolder):
@@ -2333,8 +2334,18 @@ permitted_kwargs = {'add_global_arguments': {'language', 'native'},
class Interpreter(InterpreterBase):
- def __init__(self, build, backend=None, subproject='', subdir='', subproject_dir='subprojects',
- modules = None, default_project_options=None, mock=False, ast=None):
+ def __init__(
+ self,
+ build: build.Build,
+ backend: T.Optional[Backend] = None,
+ subproject: str = '',
+ subdir: str = '',
+ subproject_dir: str = 'subprojects',
+ modules: T.Optional[T.Dict[str, ExtensionModule]] = None,
+ default_project_options: T.Optional[T.Dict[str, str]] = None,
+ mock: bool = False,
+ ast: T.Optional[mparser.CodeBlockNode] = None,
+ ) -> None:
super().__init__(build.environment.get_source_dir(), subdir, subproject)
self.an_unpicklable_object = mesonlib.an_unpicklable_object
self.build = build
@@ -2396,7 +2407,8 @@ class Interpreter(InterpreterBase):
self.builtin['target_machine'] = \
MachineHolder(self.build.environment.machines.target)
- def get_non_matching_default_options(self):
+ # TODO: Why is this in interpreter.py and not CoreData or Environment?
+ def get_non_matching_default_options(self) -> T.Iterator[T.Tuple[str, str, coredata.UserOption]]:
env = self.environment
for def_opt_name, def_opt_value in self.project_default_options.items():
for opts in env.coredata.get_all_options():
@@ -2530,7 +2542,7 @@ class Interpreter(InterpreterBase):
self.process_new_values(invalues)
return self.holderify(return_object.return_value)
- def get_build_def_files(self):
+ def get_build_def_files(self) -> T.List[str]:
return self.build_def_files
def add_build_def_file(self, f):
@@ -2599,7 +2611,9 @@ class Interpreter(InterpreterBase):
module = importlib.import_module('mesonbuild.modules.' + modname)
except ImportError:
raise InvalidArguments('Module "%s" does not exist' % (modname, ))
- self.modules[modname] = module.initialize(self)
+ ext_module = module.initialize(self)
+ assert isinstance(ext_module, ExtensionModule)
+ self.modules[modname] = ext_module
@stringArgs
@noKwargs
@@ -4598,7 +4612,7 @@ different subdirectory.
def func_join_paths(self, node, args, kwargs):
return self.join_path_strings(args)
- def run(self):
+ def run(self) -> None:
super().run()
mlog.log('Build targets in project:', mlog.bold(str(len(self.build.targets))))
FeatureNew.report(self.subproject)
@@ -4608,14 +4622,14 @@ different subdirectory.
if self.subproject == '':
self._print_summary()
- def print_extra_warnings(self):
+ def print_extra_warnings(self) -> None:
# TODO cross compilation
for c in self.coredata.compilers.host.values():
if c.get_id() == 'clang':
self.check_clang_asan_lundef()
break
- def check_clang_asan_lundef(self):
+ def check_clang_asan_lundef(self) -> None:
if 'b_lundef' not in self.coredata.base_options:
return
if 'b_sanitize' not in self.coredata.base_options:
diff --git a/mesonbuild/mcompile.py b/mesonbuild/mcompile.py
index 5466ad2..3267529 100644
--- a/mesonbuild/mcompile.py
+++ b/mesonbuild/mcompile.py
@@ -32,7 +32,7 @@ if T.TYPE_CHECKING:
import argparse
def array_arg(value: str) -> T.List[str]:
- return T.cast(T.List[str], UserArrayOption(None, value, allow_dups=True, user_input=True).value)
+ return UserArrayOption(None, value, allow_dups=True, user_input=True).value
def validate_builddir(builddir: Path) -> None:
if not (builddir / 'meson-private' / 'coredata.dat' ).is_file():
@@ -45,7 +45,9 @@ def get_backend_from_coredata(builddir: Path) -> str:
"""
Gets `backend` option value from coredata
"""
- return T.cast(str, coredata.load(str(builddir)).get_builtin_option('backend'))
+ backend = coredata.load(str(builddir)).get_builtin_option('backend')
+ assert isinstance(backend, str)
+ return backend
def parse_introspect_data(builddir: Path) -> T.Dict[str, T.List[dict]]:
"""
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
index f070355..0245155 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -15,15 +15,19 @@
import os
from . import coredata, environment, mesonlib, build, mintro, mlog
from .ast import AstIDGenerator
+import typing as T
-def add_arguments(parser):
+if T.TYPE_CHECKING:
+ import argparse
+
+def add_arguments(parser: 'argparse.ArgumentParser') -> None:
coredata.register_builtin_arguments(parser)
parser.add_argument('builddir', nargs='?', default='.')
parser.add_argument('--clearcache', action='store_true', default=False,
help='Clear cached state (e.g. found dependencies)')
-def make_lower_case(val):
+def make_lower_case(val: T.Any) -> T.Union[str, T.List[T.Any]]: # T.Any because of recursion...
if isinstance(val, bool):
return str(val).lower()
elif isinstance(val, list):
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index d60386e..1e400b0 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -254,11 +254,9 @@ def list_buildoptions(coredata: cdata.CoreData, subprojects: T.Optional[T.List[s
'compiler',
machine='host',
)
+ tmp_dict = dict(coredata.flatten_lang_iterator(coredata.compiler_options.build.items())) # type: T.Dict[str, cdata.UserOption]
add_keys(
- {
- 'build.' + k: o for k, o in
- coredata.flatten_lang_iterator(coredata.compiler_options.build.items())
- },
+ {'build.' + k: o for k, o in tmp_dict.items()},
'compiler',
machine='build',
)
@@ -305,10 +303,10 @@ def list_deps(coredata: cdata.CoreData) -> T.List[T.Dict[str, T.Union[str, T.Lis
'link_args': d.get_link_args()}]
return result
-def get_test_list(testdata: backends.TestSerialisation) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]:
+def get_test_list(testdata: T.List[backends.TestSerialisation]) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]:
result = [] # type: T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]
for t in testdata:
- to = {}
+ to = {} # type: T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]
if isinstance(t.fname, str):
fname = [t.fname]
else:
@@ -329,21 +327,21 @@ def get_test_list(testdata: backends.TestSerialisation) -> T.List[T.Dict[str, T.
result.append(to)
return result
-def list_tests(testdata: backends.TestSerialisation) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]:
+def list_tests(testdata: T.List[backends.TestSerialisation]) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]:
return get_test_list(testdata)
-def list_benchmarks(benchdata: backends.TestSerialisation) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]:
+def list_benchmarks(benchdata: T.List[backends.TestSerialisation]) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]:
return get_test_list(benchdata)
def list_projinfo(builddata: build.Build) -> T.Dict[str, T.Union[str, T.List[T.Dict[str, str]]]]:
result = {'version': builddata.project_version,
'descriptive_name': builddata.project_name,
- 'subproject_dir': builddata.subproject_dir}
+ 'subproject_dir': builddata.subproject_dir} # type: T.Dict[str, T.Union[str, T.List[T.Dict[str, str]]]]
subprojects = []
for k, v in builddata.subprojects.items():
c = {'name': k,
'version': v,
- 'descriptive_name': builddata.projects.get(k)}
+ 'descriptive_name': builddata.projects.get(k)} # type: T.Dict[str, str]
subprojects.append(c)
result['subprojects'] = subprojects
return result
@@ -391,6 +389,7 @@ def run(options: argparse.Namespace) -> int:
# Make sure that log entries in other parts of meson don't interfere with the JSON output
mlog.disable()
backend = backends.get_backend_from_name(options.backend)
+ assert backend is not None
intr = IntrospectionInterpreter(sourcedir, '', backend.name, visitors = [AstIDGenerator(), AstIndentationGenerator(), AstConditionLevel()])
intr.analyze()
# Re-enable logging just in case
diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py
index 47be039..ff27a11 100644
--- a/mesonbuild/modules/__init__.py
+++ b/mesonbuild/modules/__init__.py
@@ -19,14 +19,18 @@ import os
from .. import build
from ..mesonlib import unholder
+import typing as T
+if T.TYPE_CHECKING:
+ from ..interpreter import Interpreter
+ from ..interpreterbase import TYPE_var
class ExtensionModule:
- def __init__(self, interpreter):
+ def __init__(self, interpreter: 'Interpreter') -> None:
self.interpreter = interpreter
- self.snippets = set() # List of methods that operate only on the interpreter.
+ self.snippets = set() # type: T.Set[str] # List of methods that operate only on the interpreter.
- def is_snippet(self, funcname):
+ def is_snippet(self, funcname: str) -> bool:
return funcname in self.snippets
@@ -69,7 +73,7 @@ def is_module_library(fname):
class ModuleReturnValue:
- def __init__(self, return_value, new_objects):
+ def __init__(self, return_value: 'TYPE_var', new_objects: T.List['TYPE_var']) -> None:
self.return_value = return_value
assert(isinstance(new_objects, list))
self.new_objects = new_objects
diff --git a/mesonbuild/msetup.py b/mesonbuild/msetup.py
index f940a58..5fd88d7 100644
--- a/mesonbuild/msetup.py
+++ b/mesonbuild/msetup.py
@@ -178,12 +178,18 @@ class MesonApp:
logger_fun = mlog.log
else:
logger_fun = mlog.debug
- logger_fun('Build machine cpu family:', mlog.bold(intr.builtin['build_machine'].cpu_family_method([], {})))
- logger_fun('Build machine cpu:', mlog.bold(intr.builtin['build_machine'].cpu_method([], {})))
- mlog.log('Host machine cpu family:', mlog.bold(intr.builtin['host_machine'].cpu_family_method([], {})))
- mlog.log('Host machine cpu:', mlog.bold(intr.builtin['host_machine'].cpu_method([], {})))
- logger_fun('Target machine cpu family:', mlog.bold(intr.builtin['target_machine'].cpu_family_method([], {})))
- logger_fun('Target machine cpu:', mlog.bold(intr.builtin['target_machine'].cpu_method([], {})))
+ build_machine = intr.builtin['build_machine']
+ host_machine = intr.builtin['build_machine']
+ target_machine = intr.builtin['target_machine']
+ assert isinstance(build_machine, interpreter.MachineHolder)
+ assert isinstance(host_machine, interpreter.MachineHolder)
+ assert isinstance(target_machine, interpreter.MachineHolder)
+ logger_fun('Build machine cpu family:', mlog.bold(build_machine.cpu_family_method([], {})))
+ logger_fun('Build machine cpu:', mlog.bold(build_machine.cpu_method([], {})))
+ mlog.log('Host machine cpu family:', mlog.bold(host_machine.cpu_family_method([], {})))
+ mlog.log('Host machine cpu:', mlog.bold(host_machine.cpu_method([], {})))
+ logger_fun('Target machine cpu family:', mlog.bold(target_machine.cpu_family_method([], {})))
+ logger_fun('Target machine cpu:', mlog.bold(target_machine.cpu_method([], {})))
try:
if self.options.profile:
fname = os.path.join(self.build_dir, 'meson-private', 'profile-interpreter.log')
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index cc82bd0..86d7384 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -43,10 +43,7 @@ from . import environment
from . import mlog
from .dependencies import ExternalProgram
from .mesonlib import MesonException, get_wine_shortpath, split_args, join_args
-from .backend.backends import TestProtocol
-
-if T.TYPE_CHECKING:
- from .backend.backends import TestSerialisation
+from .backend.backends import TestProtocol, TestSerialisation
# GNU autotools interprets a return code of 77 from tests it executes to
# mean that the test should be skipped.
@@ -445,7 +442,7 @@ class JunitBuilder:
class TestRun:
@classmethod
- def make_gtest(cls, test: 'TestSerialisation', test_env: T.Dict[str, str],
+ def make_gtest(cls, test: TestSerialisation, test_env: T.Dict[str, str],
returncode: int, starttime: float, duration: float,
stdo: T.Optional[str], stde: T.Optional[str],
cmd: T.Optional[T.List[str]]) -> 'TestRun':
@@ -459,7 +456,7 @@ class TestRun:
junit=tree)
@classmethod
- def make_exitcode(cls, test: 'TestSerialisation', test_env: T.Dict[str, str],
+ def make_exitcode(cls, test: TestSerialisation, test_env: T.Dict[str, str],
returncode: int, starttime: float, duration: float,
stdo: T.Optional[str], stde: T.Optional[str],
cmd: T.Optional[T.List[str]], **kwargs: T.Any) -> 'TestRun':
@@ -474,7 +471,7 @@ class TestRun:
return cls(test, test_env, res, [], returncode, starttime, duration, stdo, stde, cmd, **kwargs)
@classmethod
- def make_tap(cls, test: 'TestSerialisation', test_env: T.Dict[str, str],
+ def make_tap(cls, test: TestSerialisation, test_env: T.Dict[str, str],
returncode: int, starttime: float, duration: float,
stdo: str, stde: str,
cmd: T.Optional[T.List[str]]) -> 'TestRun':
@@ -511,7 +508,7 @@ class TestRun:
return cls(test, test_env, res, results, returncode, starttime, duration, stdo, stde, cmd)
- def __init__(self, test: 'TestSerialisation', test_env: T.Dict[str, str],
+ def __init__(self, test: TestSerialisation, test_env: T.Dict[str, str],
res: TestResult, results: T.List[TestResult], returncode:
int, starttime: float, duration: float,
stdo: T.Optional[str], stde: T.Optional[str],
@@ -577,26 +574,32 @@ def write_json_log(jsonlogfile: T.TextIO, test_name: str, result: TestRun) -> No
def run_with_mono(fname: str) -> bool:
return fname.endswith('.exe') and not (is_windows() or is_cygwin())
-def load_benchmarks(build_dir: str) -> T.List['TestSerialisation']:
+def load_benchmarks(build_dir: str) -> T.List[TestSerialisation]:
datafile = Path(build_dir) / 'meson-private' / 'meson_benchmark_setup.dat'
if not datafile.is_file():
raise TestException('Directory {!r} does not seem to be a Meson build directory.'.format(build_dir))
with datafile.open('rb') as f:
- obj = T.cast(T.List['TestSerialisation'], pickle.load(f))
+ obj = pickle.load(f)
+ assert isinstance(obj, list)
+ for i in obj:
+ assert isinstance(i, TestSerialisation)
return obj
-def load_tests(build_dir: str) -> T.List['TestSerialisation']:
+def load_tests(build_dir: str) -> T.List[TestSerialisation]:
datafile = Path(build_dir) / 'meson-private' / 'meson_test_setup.dat'
if not datafile.is_file():
raise TestException('Directory {!r} does not seem to be a Meson build directory.'.format(build_dir))
with datafile.open('rb') as f:
- obj = T.cast(T.List['TestSerialisation'], pickle.load(f))
+ obj = pickle.load(f)
+ assert isinstance(obj, list)
+ for i in obj:
+ assert isinstance(i, TestSerialisation)
return obj
class SingleTestRunner:
- def __init__(self, test: 'TestSerialisation', test_env: T.Dict[str, str],
+ def __init__(self, test: TestSerialisation, test_env: T.Dict[str, str],
env: T.Dict[str, str], options: argparse.Namespace):
self.test = test
self.test_env = test_env
@@ -605,9 +608,9 @@ class SingleTestRunner:
def _get_cmd(self) -> T.Optional[T.List[str]]:
if self.test.fname[0].endswith('.jar'):
- return ['java', '-jar'] + T.cast(T.List[str], self.test.fname)
+ return ['java', '-jar'] + self.test.fname
elif not self.test.is_cross_built and run_with_mono(self.test.fname[0]):
- return ['mono'] + T.cast(T.List[str], self.test.fname)
+ return ['mono'] + self.test.fname
elif self.test.cmd_is_built and self.test.needs_exe_wrapper:
if self.test.exe_runner is None:
# Can not run test on cross compiled executable
@@ -620,8 +623,8 @@ class SingleTestRunner:
msg = ('The exe_wrapper defined in the cross file {!r} was not '
'found. Please check the command and/or add it to PATH.')
raise TestException(msg.format(self.test.exe_runner.name))
- return T.cast(T.List[str], self.test.exe_runner.get_command()) + T.cast(T.List[str], self.test.fname)
- return T.cast(T.List[str], self.test.fname)
+ return self.test.exe_runner.get_command() + self.test.fname
+ return self.test.fname
def run(self) -> TestRun:
cmd = self._get_cmd()
@@ -833,7 +836,7 @@ class TestHarness:
lfile.close()
setattr(self, f, None)
- def merge_suite_options(self, options: argparse.Namespace, test: 'TestSerialisation') -> T.Dict[str, str]:
+ def merge_suite_options(self, options: argparse.Namespace, test: TestSerialisation) -> T.Dict[str, str]:
if ':' in options.setup:
if options.setup not in self.build_data.test_setups:
sys.exit("Unknown test setup '{}'.".format(options.setup))
@@ -855,9 +858,9 @@ class TestHarness:
sys.exit('Conflict: both test setup and command line specify an exe wrapper.')
if options.wrapper is None:
options.wrapper = current.exe_wrapper
- return T.cast(T.Dict[str, str], current.env.get_env(os.environ.copy()))
+ return current.env.get_env(os.environ.copy())
- def get_test_runner(self, test: 'TestSerialisation') -> SingleTestRunner:
+ def get_test_runner(self, test: TestSerialisation) -> SingleTestRunner:
options = deepcopy(self.options)
if not options.setup:
options.setup = self.build_data.test_setup_default_name
@@ -889,7 +892,7 @@ class TestHarness:
sys.exit('Unknown test result encountered: {}'.format(result.res))
def print_stats(self, test_count: int, name_max_len: int,
- tests: T.List['TestSerialisation'],
+ tests: T.List[TestSerialisation],
name: str, result: TestRun, i: int) -> None:
ok_statuses = (TestResult.OK, TestResult.EXPECTEDFAIL)
bad_statuses = (TestResult.FAIL, TestResult.TIMEOUT,
@@ -983,14 +986,14 @@ class TestHarness:
@staticmethod
def split_suite_string(suite: str) -> T.Tuple[str, str]:
if ':' in suite:
- # mypy can't figure out that str.split(n, 1) will return a list of
- # length 2, so we have to help it.
- return T.cast(T.Tuple[str, str], tuple(suite.split(':', 1)))
+ split = suite.split(':', 1)
+ assert len(split) == 2
+ return split[0], split[1]
else:
return suite, ""
@staticmethod
- def test_in_suites(test: 'TestSerialisation', suites: T.List[str]) -> bool:
+ def test_in_suites(test: TestSerialisation, suites: T.List[str]) -> bool:
for suite in suites:
(prj_match, st_match) = TestHarness.split_suite_string(suite)
for prjst in test.suite:
@@ -1021,12 +1024,12 @@ class TestHarness:
return True
return False
- def test_suitable(self, test: 'TestSerialisation') -> bool:
+ def test_suitable(self, test: TestSerialisation) -> bool:
return ((not self.options.include_suites or
TestHarness.test_in_suites(test, self.options.include_suites)) and not
TestHarness.test_in_suites(test, self.options.exclude_suites))
- def get_tests(self) -> T.List['TestSerialisation']:
+ def get_tests(self) -> T.List[TestSerialisation]:
if not self.tests:
print('No tests defined.')
return []
@@ -1089,17 +1092,17 @@ class TestHarness:
wrap += options.wrapper
return wrap
- def get_pretty_suite(self, test: 'TestSerialisation') -> str:
+ def get_pretty_suite(self, test: TestSerialisation) -> str:
if len(self.suites) > 1 and test.suite:
rv = TestHarness.split_suite_string(test.suite[0])[0]
s = "+".join(TestHarness.split_suite_string(s)[1] for s in test.suite)
if s:
rv += ":"
- return rv + s + " / " + T.cast(str, test.name)
+ return rv + s + " / " + test.name
else:
- return T.cast(str, test.name)
+ return test.name
- def run_tests(self, tests: T.List['TestSerialisation']) -> None:
+ def run_tests(self, tests: T.List[TestSerialisation]) -> None:
executor = None
futures = [] # type: T.List[T.Tuple[conc.Future[TestRun], int, int, T.List[TestSerialisation], str, int]]
test_count = len(tests)
@@ -1141,7 +1144,7 @@ class TestHarness:
finally:
os.chdir(startdir)
- def drain_futures(self, futures: T.List[T.Tuple['conc.Future[TestRun]', int, int, T.List['TestSerialisation'], str, int]]) -> None:
+ def drain_futures(self, futures: T.List[T.Tuple['conc.Future[TestRun]', int, int, T.List[TestSerialisation], str, int]]) -> None:
for x in futures:
(result, test_count, name_max_len, tests, name, i) = x
if self.options.repeat > 1 and self.fail_count:
diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py
index a6fd503..75011e7 100644
--- a/mesonbuild/optinterpreter.py
+++ b/mesonbuild/optinterpreter.py
@@ -62,7 +62,6 @@ optname_regex = re.compile('[^a-zA-Z0-9_-]')
def StringParser(description, kwargs):
return coredata.UserStringOption(description,
kwargs.get('value', ''),
- kwargs.get('choices', []),
kwargs.get('yield', coredata.default_yielding))
@permitted_kwargs({'value', 'yield'})
@@ -134,11 +133,11 @@ option_types = {'string': StringParser,
} # type: T.Dict[str, T.Callable[[str, T.Dict], coredata.UserOption]]
class OptionInterpreter:
- def __init__(self, subproject):
+ def __init__(self, subproject: str) -> None:
self.options = {}
self.subproject = subproject
- def process(self, option_file):
+ def process(self, option_file: str) -> None:
try:
with open(option_file, 'r', encoding='utf8') as f:
ast = mparser.Parser(f.read(), option_file).parse()
@@ -159,7 +158,7 @@ class OptionInterpreter:
e.file = option_file
raise e
- def reduce_single(self, arg):
+ def reduce_single(self, arg: T.Union[str, mparser.BaseNode]) -> T.Union[str, int, bool]:
if isinstance(arg, str):
return arg
elif isinstance(arg, (mparser.StringNode, mparser.BooleanNode,
@@ -189,7 +188,7 @@ class OptionInterpreter:
else:
raise OptionException('Arguments may only be string, int, bool, or array of those.')
- def reduce_arguments(self, args):
+ def reduce_arguments(self, args: mparser.ArgumentNode) -> T.Tuple[T.List[T.Union[str, int, bool]], T.Dict[str, T.Union[str, int, bool]]]:
assert(isinstance(args, mparser.ArgumentNode))
if args.incorrect_order():
raise OptionException('All keyword arguments must be after positional arguments.')
@@ -202,7 +201,7 @@ class OptionInterpreter:
reduced_kw[key.value] = self.reduce_single(a)
return reduced_pos, reduced_kw
- def evaluate_statement(self, node):
+ def evaluate_statement(self, node: mparser.BaseNode) -> None:
if not isinstance(node, mparser.FunctionNode):
raise OptionException('Option file may only contain option definitions')
func_name = node.func_name
diff --git a/mesonbuild/scripts/depfixer.py b/mesonbuild/scripts/depfixer.py
index a64caca..76cf2b5 100644
--- a/mesonbuild/scripts/depfixer.py
+++ b/mesonbuild/scripts/depfixer.py
@@ -311,7 +311,7 @@ class Elf(DataSizes):
old_rpath = self.read_str()
# Some rpath entries may come from multiple sources.
# Only add each one once.
- new_rpaths = OrderedSet()
+ new_rpaths = OrderedSet() # type: OrderedSet[bytes]
if new_rpath:
new_rpaths.add(new_rpath)
if old_rpath:
diff --git a/mesonbuild/scripts/meson_exe.py b/mesonbuild/scripts/meson_exe.py
index 68ba120..df54b47 100644
--- a/mesonbuild/scripts/meson_exe.py
+++ b/mesonbuild/scripts/meson_exe.py
@@ -57,7 +57,7 @@ def run_exe(exe: ExecutableSerialisation) -> int:
if p.returncode == 0xc0000135:
# STATUS_DLL_NOT_FOUND on Windows indicating a common problem that is otherwise hard to diagnose
- raise FileNotFoundError('Missing DLLs on calling {!r}'.format(exe.name))
+ raise FileNotFoundError('Missing DLLs on calling {!r}'.format(cmd_args))
if exe.capture and p.returncode == 0:
skip_write = False
diff --git a/run_mypy.py b/run_mypy.py
index 759d667..d5ec55d 100755
--- a/run_mypy.py
+++ b/run_mypy.py
@@ -15,6 +15,7 @@ modules = [
# specific files
'mesonbuild/arglist.py',
# 'mesonbuild/compilers/mixins/intel.py',
+ # 'mesonbuild/coredata.py',
'mesonbuild/dependencies/boost.py',
'mesonbuild/dependencies/hdf5.py',
'mesonbuild/dependencies/mpi.py',