holders: remove unholder

pull/8903/head
Daniel Mensinger 3 years ago
parent 84a3e459a8
commit 34c28dc92c
  1. 18
      mesonbuild/backend/backends.py
  2. 4
      mesonbuild/backend/ninjabackend.py
  3. 77
      mesonbuild/build.py
  4. 53
      mesonbuild/interpreter/dependencyfallbacks.py
  5. 96
      mesonbuild/interpreter/interpreter.py
  6. 3
      mesonbuild/interpreter/mesonmain.py
  7. 4
      mesonbuild/interpreterbase/__init__.py
  8. 21
      mesonbuild/mesonlib/universal.py
  9. 18
      mesonbuild/modules/__init__.py
  10. 17
      mesonbuild/modules/cmake.py
  11. 70
      mesonbuild/modules/gnome.py
  12. 11
      mesonbuild/modules/hotdoc.py
  13. 3
      mesonbuild/modules/i18n.py
  14. 15
      mesonbuild/modules/pkgconfig.py
  15. 1
      mesonbuild/modules/sourceset.py
  16. 11
      mesonbuild/modules/unstable_cuda.py
  17. 11
      mesonbuild/modules/unstable_rust.py
  18. 4
      mesonbuild/modules/unstable_simd.py
  19. 12
      mesonbuild/modules/windows.py
  20. 11
      run_unittests.py

@ -32,7 +32,7 @@ from .. import mlog
from ..compilers import LANGUAGES_USING_LDFLAGS
from ..mesonlib import (
File, MachineChoice, MesonException, OptionType, OrderedSet, OptionOverrideProxy,
classify_unity_sources, unholder, OptionKey, join_args
classify_unity_sources, OptionKey, join_args
)
if T.TYPE_CHECKING:
@ -237,7 +237,7 @@ class Backend:
def generate(self) -> None:
raise RuntimeError(f'generate is not implemented in {type(self).__name__}')
def get_target_filename(self, t, *, warn_multi_output: bool = True):
def get_target_filename(self, t: T.Union[build.Target, build.CustomTargetIndex], *, warn_multi_output: bool = True):
if isinstance(t, build.CustomTarget):
if warn_multi_output and len(t.get_outputs()) != 1:
mlog.warning(f'custom_target {t.name!r} has more than one output! '
@ -250,7 +250,7 @@ class Backend:
filename = t.get_filename()
return os.path.join(self.get_target_dir(t), filename)
def get_target_filename_abs(self, target):
def get_target_filename_abs(self, target: T.Union[build.Target, build.CustomTargetIndex]) -> str:
return os.path.join(self.environment.get_build_dir(), self.get_target_filename(target))
def get_base_options_for_target(self, target: build.BuildTarget) -> OptionOverrideProxy:
@ -309,7 +309,7 @@ class Backend:
raise AssertionError(f'BUG: Tried to link to {target!r} which is not linkable')
@lru_cache(maxsize=None)
def get_target_dir(self, target):
def get_target_dir(self, target: build.Target) -> str:
if self.environment.coredata.get_option(OptionKey('layout')) == 'mirror':
dirname = target.get_subdir()
else:
@ -329,7 +329,7 @@ class Backend:
return os.path.join(self.build_to_src, target_dir)
return self.build_to_src
def get_target_private_dir(self, target):
def get_target_private_dir(self, target: build.Target) -> str:
return os.path.join(self.get_target_filename(target, warn_multi_output=False) + '.p')
def get_target_private_dir_abs(self, target):
@ -963,7 +963,7 @@ class Backend:
depends = set(t.depends)
if isinstance(exe, build.Target):
depends.add(exe)
for a in unholder(t.cmd_args):
for a in t.cmd_args:
if isinstance(a, build.Target):
depends.add(a)
if isinstance(a, build.BuildTarget):
@ -1091,10 +1091,10 @@ class Backend:
# also be built by default. XXX: Sometime in the future these should be
# built only before running tests.
for t in self.build.get_tests():
exe = unholder(t.exe)
exe = t.exe
if isinstance(exe, (build.CustomTarget, build.BuildTarget)):
result[exe.get_id()] = exe
for arg in unholder(t.cmd_args):
for arg in t.cmd_args:
if not isinstance(arg, (build.CustomTarget, build.BuildTarget)):
continue
result[arg.get_id()] = arg
@ -1133,7 +1133,7 @@ class Backend:
Returns the path to them relative to the build root directory.
'''
srcs = []
for i in unholder(target.get_sources()):
for i in target.get_sources():
if isinstance(i, str):
fname = [os.path.join(self.build_to_src, target.subdir, i)]
elif isinstance(i, build.BuildTarget):

@ -40,7 +40,7 @@ from ..compilers import (
from ..linkers import ArLinker, RSPFileSyntax
from ..mesonlib import (
File, LibType, MachineChoice, MesonException, OrderedSet, PerMachine,
ProgressBar, quote_arg, unholder,
ProgressBar, quote_arg
)
from ..mesonlib import get_compiler_for_source, has_path_sep, OptionKey
from .backends import CleanTrees
@ -937,7 +937,7 @@ int dummy;
self.generate_target(t)
def custom_target_generator_inputs(self, target):
for s in unholder(target.sources):
for s in target.sources:
if isinstance(s, build.GeneratedList):
self.generate_genlist_for_target(s, target)

@ -31,15 +31,16 @@ from .mesonlib import (
HoldableObject,
File, MesonException, MachineChoice, PerMachine, OrderedSet, listify,
extract_as_list, typeslistify, stringlistify, classify_unity_sources,
get_filenames_templates_dict, substitute_values, has_path_sep, unholder,
get_filenames_templates_dict, substitute_values, has_path_sep,
OptionKey, PerMachineDefaultable,
MesonBugException, FileOrString,
)
from .compilers import (
Compiler, is_object, clink_langs, sort_clink, lang_suffixes,
is_known_suffix
)
from .linkers import StaticLinker
from .interpreterbase import FeatureNew
from .interpreterbase import FeatureNew, TYPE_nkwargs, TYPE_nvar
if T.TYPE_CHECKING:
from ._typing import ImmutableListProtocol, ImmutableSetProtocol
@ -47,7 +48,6 @@ if T.TYPE_CHECKING:
from .mesonlib import FileMode, FileOrString
from .modules import ModuleState
from .backend.backends import Backend
from .interpreter.interpreterobjects import GeneratorHolder
pch_kwargs = {'c_pch', 'cpp_pch'}
@ -680,7 +680,7 @@ class BuildTarget(Target):
def process_objectlist(self, objects):
assert(isinstance(objects, list))
for s in unholder(objects):
for s in objects:
if isinstance(s, (str, File, ExtractedObjects)):
self.objects.append(s)
elif isinstance(s, (GeneratedList, CustomTarget)):
@ -776,7 +776,7 @@ class BuildTarget(Target):
# which is what we need.
if not is_object(s):
sources.append(s)
for d in unholder(self.external_deps):
for d in self.external_deps:
for s in d.sources:
if isinstance(s, (str, File)):
sources.append(s)
@ -847,7 +847,7 @@ class BuildTarget(Target):
link_depends.
"""
sources = listify(sources)
for s in unholder(sources):
for s in sources:
if isinstance(s, File):
self.link_depends.append(s)
elif isinstance(s, str):
@ -864,35 +864,16 @@ class BuildTarget(Target):
def get_original_kwargs(self):
return self.kwargs
def unpack_holder(self, d):
d = listify(d)
newd = []
for i in d:
if isinstance(i, list):
i = self.unpack_holder(i)
elif hasattr(i, 'held_object'):
i = i.held_object
for t in ['dependencies', 'link_with', 'include_directories', 'sources']:
if hasattr(i, t):
setattr(i, t, self.unpack_holder(getattr(i, t)))
newd.append(i)
return newd
def copy_kwargs(self, kwargs):
self.kwargs = copy.copy(kwargs)
# This sucks quite badly. Arguments
# are holders but they can't be pickled
# so unpack those known.
for k, v in self.kwargs.items():
if isinstance(v, list):
self.kwargs[k] = self.unpack_holder(v)
if hasattr(v, 'held_object'):
self.kwargs[k] = v.held_object
self.kwargs[k] = listify(v, flatten=True)
for t in ['dependencies', 'link_with', 'include_directories', 'sources']:
if t in self.kwargs:
self.kwargs[t] = self.unpack_holder(self.kwargs[t])
self.kwargs[t] = listify(self.kwargs[t], flatten=True)
def extract_objects(self, srclist):
def extract_objects(self, srclist: T.List[FileOrString]) -> ExtractedObjects:
obj_src = []
sources_set = set(self.sources)
for src in srclist:
@ -901,14 +882,14 @@ class BuildTarget(Target):
elif isinstance(src, File):
FeatureNew.single_use('File argument for extract_objects', '0.50.0', self.subproject)
else:
raise MesonException('Object extraction arguments must be strings or Files.')
raise MesonException(f'Object extraction arguments must be strings or Files (got {type(src).__name__}).')
# FIXME: It could be a generated source
if src not in sources_set:
raise MesonException(f'Tried to extract unknown source {src}.')
obj_src.append(src)
return ExtractedObjects(self, obj_src)
def extract_all_objects(self, recursive=True):
def extract_all_objects(self, recursive: bool = True) -> ExtractedObjects:
return ExtractedObjects(self, self.sources, self.generated, self.objects,
recursive)
@ -960,7 +941,7 @@ class BuildTarget(Target):
kwargs.get('modules', [])
self.need_install = kwargs.get('install', self.need_install)
llist = extract_as_list(kwargs, 'link_with')
for linktarget in unholder(llist):
for linktarget in llist:
if isinstance(linktarget, dependencies.ExternalLibrary):
raise MesonException(textwrap.dedent('''\
An external library was used in link_with keyword argument, which
@ -1003,7 +984,7 @@ class BuildTarget(Target):
if dfeature_debug:
dfeatures['debug'] = dfeature_debug
if 'd_import_dirs' in kwargs:
dfeature_import_dirs = unholder(extract_as_list(kwargs, 'd_import_dirs'))
dfeature_import_dirs = extract_as_list(kwargs, 'd_import_dirs')
for d in dfeature_import_dirs:
if not isinstance(d, IncludeDirs):
raise InvalidArguments('Arguments to d_import_dirs must be include_directories.')
@ -1200,7 +1181,7 @@ class BuildTarget(Target):
def add_deps(self, deps):
deps = listify(deps)
for dep in unholder(deps):
for dep in deps:
if dep in self.added_deps:
continue
if isinstance(dep, dependencies.InternalDependency):
@ -1250,7 +1231,7 @@ You probably should put it in link_with instead.''')
return isinstance(self, StaticLibrary) and not self.need_install
def link(self, target):
for t in unholder(listify(target)):
for t in listify(target):
if isinstance(t, BothLibraries):
t = t.get_preferred_library()
if isinstance(self, StaticLibrary) and self.need_install:
@ -1280,7 +1261,7 @@ You probably should put it in link_with instead.''')
self.link_targets.append(t)
def link_whole(self, target):
for t in unholder(listify(target)):
for t in listify(target):
# Always use the static library from BothLibraries, since shared libs aren't supported anyway
if isinstance(t, BothLibraries):
t = t.static
@ -1349,7 +1330,7 @@ You probably should put it in link_with instead.''')
def add_include_dirs(self, args, set_is_system: T.Optional[str] = None):
ids = []
for a in unholder(args):
for a in args:
if not isinstance(a, IncludeDirs):
raise InvalidArguments('Include directory to be added is not an include directory object.')
ids.append(a)
@ -2063,7 +2044,7 @@ class SharedLibrary(BuildTarget):
# Visual Studio module-definitions file
if 'vs_module_defs' in kwargs:
path = unholder(kwargs['vs_module_defs'])
path = kwargs['vs_module_defs']
if isinstance(path, str):
if os.path.isabs(path):
self.vs_module_defs = File.from_absolute_file(path)
@ -2181,7 +2162,7 @@ class BothLibraries(HoldableObject):
class CommandBase:
def flatten_command(self, cmd):
cmd = unholder(listify(cmd))
cmd = listify(cmd)
final_cmd = []
for c in cmd:
if isinstance(c, str):
@ -2256,7 +2237,7 @@ class CustomTarget(Target, CommandBase):
def get_target_dependencies(self):
deps = self.dependencies[:]
deps += self.extra_depends
for c in unholder(self.sources):
for c in self.sources:
if isinstance(c, (BuildTarget, CustomTarget)):
deps.append(c)
return deps
@ -2281,7 +2262,7 @@ class CustomTarget(Target, CommandBase):
def process_kwargs(self, kwargs, backend):
self.process_kwargs_base(kwargs)
self.sources = unholder(extract_as_list(kwargs, 'input'))
self.sources = extract_as_list(kwargs, 'input')
if 'output' not in kwargs:
raise InvalidArguments('Missing keyword argument "output".')
self.outputs = listify(kwargs['output'])
@ -2360,7 +2341,7 @@ class CustomTarget(Target, CommandBase):
if not isinstance(self.build_always_stale, bool):
raise InvalidArguments('Argument build_always_stale must be a boolean.')
extra_deps, depend_files = [extract_as_list(kwargs, c, pop=False) for c in ['depends', 'depend_files']]
for ed in unholder(extra_deps):
for ed in extra_deps:
if not isinstance(ed, (CustomTarget, BuildTarget)):
raise InvalidArguments('Can only depend on toplevel targets: custom_target or build_target '
f'(executable or a library) got: {type(ed)}({ed})')
@ -2396,7 +2377,7 @@ class CustomTarget(Target, CommandBase):
def get_generated_lists(self):
genlists = []
for c in unholder(self.sources):
for c in self.sources:
if isinstance(c, GeneratedList):
genlists.append(c)
return genlists
@ -2447,7 +2428,7 @@ class CustomTarget(Target, CommandBase):
def type_suffix(self):
return "@cus"
def __getitem__(self, index):
def __getitem__(self, index: int) -> 'CustomTargetIndex':
return CustomTargetIndex(self, self.outputs[index])
def __setitem__(self, index, value):
@ -2606,7 +2587,13 @@ class CustomTargetIndex(HoldableObject):
class ConfigurationData(HoldableObject):
def __init__(self) -> None:
super().__init__()
self.values = {} # T.Dict[str, T.Union[str, int, bool]]
self.values: T.Dict[
str,
T.Tuple[
T.Union[str, int, bool],
T.Optional[str]
]
] = {}
def __repr__(self):
return repr(self.values)
@ -2651,7 +2638,7 @@ def get_sources_string_names(sources, backend):
get all the output basenames.
'''
names = []
for s in unholder(sources):
for s in sources:
if isinstance(s, str):
names.append(s)
elif isinstance(s, (BuildTarget, CustomTarget, CustomTargetIndex, GeneratedList)):

