From 90d1f38d8e23667059ae9b32b2925f5e2a230881 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Tue, 22 Jan 2019 12:33:12 -0500 Subject: Interpreter: Set self.current_node during method/function calls The current node is useful to pass as location kwarg to mlog.warning(). The node is not passed to InterpreterObject method arguments, and it's easier to have it on the object than passing it through argument everywhere. --- mesonbuild/interpreterbase.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'mesonbuild/interpreterbase.py') diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py index 48c5220..afa4cd3 100644 --- a/mesonbuild/interpreterbase.py +++ b/mesonbuild/interpreterbase.py @@ -320,6 +320,9 @@ class BreakRequest(BaseException): class InterpreterObject: def __init__(self): self.methods = {} + # Current node set during a method call. This can be used as location + # when printing a warning message during a method call. + self.current_node = None def method_call(self, method_name, args, kwargs): if method_name in self.methods: @@ -366,6 +369,9 @@ class InterpreterBase: self.variables = {} self.argument_depth = 0 self.current_lineno = -1 + # Current node set during a function call. This can be used as location + # when printing a warning message during a method call. + self.current_node = None def load_root_meson_file(self): mesonfile = os.path.join(self.source_root, self.subdir, environment.build_filename) @@ -759,6 +765,7 @@ The result of this is undefined and will become a hard error in a future Meson r if not getattr(func, 'no-args-flattening', False): posargs = flatten(posargs) + self.current_node = node return func(node, posargs, kwargs) else: self.unknown_function_called(func_name) @@ -795,6 +802,7 @@ The result of this is undefined and will become a hard error in a future Meson r return Disabler() if method_name == 'extract_objects': self.validate_extraction(obj.held_object) + obj.current_node = node return obj.method_call(method_name, args, kwargs) def bool_method_call(self, obj, method_name, args): -- cgit v1.1 From 4b4f642e6a5edca8a6f999007c963435921dc678 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Tue, 22 Jan 2019 16:02:46 -0500 Subject: InterpreterBase: Fix extracting the node in all method/function calls Closes: #4813. --- mesonbuild/interpreterbase.py | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) (limited to 'mesonbuild/interpreterbase.py') diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py index afa4cd3..45a4cb0 100644 --- a/mesonbuild/interpreterbase.py +++ b/mesonbuild/interpreterbase.py @@ -47,14 +47,14 @@ def _get_callee_args(wrapped_args, want_subproject=False): if want_subproject and n == 2: if hasattr(s, 'subproject'): # Interpreter base types have 2 args: self, node - node_or_state = wrapped_args[1] + 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_or_state = wrapped_args[1] + node = wrapped_args[1].current_node # args and kwargs are inside the node args = None kwargs = None @@ -63,7 +63,7 @@ def _get_callee_args(wrapped_args, want_subproject=False): raise AssertionError('Unknown args: {!r}'.format(wrapped_args)) elif n == 3: # Methods on objects (*Holder, MesonMain, etc) have 3 args: self, args, kwargs - node_or_state = None # FIXME + node = s.current_node args = wrapped_args[1] kwargs = wrapped_args[2] if want_subproject: @@ -73,30 +73,32 @@ def _get_callee_args(wrapped_args, want_subproject=False): 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; except, - # PythonInstallation methods have self, interpreter, args, kwargs - node_or_state = wrapped_args[1] + # Module functions have 4 args: self, state, args, kwargs + 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 = node_or_state.subproject + subproject = wrapped_args[1].subproject elif n == 5: # Module snippets have 5 args: self, interpreter, state, args, kwargs - node_or_state = wrapped_args[2] + node = wrapped_args[2].current_node args = wrapped_args[3] kwargs = wrapped_args[4] if want_subproject: - subproject = node_or_state.subproject + subproject = wrapped_args[2].subproject else: raise AssertionError('Unknown args: {!r}'.format(wrapped_args)) # 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_or_state, args, kwargs, subproject + return s, node, args, kwargs, subproject def flatten(args): if isinstance(args, mparser.StringNode): @@ -164,19 +166,10 @@ class permittedKwargs: def __call__(self, f): @wraps(f) def wrapped(*wrapped_args, **wrapped_kwargs): - s, node_or_state, args, kwargs, _ = _get_callee_args(wrapped_args) - loc = types.SimpleNamespace() - if hasattr(s, 'subdir'): - loc.subdir = s.subdir - loc.lineno = s.current_lineno - elif node_or_state and hasattr(node_or_state, 'subdir'): - loc.subdir = node_or_state.subdir - loc.lineno = node_or_state.current_lineno - else: - loc = None + s, node, args, kwargs, _ = _get_callee_args(wrapped_args) for k in kwargs: if k not in self.permitted: - mlog.warning('''Passed invalid keyword argument "{}".'''.format(k), location=loc) + mlog.warning('''Passed invalid keyword argument "{}".'''.format(k), location=node) mlog.warning('This will become a hard error in the future.') return f(*wrapped_args, **wrapped_kwargs) return wrapped -- cgit v1.1