From 6b272973e07596b48ac95e4adaa0df9118b73b00 Mon Sep 17 00:00:00 2001
From: Dylan Baker <dylan@pnwbakers.com>
Date: Mon, 6 Dec 2021 14:27:44 -0800
Subject: dependencies: don't pass kwargs from get_pkgconfig_variable

This is a layering violation, we're relying on the way the interpreter
handles keyword arguments. Instead, pass them as free variables,
destructuring in the interpreter
---
 mesonbuild/dependencies/base.py              |  9 +++++++--
 mesonbuild/dependencies/boost.py             |  2 +-
 mesonbuild/dependencies/pkgconfig.py         | 28 +++++++++-------------------
 mesonbuild/dependencies/qt.py                | 12 ++++++------
 mesonbuild/interpreter/interpreterobjects.py |  2 +-
 mesonbuild/modules/gnome.py                  |  2 +-
 6 files changed, 25 insertions(+), 30 deletions(-)

(limited to 'mesonbuild')

diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 6881a34..713b8c4 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -27,6 +27,7 @@ from ..mesonlib import version_compare_many
 from ..interpreterbase import FeatureDeprecated
 
 if T.TYPE_CHECKING:
+    from .._typing import ImmutableListProtocol
     from ..compilers.compilers import Compiler
     from ..environment import Environment
     from ..build import BuildTarget, CustomTarget
@@ -162,7 +163,9 @@ class Dependency(HoldableObject):
     def get_exe_args(self, compiler: 'Compiler') -> T.List[str]:
         return []
 
-    def get_pkgconfig_variable(self, variable_name: str, kwargs: T.Dict[str, T.Any]) -> str:
+    def get_pkgconfig_variable(self, variable_name: str,
+                               define_variable: 'ImmutableListProtocol[str]',
+                               default: T.Optional[str]) -> str:
         raise DependencyException(f'{self.name!r} is not a pkgconfig dependency')
 
     def get_configtool_variable(self, variable_name: str) -> str:
@@ -254,7 +257,9 @@ class InternalDependency(Dependency):
             return True
         return any(d.is_built() for d in self.ext_deps)
 
-    def get_pkgconfig_variable(self, variable_name: str, kwargs: T.Dict[str, T.Any]) -> str:
+    def get_pkgconfig_variable(self, variable_name: str,
+                               define_variable: 'ImmutableListProtocol[str]',
+                               default: T.Optional[str]) -> str:
         raise DependencyException('Method "get_pkgconfig_variable()" is '
                                   'invalid for an internal dependency')
 
diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py
index aadf3f8..318bca2 100644
--- a/mesonbuild/dependencies/boost.py
+++ b/mesonbuild/dependencies/boost.py
@@ -648,7 +648,7 @@ class BoostDependency(SystemDependency):
         try:
             boost_pc = PkgConfigDependency('boost', self.env, {'required': False})
             if boost_pc.found():
-                boost_root = boost_pc.get_pkgconfig_variable('prefix', {'default': None})
+                boost_root = boost_pc.get_pkgconfig_variable('prefix', [], None)
                 if boost_root:
                     roots += [Path(boost_root)]
         except DependencyException:
diff --git a/mesonbuild/dependencies/pkgconfig.py b/mesonbuild/dependencies/pkgconfig.py
index 8f4c639..e6921e9 100644
--- a/mesonbuild/dependencies/pkgconfig.py
+++ b/mesonbuild/dependencies/pkgconfig.py
@@ -24,6 +24,7 @@ import typing as T
 
 if T.TYPE_CHECKING:
     from ..environment import Environment
+    from .._typing import ImmutableListProtocol
 
 class PkgConfigDependency(ExternalDependency):
     # The class's copy of the pkg-config path. Avoids having to search for it
@@ -380,18 +381,13 @@ class PkgConfigDependency(ExternalDependency):
             raise DependencyException(f'Could not generate libs for {self.name}:\n\n{out_raw}')
         self.link_args, self.raw_link_args = self._search_libs(out, out_raw)
 
-    def get_pkgconfig_variable(self, variable_name: str, kwargs: T.Dict[str, T.Union[str, T.List[str]]]) -> str:
+    def get_pkgconfig_variable(self, variable_name: str,
+                               define_variable: 'ImmutableListProtocol[str]',
+                               default: T.Optional[str]) -> str:
         options = ['--variable=' + variable_name, self.name]
 
-        if 'define_variable' in kwargs:
-            definition = kwargs.get('define_variable', [])
-            if not isinstance(definition, list):
-                raise DependencyException('define_variable takes a list')
-
-            if len(definition) != 2 or not all(isinstance(i, str) for i in definition):
-                raise DependencyException('define_variable must be made up of 2 strings for VARIABLENAME and VARIABLEVALUE')
-
-            options = ['--define-variable=' + '='.join(definition)] + options
+        if define_variable:
+            options = ['--define-variable=' + '='.join(define_variable)] + options
 
         ret, out, err = self._call_pkgbin(options)
         variable = ''
@@ -406,9 +402,8 @@ class PkgConfigDependency(ExternalDependency):
             if not variable:
                 ret, out, _ = self._call_pkgbin(['--print-variables', self.name])
                 if not re.search(r'^' + variable_name + r'$', out, re.MULTILINE):
-                    if 'default' in kwargs:
-                        assert isinstance(kwargs['default'], str)
-                        variable = kwargs['default']
+                    if default:
+                        variable = default
                     else:
                         mlog.warning(f"pkgconfig variable '{variable_name}' not defined for dependency {self.name}.")
 
