From 7549a39a174125f46098543413c5ac77ea08c494 Mon Sep 17 00:00:00 2001 From: Alexis Jeandet Date: Tue, 29 Aug 2017 11:20:25 +0200 Subject: [PATCH 1/4] Introduction of listify method. Test on build.py module to see benefits. Signed-off-by: Alexis Jeandet --- mesonbuild/build.py | 93 ++++++++++++++---------------------------- mesonbuild/mesonlib.py | 11 +++++ 2 files changed, 41 insertions(+), 63 deletions(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 5bf2874fd..230a3f903 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -20,7 +20,7 @@ from . import environment from . import dependencies from . import mlog from .mesonlib import File, MesonException -from .mesonlib import flatten, typeslistify, stringlistify, classify_unity_sources +from .mesonlib import flatten, typeslistify, stringlistify, classify_unity_sources, listify from .mesonlib import get_filenames_templates_dict, substitute_values from .environment import for_windows, for_darwin, for_cygwin from .compilers import is_object, clike_langs, sort_clike, lang_suffixes @@ -414,8 +414,7 @@ class BuildTarget(Target): raise InvalidArguments(msg) def process_sourcelist(self, sources): - if not isinstance(sources, list): - sources = [sources] + sources = listify(sources) added_sources = {} # If the same source is defined multiple times, use it only once. for s in sources: # Holder unpacking. Ugly. @@ -528,8 +527,7 @@ class BuildTarget(Target): generated twice, since the output needs to be passed to the ld_args and link_depends. """ - if not isinstance(sources, list): - sources = [sources] + sources = listify(sources) for s in sources: if hasattr(s, 'held_object'): s = s.held_object @@ -551,8 +549,7 @@ class BuildTarget(Target): return self.kwargs def unpack_holder(self, d): - if not isinstance(d, list): - d = [d] + d = listify(d) newd = [] for i in d: if isinstance(i, list): @@ -610,64 +607,42 @@ class BuildTarget(Target): self.copy_kwargs(kwargs) kwargs.get('modules', []) self.need_install = kwargs.get('install', self.need_install) - llist = kwargs.get('link_with', []) - if not isinstance(llist, list): - llist = [llist] + llist = listify(kwargs.get('link_with', [])) for linktarget in llist: # Sorry for this hack. Keyword targets are kept in holders # in kwargs. Unpack here without looking at the exact type. if hasattr(linktarget, "held_object"): linktarget = linktarget.held_object self.link(linktarget) - lwhole = kwargs.get('link_whole', []) - if not isinstance(lwhole, list): - lwhole = [lwhole] + lwhole = listify(kwargs.get('link_whole', [])) for linktarget in lwhole: # Sorry for this hack. Keyword targets are kept in holders # in kwargs. Unpack here without looking at the exact type. if hasattr(linktarget, "held_object"): linktarget = linktarget.held_object self.link_whole(linktarget) - c_pchlist = kwargs.get('c_pch', []) - if not isinstance(c_pchlist, list): - c_pchlist = [c_pchlist] + + c_pchlist, cpp_pchlist, clist, cpplist, cslist, valalist, objclist, objcpplist, fortranlist, rustlist = \ + listify(kwargs.get('c_pch', []), + kwargs.get('cpp_pch', []), + kwargs.get('c_args', []), + kwargs.get('cpp_args', []), + kwargs.get('cs_args', []), + kwargs.get('vala_args', []), + kwargs.get('objc_args', []), + kwargs.get('objcpp_args', []), + kwargs.get('fortran_args', []), + kwargs.get('rust_args', []) + ) + self.add_pch('c', c_pchlist) - cpp_pchlist = kwargs.get('cpp_pch', []) - if not isinstance(cpp_pchlist, list): - cpp_pchlist = [cpp_pchlist] self.add_pch('cpp', cpp_pchlist) - clist = kwargs.get('c_args', []) - if not isinstance(clist, list): - clist = [clist] - self.add_compiler_args('c', clist) - cpplist = kwargs.get('cpp_args', []) - if not isinstance(cpplist, list): - cpplist = [cpplist] - self.add_compiler_args('cpp', cpplist) - cslist = kwargs.get('cs_args', []) - if not isinstance(cslist, list): - cslist = [cslist] - self.add_compiler_args('cs', cslist) - valalist = kwargs.get('vala_args', []) - if not isinstance(valalist, list): - valalist = [valalist] - self.add_compiler_args('vala', valalist) - objclist = kwargs.get('objc_args', []) - if not isinstance(objclist, list): - objclist = [objclist] - self.add_compiler_args('objc', objclist) - objcpplist = kwargs.get('objcpp_args', []) - if not isinstance(objcpplist, list): - objcpplist = [objcpplist] - self.add_compiler_args('objcpp', objcpplist) - fortranlist = kwargs.get('fortran_args', []) - if not isinstance(fortranlist, list): - fortranlist = [fortranlist] - self.add_compiler_args('fortran', fortranlist) - rustlist = kwargs.get('rust_args', []) - if not isinstance(rustlist, list): - rustlist = [rustlist] - self.add_compiler_args('rust', rustlist) + compiler_args = {'c':clist, 'cpp':cpplist, 'cs':cslist, 'vala':valalist, 'objc':objclist, 'objcpp':objclist, + 'fortran':fortranlist, 'rust':rustlist + } + for key,value in compiler_args.items(): + self.add_compiler_args(key,value) + if not isinstance(self, Executable): self.vala_header = kwargs.get('vala_header', self.name + '.h') self.vala_vapi = kwargs.get('vala_vapi', self.name + '.vapi') @@ -700,14 +675,10 @@ This will become a hard error in a future Meson release.''') self.process_link_depends(kwargs.get('link_depends', []), environment) # Target-specific include dirs must be added BEFORE include dirs from # internal deps (added inside self.add_deps()) to override them. - inclist = kwargs.get('include_directories', []) - if not isinstance(inclist, list): - inclist = [inclist] + inclist = listify(kwargs.get('include_directories', [])) self.add_include_dirs(inclist) # Add dependencies (which also have include_directories) - deplist = kwargs.get('dependencies', []) - if not isinstance(deplist, list): - deplist = [deplist] + deplist = listify(kwargs.get('dependencies', [])) self.add_deps(deplist) # If an item in this list is False, the output corresponding to # the list index of that item will not be installed @@ -723,9 +694,7 @@ This will become a hard error in a future Meson release.''') raise InvalidArguments('Argument gui_app must be boolean.') elif 'gui_app' in kwargs: raise InvalidArguments('Argument gui_app can only be used on executables.') - extra_files = kwargs.get('extra_files', []) - if not isinstance(extra_files, list): - extra_files = [extra_files] + extra_files = listify(kwargs.get('extra_files', [])) for i in extra_files: assert(isinstance(i, File)) trial = os.path.join(environment.get_source_dir(), i.subdir, i.fname) @@ -738,9 +707,7 @@ This will become a hard error in a future Meson release.''') self.build_rpath = kwargs.get('build_rpath', '') if not isinstance(self.build_rpath, str): raise InvalidArguments('Build_rpath is not a string.') - resources = kwargs.get('resources', []) - if not isinstance(resources, list): - resources = [resources] + resources = listify(kwargs.get('resources', [])) for r in resources: if not isinstance(r, str): raise InvalidArguments('Resource argument is not a string.') diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index d03e5a244..1268b0035 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -473,6 +473,17 @@ def replace_if_different(dst, dst_tmp): else: os.unlink(dst_tmp) + +def listify(*args): + ''' + Returns a list with all args embedded in a list if they are not of type list. + This function preserve order. + ''' + if len(args) == 1: # Special case with one single arg + return args[0] if type(args[0]) is list else [args[0]] + return [item if type(item) is list else [item] for item in args] + + def typeslistify(item, types): ''' Ensure that type(@item) is one of @types or a From 55975f852e502137e3d78d6af204f1bc58a98551 Mon Sep 17 00:00:00 2001 From: Alexis Jeandet Date: Tue, 29 Aug 2017 18:36:40 +0200 Subject: [PATCH 2/4] Introduced extract_as_list. Corrected code style and typo. Signed-off-by: Alexis Jeandet --- mesonbuild/build.py | 39 +++++++++++++++------------------------ mesonbuild/mesonlib.py | 9 ++++++++- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 230a3f903..99827423c 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -19,8 +19,8 @@ import itertools from . import environment from . import dependencies from . import mlog -from .mesonlib import File, MesonException -from .mesonlib import flatten, typeslistify, stringlistify, classify_unity_sources, listify +from .mesonlib import File, MesonException, listify, extract_as_list +from .mesonlib import flatten, typeslistify, stringlistify, classify_unity_sources from .mesonlib import get_filenames_templates_dict, substitute_values from .environment import for_windows, for_darwin, for_cygwin from .compilers import is_object, clike_langs, sort_clike, lang_suffixes @@ -607,14 +607,14 @@ class BuildTarget(Target): self.copy_kwargs(kwargs) kwargs.get('modules', []) self.need_install = kwargs.get('install', self.need_install) - llist = listify(kwargs.get('link_with', [])) + llist = extract_as_list(kwargs, 'link_with') for linktarget in llist: # Sorry for this hack. Keyword targets are kept in holders # in kwargs. Unpack here without looking at the exact type. if hasattr(linktarget, "held_object"): linktarget = linktarget.held_object self.link(linktarget) - lwhole = listify(kwargs.get('link_whole', [])) + lwhole = extract_as_list(kwargs, 'link_whole') for linktarget in lwhole: # Sorry for this hack. Keyword targets are kept in holders # in kwargs. Unpack here without looking at the exact type. @@ -622,26 +622,17 @@ class BuildTarget(Target): linktarget = linktarget.held_object self.link_whole(linktarget) - c_pchlist, cpp_pchlist, clist, cpplist, cslist, valalist, objclist, objcpplist, fortranlist, rustlist = \ - listify(kwargs.get('c_pch', []), - kwargs.get('cpp_pch', []), - kwargs.get('c_args', []), - kwargs.get('cpp_args', []), - kwargs.get('cs_args', []), - kwargs.get('vala_args', []), - kwargs.get('objc_args', []), - kwargs.get('objcpp_args', []), - kwargs.get('fortran_args', []), - kwargs.get('rust_args', []) - ) + c_pchlist, cpp_pchlist, clist, cpplist, cslist, valalist, objclist, objcpplist, fortranlist, rustlist \ + = extract_as_list(kwargs, 'c_pch', 'cpp_pch', 'c_args', 'cpp_args', 'cs_args', 'vala_args', 'objc_args', + 'objcpp_args', 'fortran_args', 'rust_args') self.add_pch('c', c_pchlist) self.add_pch('cpp', cpp_pchlist) - compiler_args = {'c':clist, 'cpp':cpplist, 'cs':cslist, 'vala':valalist, 'objc':objclist, 'objcpp':objclist, - 'fortran':fortranlist, 'rust':rustlist + compiler_args = {'c': clist, 'cpp': cpplist, 'cs': cslist, 'vala': valalist, 'objc': objclist, 'objcpp': objcpplist, + 'fortran': fortranlist, 'rust': rustlist } - for key,value in compiler_args.items(): - self.add_compiler_args(key,value) + for key, value in compiler_args.items(): + self.add_compiler_args(key, value) if not isinstance(self, Executable): self.vala_header = kwargs.get('vala_header', self.name + '.h') @@ -675,10 +666,10 @@ This will become a hard error in a future Meson release.''') self.process_link_depends(kwargs.get('link_depends', []), environment) # Target-specific include dirs must be added BEFORE include dirs from # internal deps (added inside self.add_deps()) to override them. - inclist = listify(kwargs.get('include_directories', [])) + inclist = extract_as_list(kwargs, 'include_directories') self.add_include_dirs(inclist) # Add dependencies (which also have include_directories) - deplist = listify(kwargs.get('dependencies', [])) + deplist = extract_as_list(kwargs, 'dependencies') self.add_deps(deplist) # If an item in this list is False, the output corresponding to # the list index of that item will not be installed @@ -694,7 +685,7 @@ This will become a hard error in a future Meson release.''') raise InvalidArguments('Argument gui_app must be boolean.') elif 'gui_app' in kwargs: raise InvalidArguments('Argument gui_app can only be used on executables.') - extra_files = listify(kwargs.get('extra_files', [])) + extra_files = extract_as_list(kwargs, 'extra_files') for i in extra_files: assert(isinstance(i, File)) trial = os.path.join(environment.get_source_dir(), i.subdir, i.fname) @@ -707,7 +698,7 @@ This will become a hard error in a future Meson release.''') self.build_rpath = kwargs.get('build_rpath', '') if not isinstance(self.build_rpath, str): raise InvalidArguments('Build_rpath is not a string.') - resources = listify(kwargs.get('resources', [])) + resources = extract_as_list(kwargs, 'resources') for r in resources: if not isinstance(r, str): raise InvalidArguments('Resource argument is not a string.') diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 1268b0035..7f1651263 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -477,13 +477,20 @@ def replace_if_different(dst, dst_tmp): def listify(*args): ''' Returns a list with all args embedded in a list if they are not of type list. - This function preserve order. + This function preserves order. ''' if len(args) == 1: # Special case with one single arg return args[0] if type(args[0]) is list else [args[0]] return [item if type(item) is list else [item] for item in args] +def extract_as_list(dict_object, *keys): + ''' + Extracts all values from given dict_object and listifies them. + ''' + return listify(*[dict_object.get(key, []) for key in keys]) + + def typeslistify(item, types): ''' Ensure that type(@item) is one of @types or a From bf64cf569b6ecf90db0f2bb181edb8f0ff0c9a3b Mon Sep 17 00:00:00 2001 From: Alexis Jeandet Date: Tue, 29 Aug 2017 22:21:11 +0200 Subject: [PATCH 3/4] Gnome, pkgconfig, Qt4, Qt5 and windows modules slightly refactored. Signed-off-by: Alexis Jeandet --- mesonbuild/mesonlib.py | 4 ++- mesonbuild/modules/gnome.py | 61 ++++++++++----------------------- mesonbuild/modules/pkgconfig.py | 3 +- mesonbuild/modules/qt4.py | 19 ++-------- mesonbuild/modules/qt5.py | 19 ++-------- mesonbuild/modules/windows.py | 6 ++-- 6 files changed, 30 insertions(+), 82 deletions(-) diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 7f1651263..b5a63189c 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -484,10 +484,12 @@ def listify(*args): return [item if type(item) is list else [item] for item in args] -def extract_as_list(dict_object, *keys): +def extract_as_list(dict_object, *keys, pop = False): ''' Extracts all values from given dict_object and listifies them. ''' + if pop: + return listify(*[dict_object.pop(key, []) for key in keys]) return listify(*[dict_object.get(key, []) for key in keys]) diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index fcdd1938c..972c8f0c0 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -98,17 +98,12 @@ class GnomeModule(ExtensionModule): cmd = ['glib-compile-resources', '@INPUT@'] - source_dirs = kwargs.pop('source_dir', []) - if not isinstance(source_dirs, list): - source_dirs = [source_dirs] + source_dirs, dependencies = mesonlib.extract_as_list(kwargs, 'source_dir', 'dependencies', pop=True) if len(args) < 2: raise MesonException('Not enough arguments; the name of the resource ' 'and the path to the XML file are required') - dependencies = kwargs.pop('dependencies', []) - if not isinstance(dependencies, list): - dependencies = [dependencies] # Validate dependencies for (ii, dep) in enumerate(dependencies): if hasattr(dep, 'held_object'): @@ -328,8 +323,7 @@ class GnomeModule(ExtensionModule): cflags = OrderedSet() ldflags = OrderedSet() gi_includes = OrderedSet() - if not isinstance(deps, list): - deps = [deps] + deps = mesonlib.listify(deps) for dep in deps: if hasattr(dep, 'held_object'): @@ -464,17 +458,14 @@ class GnomeModule(ExtensionModule): scan_command += ['--filelist=' + gir_filelist_filename] if 'link_with' in kwargs: - link_with = kwargs.pop('link_with') - if not isinstance(link_with, list): - link_with = [link_with] + link_with = mesonlib.extract_as_list(kwargs, 'link_with', pop = True) + for link in link_with: scan_command += self._get_link_args(state, link.held_object, depends, use_gir_args=True) if 'includes' in kwargs: - includes = kwargs.pop('includes') - if not isinstance(includes, list): - includes = [includes] + includes = mesonlib.extract_as_list(kwargs, 'includes', pop = True) for inc in includes: if hasattr(inc, 'held_object'): inc = inc.held_object @@ -515,17 +506,17 @@ class GnomeModule(ExtensionModule): # FIXME: Linking directly to libasan is not recommended but g-ir-scanner # does not understand -f LDFLAGS. https://bugzilla.gnome.org/show_bug.cgi?id=783892 # ldflags += compilers.sanitizer_link_args(sanitize) - if kwargs.get('symbol_prefix'): + if 'symbol_prefix' in kwargs: sym_prefix = kwargs.pop('symbol_prefix') if not isinstance(sym_prefix, str): raise MesonException('Gir symbol prefix must be str') scan_command += ['--symbol-prefix=%s' % sym_prefix] - if kwargs.get('identifier_prefix'): + if 'identifier_prefix' in kwargs: identifier_prefix = kwargs.pop('identifier_prefix') if not isinstance(identifier_prefix, str): raise MesonException('Gir identifier prefix must be str') scan_command += ['--identifier-prefix=%s' % identifier_prefix] - if kwargs.get('export_packages'): + if 'export_packages' in kwargs: pkgs = kwargs.pop('export_packages') if isinstance(pkgs, str): scan_command += ['--pkg-export=%s' % pkgs] @@ -534,9 +525,7 @@ class GnomeModule(ExtensionModule): else: raise MesonException('Gir export packages must be str or list') - deps = kwargs.pop('dependencies', []) - if not isinstance(deps, list): - deps = [deps] + deps = mesonlib.extract_as_list(kwargs, 'dependencies', pop = True) deps = (girtarget.get_all_link_deps() + girtarget.get_external_deps() + deps) # Need to recursively add deps on GirTarget sources from our @@ -593,9 +582,7 @@ class GnomeModule(ExtensionModule): for i in gi_includes: scan_command += ['--add-include-path=%s' % i] - inc_dirs = kwargs.pop('include_directories', []) - if not isinstance(inc_dirs, list): - inc_dirs = [inc_dirs] + inc_dirs = mesonlib.extract_as_list(kwargs, 'include_directories', pop = True) for incd in inc_dirs: if not isinstance(incd.held_object, (str, build.IncludeDirs)): raise MesonException( @@ -618,7 +605,7 @@ class GnomeModule(ExtensionModule): scankwargs = {'output': girfile, 'command': scan_command, 'depends': depends} - if kwargs.get('install'): + if 'install' in kwargs: scankwargs['install'] = kwargs['install'] scankwargs['install_dir'] = kwargs.get('install_dir_gir', os.path.join(state.environment.get_datadir(), 'gir-1.0')) @@ -636,7 +623,7 @@ class GnomeModule(ExtensionModule): 'output': typelib_output, 'command': typelib_cmd, } - if kwargs.get('install'): + if 'install' in kwargs: typelib_kwargs['install'] = kwargs['install'] typelib_kwargs['install_dir'] = kwargs.get('install_dir_typelib', os.path.join(state.environment.get_libdir(), 'girepository-1.0')) @@ -759,9 +746,7 @@ This will become a hard error in the future.''') if mode not in VALID_MODES: raise MesonException('gtkdoc: Mode {} is not a valid mode: {}'.format(mode, VALID_MODES)) - src_dirs = kwargs['src_dir'] - if not isinstance(src_dirs, list): - src_dirs = [src_dirs] + src_dirs = mesonlib.extract_as_list(kwargs, 'src_dir') header_dirs = [] for src_dir in src_dirs: if hasattr(src_dir, 'held_object'): @@ -806,9 +791,7 @@ This will become a hard error in the future.''') def _get_build_args(self, kwargs, state): args = [] cflags, ldflags, gi_includes = self._get_dependencies_flags(kwargs.get('dependencies', []), state, include_rpath=True) - inc_dirs = kwargs.get('include_directories', []) - if not isinstance(inc_dirs, list): - inc_dirs = [inc_dirs] + inc_dirs = mesonlib.extract_as_list(kwargs, 'include_directories') for incd in inc_dirs: if not isinstance(incd.held_object, (str, build.IncludeDirs)): raise MesonException( @@ -839,9 +822,7 @@ This will become a hard error in the future.''') if kwarg_name not in kwargs: return [] - new_args = kwargs[kwarg_name] - if not isinstance(new_args, list): - new_args = [new_args] + new_args = mesonlib.extract_as_list(kwargs, kwarg_name) args = [] for i in new_args: if expend_file_state and isinstance(i, mesonlib.File): @@ -1200,12 +1181,8 @@ G_END_DECLS''' @staticmethod def _vapi_args_to_command(prefix, variable, kwargs, accept_vapi=False): - arg_list = kwargs.get(variable) - if not arg_list: - return [] + arg_list = mesonlib.extract_as_list(kwargs, variable) ret = [] - if not isinstance(arg_list, list): - arg_list = [arg_list] for arg in arg_list: if not isinstance(arg, str): types = 'strings' + ' or InternalDependencys' if accept_vapi else '' @@ -1300,12 +1277,10 @@ G_END_DECLS''' cmd += pkg_cmd cmd += ['--metadatadir=' + source_dir] - inputs = kwargs.get('sources') - if not inputs: + if 'sources' not in kwargs: raise MesonException('sources are required to generate the vapi file') - if not isinstance(inputs, list): - inputs = [inputs] + inputs = mesonlib.extract_as_list(kwargs, 'sources') link_with = [] for i in inputs: diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py index a7a35d5e8..824ba786b 100644 --- a/mesonbuild/modules/pkgconfig.py +++ b/mesonbuild/modules/pkgconfig.py @@ -108,8 +108,7 @@ class PkgConfigModule(ExtensionModule): ofile.write('\n') def process_libs(self, libs): - if not isinstance(libs, list): - libs = [libs] + libs = mesonlib.listify(libs) processed_libs = [] for l in libs: if hasattr(l, 'held_object'): diff --git a/mesonbuild/modules/qt4.py b/mesonbuild/modules/qt4.py index 4056b6d49..37e630b33 100644 --- a/mesonbuild/modules/qt4.py +++ b/mesonbuild/modules/qt4.py @@ -15,7 +15,7 @@ import os from .. import mlog from .. import build -from ..mesonlib import MesonException, Popen_safe +from ..mesonlib import MesonException, Popen_safe, extract_as_list from ..dependencies import Qt4Dependency from . import ExtensionModule import xml.etree.ElementTree as ET @@ -99,21 +99,8 @@ class Qt4Module(ExtensionModule): @permittedKwargs({'moc_headers', 'moc_sources', 'ui_files', 'qresources', 'method'}) def preprocess(self, state, args, kwargs): - rcc_files = kwargs.pop('qresources', []) - if not isinstance(rcc_files, list): - rcc_files = [rcc_files] - ui_files = kwargs.pop('ui_files', []) - if not isinstance(ui_files, list): - ui_files = [ui_files] - moc_headers = kwargs.pop('moc_headers', []) - if not isinstance(moc_headers, list): - moc_headers = [moc_headers] - moc_sources = kwargs.pop('moc_sources', []) - if not isinstance(moc_sources, list): - moc_sources = [moc_sources] - sources = kwargs.pop('sources', []) - if not isinstance(sources, list): - sources = [sources] + rcc_files, ui_files, moc_headers, moc_sources, sources \ + = extract_as_list(kwargs, 'qresources', 'ui_files', 'moc_headers', 'moc_sources', 'sources', pop = True) sources += args[1:] method = kwargs.get('method', 'auto') self._detect_tools(state.environment, method) diff --git a/mesonbuild/modules/qt5.py b/mesonbuild/modules/qt5.py index 6194a2372..ef3d52fdc 100644 --- a/mesonbuild/modules/qt5.py +++ b/mesonbuild/modules/qt5.py @@ -15,7 +15,7 @@ import os from .. import mlog from .. import build -from ..mesonlib import MesonException, Popen_safe +from ..mesonlib import MesonException, Popen_safe, extract_as_list from ..dependencies import Qt5Dependency from . import ExtensionModule import xml.etree.ElementTree as ET @@ -105,21 +105,8 @@ class Qt5Module(ExtensionModule): @permittedKwargs({'moc_headers', 'moc_sources', 'ui_files', 'qresources', 'method'}) def preprocess(self, state, args, kwargs): - rcc_files = kwargs.pop('qresources', []) - if not isinstance(rcc_files, list): - rcc_files = [rcc_files] - ui_files = kwargs.pop('ui_files', []) - if not isinstance(ui_files, list): - ui_files = [ui_files] - moc_headers = kwargs.pop('moc_headers', []) - if not isinstance(moc_headers, list): - moc_headers = [moc_headers] - moc_sources = kwargs.pop('moc_sources', []) - if not isinstance(moc_sources, list): - moc_sources = [moc_sources] - sources = kwargs.pop('sources', []) - if not isinstance(sources, list): - sources = [sources] + rcc_files, ui_files, moc_headers, moc_sources, sources \ + = extract_as_list(kwargs, 'qresources', 'ui_files', 'moc_headers', 'moc_sources', 'sources', pop = True) sources += args[1:] method = kwargs.get('method', 'auto') self._detect_tools(state.environment, method) diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py index 6fef5bba6..ab215dc39 100644 --- a/mesonbuild/modules/windows.py +++ b/mesonbuild/modules/windows.py @@ -16,7 +16,7 @@ import os from .. import mlog from .. import mesonlib, dependencies, build -from ..mesonlib import MesonException +from ..mesonlib import MesonException, extract_as_list from . import get_include_args from . import ModuleReturnValue from . import ExtensionModule @@ -35,9 +35,7 @@ class WindowsModule(ExtensionModule): comp = self.detect_compiler(state.compilers) extra_args = mesonlib.stringlistify(kwargs.get('args', [])) - inc_dirs = kwargs.pop('include_directories', []) - if not isinstance(inc_dirs, list): - inc_dirs = [inc_dirs] + inc_dirs = extract_as_list(kwargs, 'include_directories', pop = True) for incd in inc_dirs: if not isinstance(incd.held_object, (str, build.IncludeDirs)): raise MesonException('Resource include dirs should be include_directories().') From e553d0807bad5db8290e26954ce7634bc0e181fd Mon Sep 17 00:00:00 2001 From: Alexis Jeandet Date: Mon, 18 Sep 2017 22:19:12 +0200 Subject: [PATCH 4/4] Last round with listify function refactoring. Signed-off-by: Alexis Jeandet --- mesonbuild/build.py | 24 +++------- mesonbuild/compilers/c.py | 5 +-- mesonbuild/dependencies/base.py | 7 +-- mesonbuild/dependencies/misc.py | 6 +-- mesonbuild/dependencies/ui.py | 9 ++-- mesonbuild/interpreter.py | 70 +++++++++-------------------- mesonbuild/modules/gnome.py | 4 +- mesonbuild/modules/unstable_simd.py | 4 +- 8 files changed, 37 insertions(+), 92 deletions(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 99827423c..281b060bb 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -787,8 +787,7 @@ This will become a hard error in a future Meson release.''') return self.include_dirs def add_deps(self, deps): - if not isinstance(deps, list): - deps = [deps] + deps = listify(deps) for dep in deps: if hasattr(dep, 'held_object'): dep = dep.held_object @@ -1016,9 +1015,7 @@ class Generator: self.arglist = args if 'output' not in kwargs: raise InvalidArguments('Generator must have "output" keyword argument.') - outputs = kwargs['output'] - if not isinstance(outputs, list): - outputs = [outputs] + outputs = listify(kwargs['output']) for rule in outputs: if not isinstance(rule, str): raise InvalidArguments('"output" may only contain strings.') @@ -1514,8 +1511,7 @@ class CustomTarget(Target): return deps def flatten_command(self, cmd): - if not isinstance(cmd, list): - cmd = [cmd] + cmd = listify(cmd) final_cmd = [] for c in cmd: if hasattr(c, 'held_object'): @@ -1550,9 +1546,7 @@ class CustomTarget(Target): self.sources.append(s) if 'output' not in kwargs: raise InvalidArguments('Missing keyword argument "output".') - self.outputs = kwargs['output'] - if not isinstance(self.outputs, list): - self.outputs = [self.outputs] + self.outputs = listify(kwargs['output']) # This will substitute values from the input into output and return it. inputs = get_sources_string_names(self.sources) values = get_filenames_templates_dict(inputs, []) @@ -1606,18 +1600,13 @@ class CustomTarget(Target): self.build_always = kwargs.get('build_always', False) if not isinstance(self.build_always, bool): raise InvalidArguments('Argument build_always must be a boolean.') - extra_deps = kwargs.get('depends', []) - if not isinstance(extra_deps, list): - extra_deps = [extra_deps] + extra_deps, depend_files = extract_as_list(kwargs, 'depends', 'depend_files', pop = False) for ed in extra_deps: while hasattr(ed, 'held_object'): ed = ed.held_object if not isinstance(ed, (CustomTarget, BuildTarget)): raise InvalidArguments('Can only depend on toplevel targets: custom_target or build_target (executable or a library)') self.extra_depends.append(ed) - depend_files = kwargs.get('depend_files', []) - if not isinstance(depend_files, list): - depend_files = [depend_files] for i in depend_files: if isinstance(i, (File, str)): self.depend_files.append(i) @@ -1767,8 +1756,7 @@ class Data: self.sources = sources self.install_dir = install_dir self.install_mode = install_mode - if not isinstance(self.sources, list): - self.sources = [self.sources] + self.sources = listify(self.sources) for s in self.sources: assert(isinstance(s, File)) diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index ec1613497..255a50637 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -16,7 +16,7 @@ import subprocess, os.path, tempfile from .. import mlog from .. import coredata -from ..mesonlib import EnvironmentException, version_compare, Popen_safe +from ..mesonlib import EnvironmentException, version_compare, Popen_safe, listify from .compilers import ( GCC_MINGW, @@ -1013,8 +1013,7 @@ class VisualStudioCCompiler(CCompiler): def get_link_whole_for(self, args): # Only since VS2015 - if not isinstance(args, list): - args = [args] + args = listify(args) return ['/WHOLEARCHIVE:' + x for x in args] def get_instruction_set_args(self, instruction_set): diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index cc4837ad7..7c7f986f0 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -23,7 +23,7 @@ from enum import Enum from .. import mlog from .. import mesonlib -from ..mesonlib import MesonException, Popen_safe, flatten, version_compare_many +from ..mesonlib import MesonException, Popen_safe, flatten, version_compare_many, listify # These must be defined in this file to avoid cyclical references. @@ -374,10 +374,7 @@ class ExternalProgram: def __init__(self, name, command=None, silent=False, search_dir=None): self.name = name if command is not None: - if not isinstance(command, list): - self.command = [command] - else: - self.command = command + self.command = listify(command) else: self.command = self._search(name, search_dir) if not silent: diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 12e0239dc..c0ac5a801 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -24,7 +24,7 @@ import sysconfig from .. import mlog from .. import mesonlib -from ..mesonlib import Popen_safe +from ..mesonlib import Popen_safe, extract_as_list from ..environment import detect_cpu_family from .base import DependencyException, DependencyMethods @@ -132,9 +132,7 @@ class BoostDependency(ExternalDependency): return args def get_requested(self, kwargs): - candidates = kwargs.get('modules', []) - if not isinstance(candidates, list): - candidates = [candidates] + candidates = extract_as_list(kwargs, 'modules') for c in candidates: if not isinstance(c, str): raise DependencyException('Boost module argument is not a string.') diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py index 99e017b38..8f183e54d 100644 --- a/mesonbuild/dependencies/ui.py +++ b/mesonbuild/dependencies/ui.py @@ -23,7 +23,7 @@ from collections import OrderedDict from .. import mlog from .. import mesonlib -from ..mesonlib import MesonException, Popen_safe, version_compare +from ..mesonlib import MesonException, Popen_safe, version_compare, extract_as_list from ..environment import for_windows, detect_cpu from .base import DependencyException, DependencyMethods @@ -468,12 +468,9 @@ class WxDependency(ExternalDependency): self.link_args = out.split() def get_requested(self, kwargs): - modules = 'modules' - if modules not in kwargs: + if 'modules' not in kwargs: return [] - candidates = kwargs[modules] - if not isinstance(candidates, list): - candidates = [candidates] + candidates = extract_as_list(kwargs, 'modules') for c in candidates: if not isinstance(c, str): raise DependencyException('wxwidgets module argument is not a string') diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index fc0e4eef0..6e37dc2c9 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -21,7 +21,7 @@ from . import optinterpreter from . import compilers from .wrap import wrap, WrapMode from . import mesonlib -from .mesonlib import FileMode, Popen_safe +from .mesonlib import FileMode, Popen_safe, listify, extract_as_list from .dependencies import ExternalProgram from .dependencies import InternalDependency, Dependency, DependencyException from .interpreterbase import InterpreterBase @@ -264,8 +264,7 @@ class DependencyHolder(InterpreterObject): return self.held_object.get_version() def pkgconfig_method(self, args, kwargs): - if not isinstance(args, list): - args = [args] + args = listify(args) if len(args) != 1: raise InterpreterException('get_pkgconfig_variable takes exactly one argument.') varname = args[0] @@ -669,9 +668,7 @@ class CompilerHolder(InterpreterObject): if not isinstance(nobuiltins, bool): raise InterpreterException('Type of no_builtin_args not a boolean.') args = [] - incdirs = kwargs.get('include_directories', []) - if not isinstance(incdirs, list): - incdirs = [incdirs] + incdirs = extract_as_list(kwargs, 'include_directories') for i in incdirs: if not isinstance(i, IncludeDirsHolder): raise InterpreterException('Include directories argument must be an include_directories object.') @@ -688,8 +685,7 @@ class CompilerHolder(InterpreterObject): def determine_dependencies(self, kwargs): deps = kwargs.get('dependencies', None) if deps is not None: - if not isinstance(deps, list): - deps = [deps] + deps = listify(deps) final_deps = [] for d in deps: try: @@ -1460,8 +1456,7 @@ class Interpreter(InterpreterBase): raise InterpreterException('Module returned a value of unknown type.') def process_new_values(self, invalues): - if not isinstance(invalues, list): - invalues = [invalues] + invalues = listify(invalues) for v in invalues: if isinstance(v, (build.BuildTarget, build.CustomTarget, build.RunTarget)): self.add_target(v.name, v) @@ -1541,19 +1536,12 @@ class Interpreter(InterpreterBase): version = kwargs.get('version', self.project_version) if not isinstance(version, str): raise InterpreterException('Version must be a string.') - incs = kwargs.get('include_directories', []) - if not isinstance(incs, list): - incs = [incs] - libs = kwargs.get('link_with', []) - if not isinstance(libs, list): - libs = [libs] - sources = kwargs.get('sources', []) - if not isinstance(sources, list): - sources = [sources] + incs = extract_as_list(kwargs, 'include_directories') + libs = extract_as_list(kwargs, 'link_with') + sources = extract_as_list(kwargs, 'sources') sources = self.source_strings_to_files(self.flatten(sources)) deps = self.flatten(kwargs.get('dependencies', [])) - if not isinstance(deps, list): - deps = [deps] + deps = listify(deps) compile_args = mesonlib.stringlistify(kwargs.get('compile_args', [])) link_args = mesonlib.stringlistify(kwargs.get('link_args', [])) final_deps = [] @@ -1741,8 +1729,7 @@ class Interpreter(InterpreterBase): return ConfigurationDataHolder() def parse_default_options(self, default_options): - if not isinstance(default_options, list): - default_options = [default_options] + default_options = listify(default_options) for option in default_options: if not isinstance(option, str): mlog.debug(option) @@ -2288,12 +2275,8 @@ class Interpreter(InterpreterBase): elif len(args) == 1: if 'command' not in kwargs: raise InterpreterException('Missing "command" keyword argument') - all_args = kwargs['command'] - if not isinstance(all_args, list): - all_args = [all_args] - deps = kwargs.get('depends', []) - if not isinstance(deps, list): - deps = [deps] + all_args = extract_as_list(kwargs, 'command') + deps = extract_as_list(kwargs, 'depends') else: raise InterpreterException('Run_target needs at least one positional argument.') @@ -2344,8 +2327,7 @@ class Interpreter(InterpreterBase): if isinstance(envlist, EnvironmentVariablesHolder): env = envlist.held_object else: - if not isinstance(envlist, list): - envlist = [envlist] + envlist = listify(envlist) # Convert from array to environment object env = EnvironmentVariablesHolder() for e in envlist: @@ -2374,9 +2356,7 @@ class Interpreter(InterpreterBase): par = kwargs.get('is_parallel', True) if not isinstance(par, bool): raise InterpreterException('Keyword argument is_parallel must be a boolean.') - cmd_args = kwargs.get('args', []) - if not isinstance(cmd_args, list): - cmd_args = [cmd_args] + cmd_args = extract_as_list(kwargs, 'args') for i in cmd_args: if not isinstance(i, (str, mesonlib.File, TargetHolder)): raise InterpreterException('Command line arguments must be strings, files or targets.') @@ -2515,9 +2495,7 @@ class Interpreter(InterpreterBase): if not isinstance(install_dir, str): raise InvalidArguments('Keyword argument install_dir not a string.') if 'exclude_files' in kwargs: - exclude = kwargs['exclude_files'] - if not isinstance(exclude, list): - exclude = [exclude] + exclude = extract_as_list(kwargs, 'exclude_files') for f in exclude: if not isinstance(f, str): raise InvalidArguments('Exclude argument not a string.') @@ -2527,9 +2505,7 @@ class Interpreter(InterpreterBase): else: exclude_files = set() if 'exclude_directories' in kwargs: - exclude = kwargs['exclude_directories'] - if not isinstance(exclude, list): - exclude = [exclude] + exclude = extract_as_list(kwargs, 'exclude_directories') for d in exclude: if not isinstance(d, str): raise InvalidArguments('Exclude argument not a string.') @@ -2692,9 +2668,7 @@ different subdirectory. if re.fullmatch('[_a-zA-Z][_0-9a-zA-Z]*', setup_name) is None: raise InterpreterException('Setup name may only contain alphanumeric characters.') try: - inp = kwargs.get('exe_wrapper', []) - if not isinstance(inp, list): - inp = [inp] + inp = extract_as_list(kwargs, 'exe_wrapper') exe_wrapper = [] for i in inp: if hasattr(i, 'held_object'): @@ -2836,8 +2810,7 @@ different subdirectory. is_cross = False try: kw_src = self.flatten(kwargs['sources']) - if not isinstance(kw_src, list): - kw_src = [kw_src] + kw_src = listify(kw_src) except KeyError: kw_src = [] sources += kw_src @@ -2845,12 +2818,9 @@ different subdirectory. objs = self.flatten(kwargs.get('objects', [])) kwargs['dependencies'] = self.flatten(kwargs.get('dependencies', [])) if 'extra_files' in kwargs: - ef = kwargs['extra_files'] - if not isinstance(ef, list): - ef = [ef] + ef = extract_as_list(kwargs, 'extra_files') kwargs['extra_files'] = self.source_strings_to_files(ef) - if not isinstance(objs, list): - objs = [objs] + objs = listify(objs) self.check_sources_exist(os.path.join(self.source_root, self.subdir), sources) if targetholder is ExecutableHolder: targetclass = build.Executable diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 972c8f0c0..137d380a5 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -1201,9 +1201,7 @@ G_END_DECLS''' arg_list = kwargs.get('packages') if not arg_list: return [], [], [], [] - if not isinstance(arg_list, list): - arg_list = [arg_list] - + arg_list = mesonlib.listify(arg_list) vapi_depends = [] vapi_packages = [] vapi_includes = [] diff --git a/mesonbuild/modules/unstable_simd.py b/mesonbuild/modules/unstable_simd.py index 828afecf1..b774cff18 100644 --- a/mesonbuild/modules/unstable_simd.py +++ b/mesonbuild/modules/unstable_simd.py @@ -73,9 +73,7 @@ class SimdModule(ExtensionModule): } lib_kwargs.update(basic_kwargs) langarg_key = compiler.get_language() + '_args' - old_lang_args = lib_kwargs.get(langarg_key, []) - if not isinstance(old_lang_args, list): - old_lang_args = [old_lang_args] + old_lang_args = mesonlib.extract_as_list(lib_kwargs, langarg_key) all_lang_args = old_lang_args + args lib_kwargs[langarg_key] = all_lang_args result.append(interpreter.func_static_lib(None, [libname], lib_kwargs))