diff options
-rw-r--r-- | mesonbuild/interpreterbase.py | 11 | ||||
-rwxr-xr-x | run_unittests.py | 10 |
2 files changed, 20 insertions, 1 deletions
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py index 136eb6e..0273c36 100644 --- a/mesonbuild/interpreterbase.py +++ b/mesonbuild/interpreterbase.py @@ -428,6 +428,10 @@ class KwargInfo(T.Generic[_T]): intended for cases where a string is expected, but only a few specific values are accepted. Must return None if the input is valid, or a message if the input is invalid + :param convertor: A callable that converts the raw input value into a + different type. This is intended for cases such as the meson DSL using a + string, but the implementation using an Enum. This should not do + validation, just converstion. """ def __init__(self, name: str, types: T.Union[T.Type[_T], T.Tuple[T.Type[_T], ...], ContainerTypeInfo], @@ -435,7 +439,8 @@ class KwargInfo(T.Generic[_T]): default: T.Optional[_T] = None, since: T.Optional[str] = None, deprecated: T.Optional[str] = None, - validator: T.Optional[T.Callable[[_T], T.Optional[str]]] = None): + validator: T.Optional[T.Callable[[_T], T.Optional[str]]] = None, + convertor: T.Optional[T.Callable[[_T], TYPE_nvar]] = None): self.name = name self.types = types self.required = required @@ -444,6 +449,7 @@ class KwargInfo(T.Generic[_T]): self.since = since self.deprecated = deprecated self.validator = validator + self.convertor = convertor def typed_kwargs(name: str, *types: KwargInfo) -> T.Callable[..., T.Any]: @@ -517,6 +523,9 @@ def typed_kwargs(name: str, *types: KwargInfo) -> T.Callable[..., T.Any]: else: kwargs[info.name] = info.default + if info.convertor: + kwargs[info.name] = info.convertor(kwargs[info.name]) + return f(*wrapped_args, **wrapped_kwargs) return T.cast(TV_func, wrapper) return inner diff --git a/run_unittests.py b/run_unittests.py index 9f66d9c..21bb30e 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -1644,6 +1644,16 @@ class InternalTests(unittest.TestCase): _(None, mock.Mock(), tuple(), dict(input='bar')) self.assertEqual(str(cm.exception), "testfunc keyword argument \"input\" invalid!") + def test_typed_kwarg_convertor(self) -> None: + @typed_kwargs( + 'testfunc', + KwargInfo('native', bool, convertor=lambda n: MachineChoice.BUILD if n else MachineChoice.HOST) + ) + def _(obj, node, args: T.Tuple, kwargs: T.Dict[str, MachineChoice]) -> None: + assert isinstance(kwargs['native'], MachineChoice) + + _(None, mock.Mock(), tuple(), dict(native=True)) + @unittest.skipIf(is_tarball(), 'Skipping because this is a tarball release') class DataTests(unittest.TestCase): |