diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py index 095f30c14..f9a6e11c0 100644 --- a/mesonbuild/ast/introspection.py +++ b/mesonbuild/ast/introspection.py @@ -5,7 +5,6 @@ # or an interpreter-based tool from __future__ import annotations -import argparse import copy import os import typing as T @@ -31,13 +30,13 @@ BUILD_TARGET_FUNCTIONS = [ 'static_library', 'both_libraries' ] -class IntrospectionHelper(argparse.Namespace): +class IntrospectionHelper: # mimic an argparse namespace - def __init__(self, cross_file: str): - super().__init__() - self.cross_file = cross_file - self.native_file: str = None - self.cmd_line_options: T.Dict[str, str] = {} + def __init__(self, cross_file: T.Optional[str]): + self.cross_file = [cross_file] if cross_file is not None else [] + self.native_file: T.List[str] = [] + self.cmd_line_options: T.Dict[OptionKey, str] = {} + self.projectoptions: T.List[str] = [] def __eq__(self, other: object) -> bool: return NotImplemented diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index a6a14c8ab..e361eb2fc 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -1,5 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright 2013-2023 The Meson development team +# Copyright © 2023 Intel Corporation from __future__ import annotations @@ -31,6 +32,8 @@ import shlex import typing as T if T.TYPE_CHECKING: + from typing_extensions import Protocol + from . import dependencies from .compilers.compilers import Compiler, CompileResult, RunResult, CompileCheckMode from .dependencies.detect import TV_DepID @@ -38,6 +41,21 @@ if T.TYPE_CHECKING: from .mesonlib import FileOrString from .cmake.traceparser import CMakeCacheEntry + class SharedCMDOptions(Protocol): + + """Representation of command line options from Meson setup, configure, + and dist. + + :param projectoptions: The raw list of command line options given + :param cmd_line_options: command line options parsed into an OptionKey: + str mapping + """ + + cmd_line_options: T.Dict[OptionKey, str] + projectoptions: T.List[str] + cross_file: T.List[str] + native_file: T.List[str] + OptionDictType = T.Union[T.Dict[str, 'UserOption[T.Any]'], 'OptionsView'] MutableKeyedOptionDictType = T.Dict['OptionKey', 'UserOption[T.Any]'] KeyedOptionDictType = T.Union[MutableKeyedOptionDictType, 'OptionsView'] @@ -546,7 +564,7 @@ _V = T.TypeVar('_V') class CoreData: - def __init__(self, options: argparse.Namespace, scratch_dir: str, meson_command: T.List[str]): + def __init__(self, options: SharedCMDOptions, scratch_dir: str, meson_command: T.List[str]): self.lang_guids = { 'default': '8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942', 'c': '8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942', @@ -587,7 +605,7 @@ class CoreData: self.init_builtins('') @staticmethod - def __load_config_files(options: argparse.Namespace, scratch_dir: str, ftype: str) -> T.List[str]: + def __load_config_files(options: SharedCMDOptions, scratch_dir: str, ftype: str) -> T.List[str]: # Need to try and make the passed filenames absolute because when the # files are parsed later we'll have chdir()d. if ftype == 'cross': @@ -1123,7 +1141,7 @@ def parse_machine_files(filenames: T.List[str], sourcedir: str): 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: str, options: argparse.Namespace) -> None: +def read_cmd_line_file(build_dir: str, options: SharedCMDOptions) -> None: filename = get_cmd_line_file(build_dir) if not os.path.isfile(filename): return @@ -1145,7 +1163,7 @@ def read_cmd_line_file(build_dir: str, options: argparse.Namespace) -> None: # literal_eval to get it into the list of strings. options.native_file = ast.literal_eval(properties.get('native_file', '[]')) -def write_cmd_line_file(build_dir: str, options: argparse.Namespace) -> None: +def write_cmd_line_file(build_dir: str, options: SharedCMDOptions) -> None: filename = get_cmd_line_file(build_dir) config = CmdLineFileParser() @@ -1160,7 +1178,7 @@ def write_cmd_line_file(build_dir: str, options: argparse.Namespace) -> None: with open(filename, 'w', encoding='utf-8') as f: config.write(f) -def update_cmd_line_file(build_dir: str, options: argparse.Namespace) -> None: +def update_cmd_line_file(build_dir: str, options: SharedCMDOptions) -> None: filename = get_cmd_line_file(build_dir) config = CmdLineFileParser() config.read(filename) @@ -1168,7 +1186,7 @@ def update_cmd_line_file(build_dir: str, options: argparse.Namespace) -> None: with open(filename, 'w', encoding='utf-8') as f: config.write(f) -def format_cmd_line_options(options: argparse.Namespace) -> str: +def format_cmd_line_options(options: SharedCMDOptions) -> str: cmdline = ['-D{}={}'.format(str(k), v) for k, v in options.cmd_line_options.items()] if options.cross_file: cmdline += [f'--cross-file={f}' for f in options.cross_file] @@ -1226,7 +1244,7 @@ def create_options_dict(options: T.List[str], subproject: str = '') -> T.Dict[Op result[k] = value return result -def parse_cmd_line_options(args: argparse.Namespace) -> None: +def parse_cmd_line_options(args: SharedCMDOptions) -> None: args.cmd_line_options = create_options_dict(args.projectoptions) # Merge builtin options set with --option into the dict. diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 326a1c9ed..14e4ee856 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -1,5 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright 2012-2020 The Meson development team +# Copyright © 2023 Intel Corporation from __future__ import annotations @@ -35,7 +36,6 @@ from functools import lru_cache from mesonbuild import envconfig if T.TYPE_CHECKING: - import argparse from configparser import ConfigParser from .compilers import Compiler @@ -485,7 +485,7 @@ class Environment: log_dir = 'meson-logs' info_dir = 'meson-info' - def __init__(self, source_dir: str, build_dir: str, options: 'argparse.Namespace') -> None: + def __init__(self, source_dir: str, build_dir: str, options: coredata.SharedCMDOptions) -> None: self.source_dir = source_dir self.build_dir = build_dir # Do not try to create build directories when build_dir is none. @@ -780,7 +780,7 @@ class Environment: self.properties[for_machine].properties.setdefault(name, p_env) break - def create_new_coredata(self, options: 'argparse.Namespace') -> None: + def create_new_coredata(self, options: coredata.SharedCMDOptions) -> 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. diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index deb3a9caf..7e9fe4a55 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -106,8 +106,6 @@ import importlib import copy if T.TYPE_CHECKING: - import argparse - from . import kwargs as kwtypes from ..backend.backends import Backend from ..interpreterbase.baseobjects import InterpreterObject, TYPE_var, TYPE_kwargs @@ -269,7 +267,7 @@ class Interpreter(InterpreterBase, HoldableObject): ast: T.Optional[mparser.CodeBlockNode] = None, is_translated: bool = False, relaxations: T.Optional[T.Set[InterpreterRuleRelaxation]] = None, - user_defined_options: T.Optional['argparse.Namespace'] = None, + user_defined_options: T.Optional[coredata.SharedCMDOptions] = None, ) -> None: super().__init__(_build.environment.get_source_dir(), subdir, subproject) self.active_projectname = '' diff --git a/mesonbuild/mdist.py b/mesonbuild/mdist.py index 67442885a..f9a63bc02 100644 --- a/mesonbuild/mdist.py +++ b/mesonbuild/mdist.py @@ -1,5 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright 2017 The Meson development team +# Copyright © 2023 Intel Corporation from __future__ import annotations @@ -304,7 +305,7 @@ def check_dist(packagename: str, meson_command: ImmutableListProtocol[str], extr def create_cmdline_args(bld_root: str) -> T.List[str]: parser = argparse.ArgumentParser() msetup_argparse(parser) - args = parser.parse_args([]) + args = T.cast('coredata.SharedCMDOptions', parser.parse_args([])) coredata.parse_cmd_line_options(args) coredata.read_cmd_line_file(bld_root, args) args.cmd_line_options.pop(OptionKey('backend'), '') diff --git a/run_tests.py b/run_tests.py index 5347be87b..207653219 100755 --- a/run_tests.py +++ b/run_tests.py @@ -1,6 +1,9 @@ #!/usr/bin/env python3 # SPDX-License-Identifier: Apache-2.0 # Copyright 2012-2021 The Meson development team +# Copyright © 2023-2024 Intel Corporation + +from __future__ import annotations # Work around some pathlib bugs... from mesonbuild import _pathlib @@ -33,6 +36,9 @@ from mesonbuild.environment import Environment, detect_ninja, detect_machine_inf from mesonbuild.coredata import backendlist, version as meson_version from mesonbuild.mesonlib import OptionKey, setup_vsenv +if T.TYPE_CHECKING: + from mesonbuild.coredata import SharedCMDOptions + NINJA_1_9_OR_NEWER = False NINJA_CMD = None # If we're on CI, detecting ninja for every subprocess unit test that we run is slow @@ -133,9 +139,8 @@ class FakeCompilerOptions: def __init__(self): self.value = [] -# TODO: use a typing.Protocol here -def get_fake_options(prefix: str = '') -> argparse.Namespace: - opts = argparse.Namespace() +def get_fake_options(prefix: str = '') -> SharedCMDOptions: + opts = T.cast('SharedCMDOptions', argparse.Namespace()) opts.native_file = [] opts.cross_file = None opts.wrap_mode = None