add message option to since_values and deprecated_values

This allows these two arguments to take a tuple of (version, message),
where the message will be passed to Feature*'s message parameter
pull/9666/head
Dylan Baker 3 years ago committed by Eli Schwartz
parent 51845a3a45
commit f5d961f127
  1. 21
      mesonbuild/interpreterbase/decorators.py
  2. 10
      unittests/internaltests.py

@ -388,10 +388,10 @@ class KwargInfo(T.Generic[_T]):
default: T.Optional[_T] = None,
since: T.Optional[str] = None,
since_message: T.Optional[str] = None,
since_values: T.Optional[T.Dict[_T, str]] = None,
since_values: T.Optional[T.Dict[_T, T.Union[str, T.Tuple[str, str]]]] = None,
deprecated: T.Optional[str] = None,
deprecated_message: T.Optional[str] = None,
deprecated_values: T.Optional[T.Dict[_T, str]] = None,
deprecated_values: T.Optional[T.Dict[_T, T.Union[str, T.Tuple[str, str]]]] = None,
validator: T.Optional[T.Callable[[T.Any], T.Optional[str]]] = None,
convertor: T.Optional[T.Callable[[_T], object]] = None,
not_set_warning: T.Optional[str] = None):
@ -417,10 +417,10 @@ class KwargInfo(T.Generic[_T]):
default: T.Union[_T, None, _NULL_T] = _NULL,
since: T.Union[str, None, _NULL_T] = _NULL,
since_message: T.Union[str, None, _NULL_T] = _NULL,
since_values: T.Union[T.Dict[_T, str], None, _NULL_T] = _NULL,
since_values: T.Union[T.Dict[_T, T.Union[str, T.Tuple[str, str]]], None, _NULL_T] = _NULL,
deprecated: T.Union[str, None, _NULL_T] = _NULL,
deprecated_message: T.Union[str, None, _NULL_T] = _NULL,
deprecated_values: T.Union[T.Dict[_T, str], None, _NULL_T] = _NULL,
deprecated_values: T.Union[T.Dict[_T, T.Union[str, T.Tuple[str, str]]], None, _NULL_T] = _NULL,
validator: T.Union[T.Callable[[_T], T.Optional[str]], None, _NULL_T] = _NULL,
convertor: T.Union[T.Callable[[_T], TYPE_var], None, _NULL_T] = _NULL) -> 'KwargInfo':
"""Create a shallow copy of this KwargInfo, with modifications.
@ -535,6 +535,7 @@ def typed_kwargs(name: str, *types: KwargInfo) -> T.Callable[..., T.Any]:
raise InvalidArguments(f'{name} keyword argument "{info.name}" {msg}')
warn: bool
msg: T.Optional[str]
if info.deprecated_values is not None:
for n, version in info.deprecated_values.items():
if isinstance(value, (dict, list)):
@ -543,7 +544,11 @@ 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, location=node)
if isinstance(version, tuple):
version, msg = version
else:
msg = None
FeatureDeprecated.single_use(f'"{name}" keyword argument "{info.name}" value "{n}"', version, subproject, msg, location=node)
if info.since_values is not None:
for n, version in info.since_values.items():
@ -553,7 +558,11 @@ 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, location=node)
if isinstance(version, tuple):
version, msg = version
else:
msg = None
FeatureNew.single_use(f'"{name}" keyword argument "{info.name}" value "{n}"', version, subproject, msg, location=node)
elif info.required:
raise InvalidArguments(f'{name} is missing required keyword argument "{info.name}"')

@ -1379,7 +1379,7 @@ class InternalTests(unittest.TestCase):
@typed_kwargs(
'testfunc',
KwargInfo('input', ContainerTypeInfo(list, str), listify=True, default=[], deprecated_values={'foo': '0.9'}, since_values={'bar': '1.1'}),
KwargInfo('output', ContainerTypeInfo(dict, str), default={}, deprecated_values={'foo': '0.9'}, since_values={'bar': '1.1'}),
KwargInfo('output', ContainerTypeInfo(dict, str), default={}, deprecated_values={'foo': '0.9', 'foo2': ('0.9', 'dont use it')}, since_values={'bar': '1.1', 'bar2': ('1.1', 'use this')}),
KwargInfo('install_dir', (bool, str, NoneType), deprecated_values={False: '0.9'}),
KwargInfo(
'mode',
@ -1403,10 +1403,18 @@ class InternalTests(unittest.TestCase):
_(None, mock.Mock(subproject=''), [], {'output': {'foo': 'a'}})
self.assertRegex(out.getvalue(), r"""WARNING:.Project targeting '1.0'.*deprecated since '0.9': "testfunc" keyword argument "output" value "foo".*""")
with self.subTest('deprecated dict string value with msg'), mock.patch('sys.stdout', io.StringIO()) as out:
_(None, mock.Mock(subproject=''), [], {'output': {'foo2': 'a'}})
self.assertRegex(out.getvalue(), r"""WARNING:.Project targeting '1.0'.*deprecated since '0.9': "testfunc" keyword argument "output" value "foo2". dont use it.*""")
with self.subTest('new dict string value'), mock.patch('sys.stdout', io.StringIO()) as out:
_(None, mock.Mock(subproject=''), [], {'output': {'bar': 'b'}})
self.assertRegex(out.getvalue(), r"""WARNING:.Project targeting '1.0'.*introduced in '1.1': "testfunc" keyword argument "output" value "bar".*""")
with self.subTest('new dict string value with msg'), mock.patch('sys.stdout', io.StringIO()) as out:
_(None, mock.Mock(subproject=''), [], {'output': {'bar2': 'a'}})
self.assertRegex(out.getvalue(), r"""WARNING:.Project targeting '1.0'.*introduced in '1.1': "testfunc" keyword argument "output" value "bar2". use this.*""")
with self.subTest('non string union'), mock.patch('sys.stdout', io.StringIO()) as out:
_(None, mock.Mock(subproject=''), [], {'install_dir': False})
self.assertRegex(out.getvalue(), r"""WARNING:.Project targeting '1.0'.*deprecated since '0.9': "testfunc" keyword argument "install_dir" value "False".*""")

Loading…
Cancel
Save