diff options
author | Eli Schwartz <eschwartz@archlinux.org> | 2021-11-14 02:16:57 -0500 |
---|---|---|
committer | Eli Schwartz <eschwartz@archlinux.org> | 2021-11-20 20:48:30 -0500 |
commit | 8dbb0ee476493d3059a5b4a4db61fbc3bd162bef (patch) | |
tree | 9fcf8c211ae510d949e6892322dabf62c0c0b0fa | |
parent | 7a033c78870e55b00d10a6499b40ad98b88a0509 (diff) | |
download | meson-8dbb0ee476493d3059a5b4a4db61fbc3bd162bef.zip meson-8dbb0ee476493d3059a5b4a4db61fbc3bd162bef.tar.gz meson-8dbb0ee476493d3059a5b4a4db61fbc3bd162bef.tar.bz2 |
Feature kwargs decorator: automatically report the nodes which trigger an issue
-rw-r--r-- | mesonbuild/interpreterbase/decorators.py | 20 | ||||
-rw-r--r-- | test cases/warning/1 version for string div/test.json | 2 | ||||
-rw-r--r-- | unittests/allplatformstests.py | 4 |
3 files changed, 14 insertions, 12 deletions
diff --git a/mesonbuild/interpreterbase/decorators.py b/mesonbuild/interpreterbase/decorators.py index d91b020..92a0159 100644 --- a/mesonbuild/interpreterbase/decorators.py +++ b/mesonbuild/interpreterbase/decorators.py @@ -458,7 +458,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)[2:4] + node, _, _kwargs, subproject = get_callee_args(wrapped_args) # 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) @@ -492,10 +492,10 @@ def typed_kwargs(name: str, *types: KwargInfo) -> T.Callable[..., T.Any]: if value is not None: if info.since: feature_name = info.name + ' arg in ' + name - FeatureNew.single_use(feature_name, info.since, subproject) + FeatureNew.single_use(feature_name, info.since, subproject, location=node) if info.deprecated: feature_name = info.name + ' arg in ' + name - FeatureDeprecated.single_use(feature_name, info.deprecated, subproject) + FeatureDeprecated.single_use(feature_name, info.deprecated, subproject, location=node) if info.listify: kwargs[info.name] = value = mesonlib.listify(value) if not check_value_type(value): @@ -516,7 +516,7 @@ def typed_kwargs(name: str, *types: KwargInfo) -> T.Callable[..., T.Any]: warn = n == value if warn: - FeatureDeprecated.single_use(f'"{name}" keyword argument "{info.name}" value "{n}"', version, subproject) + FeatureDeprecated.single_use(f'"{name}" keyword argument "{info.name}" value "{n}"', version, subproject, location=node) if info.since_values is not None: for n, version in info.since_values.items(): @@ -526,7 +526,7 @@ def typed_kwargs(name: str, *types: KwargInfo) -> T.Callable[..., T.Any]: warn = n == value if warn: - FeatureNew.single_use(f'"{name}" keyword argument "{info.name}" value "{n}"', version, subproject) + FeatureNew.single_use(f'"{name}" keyword argument "{info.name}" value "{n}"', version, subproject, location=node) elif info.required: raise InvalidArguments(f'{name} is missing required keyword argument "{info.name}"') @@ -615,9 +615,10 @@ 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)[3] + node, _, _, subproject = get_callee_args(wrapped_args) if subproject is None: raise AssertionError(f'{wrapped_args!r}') + self.location = node self.use(subproject) return f(*wrapped_args, **wrapped_kwargs) return T.cast(TV_func, wrapped) @@ -693,16 +694,17 @@ class FeatureCheckKwargsBase(metaclass=abc.ABCMeta): pass def __init__(self, feature_name: str, feature_version: str, - kwargs: T.List[str], extra_message: T.Optional[str] = None): + kwargs: T.List[str], extra_message: T.Optional[str] = None, location: T.Optional['mparser.BaseNode'] = None): self.feature_name = feature_name self.feature_version = feature_version self.kwargs = kwargs self.extra_message = extra_message + self.location = location 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)[2:4] + node, _, kwargs, subproject = get_callee_args(wrapped_args) if subproject is None: raise AssertionError(f'{wrapped_args!r}') for arg in self.kwargs: @@ -710,7 +712,7 @@ class FeatureCheckKwargsBase(metaclass=abc.ABCMeta): continue name = arg + ' arg in ' + self.feature_name self.feature_check_class.single_use( - name, self.feature_version, subproject, self.extra_message) + name, self.feature_version, subproject, self.extra_message, node) return f(*wrapped_args, **wrapped_kwargs) return T.cast(TV_func, wrapped) diff --git a/test cases/warning/1 version for string div/test.json b/test cases/warning/1 version for string div/test.json index c37931a..4622c1e 100644 --- a/test cases/warning/1 version for string div/test.json +++ b/test cases/warning/1 version for string div/test.json @@ -2,7 +2,7 @@ "stdout": [ { "comment": "literal '/' appears in output, irrespective of os.path.sep, as that's the operator", - "line": "WARNING: Project targeting '>=0.48.0' but tried to use feature introduced in '0.49.0': / with string arguments." + "line": "test cases/warning/1 version for string div/meson.build:3: WARNING: Project targeting '>=0.48.0' but tried to use feature introduced in '0.49.0': / with string arguments." } ] } diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index aec832a..ec0b393 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -2241,8 +2241,8 @@ class AllPlatformTests(BasePlatformTests): # Parent project warns correctly self.assertRegex(out, "WARNING: Project targeting '>=0.45'.*'0.47.0': dict") # Subprojects warn correctly - self.assertRegex(out, r"\| WARNING: Project targeting '>=0.40'.*'0.44.0': disabler") - self.assertRegex(out, r"\| WARNING: Project targeting '!=0.40'.*'0.44.0': disabler") + self.assertRegex(out, r"foo\| .*WARNING: Project targeting '>=0.40'.*'0.44.0': disabler") + self.assertRegex(out, r"baz\| .*WARNING: Project targeting '!=0.40'.*'0.44.0': disabler") # Subproject has a new-enough meson_version, no warning self.assertNotRegex(out, "WARNING: Project targeting.*Python") # Ensure a summary is printed in the subproject and the outer project |