diff options
-rw-r--r-- | mesonbuild/interpreterbase/__init__.py | 2 | ||||
-rw-r--r-- | mesonbuild/interpreterbase/decorators.py | 52 | ||||
-rw-r--r-- | mesonbuild/interpreterbase/helpers.py | 55 | ||||
-rw-r--r-- | mesonbuild/interpreterbase/interpreterbase.py | 12 |
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, |