From 0490372449251fc2720748a0c58fb1bbdb5ca28f Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 30 Aug 2020 14:55:52 +0200 Subject: [PATCH] typing: fully annotate mintro and mtest --- mesonbuild/mintro.py | 24 ++++++++++++------------ mesonbuild/mtest.py | 26 +++++++++++++------------- run_mypy.py | 2 ++ 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index d55227af7..d60386e3c 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -30,7 +30,7 @@ from .mparser import BaseNode, FunctionNode, ArrayNode, ArgumentNode, StringNode from .interpreter import Interpreter from pathlib import PurePath import typing as T -import os +import os, argparse def get_meson_info_file(info_dir: str) -> str: return os.path.join(info_dir, 'meson-info.json') @@ -76,7 +76,7 @@ def get_meson_introspection_types(coredata: T.Optional[cdata.CoreData] = None, ('tests', IntroCommand('List all unit tests', func=lambda: list_tests(testdata))), ]) -def add_arguments(parser): +def add_arguments(parser: argparse.ArgumentParser) -> None: intro_types = get_meson_introspection_types() for key, val in intro_types.items(): flag = '--' + key.replace('_', '-') @@ -97,7 +97,7 @@ def dump_ast(intr: IntrospectionInterpreter) -> T.Dict[str, T.Any]: intr.ast.accept(printer) return printer.result -def list_installed(installdata): +def list_installed(installdata: backends.InstallData) -> T.Dict[str, str]: res = {} if installdata is not None: for t in installdata.targets: @@ -157,7 +157,7 @@ def list_targets_from_source(intr: IntrospectionInterpreter) -> T.List[T.Dict[st return tlist -def list_targets(builddata: build.Build, installdata, backend: backends.Backend) -> T.List[T.Dict[str, T.Union[bool, str, T.List[T.Union[str, T.Dict[str, T.Union[str, T.List[str], bool]]]]]]]: +def list_targets(builddata: build.Build, installdata: backends.InstallData, backend: backends.Backend) -> T.List[T.Dict[str, T.Union[bool, str, T.List[T.Union[str, T.Dict[str, T.Union[str, T.List[str], bool]]]]]]]: tlist = [] # type: T.List[T.Dict[str, T.Union[bool, str, T.List[T.Union[str, T.Dict[str, T.Union[str, T.List[str], bool]]]]]]] build_dir = builddata.environment.get_build_dir() src_dir = builddata.environment.get_source_dir() @@ -267,7 +267,7 @@ def list_buildoptions(coredata: cdata.CoreData, subprojects: T.Optional[T.List[s add_keys(test_options, 'test') return optlist -def find_buildsystem_files_list(src_dir) -> T.List[str]: +def find_buildsystem_files_list(src_dir: str) -> T.List[str]: # I feel dirty about this. But only slightly. filelist = [] # type: T.List[str] for root, _, files in os.walk(src_dir): @@ -278,7 +278,7 @@ def find_buildsystem_files_list(src_dir) -> T.List[str]: def list_buildsystem_files(builddata: build.Build, interpreter: Interpreter) -> T.List[str]: src_dir = builddata.environment.get_source_dir() - filelist = interpreter.get_build_def_files() + filelist = interpreter.get_build_def_files() # type: T.List[str] filelist = [PurePath(src_dir, x).as_posix() for x in filelist] return filelist @@ -305,7 +305,7 @@ 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) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]: +def get_test_list(testdata: 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 = {} @@ -329,10 +329,10 @@ def get_test_list(testdata) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], result.append(to) return result -def list_tests(testdata) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]: +def list_tests(testdata: 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) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]: +def list_benchmarks(benchdata: 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]]]]: @@ -362,7 +362,7 @@ def list_projinfo_from_source(intr: IntrospectionInterpreter) -> T.Dict[str, T.U intr.project_data['subproject_dir'] = intr.subproject_dir return intr.project_data -def print_results(options, results: T.Sequence[T.Tuple[str, T.Union[dict, T.List[T.Any]]]], indent: int) -> int: +def print_results(options: argparse.Namespace, results: T.Sequence[T.Tuple[str, T.Union[dict, T.List[T.Any]]]], indent: int) -> int: if not results and not options.force_dict: print('No command specified') return 1 @@ -376,7 +376,7 @@ def print_results(options, results: T.Sequence[T.Tuple[str, T.Union[dict, T.List print(json.dumps(out, indent=indent)) return 0 -def run(options) -> int: +def run(options: argparse.Namespace) -> int: datadir = 'meson-private' infodir = 'meson-info' if options.builddir is not None: @@ -461,7 +461,7 @@ def generate_introspection_file(builddata: build.Build, backend: backends.Backen write_intro_info(intro_info, builddata.environment.info_dir) -def update_build_options(coredata: cdata.CoreData, info_dir) -> None: +def update_build_options(coredata: cdata.CoreData, info_dir: str) -> None: intro_info = [ ('buildoptions', list_buildoptions(coredata)) ] diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index b9a117617..cc82bd072 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -462,7 +462,7 @@ class TestRun: 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) -> 'TestRun': + cmd: T.Optional[T.List[str]], **kwargs: T.Any) -> 'TestRun': if returncode == GNU_SKIP_RETURNCODE: res = TestResult.SKIP elif returncode == GNU_ERROR_RETURNCODE: @@ -605,9 +605,9 @@ class SingleTestRunner: def _get_cmd(self) -> T.Optional[T.List[str]]: if self.test.fname[0].endswith('.jar'): - return ['java', '-jar'] + self.test.fname + return ['java', '-jar'] + T.cast(T.List[str], self.test.fname) elif not self.test.is_cross_built and run_with_mono(self.test.fname[0]): - return ['mono'] + self.test.fname + return ['mono'] + T.cast(T.List[str], 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 +620,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 self.test.exe_runner.get_command() + self.test.fname - return self.test.fname + 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) def run(self) -> TestRun: cmd = self._get_cmd() @@ -680,7 +680,7 @@ class SingleTestRunner: # We don't want setsid() in gdb because gdb needs the # terminal in order to handle ^C and not show tcsetpgrp() # errors avoid not being able to use the terminal. - os.setsid() # type: ignore + os.setsid() extra_cmd = [] # type: T.List[str] if self.test.protocol is TestProtocol.GTEST: @@ -727,10 +727,10 @@ class SingleTestRunner: subprocess.run(['taskkill', '/F', '/T', '/PID', str(p.pid)]) else: - def _send_signal_to_process_group(pgid : int, signum : int): + def _send_signal_to_process_group(pgid : int, signum : int) -> None: """ sends a signal to a process group """ try: - os.killpg(pgid, signum) # type: ignore + os.killpg(pgid, signum) except ProcessLookupError: # Sometimes (e.g. with Wine) this happens. # There's nothing we can do (maybe the process @@ -820,10 +820,10 @@ class TestHarness: def __del__(self) -> None: self.close_logfiles() - def __enter__(self): + def __enter__(self) -> 'TestHarness': return self - def __exit__(self, exc_type, exc_value, traceback) -> None: + def __exit__(self, exc_type: T.Any, exc_value: T.Any, traceback: T.Any) -> None: self.close_logfiles() def close_logfiles(self) -> None: @@ -855,7 +855,7 @@ 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 current.env.get_env(os.environ.copy()) + return T.cast(T.Dict[str, str], current.env.get_env(os.environ.copy())) def get_test_runner(self, test: 'TestSerialisation') -> SingleTestRunner: options = deepcopy(self.options) @@ -1095,9 +1095,9 @@ class TestHarness: s = "+".join(TestHarness.split_suite_string(s)[1] for s in test.suite) if s: rv += ":" - return rv + s + " / " + test.name + return rv + s + " / " + T.cast(str, test.name) else: - return test.name + return T.cast(str, test.name) def run_tests(self, tests: T.List['TestSerialisation']) -> None: executor = None diff --git a/run_mypy.py b/run_mypy.py index 38457325b..e2b0415d1 100755 --- a/run_mypy.py +++ b/run_mypy.py @@ -32,7 +32,9 @@ normal_modules = [ strict_modules = [ 'mesonbuild/interpreterbase.py', + 'mesonbuild/mtest.py', 'mesonbuild/minit.py', + 'mesonbuild/mintro.py', 'mesonbuild/mparser.py', 'mesonbuild/msetup.py', 'mesonbuild/mcompile.py',