From 74dd77ed81c90e3655b3dff5bfe98410a85dd4f0 Mon Sep 17 00:00:00 2001 From: Andrew McNulty Date: Sat, 7 Sep 2024 13:19:01 +0100 Subject: [PATCH] Prevent raw exception during project() If a user imports a module and invokes a method on it, a raw Python exception is raised to the user. This commit adds a check to ensure that in this case an appropriate exception is raised instead. A test has been added to ensure that this exception is in fact raised on offending code. Fixes: #11393, #5134 --- mesonbuild/interpreter/interpreterobjects.py | 6 +++++- .../failing/132 module use inside project decl/meson.build | 6 ++++++ .../failing/132 module use inside project decl/test.json | 7 +++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 test cases/failing/132 module use inside project decl/meson.build create mode 100644 test cases/failing/132 module use inside project decl/test.json diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index 2cd55321b..1d6028285 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -12,7 +12,7 @@ from .. import options from .. import build from .. import mlog -from ..modules import ModuleReturnValue, ModuleObject, ModuleState, ExtensionModule +from ..modules import ModuleReturnValue, ModuleObject, ModuleState, ExtensionModule, NewExtensionModule from ..backend.backends import TestProtocol from ..interpreterbase import ( ContainerTypeInfo, KwargInfo, MesonOperator, @@ -872,6 +872,10 @@ class ModuleObjectHolder(ObjectHolder[ModuleObject]): args = flatten(args) if not getattr(method, 'no-second-level-holder-flattening', False): args, kwargs = resolve_second_level_holders(args, kwargs) + if not self.interpreter.active_projectname: + assert isinstance(modobj, (ExtensionModule, NewExtensionModule)), 'for mypy' + full_method_name = f'{modobj.INFO.name}.{method_name}' + raise mesonlib.MesonException(f'Module methods ({full_method_name}) cannot be invoked during project declaration.') state = ModuleState(self.interpreter) # Many modules do for example self.interpreter.find_program_impl(), # so we have to ensure they use the current interpreter and not the one diff --git a/test cases/failing/132 module use inside project decl/meson.build b/test cases/failing/132 module use inside project decl/meson.build new file mode 100644 index 000000000..8f82a5d30 --- /dev/null +++ b/test cases/failing/132 module use inside project decl/meson.build @@ -0,0 +1,6 @@ +# GH issue 11393 +project('module use inside project decl', 'c', + version: run_command( + import('python').find_installation('python3') + ) +) diff --git a/test cases/failing/132 module use inside project decl/test.json b/test cases/failing/132 module use inside project decl/test.json new file mode 100644 index 000000000..33e377b84 --- /dev/null +++ b/test cases/failing/132 module use inside project decl/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/132 module use inside project decl/meson.build:4:21: ERROR: Module methods (python.find_installation) cannot be invoked during project declaration." + } + ] + }