@ -1,12 +1,12 @@
from .interpreterobjects import DependencyHolder, SubprojectHolder, extract_required_kwarg
from .interpreterobjects import SubprojectHolder, extract_required_kwarg
from .. import mlog
from .. import dependencies
from .. import build
from ..wrap import WrapMode
from ..mesonlib import OptionKey, extract_as_list, stringlistify, version_compare_many
from ..dependencies import DependencyException, NotFoundDependency
from ..interpreterbase import (InterpreterObject, FeatureNew,
from ..dependencies import Dependency, DependencyException, NotFoundDependency
from ..interpreterbase import (MesonInterpreterObject, FeatureNew,
InterpreterException, InvalidArguments,
TYPE_nkwargs, TYPE_nvar)
@ -15,7 +15,7 @@ if T.TYPE_CHECKING:
from .interpreter import Interpreter
class DependencyFallbacksHolder(InterpreterObject):
class DependencyFallbacksHolder(MesonInterpreterObject):
def __init__(self, interpreter: 'Interpreter', names: T.List[str], allow_fallback: T.Optional[bool] = None) -> None:
super().__init__()
self.interpreter = interpreter
@ -75,14 +75,14 @@ class DependencyFallbacksHolder(InterpreterObject):
self.subproject_varname = varname
self.subproject_kwargs = kwargs
def _do_dependency_cache(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: TYPE_nkwargs) -> T.Optional[DependencyHolder]:
def _do_dependency_cache(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: TYPE_nkwargs) -> T.Optional[Dependency]:
name = func_args[0]
cached_dep = self._get_cached_dep(name, kwargs)
if cached_dep:
self._verify_fallback_consistency(cached_dep)
return cached_dep
def _do_dependency(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: TYPE_nkwargs) -> T.Optional[DependencyHolder]:
def _do_dependency(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: TYPE_nkwargs) -> T.Optional[Dependency]:
# Note that there is no df.dependency() method, this is called for names
# given as positional arguments to dependency_fallbacks(name1, ...).
# We use kwargs from the dependency() function, for things like version,
@ -94,17 +94,17 @@ class DependencyFallbacksHolder(InterpreterObject):
for_machine = self.interpreter.machine_from_native_kwarg(kwargs)
identifier = dependencies.get_dep_identifier(name, kwargs)
self.coredata.deps[for_machine].put(identifier, dep)
return DependencyHolder(dep, self.subproject)
return dep
return None
def _do_existing_subproject(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: TYPE_nkwargs) -> T.Optional[DependencyHolder]:
def _do_existing_subproject(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: TYPE_nkwargs) -> T.Optional[Dependency]:
subp_name = func_args[0]
varname = self.subproject_varname
if subp_name and self._get_subproject(subp_name):
return self._get_subproject_dep(subp_name, varname, kwargs)
return None
def _do_subproject(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: TYPE_nkwargs) -> T.Optional[DependencyHolder]:
def _do_subproject(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: TYPE_nkwargs) -> T.Optional[Dependency]:
if self.nofallback:
mlog.log('Not looking for a fallback subproject for the dependency',
mlog.bold(self.display_name), 'because:\nUse of fallback dependencies is disabled.')
@ -128,7 +128,7 @@ class DependencyFallbacksHolder(InterpreterObject):
return sub
return None
def _get_subproject_dep(self, subp_name: str, varname: str, kwargs: TYPE_nkwargs) -> T.Optional[DependencyHolder]:
def _get_subproject_dep(self, subp_name: str, varname: str, kwargs: TYPE_nkwargs) -> T.Optional[Dependency]:
# Verify the subproject is found
subproject = self._get_subproject(subp_name)
if not subproject:
@ -170,7 +170,7 @@ class DependencyFallbacksHolder(InterpreterObject):
return var_dep
wanted = stringlistify(kwargs.get('version', []))
found = var_dep.held_object.get_version()
found = var_dep.get_version()
if not self._check_version(wanted, found):
mlog.log('Dependency', mlog.bold(self.display_name), 'from subproject',
mlog.bold(subproject.subdir), 'found:', mlog.red('NO'),
@ -183,7 +183,7 @@ class DependencyFallbacksHolder(InterpreterObject):
mlog.normal_cyan(found) if found else None)
return var_dep
def _get_cached_dep(self, name: str, kwargs: TYPE_nkwargs) -> T.Optional[DependencyHolder]:
def _get_cached_dep(self, name: str, kwargs: TYPE_nkwargs) -> T.Optional[Dependency]:
# Unlike other methods, this one returns not-found dependency instead
# of None in the case the dependency is cached as not-found, or if cached
# version does not match. In that case we don't want to continue with
@ -202,7 +202,7 @@ class DependencyFallbacksHolder(InterpreterObject):
if not cached_dep.found():
mlog.log('Dependency', mlog.bold(self.display_name),
'found:', mlog.red('NO'), *info)
return DependencyHolder(cached_dep, self.subproject)
return cached_dep
else:
info = [mlog.blue('(cached)')]
cached_dep = self.coredata.deps[for_machine].get(identifier)
@ -220,24 +220,27 @@ class DependencyFallbacksHolder(InterpreterObject):
info = [mlog.normal_cyan(found_vers), *info]
mlog.log('Dependency', mlog.bold(self.display_name),
'found:', mlog.green('YES'), *info)
return DependencyHolder(cached_dep, self.subproject)
return cached_dep
return None
def _get_subproject_variable(self, subproject: SubprojectHolder, varname: str) -> T.Optional[DependencyHolder]:
var_dep = subproject.held_object.variables.get(varname)
if not isinstance(var_dep, DependencyHolder):
def _get_subproject_variable(self, subproject: SubprojectHolder, varname: str) -> T.Optional[Dependency]:
try:
var_dep = subproject.get_variable_method([varname], {})
except InvalidArguments:
var_dep = None
if not isinstance(var_dep, Dependency):
mlog.warning(f'Variable {varname!r} in the subproject {subproject.subdir!r} is',
'not found' if var_dep is None else 'not a dependency object')
return None
return var_dep
def _verify_fallback_consistency(self, cached_dep: DependencyHolder):
def _verify_fallback_consistency(self, cached_dep: Dependency):
subp_name = self.subproject_name
varname = self.subproject_varname
subproject = self._get_subproject(subp_name)
if subproject and varname:
var_dep = self._get_subproject_variable(subproject, varname)
if var_dep and cached_dep.found() and var_dep.held_object != cached_dep.held_object:
if var_dep and cached_dep.found() and var_dep != cached_dep:
mlog.warning(f'Inconsistency: Subproject has overridden the dependency with another variable than {varname!r}')
def _handle_featurenew_dependencies(self, name: str) -> None:
@ -253,8 +256,8 @@ class DependencyFallbacksHolder(InterpreterObject):
elif name == 'openmp':
FeatureNew.single_use('OpenMP Dependency', '0.46.0', self.subproject)
def _notfound_dependency(self) -> DependencyHolder:
return DependencyHolder(NotFoundDependency(self.environment), self.subproject)
def _notfound_dependency(self) -> NotFoundDependency:
return NotFoundDependency(self.environment)
@staticmethod
def _check_version(wanted: T.Optional[str], found: str) -> bool:
@ -264,7 +267,7 @@ class DependencyFallbacksHolder(InterpreterObject):
return False
return True
def _get_candidates(self) -> T.List[T.Tuple[T.Callable[[TYPE_nkwargs, TYPE_nvar, TYPE_nkwargs], T.Optional[DependencyHolder]], TYPE_nvar, TYPE_nkwargs]]:
def _get_candidates(self) -> T.List[T.Tuple[T.Callable[[TYPE_nkwargs, TYPE_nvar, TYPE_nkwargs], T.Optional[Dependency]], TYPE_nvar, TYPE_nkwargs]]:
candidates = []
# 1. check if any of the names is cached already.
for name in self.names:
@ -281,7 +284,7 @@ class DependencyFallbacksHolder(InterpreterObject):
candidates.append((self._do_subproject, [self.subproject_name], self.subproject_kwargs))
return candidates
def lookup(self, kwargs: TYPE_nkwargs, force_fallback: bool = False) -> DependencyHolder:
def lookup(self, kwargs: TYPE_nkwargs, force_fallback: bool = False) -> Dependency:
self.display_name = self.names[0] if self.names else '(anonymous)'
mods = extract_as_list(kwargs, 'modules')
if mods:
@ -329,7 +332,7 @@ class DependencyFallbacksHolder(InterpreterObject):
func_kwargs['required'] = required and (i == last)
kwargs['required'] = required and (i == last)
dep = func(kwargs, func_args, func_kwargs)
if dep and dep.held_object.found():
if dep and dep.found():
# Override this dependency to have consistent results in subsequent
# dependency lookups.
for name in self.names:
@ -337,7 +340,7 @@ class DependencyFallbacksHolder(InterpreterObject):
identifier = dependencies.get_dep_identifier(name, kwargs)
if identifier not in self.build.dependency_overrides[for_machine]:
self.build.dependency_overrides[for_machine][identifier] = \
build.DependencyOverride(dep.held_object, self.interpreter.current_node, explicit=False)
build.DependencyOverride(dep, self.interpreter.current_node, explicit=False)
return dep
elif required and (dep or i == last):
# This was the last candidate or the dependency has been cached

@ -128,7 +128,6 @@ class Summary:
raise InterpreterException(f'Summary section {section!r} already have key {k!r}')
formatted_values = []
for i in listify(v):
i = unholder(i)
if isinstance(i, bool) and bool_yn:
formatted_values.append(mlog.green('YES') if i else mlog.red('NO'))
elif isinstance(i, (str, int, bool)):
@ -609,20 +608,16 @@ class Interpreter(InterpreterBase, HoldableObject):
if not isinstance(version, str):
raise InterpreterException('Version must be a string.')
incs = self.extract_incdirs(kwargs)
libs = unholder(extract_as_list(kwargs, 'link_with'))
libs_whole = unholder(extract_as_list(kwargs, 'link_whole'))
libs = extract_as_list(kwargs, 'link_with')
libs_whole = extract_as_list(kwargs, 'link_whole')
sources = extract_as_list(kwargs, 'sources')
sources = unholder(listify(self.source_strings_to_files(sources)))
deps = unholder(extract_as_list(kwargs, 'dependencies'))
sources = listify(self.source_strings_to_files(sources))
deps = extract_as_list(kwargs, 'dependencies')
compile_args = mesonlib.stringlistify(kwargs.get('compile_args', []))
link_args = mesonlib.stringlistify(kwargs.get('link_args', []))
variables = self.extract_variables(kwargs, list_new=True)
final_deps = []
for d in deps:
try:
d = d.held_object
except Exception:
pass
if not isinstance(d, (dependencies.Dependency, dependencies.ExternalLibrary, dependencies.InternalDependency)):
raise InterpreterException('Dependencies must be external deps')
final_deps.append(d)
@ -690,17 +685,16 @@ external dependencies (including libraries) must go to "dependencies".''')
m = 'must be a string, or the output of find_program(), files() '\
'or configure_file(), or a compiler object; not {!r}'
expanded_args = []
if isinstance(cmd, ExternalProgramHolder):
cmd = cmd.held_object
if isinstance(cmd, build.Executable):
progname = node.args.arguments[0].value
msg = 'Program {!r} was overridden with the compiled executable {!r}'\
' and therefore cannot be used during configuration'
raise InterpreterException(msg.format(progname, cmd.description()))
if isinstance(cmd, build.Executable):
progname = node.args.arguments[0].value
msg = 'Program {!r} was overridden with the compiled executable {!r}'\
' and therefore cannot be used during configuration'
raise InterpreterException(msg.format(progname, cmd.description()))
if isinstance(cmd, ExternalProgram):
if not cmd.found():
raise InterpreterException(f'command {cmd.get_name()!r} not found or not executable')
elif isinstance(cmd, CompilerHolder):
exelist = cmd.compiler.get_exelist()
elif isinstance(cmd, compilers.Compiler):
exelist = cmd.get_exelist()
cmd = exelist[0]
prog = ExternalProgram(cmd, silent=True)
if not prog.found():
@ -725,8 +719,8 @@ external dependencies (including libraries) must go to "dependencies".''')
expanded_args.append(a)
elif isinstance(a, mesonlib.File):
expanded_args.append(a.absolute_path(srcdir, builddir))
elif isinstance(a, ExternalProgramHolder):
expanded_args.append(a.held_object.get_path())
elif isinstance(a, ExternalProgram):
expanded_args.append(a.get_path())
else:
raise InterpreterException('Arguments ' + m.format(a))
# If any file that was used as an argument to the command
@ -880,7 +874,7 @@ external dependencies (including libraries) must go to "dependencies".''')
prefix = self.coredata.options[OptionKey('prefix')].value
from ..modules.cmake import CMakeSubprojectOptions
options = unholder(kwargs.get('options', CMakeSubprojectOptions()))
options = kwargs.get('options', CMakeSubprojectOptions())
if not isinstance(options, CMakeSubprojectOptions):
raise InterpreterException('"options" kwarg must be CMakeSubprojectOptions'
' object (created by cmake.subproject_options())')
@ -1290,14 +1284,14 @@ external dependencies (including libraries) must go to "dependencies".''')
return success
def program_from_file_for(self, for_machine, prognames):
for p in unholder(prognames):
for p in prognames:
if isinstance(p, mesonlib.File):
continue # Always points to a local (i.e. self generated) file.
if not isinstance(p, str):
raise InterpreterException('Executable name must be a string')
prog = ExternalProgram.from_bin_list(self.environment, for_machine, p)
if prog.found():
return ExternalProgramHolder(prog, self.subproject)
return prog
return None
def program_from_system(self, args, search_dirs, extra_info):
@ -1368,7 +1362,7 @@ external dependencies (including libraries) must go to "dependencies".''')
if progobj is None:
progobj = self.notfound_program(args)
if not progobj.found():
if isinstance(progobj, ExternalProgram) and not progobj.found():
mlog.log('Program', mlog.bold(progobj.get_name()), 'found:', mlog.red('NO'))
if required:
m = 'Program {!r} not found'
@ -1484,7 +1478,7 @@ external dependencies (including libraries) must go to "dependencies".''')
if not_found_message:
self.message_impl([not_found_message])
raise
assert isinstance(d, DependencyHolder)
assert isinstance(d, Dependency)
if not d.found() and not_found_message:
self.message_impl([not_found_message])
self.message_impl([not_found_message])
@ -1653,12 +1647,12 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
if 'command' not in kwargs:
raise InterpreterException('Missing "command" keyword argument')
all_args = extract_as_list(kwargs, 'command')
deps = unholder(extract_as_list(kwargs, 'depends'))
deps = extract_as_list(kwargs, 'depends')
else:
raise InterpreterException('Run_target needs at least one positional argument.')
cleaned_args = []
for i in unholder(listify(all_args)):
for i in listify(all_args):
if not isinstance(i, (str, build.BuildTarget, build.CustomTarget, ExternalProgram, mesonlib.File)):
mlog.debug('Wrong type:', str(i))
raise InterpreterException('Invalid argument to run_target.')
@ -1676,8 +1670,8 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
raise InterpreterException('Depends items must be build targets.')
cleaned_deps.append(d)
env = self.unpack_env_kwarg(kwargs)
tg = RunTargetHolder(build.RunTarget(name, cleaned_args, cleaned_deps, self.subdir, self.subproject, env), self)
self.add_target(name, tg.held_object)
tg = build.RunTarget(name, cleaned_args, cleaned_deps, self.subdir, self.subproject, env)
self.add_target(name, tg)
full_name = (self.subproject, name)
assert(full_name not in self.build.run_target_names)
self.build.run_target_names.add(full_name)
@ -1691,28 +1685,28 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
name = args[0]
if not isinstance(name, str):
raise InterpreterException('First argument must be a string.')
deps = unholder(listify(args[1:]))
deps = listify(args[1:])
for d in deps:
if not isinstance(d, (build.BuildTarget, build.CustomTarget)):
raise InterpreterException('Depends items must be build targets.')
tg = RunTargetHolder(build.AliasTarget(name, deps, self.subdir, self.subproject), self)
self.add_target(name, tg.held_object)
tg = build.AliasTarget(name, deps, self.subdir, self.subproject)
self.add_target(name, tg)
return tg
@permittedKwargs({'arguments', 'output', 'depends', 'depfile', 'capture',
'preserve_path_from'})
@typed_pos_args('generator', (ExecutableHolder, ExternalProgramHolder))
@typed_pos_args('generator', (build.Executable, ExternalProgram))
@typed_kwargs(
'generator',
KwargInfo('arguments', ContainerTypeInfo(list, str, allow_empty=False), required=True, listify=True),
KwargInfo('output', ContainerTypeInfo(list, str, allow_empty=False), required=True, listify=True),
KwargInfo('depfile', str, validator=lambda x: 'Depfile must be a plain filename with a subdirectory' if has_path_sep(x) else None),
KwargInfo('capture', bool, default=False, since='0.43.0'),
KwargInfo('depends', ContainerTypeInfo(list, (BuildTargetHolder, CustomTargetHolder)), default=[], listify=True),
KwargInfo('depends', ContainerTypeInfo(list, (build.BuildTarget, build.CustomTarget)), default=[], listify=True),
)
def func_generator(self, node: mparser.FunctionNode,
args: T.Tuple[T.Union[ExecutableHolder, ExternalProgramHolder]],
kwargs: 'kwargs.FuncGenerator') -> GeneratorHolder:
args: T.Tuple[T.Union[build.Executable, ExternalProgram]],
kwargs: 'kwargs.FuncGenerator') -> build.Generator:
for rule in kwargs['output']:
if '@BASENAME@' not in rule and '@PLAINNAME@' not in rule:
raise InvalidArguments('Every element of "output" must contain @BASENAME@ or @PLAINNAME@.')
@ -1723,12 +1717,9 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
if '@OUTPUT@' in o:
raise InvalidArguments('Tried to use @OUTPUT@ in a rule with more than one output.')
depends = [d.held_object for d in kwargs.pop('depends')]
gen = build.Generator(args[0].held_object, depends=depends, **kwargs)
holder = GeneratorHolder(gen, self)
self.generators.append(holder)
return holder
gen = build.Generator(args[0], **kwargs)
self.generators.append(gen)
return gen
@typed_pos_args('benchmark', str, (ExecutableHolder, JarHolder, ExternalProgramHolder, mesonlib.File))
@typed_kwargs('benchmark', *TEST_KWARGS)
@ -1786,10 +1777,10 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
return Test(name,
prj,
suite,
exe.held_object,
[d.held_object for d in kwargs['depends']],
exe,
kwargs['depends'],
kwargs.get('is_parallel', False),
[c.held_object if isinstance(c, ObjectHolder) else c for c in kwargs['args']],
kwargs['args'],
env,
kwargs['should_fail'],
kwargs['timeout'],
@ -1862,9 +1853,9 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
if self.subdir == '' and args[0].startswith('meson-'):
raise InvalidArguments('The "meson-" prefix is reserved and cannot be used for top-level subdir().')
for i in mesonlib.extract_as_list(kwargs, 'if_found'):
if not hasattr(i, 'found_method'):
if not hasattr(i, 'found'):
raise InterpreterException('Object used in if_found does not have a found method.')
if not i.found_method([], {}):
if not i.found():
return
prev_subdir = self.subdir
subdir = os.path.join(prev_subdir, args[0])
@ -2102,7 +2093,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
os.makedirs(os.path.join(self.environment.build_dir, self.subdir), exist_ok=True)
file_encoding = kwargs.setdefault('encoding', 'utf-8')
missing_variables, confdata_useless = \
mesonlib.do_conf_file(inputs_abs[0], ofile_abs, conf.held_object,
mesonlib.do_conf_file(inputs_abs[0], ofile_abs, conf.conf_data,
fmt, file_encoding)
if missing_variables:
var_list = ", ".join(map(repr, sorted(missing_variables)))
@ -2117,7 +2108,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
'copy a file to the build dir, use the \'copy:\' keyword '
'argument added in 0.47.0'.format(ifbase), location=node)
else:
mesonlib.dump_conf_header(ofile_abs, conf.held_object, output_format)
mesonlib.dump_conf_header(ofile_abs, conf.conf_data, output_format)
conf.mark_used()
elif 'command' in kwargs:
if len(inputs) > 1:
@ -2275,7 +2266,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
if ":" not in setup_name:
setup_name = (self.subproject if self.subproject else self.build.project_name) + ":" + setup_name
try:
inp = unholder(extract_as_list(kwargs, 'exe_wrapper'))
inp = extract_as_list(kwargs, 'exe_wrapper')
exe_wrapper = []
for i in inp:
if isinstance(i, str):
@ -2611,10 +2602,9 @@ Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey
target.project_version = self.project_version
self.add_stdlib_info(target)
l = targetholder(target, self)
self.add_target(name, l.held_object)
self.add_target(name, target)
self.project_args_frozen = True
return l
return target
def kwarg_strings_to_includedirs(self, kwargs):
if 'd_import_dirs' in kwargs:

@ -75,7 +75,6 @@ class MesonMain(MesonInterpreterObject):
script_args = [] # T.List[str]
new = False
for a in args:
a = unholder(a)
if isinstance(a, str):
script_args.append(a)
elif isinstance(a, mesonlib.File):
@ -287,7 +286,6 @@ class MesonMain(MesonInterpreterObject):
name, exe = args
if not isinstance(name, str):
raise InterpreterException('First argument must be a string')
exe = unholder(exe)
if isinstance(exe, mesonlib.File):
abspath = exe.absolute_path(self.interpreter.environment.source_dir,
self.interpreter.environment.build_dir)
@ -307,7 +305,6 @@ class MesonMain(MesonInterpreterObject):
dep = args[1]
if not isinstance(name, str) or not name:
raise InterpreterException('First argument must be a string and cannot be empty')
dep = unholder(dep)
if not isinstance(dep, dependencies.Dependency):
raise InterpreterException('Second argument must be a dependency object')
identifier = dependencies.get_dep_identifier(name, kwargs)

@ -46,6 +46,7 @@ __all__ = [
'ContainerTypeInfo',
'KwargInfo',
'typed_kwargs',
'FeatureCheckBase',
'FeatureNew',
'FeatureDeprecated',
'FeatureNewKwargs',
@ -60,6 +61,7 @@ __all__ = [
'TYPE_elementary',
'TYPE_var',
'TYPE_nvar',
'TYPE_kwargs',
'TYPE_nkwargs',
'TYPE_key_resolver',
]
@ -78,6 +80,7 @@ from .baseobjects import (
TYPE_elementary,
TYPE_var,
TYPE_nvar,
TYPE_kwargs,
TYPE_nkwargs,
TYPE_key_resolver,
)
@ -95,6 +98,7 @@ from .decorators import (
ContainerTypeInfo,
KwargInfo,
typed_kwargs,
FeatureCheckBase,
FeatureNew,
FeatureDeprecated,
FeatureNewKwargs,

@ -131,7 +131,6 @@ __all__ = [
'substitute_values',
'substring_is_in_list',
'typeslistify',
'unholder',
'verbose_git',
'version_compare',
'version_compare_condition_with_min',
@ -1246,26 +1245,6 @@ def replace_if_different(dst: str, dst_tmp: str) -> None:
os.unlink(dst_tmp)
@T.overload
def unholder(item: 'ObjectHolder[_T]') -> _T: ...
@T.overload
def unholder(item: T.List['ObjectHolder[_T]']) -> T.List[_T]: ...
@T.overload
def unholder(item: T.List[_T]) -> T.List[_T]: ...
@T.overload
def unholder(item: T.List[T.Union[_T, 'ObjectHolder[_T]']]) -> T.List[_T]: ...
def unholder(item): # type: ignore # TODO fix overload (somehow)
"""Get the held item of an object holder or list of object holders."""
if isinstance(item, list):
return [i.held_object if hasattr(i, 'held_object') else i for i in item]
if hasattr(item, 'held_object'):
return item.held_object
return item
def listify(item: T.Any, flatten: bool = True) -> T.List[T.Any]:
'''

@ -18,13 +18,12 @@
import os
from .. import build
from ..mesonlib import unholder, relpath
from ..mesonlib import relpath, HoldableObject
import typing as T
if T.TYPE_CHECKING:
from ..interpreter import Interpreter
from ..interpreter.interpreterobjects import IncludeDirsHolder, ExternalProgramHolder
from ..interpreterbase import TYPE_var, TYPE_nvar, TYPE_nkwargs
from ..interpreterbase import TYPE_var, TYPE_kwargs
from ..programs import ExternalProgram
class ModuleState:
@ -61,7 +60,7 @@ class ModuleState:
self.target_machine = interpreter.builtin['target_machine'].held_object
self.current_node = interpreter.current_node
def get_include_args(self, include_dirs: T.Iterable[T.Union[str, 'IncludeDirsHolder']], prefix: str = '-I') -> T.List[str]:
def get_include_args(self, include_dirs: T.Iterable[T.Union[str, build.IncludeDirs]], prefix: str = '-I') -> T.List[str]:
if not include_dirs:
return []
@ -69,7 +68,7 @@ class ModuleState:
builddir = self.environment.get_build_dir()
dirs_str: T.List[str] = []
for dirs in unholder(include_dirs):
for dirs in include_dirs:
if isinstance(dirs, str):
dirs_str += [f'{prefix}{dirs}']
continue
@ -89,14 +88,17 @@ class ModuleState:
def find_program(self, prog: T.Union[str, T.List[str]], required: bool = True,
version_func: T.Optional[T.Callable[['ExternalProgram'], str]] = None,
wanted: T.Optional[str] = None) -> 'ExternalProgramHolder':
wanted: T.Optional[str] = None) -> 'ExternalProgram':
return self._interpreter.find_program_impl(prog, required=required, version_func=version_func, wanted=wanted)
class ModuleObject:
class ModuleObject(HoldableObject):
"""Base class for all objects returned by modules
"""
def __init__(self) -> None:
self.methods = {} # type: T.Dict[str, T.Callable[[ModuleState, T.List[TYPE_nvar], TYPE_nkwargs], T.Union[ModuleReturnValue, TYPE_var]]]
self.methods: T.Dict[
str,
T.Callable[[ModuleState, T.List[TYPE_var], TYPE_kwargs], T.Union[ModuleReturnValue, TYPE_var]]
] = {}
class MutableModuleObject(ModuleObject):
pass

@ -18,9 +18,9 @@ import typing as T
from . import ExtensionModule, ModuleReturnValue, ModuleObject
from .. import build, mesonlib, mlog
from .. import build, mesonlib, mlog, dependencies
from ..cmake import SingleTargetOptions, TargetOptions, cmake_defines_to_args
from ..interpreter import ConfigurationDataHolder, SubprojectHolder, DependencyHolder
from ..interpreter import ConfigurationDataObject, SubprojectHolder
from ..interpreterbase import (
FeatureNew,
FeatureNewKwargs,
@ -32,6 +32,7 @@ from ..interpreterbase import (
noKwargs,
InvalidArguments,
InterpreterException,
)
from ..programs import ExternalProgram
@ -109,11 +110,11 @@ class CMakeSubproject(ModuleObject):
def dependency(self, state, args, kwargs):
info = self._args_to_info(args)
orig = self.get_variable(state, [info['dep']], {})
assert isinstance(orig, DependencyHolder)
actual = orig.include_type_method([], {})
assert isinstance(orig, dependencies.Dependency)
actual = orig.include_type
if 'include_type' in kwargs and kwargs['include_type'] != actual:
mlog.debug('Current include type is {}. Converting to requested {}'.format(actual, kwargs['include_type']))
return orig.as_system_method([kwargs['include_type']], {})
return orig.generate_system_dependency(kwargs['include_type'])
return orig
@noKwargs
@ -351,7 +352,7 @@ class CmakeModule(ExtensionModule):
if 'configuration' not in kwargs:
raise mesonlib.MesonException('"configuration" not specified.')
conf = kwargs['configuration']
if not isinstance(conf, ConfigurationDataHolder):
if not isinstance(conf, ConfigurationDataObject):
raise mesonlib.MesonException('Argument "configuration" is not of type configuration_data')
prefix = state.environment.coredata.get_option(mesonlib.OptionKey('prefix'))
@ -365,7 +366,7 @@ class CmakeModule(ExtensionModule):
extra = PACKAGE_INIT_EXT.replace('@absInstallDir@', abs_install_dir)
extra = extra.replace('@installPrefix@', prefix)
self.create_package_file(ifile_abs, ofile_abs, PACKAGE_RELATIVE_PATH, extra, conf.held_object)
self.create_package_file(ifile_abs, ofile_abs, PACKAGE_RELATIVE_PATH, extra, conf.conf_data)
conf.mark_used()
conffile = os.path.normpath(inputfile.relative_name())
@ -389,7 +390,7 @@ class CmakeModule(ExtensionModule):
raise InterpreterException('"options" cannot be used together with "cmake_options"')
dirname = args[0]
subp = self.interpreter.do_subproject(dirname, 'cmake', kwargs)
if not subp.held_object:
if not subp.found():
return subp
return CMakeSubproject(subp, dirname)

@ -30,7 +30,7 @@ from . import ExtensionModule
from . import ModuleReturnValue
from ..mesonlib import (
MachineChoice, MesonException, OrderedSet, Popen_safe, extract_as_list,
join_args, unholder,
join_args, HoldableObject
)
from ..dependencies import Dependency, PkgConfigDependency, InternalDependency
from ..interpreterbase import noPosargs, noKwargs, permittedKwargs, FeatureNew, FeatureNewKwargs, FeatureDeprecatedKwargs
@ -39,6 +39,7 @@ from ..build import CustomTarget, CustomTargetIndex, GeneratedList
if T.TYPE_CHECKING:
from ..compilers import Compiler
from ..interpreter import Interpreter
# gresource compilation is broken due to the way
# the resource compiler and Ninja clash about it
@ -103,14 +104,13 @@ class GnomeModule(ExtensionModule):
def _get_dep(self, state, depname, native=False, required=True):
kwargs = {'native': native, 'required': required}
holder = self.interpreter.func_dependency(state.current_node, [depname], kwargs)
return holder.held_object
return self.interpreter.func_dependency(state.current_node, [depname], kwargs)
def _get_native_binary(self, state, name, depname, varname, required=True):
# Look in overrides in case glib/gtk/etc are built as subproject
prog = self.interpreter.program_from_overrides([name], [])
if prog is not None:
return unholder(prog)
return prog
# Look in machine file
prog = state.environment.lookup_binary_entry(MachineChoice.HOST, name)
@ -125,7 +125,7 @@ class GnomeModule(ExtensionModule):
return ExternalProgram(name, value)
# Normal program lookup
return unholder(state.find_program(name, required=required))
return state.find_program(name, required=required)
@permittedKwargs({'glib_compile_schemas', 'gio_querymodules', 'gtk_update_icon_cache'})
@noPosargs
@ -179,7 +179,7 @@ class GnomeModule(ExtensionModule):
# Validate dependencies
subdirs = []
depends = []
for (ii, dep) in enumerate(unholder(dependencies)):
for (ii, dep) in enumerate(dependencies):
if isinstance(dep, mesonlib.File):
subdirs.append(dep.subdir)
elif isinstance(dep, (build.CustomTarget, build.CustomTargetIndex)):
@ -323,7 +323,7 @@ class GnomeModule(ExtensionModule):
subdirs = []
for resfile in dep_files[:]:
resbasename = os.path.basename(resfile)
for dep in unholder(dependencies):
for dep in dependencies:
if isinstance(dep, mesonlib.File):
if dep.fname != resbasename:
continue
@ -399,7 +399,7 @@ class GnomeModule(ExtensionModule):
# require two args in order, such as -framework AVFoundation
external_ldflags_nodedup = []
gi_includes = OrderedSet()
deps = mesonlib.unholder(mesonlib.listify(deps))
deps = mesonlib.listify(deps)
for dep in deps:
if isinstance(dep, Dependency):
@ -409,7 +409,7 @@ class GnomeModule(ExtensionModule):
if isinstance(dep, InternalDependency):
cflags.update(dep.get_compile_args())
cflags.update(state.get_include_args(dep.include_directories))
for lib in unholder(dep.libraries):
for lib in dep.libraries:
if isinstance(lib, build.SharedLibrary):
internal_ldflags.update(self._get_link_args(state, lib, depends, include_rpath))
libdepflags = self._get_dependencies_flags(lib.get_external_deps(), state, depends, include_rpath,
@ -426,7 +426,7 @@ class GnomeModule(ExtensionModule):
external_ldflags.update(extdepflags[2])
external_ldflags_nodedup += extdepflags[3]
gi_includes.update(extdepflags[4])
for source in unholder(dep.sources):
for source in dep.sources:
if isinstance(source, GirTarget):
gi_includes.update([os.path.join(state.environment.get_build_dir(),
source.get_subdir())])
@ -480,9 +480,6 @@ class GnomeModule(ExtensionModule):
return cflags, internal_ldflags, external_ldflags, external_ldflags_nodedup, gi_includes
def _unwrap_gir_target(self, girtarget, state):
while hasattr(girtarget, 'held_object'):
girtarget = girtarget.held_object
if not isinstance(girtarget, (build.Executable, build.SharedLibrary,
build.StaticLibrary)):
raise MesonException('Gir target must be an executable or library')
@ -512,8 +509,6 @@ class GnomeModule(ExtensionModule):
@functools.lru_cache(maxsize=None)
def _gir_has_option(self, option) -> bool:
exe = self.giscanner
if hasattr(exe, 'held_object'):
exe = exe.held_object
if isinstance(exe, OverrideProgram):
# Handle overridden g-ir-scanner
assert option in ['--extra-library', '--sources-top-dirs']
@ -539,7 +534,7 @@ class GnomeModule(ExtensionModule):
link_with = mesonlib.extract_as_list(kwargs, 'link_with', pop = True)
for link in link_with:
ret += self._get_link_args(state, link.held_object, depends,
ret += self._get_link_args(state, link, depends,
use_gir_args=True)
return ret
@ -549,7 +544,7 @@ class GnomeModule(ExtensionModule):
if 'includes' in kwargs:
includes = mesonlib.extract_as_list(kwargs, 'includes', pop = True)
for inc in unholder(includes):
for inc in includes:
if isinstance(inc, str):
ret += [f'--include={inc}']
elif isinstance(inc, GirTarget):
@ -605,7 +600,7 @@ class GnomeModule(ExtensionModule):
def _scan_inc_dirs(self, kwargs):
ret = mesonlib.extract_as_list(kwargs, 'include_directories', pop = True)
for incd in ret:
if not isinstance(incd.held_object, (str, build.IncludeDirs)):
if not isinstance(incd, (str, build.IncludeDirs)):
raise MesonException(
'Gir include dirs should be include_directories().')
return ret
@ -708,7 +703,7 @@ class GnomeModule(ExtensionModule):
gir_filelist_filename = os.path.join(gir_filelist_dir, f'{ns}_{nsversion}_gir_filelist')
with open(gir_filelist_filename, 'w', encoding='utf-8') as gir_filelist:
for s in unholder(libsources):
for s in libsources:
if isinstance(s, (build.CustomTarget, build.CustomTargetIndex)):
for custom_output in s.get_outputs():
gir_filelist.write(os.path.join(state.environment.get_build_dir(),
@ -763,11 +758,11 @@ class GnomeModule(ExtensionModule):
# dependencies and also find the include directories needed for the
# typelib generation custom target below.
typelib_includes = []
for dep in unholder(deps):
for dep in deps:
# Add a dependency on each GirTarget listed in dependencies and add
# the directory where it will be generated to the typelib includes
if isinstance(dep, InternalDependency):
for source in unholder(dep.sources):
for source in dep.sources:
if isinstance(source, GirTarget) and source not in depends:
depends.append(source)
subdir = os.path.join(state.environment.get_build_dir(),
@ -846,7 +841,7 @@ class GnomeModule(ExtensionModule):
langs_compilers = self._get_girtargets_langs_compilers(girtargets)
cflags, internal_ldflags, external_ldflags = self._get_langs_compilers_flags(state, langs_compilers)
deps = self._get_gir_targets_deps(girtargets)
deps += mesonlib.unholder(extract_as_list(kwargs, 'dependencies', pop=True))
deps += extract_as_list(kwargs, 'dependencies', pop=True)
deps += [gir_dep]
typelib_includes = self._gather_typelib_includes_and_update_depends(state, deps, depends)
# ldflags will be misinterpreted by gir scanner (showing
@ -898,7 +893,7 @@ class GnomeModule(ExtensionModule):
if fatal_warnings:
scan_command.append('--warn-error')
generated_files = [unholder(f) for f in libsources if isinstance(unholder(f), (GeneratedList, CustomTarget, CustomTargetIndex))]
generated_files = [f for f in libsources if isinstance(f, (GeneratedList, CustomTarget, CustomTargetIndex))]
scan_target = self._make_gir_target(state, girfile, scan_command, generated_files, depends, kwargs)
@ -1044,8 +1039,7 @@ class GnomeModule(ExtensionModule):
src_dirs = mesonlib.extract_as_list(kwargs, 'src_dir')
header_dirs = []
for src_dir in src_dirs:
if hasattr(src_dir, 'held_object'):
src_dir = src_dir.held_object
if isinstance(src_dir, HoldableObject):
if not isinstance(src_dir, build.IncludeDirs):
raise MesonException('Invalid keyword argument for src_dir.')
for inc_dir in src_dir.get_incdirs():
@ -1068,7 +1062,7 @@ class GnomeModule(ExtensionModule):
for tool in ['scan', 'scangobj', 'mkdb', 'mkhtml', 'fixxref']:
program_name = 'gtkdoc-' + tool
program = state.find_program(program_name)
path = program.held_object.get_path()
path = program.get_path()
args.append(f'--{program_name}={path}')
if namespace:
args.append('--namespace=' + namespace)
@ -1082,7 +1076,7 @@ class GnomeModule(ExtensionModule):
depends = []
content_files = []
for s in unholder(mesonlib.extract_as_list(kwargs, 'content_files')):
for s in mesonlib.extract_as_list(kwargs, 'content_files'):
if isinstance(s, (build.CustomTarget, build.CustomTargetIndex)):
depends.append(s)
for o in s.get_outputs():
@ -1134,14 +1128,14 @@ class GnomeModule(ExtensionModule):
def _get_build_args(self, kwargs, state, depends):
args = []
deps = mesonlib.unholder(extract_as_list(kwargs, 'dependencies'))
deps = extract_as_list(kwargs, 'dependencies')
cflags = []
cflags.extend(mesonlib.stringlistify(kwargs.pop('c_args', [])))
deps_cflags, internal_ldflags, external_ldflags, gi_includes = \
self._get_dependencies_flags(deps, state, depends, include_rpath=True)
inc_dirs = mesonlib.extract_as_list(kwargs, 'include_directories')
for incd in inc_dirs:
if not isinstance(incd.held_object, (str, build.IncludeDirs)):
if not isinstance(incd, (str, build.IncludeDirs)):
raise MesonException(
'Gir include dirs should be include_directories().')
@ -1678,7 +1672,7 @@ G_END_DECLS'''
vapi_includes = []
ret = []
remaining_args = []
for arg in unholder(arg_list):
for arg in arg_list:
if isinstance(arg, InternalDependency):
targets = [t for t in arg.sources if isinstance(t, VapiTarget)]
for target in targets:
@ -1752,11 +1746,11 @@ G_END_DECLS'''
for i in inputs:
if isinstance(i, str):
cmd.append(os.path.join(source_dir, i))
elif hasattr(i, 'held_object') and isinstance(i.held_object, GirTarget):
link_with += self._get_vapi_link_with(i.held_object)
elif isinstance(i, GirTarget):
link_with += self._get_vapi_link_with(i)
subdir = os.path.join(state.environment.get_build_dir(),
i.held_object.get_subdir())
gir_file = os.path.join(subdir, i.held_object.get_outputs()[0])
i.get_subdir())
gir_file = os.path.join(subdir, i.get_outputs()[0])
cmd.append(gir_file)
else:
raise MesonException('Input must be a str or GirTarget')
@ -1791,4 +1785,10 @@ G_END_DECLS'''
return ModuleReturnValue(rv, created_values)
def initialize(*args, **kwargs):
return GnomeModule(*args, **kwargs)
mod = GnomeModule(*args, **kwargs)
mod.interpreter.append_holder_map(GResourceTarget, interpreter.CustomTargetHolder)
mod.interpreter.append_holder_map(GResourceHeaderTarget, interpreter.CustomTargetHolder)
mod.interpreter.append_holder_map(GirTarget, interpreter.CustomTargetHolder)
mod.interpreter.append_holder_map(TypelibTarget, interpreter.CustomTargetHolder)
mod.interpreter.append_holder_map(VapiTarget, interpreter.CustomTargetHolder)
return mod

@ -105,7 +105,6 @@ class HotdocTargetBuilder:
self.cmd.extend([option, value])
def check_extra_arg_type(self, arg, value):
value = getattr(value, 'held_object', value)
if isinstance(value, list):
for v in value:
self.check_extra_arg_type(arg, v)
@ -188,7 +187,6 @@ class HotdocTargetBuilder:
def process_dependencies(self, deps):
cflags = set()
for dep in mesonlib.listify(ensure_list(deps)):
dep = getattr(dep, "held_object", dep)
if isinstance(dep, InternalDependency):
inc_args = self.state.get_include_args(dep.include_directories)
cflags.update([self.replace_dirs_in_string(x)
@ -232,7 +230,6 @@ class HotdocTargetBuilder:
def flatten_config_command(self):
cmd = []
for arg in mesonlib.listify(self.cmd, flatten=True):
arg = getattr(arg, 'held_object', arg)
if isinstance(arg, mesonlib.File):
arg = arg.absolute_path(self.state.environment.get_source_dir(),
self.state.environment.get_build_dir())
@ -371,7 +368,7 @@ class HotdocTargetHolder(CustomTargetHolder):
def config_path_method(self, *args, **kwargs):
conf = self.held_object.hotdoc_conf.absolute_path(self.interpreter.environment.source_dir,
self.interpreter.environment.build_dir)
return self.interpreter.holderify(conf)
return conf
class HotdocTarget(build.CustomTarget):
@ -422,7 +419,7 @@ class HotDocModule(ExtensionModule):
project_name = args[0]
builder = HotdocTargetBuilder(project_name, state, self.hotdoc, self.interpreter, kwargs)
target, install_script = builder.make_targets()
targets = [HotdocTargetHolder(target, self.interpreter)]
targets = [target]
if install_script:
targets.append(install_script)
@ -430,4 +427,6 @@ class HotDocModule(ExtensionModule):
def initialize(interpreter):
return HotDocModule(interpreter)
mod = HotDocModule(interpreter)
mod.interpreter.append_holder_map(HotdocTarget, HotdocTargetHolder)
return mod

@ -108,7 +108,8 @@ class I18nModule(ExtensionModule):
kwargs['command'] = command
inputfile = kwargs['input']
if hasattr(inputfile, 'held_object'):
# I have no idea why/how this if isinstance(inputfile, mesonlib.HoldableObject) works / used to work...
if isinstance(inputfile, mesonlib.HoldableObject):
ct = build.CustomTarget(kwargs['output'] + '_merge', state.subdir, state.subproject, kwargs)
else:
if isinstance(inputfile, list):

@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os, types
import os
from pathlib import PurePath
from .. import build
@ -22,7 +22,9 @@ from .. import mesonlib
from .. import mlog
from . import ModuleReturnValue
from . import ExtensionModule
from ..interpreterbase import permittedKwargs, FeatureNew, FeatureNewKwargs
from ..interpreterbase import permittedKwargs, FeatureNew, FeatureNewKwargs, TYPE_var, TYPE_kwargs
import typing as T
already_warned_objs = set()
@ -75,7 +77,7 @@ class DependenciesHelper:
def _process_reqs(self, reqs):
'''Returns string names of requirements'''
processed_reqs = []
for obj in mesonlib.unholder(mesonlib.listify(reqs)):
for obj in mesonlib.listify(reqs):
if not isinstance(obj, str):
FeatureNew.single_use('pkgconfig.generate requirement from non-string object', '0.46.0', self.state.subproject)
if hasattr(obj, 'generated_pc'):
@ -108,14 +110,13 @@ class DependenciesHelper:
def add_cflags(self, cflags):
self.cflags += mesonlib.stringlistify(cflags)
def _process_libs(self, libs, public):
libs = mesonlib.unholder(mesonlib.listify(libs))
def _process_libs(self, libs, public: bool):
libs = mesonlib.listify(libs)
libs = [x.get_preferred_library() if isinstance(x, build.BothLibraries) else x for x in libs]
processed_libs = []
processed_reqs = []
processed_cflags = []
for obj in libs:
shared_library_only = getattr(obj, 'shared_library_only', False)
if hasattr(obj, 'pcdep'):
pcdeps = mesonlib.listify(obj.pcdep)
for d in pcdeps:
@ -488,7 +489,7 @@ class PkgConfigModule(ExtensionModule):
FeatureNew.single_use('pkgconfig.generate implicit version keyword', '0.46.0', state.subproject)
elif len(args) == 1:
FeatureNew.single_use('pkgconfig.generate optional positional argument', '0.46.0', state.subproject)
mainlib = getattr(args[0], 'held_object', args[0])
mainlib = args[0]
if not isinstance(mainlib, (build.StaticLibrary, build.SharedLibrary)):
raise mesonlib.MesonException('Pkgconfig_gen first positional argument must be a library object')
default_name = mainlib.name

@ -101,7 +101,6 @@ class SourceSet(MutableModuleObject):
if_true = args
elif args:
raise InterpreterException('add_all called with both positional and keyword arguments')
if_true = mesonlib.unholder(if_true)
keys, dependencies = self.check_conditions(when)
for s in if_true:
if not isinstance(s, SourceSet):

@ -16,8 +16,7 @@ import typing as T
import re
from ..mesonlib import version_compare
from ..interpreter import CompilerHolder
from ..compilers import CudaCompiler
from ..compilers import CudaCompiler, Compiler
from . import ModuleObject
@ -83,7 +82,7 @@ class CudaModule(ModuleObject):
@permittedKwargs(['detected'])
def nvcc_arch_flags(self, state: 'ModuleState',
args: T.Tuple[T.Union[CompilerHolder, CudaCompiler, str]],
args: T.Tuple[T.Union[Compiler, CudaCompiler, str]],
kwargs: T.Dict[str, T.Any]) -> T.List[str]:
nvcc_arch_args = self._validate_nvcc_arch_args(args, kwargs)
ret = self._nvcc_arch_flags(*nvcc_arch_args)[0]
@ -91,7 +90,7 @@ class CudaModule(ModuleObject):
@permittedKwargs(['detected'])
def nvcc_arch_readable(self, state: 'ModuleState',
args: T.Tuple[T.Union[CompilerHolder, CudaCompiler, str]],
args: T.Tuple[T.Union[Compiler, CudaCompiler, str]],
kwargs: T.Dict[str, T.Any]) -> T.List[str]:
nvcc_arch_args = self._validate_nvcc_arch_args(args, kwargs)
ret = self._nvcc_arch_flags(*nvcc_arch_args)[1]
@ -105,16 +104,12 @@ class CudaModule(ModuleObject):
@staticmethod
def _detected_cc_from_compiler(c):
if isinstance(c, CompilerHolder):
c = c.compiler
if isinstance(c, CudaCompiler):
return c.detected_cc
return ''
@staticmethod
def _version_from_compiler(c):
if isinstance(c, CompilerHolder):
c = c.compiler
if isinstance(c, CudaCompiler):
return c.version
if isinstance(c, str):

@ -109,7 +109,7 @@ class RustModule(ExtensionModule):
```
"""
name = args[0]
base_target: BuildTarget = unholder(args[1])
base_target: BuildTarget = args[1]
if not base_target.uses_rust():
raise InterpreterException('Second positional argument to rustmod.test() must be a rust based target')
extra_args = kwargs['args']
@ -129,7 +129,7 @@ class RustModule(ExtensionModule):
del extra_args[i]
break
dependencies = [d.held_object for d in kwargs['dependencies']]
dependencies = [d for d in kwargs['dependencies']]
# We need to cast here, as currently these don't have protocol in them, but test itself does.
tkwargs = T.cast('_kwargs.FuncTest', kwargs.copy())
@ -168,7 +168,7 @@ class RustModule(ExtensionModule):
header: 'SourceOutputs'
_deps: T.Sequence['SourceOutputs']
try:
header, *_deps = unholder(self.interpreter.source_strings_to_files(listify(kwargs['input'])))
header, *_deps = self.interpreter.source_strings_to_files(listify(kwargs['input']))
except KeyError:
raise InvalidArguments('rustmod.bindgen() `input` argument must have at least one element.')
@ -179,7 +179,7 @@ class RustModule(ExtensionModule):
if not isinstance(output, str):
raise InvalidArguments('rustmod.bindgen() `output` argument must be a string.')
include_dirs: T.List[IncludeDirs] = typeslistify(unholder(listify(kwargs.get('include_directories', []))), IncludeDirs)
include_dirs: T.List[IncludeDirs] = typeslistify(listify(kwargs.get('include_directories', [])), IncludeDirs)
c_args: T.List[str] = stringlistify(listify(kwargs.get('c_args', [])))
bind_args: T.List[str] = stringlistify(listify(kwargs.get('args', [])))
@ -198,8 +198,7 @@ class RustModule(ExtensionModule):
inc_strs.extend([f'-I{x}' for x in i.to_string_list(state.environment.get_source_dir())])
if self._bindgen_bin is None:
# there's some bugs in the interpreter typeing.
self._bindgen_bin = state.find_program('bindgen').held_object
self._bindgen_bin = state.find_program('bindgen')
name: str
if isinstance(header, File):

@ -54,11 +54,11 @@ class SimdModule(ExtensionModule):
for key, value in kwargs.items():
if key not in self.isets and key != 'compiler':
basic_kwargs[key] = value
compiler = kwargs['compiler'].compiler
compiler = kwargs['compiler']
if not isinstance(compiler, compilers.compilers.Compiler):
raise mesonlib.MesonException('Compiler argument must be a compiler object.')
cdata = self.interpreter.func_configuration_data(None, [], {})
conf = cdata.held_object
conf = cdata.conf_data
for iset in self.isets:
if iset not in kwargs:
continue

@ -18,10 +18,9 @@ import re
from .. import mlog
from .. import mesonlib, build
from ..mesonlib import MachineChoice, MesonException, extract_as_list, unholder
from ..mesonlib import MachineChoice, MesonException, extract_as_list
from . import ModuleReturnValue
from . import ExtensionModule
from ..interpreter import CustomTargetHolder
from ..interpreterbase import permittedKwargs, FeatureNewKwargs, flatten
from ..programs import ExternalProgram
@ -86,11 +85,13 @@ class WindowsModule(ExtensionModule):
wrc_depend_files = extract_as_list(kwargs, 'depend_files', pop = True)
wrc_depends = extract_as_list(kwargs, 'depends', pop = True)
for d in wrc_depends:
if isinstance(d, CustomTargetHolder):
extra_args += state.get_include_args([d.outdir_include()])
if isinstance(d, build.CustomTarget):
extra_args += state.get_include_args([
build.IncludeDirs('', [], False, [os.path.join('@BUILD_ROOT@', self.interpreter.backend.get_target_dir(d))])
])
inc_dirs = extract_as_list(kwargs, 'include_directories', pop = True)
for incd in inc_dirs:
if not isinstance(incd.held_object, (str, build.IncludeDirs)):
if not isinstance(incd, (str, build.IncludeDirs)):
raise MesonException('Resource include dirs should be include_directories().')
extra_args += state.get_include_args(inc_dirs)
@ -120,7 +121,6 @@ class WindowsModule(ExtensionModule):
for subsrc in src:
add_target(subsrc)
return
src = unholder(src)
if isinstance(src, str):
name_formatted = src

@ -741,17 +741,6 @@ class InternalTests(unittest.TestCase):
self.assertEqual([holder1, 2], listify([holder1, 2]))
self.assertEqual([holder1, 2, 3], listify([holder1, 2, [3]]))
def test_unholder(self):
unholder = mesonbuild.mesonlib.unholder
holder1 = ObjectHolder(1)
holder3 = ObjectHolder(3)
holders = [holder1, holder3]
self.assertEqual(1, unholder(holder1))
self.assertEqual([1], unholder([holder1]))
self.assertEqual([1, 3], unholder(holders))
def test_extract_as_list(self):
extract = mesonbuild.mesonlib.extract_as_list
# Test sanity

Loading…
Cancel
Save