aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2021-08-27 17:07:40 -0400
committerXavier Claessens <xclaesse@gmail.com>2021-08-30 14:00:54 -0400
commitf8cfd91d719b2916355da44dda4870b9518ff905 (patch)
tree48dc83647896d15c1a14f9e3e1944e9163c42b1a
parentab773ff9e8cecce7c761e8d99652869862fa8cad (diff)
downloadmeson-f8cfd91d719b2916355da44dda4870b9518ff905.zip
meson-f8cfd91d719b2916355da44dda4870b9518ff905.tar.gz
meson-f8cfd91d719b2916355da44dda4870b9518ff905.tar.bz2
Simplify get_callee_args
-rw-r--r--mesonbuild/interpreterbase/__init__.py2
-rw-r--r--mesonbuild/interpreterbase/decorators.py52
-rw-r--r--mesonbuild/interpreterbase/helpers.py55
-rw-r--r--mesonbuild/interpreterbase/interpreterbase.py12
4 files changed, 34 insertions, 87 deletions
diff --git a/mesonbuild/interpreterbase/__init__.py b/mesonbuild/interpreterbase/__init__.py
index 8e45cdb..f7b12a5 100644
--- a/mesonbuild/interpreterbase/__init__.py
+++ b/mesonbuild/interpreterbase/__init__.py
@@ -36,7 +36,6 @@ __all__ = [
'resolve_second_level_holders',
'noPosargs',
- 'builtinMethodNoKwargs',
'noKwargs',
'stringArgs',
'noArgsFlattening',
@@ -89,7 +88,6 @@ from .baseobjects import (
from .decorators import (
noPosargs,
- builtinMethodNoKwargs,
noKwargs,
stringArgs,
noArgsFlattening,
diff --git a/mesonbuild/interpreterbase/decorators.py b/mesonbuild/interpreterbase/decorators.py
index 6aa4fca..a95dd15 100644
--- a/mesonbuild/interpreterbase/decorators.py
+++ b/mesonbuild/interpreterbase/decorators.py
@@ -13,43 +13,47 @@
# limitations under the License.
from .. import mesonlib, mlog
-from .baseobjects import TV_func, TYPE_var
+from .baseobjects import TV_func, TYPE_var, TYPE_kwargs
from .disabler import Disabler
from .exceptions import InterpreterException, InvalidArguments
-from .helpers import check_stringlist, get_callee_args
+from .helpers import check_stringlist
from ._unholder import _unholder
from functools import wraps
import abc
import itertools
import typing as T
+if T.TYPE_CHECKING:
+ from .. import mparser
+
+def get_callee_args(wrapped_args: T.Sequence[T.Any]) -> T.Tuple['mparser.BaseNode', T.List['TYPE_var'], 'TYPE_kwargs', str]:
+ # First argument could be InterpreterBase, InterpreterObject or ModuleObject.
+ # In the case of a ModuleObject it is the 2nd argument (ModuleState) that
+ # contains the needed information.
+ s = wrapped_args[0]
+ if not hasattr(s, 'current_node'):
+ s = wrapped_args[1]
+ node = s.current_node
+ subproject = s.subproject
+ args = kwargs = None
+ if len(wrapped_args) >= 3:
+ args = wrapped_args[-2]
+ kwargs = wrapped_args[-1]
+ return node, args, kwargs, subproject
def noPosargs(f: TV_func) -> TV_func:
@wraps(f)
def wrapped(*wrapped_args: T.Any, **wrapped_kwargs: T.Any) -> T.Any:
- args = get_callee_args(wrapped_args)[2]
+ args = get_callee_args(wrapped_args)[1]
if args:
raise InvalidArguments('Function does not take positional arguments.')
return f(*wrapped_args, **wrapped_kwargs)
return T.cast(TV_func, wrapped)
-def builtinMethodNoKwargs(f: TV_func) -> TV_func:
- @wraps(f)
- def wrapped(*wrapped_args: T.Any, **wrapped_kwargs: T.Any) -> T.Any:
- node = wrapped_args[0].current_node
- method_name = wrapped_args[2]
- kwargs = wrapped_args[4]
- if kwargs:
- mlog.warning(f'Method {method_name!r} does not take keyword arguments.',
- 'This will become a hard error in the future',
- location=node)
- return f(*wrapped_args, **wrapped_kwargs)
- return T.cast(TV_func, wrapped)
-
def noKwargs(f: TV_func) -> TV_func:
@wraps(f)
def wrapped(*wrapped_args: T.Any, **wrapped_kwargs: T.Any) -> T.Any:
- kwargs = get_callee_args(wrapped_args)[3]
+ kwargs = get_callee_args(wrapped_args)[2]
if kwargs:
raise InvalidArguments('Function does not take keyword arguments.')
return f(*wrapped_args, **wrapped_kwargs)
@@ -58,7 +62,7 @@ def noKwargs(f: TV_func) -> TV_func:
def stringArgs(f: TV_func) -> TV_func:
@wraps(f)
def wrapped(*wrapped_args: T.Any, **wrapped_kwargs: T.Any) -> T.Any:
- args = get_callee_args(wrapped_args)[2]
+ args = get_callee_args(wrapped_args)[1]
assert(isinstance(args, list))
check_stringlist(args)
return f(*wrapped_args, **wrapped_kwargs)
@@ -82,7 +86,7 @@ def permissive_unholder_return(f: TV_func) -> T.Callable[..., TYPE_var]:
def disablerIfNotFound(f: TV_func) -> TV_func:
@wraps(f)
def wrapped(*wrapped_args: T.Any, **wrapped_kwargs: T.Any) -> T.Any:
- kwargs = get_callee_args(wrapped_args)[3]
+ kwargs = get_callee_args(wrapped_args)[2]
disabler = kwargs.pop('disabler', False)
ret = f(*wrapped_args, **wrapped_kwargs)
if disabler and not ret.found():
@@ -98,7 +102,7 @@ class permittedKwargs:
def __call__(self, f: TV_func) -> TV_func:
@wraps(f)
def wrapped(*wrapped_args: T.Any, **wrapped_kwargs: T.Any) -> T.Any:
- s, node, args, kwargs, _ = get_callee_args(wrapped_args)
+ node, args, kwargs, _ = get_callee_args(wrapped_args)
for k in kwargs:
if k not in self.permitted:
mlog.warning(f'''Passed invalid keyword argument "{k}".''', location=node)
@@ -159,7 +163,7 @@ def typed_pos_args(name: str, *types: T.Union[T.Type, T.Tuple[T.Type, ...]],
@wraps(f)
def wrapper(*wrapped_args: T.Any, **wrapped_kwargs: T.Any) -> T.Any:
- args = get_callee_args(wrapped_args)[2]
+ args = get_callee_args(wrapped_args)[1]
# These are implementation programming errors, end users should never see them.
assert isinstance(args, list), args
@@ -395,7 +399,7 @@ def typed_kwargs(name: str, *types: KwargInfo) -> T.Callable[..., T.Any]:
@wraps(f)
def wrapper(*wrapped_args: T.Any, **wrapped_kwargs: T.Any) -> T.Any:
- _kwargs, subproject = get_callee_args(wrapped_args, want_subproject=True)[3:5]
+ _kwargs, subproject = get_callee_args(wrapped_args)[2:4]
# Cast here, as the convertor function may place something other than a TYPE_var in the kwargs
kwargs = T.cast(T.Dict[str, object], _kwargs)
@@ -551,7 +555,7 @@ class FeatureCheckBase(metaclass=abc.ABCMeta):
def __call__(self, f: TV_func) -> TV_func:
@wraps(f)
def wrapped(*wrapped_args: T.Any, **wrapped_kwargs: T.Any) -> T.Any:
- subproject = get_callee_args(wrapped_args, want_subproject=True)[4]
+ subproject = get_callee_args(wrapped_args)[3]
if subproject is None:
raise AssertionError(f'{wrapped_args!r}')
self.use(subproject)
@@ -638,7 +642,7 @@ class FeatureCheckKwargsBase(metaclass=abc.ABCMeta):
def __call__(self, f: TV_func) -> TV_func:
@wraps(f)
def wrapped(*wrapped_args: T.Any, **wrapped_kwargs: T.Any) -> T.Any:
- kwargs, subproject = get_callee_args(wrapped_args, want_subproject=True)[3:5]
+ kwargs, subproject = get_callee_args(wrapped_args)[2:4]
if subproject is None:
raise AssertionError(f'{wrapped_args!r}')
for arg in self.kwargs:
diff --git a/mesonbuild/interpreterbase/helpers.py b/mesonbuild/interpreterbase/helpers.py
index 2352577..3d45e1f 100644
--- a/mesonbuild/interpreterbase/helpers.py
+++ b/mesonbuild/interpreterbase/helpers.py
@@ -61,58 +61,3 @@ def default_resolve_key(key: mparser.BaseNode) -> str:
if not isinstance(key, mparser.IdNode):
raise InterpreterException('Invalid kwargs format.')
return key.value
-
-def get_callee_args(wrapped_args: T.Sequence[T.Any], want_subproject: bool = False) -> T.Tuple[T.Any, mparser.BaseNode, T.List['TYPE_var'], 'TYPE_kwargs', T.Optional[str]]:
- s = wrapped_args[0]
- n = len(wrapped_args)
- # Raise an error if the codepaths are not there
- subproject = None # type: T.Optional[str]
- if want_subproject and n == 2:
- if hasattr(s, 'subproject'):
- # Interpreter base types have 2 args: self, node
- node = wrapped_args[1]
- # args and kwargs are inside the node
- args = None
- kwargs = None
- subproject = s.subproject
- elif hasattr(wrapped_args[1], 'subproject'):
- # Module objects have 2 args: self, interpreter
- node = wrapped_args[1].current_node
- # args and kwargs are inside the node
- args = None
- kwargs = None
- subproject = wrapped_args[1].subproject
- else:
- raise AssertionError(f'Unknown args: {wrapped_args!r}')
- elif n == 3:
- # Methods on objects (*Holder, MesonMain, etc) have 3 args: self, args, kwargs
- node = s.current_node
- args = wrapped_args[1]
- kwargs = wrapped_args[2]
- if want_subproject:
- if hasattr(s, 'subproject'):
- subproject = s.subproject
- elif hasattr(s, 'interpreter'):
- subproject = s.interpreter.subproject
- elif n == 4:
- # Meson functions have 4 args: self, node, args, kwargs
- # Module functions have 4 args: self, state, args, kwargs
- from .interpreterbase import InterpreterBase # TODO: refactor to avoid this import
- if isinstance(s, InterpreterBase):
- node = wrapped_args[1]
- else:
- node = wrapped_args[1].current_node
- args = wrapped_args[2]
- kwargs = wrapped_args[3]
- if want_subproject:
- if isinstance(s, InterpreterBase):
- subproject = s.subproject
- else:
- subproject = wrapped_args[1].subproject
- else:
- raise AssertionError(f'Unknown args: {wrapped_args!r}')
- # Sometimes interpreter methods are called internally with None instead of
- # empty list/dict
- args = args if args is not None else []
- kwargs = kwargs if kwargs is not None else {}
- return s, node, args, kwargs, subproject
diff --git a/mesonbuild/interpreterbase/interpreterbase.py b/mesonbuild/interpreterbase/interpreterbase.py
index 3b23e19..9ab6ee0 100644
--- a/mesonbuild/interpreterbase/interpreterbase.py
+++ b/mesonbuild/interpreterbase/interpreterbase.py
@@ -40,7 +40,7 @@ from .exceptions import (
BreakRequest
)
-from .decorators import FeatureNew, builtinMethodNoKwargs
+from .decorators import FeatureNew, noKwargs
from .disabler import Disabler, is_disabled
from .helpers import check_stringlist, default_resolve_key, flatten, resolve_second_level_holders
from ._unholder import _unholder
@@ -644,7 +644,7 @@ The result of this is undefined and will become a hard error in a future Meson r
kwargs: T.Dict[str, T.Union[TYPE_var, InterpreterObject]]) -> T.Tuple[T.List[TYPE_var], TYPE_kwargs]:
return [_unholder(x) for x in args], {k: _unholder(v) for k, v in kwargs.items()}
- @builtinMethodNoKwargs
+ @noKwargs
def bool_method_call(self, obj: bool, method_name: str, posargs: T.List[TYPE_var], kwargs: TYPE_kwargs) -> T.Union[str, int]:
if method_name == 'to_string':
if not posargs:
@@ -667,7 +667,7 @@ The result of this is undefined and will become a hard error in a future Meson r
else:
raise InterpreterException('Unknown method "%s" for a boolean.' % method_name)
- @builtinMethodNoKwargs
+ @noKwargs
def int_method_call(self, obj: int, method_name: str, posargs: T.List[TYPE_var], kwargs: TYPE_kwargs) -> T.Union[str, bool]:
if method_name == 'is_even':
if not posargs:
@@ -698,7 +698,7 @@ The result of this is undefined and will become a hard error in a future Meson r
return s
return None
- @builtinMethodNoKwargs
+ @noKwargs
def string_method_call(self, obj: str, method_name: str, posargs: T.List[TYPE_var], kwargs: TYPE_kwargs) -> T.Union[str, int, bool, T.List[str]]:
if method_name == 'strip':
s1 = self._get_one_string_posarg(posargs, 'strip')
@@ -791,7 +791,7 @@ The result of this is undefined and will become a hard error in a future Meson r
def unknown_function_called(self, func_name: str) -> None:
raise InvalidCode('Unknown function "%s".' % func_name)
- @builtinMethodNoKwargs
+ @noKwargs
def array_method_call(self,
obj: T.List[T.Union[TYPE_elementary, InterpreterObject]],
method_name: str,
@@ -835,7 +835,7 @@ The result of this is undefined and will become a hard error in a future Meson r
return obj[index]
raise InterpreterException(f'Arrays do not have a method called {method_name!r}.')
- @builtinMethodNoKwargs
+ @noKwargs
def dict_method_call(self,
obj: T.Dict[str, T.Union[TYPE_elementary, InterpreterObject]],
method_name: str,