@@ -483,13 +478,8 @@ class PkgConfigDependency(ExternalDependency):
                      default_value: T.Optional[str] = None,
                      pkgconfig_define: T.Optional[T.List[str]] = None) -> T.Union[str, T.List[str]]:
         if pkgconfig:
-            kwargs: T.Dict[str, T.Union[str, T.List[str]]] = {}
-            if default_value is not None:
-                kwargs['default'] = default_value
-            if pkgconfig_define is not None:
-                kwargs['define_variable'] = pkgconfig_define
             try:
-                return self.get_pkgconfig_variable(pkgconfig, kwargs)
+                return self.get_pkgconfig_variable(pkgconfig, pkgconfig_define or [], default_value)
             except DependencyException:
                 pass
         if default_value is not None:
diff --git a/mesonbuild/dependencies/qt.py b/mesonbuild/dependencies/qt.py
index 9dc928c..a004688 100644
--- a/mesonbuild/dependencies/qt.py
+++ b/mesonbuild/dependencies/qt.py
@@ -181,7 +181,7 @@ class QtPkgConfigDependency(_QtBase, PkgConfigDependency, metaclass=abc.ABCMeta)
                 self.is_found = False
                 return
             if self.private_headers:
-                qt_inc_dir = mod.get_pkgconfig_variable('includedir', {})
+                qt_inc_dir = mod.get_pkgconfig_variable('includedir', [], None)
                 mod_private_dir = os.path.join(qt_inc_dir, 'Qt' + m)
                 if not os.path.isdir(mod_private_dir):
                     # At least some versions of homebrew don't seem to set this
@@ -203,7 +203,7 @@ class QtPkgConfigDependency(_QtBase, PkgConfigDependency, metaclass=abc.ABCMeta)
                 if arg == f'-l{debug_lib_name}' or arg.endswith(f'{debug_lib_name}.lib') or arg.endswith(f'{debug_lib_name}.a'):
                     is_debug = True
                     break
-            libdir = self.get_pkgconfig_variable('libdir', {})
+            libdir = self.get_pkgconfig_variable('libdir', [], None)
             if not self._link_with_qtmain(is_debug, libdir):
                 self.is_found = False
                 return
@@ -211,7 +211,7 @@ class QtPkgConfigDependency(_QtBase, PkgConfigDependency, metaclass=abc.ABCMeta)
         self.bindir = self.get_pkgconfig_host_bins(self)
         if not self.bindir:
             # If exec_prefix is not defined, the pkg-config file is broken
-            prefix = self.get_pkgconfig_variable('exec_prefix', {})
+            prefix = self.get_pkgconfig_variable('exec_prefix', [], None)
             if prefix:
                 self.bindir = os.path.join(prefix, 'bin')
 
@@ -387,7 +387,7 @@ class Qt4PkgConfigDependency(QtPkgConfigDependency):
         applications = ['moc', 'uic', 'rcc', 'lupdate', 'lrelease']
         for application in applications:
             try:
-                return os.path.dirname(core.get_pkgconfig_variable(f'{application}_location', {}))
+                return os.path.dirname(core.get_pkgconfig_variable(f'{application}_location', [], None))
             except mesonlib.MesonException:
                 pass
         return None
@@ -400,7 +400,7 @@ class Qt5PkgConfigDependency(QtPkgConfigDependency):
 
     @staticmethod
     def get_pkgconfig_host_bins(core: PkgConfigDependency) -> str:
-        return core.get_pkgconfig_variable('host_bins', {})
+        return core.get_pkgconfig_variable('host_bins', [], None)
 
     def get_private_includes(self, mod_inc_dir: str, module: str) -> T.List[str]:
         return _qt_get_private_includes(mod_inc_dir, module, self.version)
@@ -410,7 +410,7 @@ class Qt6PkgConfigDependency(QtPkgConfigDependency):
 
     @staticmethod
     def get_pkgconfig_host_bins(core: PkgConfigDependency) -> str:
-        return core.get_pkgconfig_variable('host_bins', {})
+        return core.get_pkgconfig_variable('host_bins', [], None)
 
     def get_private_includes(self, mod_inc_dir: str, module: str) -> T.List[str]:
         return _qt_get_private_includes(mod_inc_dir, module, self.version)
diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py
index fe24aef..3093181 100644
--- a/mesonbuild/interpreter/interpreterobjects.py
+++ b/mesonbuild/interpreter/interpreterobjects.py
@@ -464,7 +464,7 @@ class DependencyHolder(ObjectHolder[Dependency]):
     @permittedKwargs({'define_variable', 'default'})
     @typed_pos_args('dependency.get_pkgconfig_variable', str)
     def pkgconfig_method(self, args: T.Tuple[str], kwargs: TYPE_kwargs) -> str:
-        return self.held_object.get_pkgconfig_variable(args[0], kwargs)
+        return self.held_object.get_pkgconfig_variable(args[0], **kwargs)
 
     @FeatureNew('dependency.get_configtool_variable', '0.44.0')
     @FeatureDeprecated('dependency.get_configtool_variable', '0.56.0',
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index 78e09e6..fc084c2 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -325,7 +325,7 @@ class GnomeModule(ExtensionModule):
         # Check if pkgconfig has a variable
         dep = self._get_dep(state, depname, native=True, required=False)
         if dep.found() and dep.type_name == 'pkgconfig':
-            value = dep.get_pkgconfig_variable(varname, {})
+            value = dep.get_pkgconfig_variable(varname, [], None)
             if value:
                 return ExternalProgram(name, [value])
 
-- 
cgit v1.1