interpreterobjects: use typed_* for configuration_data.set*

This removes the ability to use ConfigurationData as a dict, but
restricting the inputs to `str | int | bool`. This may be a little too
soon for this, and we may want to wait on that part, it's only bee 8
months since we started warning about this.
pull/9850/head
Dylan Baker 3 years ago committed by Eli Schwartz
parent 7641bfd0ce
commit 574525673f
  1. 66
      mesonbuild/interpreter/interpreterobjects.py
  2. 5
      mesonbuild/interpreter/kwargs.py
  3. 3
      test cases/common/14 configure file/meson.build
  4. 8
      test cases/common/187 args flattening/meson.build
  5. 1
      unittests/allplatformstests.py

@ -276,8 +276,11 @@ class EnvironmentVariablesHolder(ObjectHolder[build.EnvironmentVariables], Mutab
self.held_object.prepend(name, values, kwargs['separator'])
_CONF_DATA_SET_KWS: KwargInfo[T.Optional[str]] = KwargInfo('description', (str, NoneType))
class ConfigurationDataObject(MutableInterpreterObject, MesonInterpreterObject):
def __init__(self, subproject: str, initial_values: T.Optional[T.Dict[str, T.Any]] = None) -> None:
def __init__(self, subproject: str, initial_values: T.Optional[T.Dict[str, T.Union[str, int, bool]]] = None) -> None:
self.used = False # These objects become immutable after use in configure_file.
super().__init__(subproject=subproject)
self.conf_data = build.ConfigurationData()
@ -302,51 +305,28 @@ class ConfigurationDataObject(MutableInterpreterObject, MesonInterpreterObject):
def mark_used(self) -> None:
self.used = True
def validate_args(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> T.Tuple[str, T.Union[str, int, bool], T.Optional[str]]:
if len(args) == 1 and isinstance(args[0], list) and len(args[0]) == 2:
mlog.deprecation('Passing a list as the single argument to '
'configuration_data.set is deprecated. This will '
'become a hard error in the future.',
location=self.current_node)
args = args[0]
if len(args) != 2:
raise InterpreterException("Configuration set requires 2 arguments.")
def __check_used(self) -> None:
if self.used:
raise InterpreterException("Can not set values on configuration object that has been used.")
name, val = args
if not isinstance(val, (int, str)):
msg = f'Setting a configuration data value to {val!r} is invalid, ' \
'and will fail at configure_file(). If you are using it ' \
'just to store some values, please use a dict instead.'
mlog.deprecation(msg, location=self.current_node)
desc = kwargs.get('description', None)
if not isinstance(name, str):
raise InterpreterException("First argument to set must be a string.")
if desc is not None and not isinstance(desc, str):
raise InterpreterException('Description must be a string.')
# TODO: Remove the cast once we get rid of the deprecation
return name, T.cast(T.Union[str, bool, int], val), desc
@noArgsFlattening
def set_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> None:
(name, val, desc) = self.validate_args(args, kwargs)
self.conf_data.values[name] = (val, desc)
def set_quoted_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> None:
(name, val, desc) = self.validate_args(args, kwargs)
if not isinstance(val, str):
raise InterpreterException("Second argument to set_quoted must be a string.")
escaped_val = '\\"'.join(val.split('"'))
self.conf_data.values[name] = ('"' + escaped_val + '"', desc)
def set10_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> None:
(name, val, desc) = self.validate_args(args, kwargs)
if val:
self.conf_data.values[name] = (1, desc)
else:
self.conf_data.values[name] = (0, desc)
@typed_pos_args('configuration_data.set', str, (str, int, bool))
@typed_kwargs('configuration_data.set', _CONF_DATA_SET_KWS)
def set_method(self, args: T.Tuple[str, T.Union[str, int, bool]], kwargs: 'kwargs.ConfigurationDataSet') -> None:
self.__check_used()
self.conf_data.values[args[0]] = (args[1], kwargs['description'])
@typed_pos_args('configuration_data.set_quoted', str, str)
@typed_kwargs('configuration_data.set_quoted', _CONF_DATA_SET_KWS)
def set_quoted_method(self, args: T.Tuple[str, str], kwargs: 'kwargs.ConfigurationDataSet') -> None:
self.__check_used()
escaped_val = '\\"'.join(args[1].split('"'))
self.conf_data.values[args[0]] = (f'"{escaped_val}"', kwargs['description'])
@typed_pos_args('configuration_data.set10', str, (int, bool))
@typed_kwargs('configuration_data.set10', _CONF_DATA_SET_KWS)
def set10_method(self, args: T.Tuple[str, T.Union[int, bool]], kwargs: 'kwargs.ConfigurationDataSet') -> None:
self.__check_used()
self.conf_data.values[args[0]] = (int(args[1]), kwargs['description'])
@typed_pos_args('configuration_data.has', (str, int, bool))
@noKwargs

@ -261,3 +261,8 @@ class DependencyGetVariable(TypedDict):
internal: T.Optional[str]
default_value: T.Optional[str]
pkgconfig_define: T.List[str]
class ConfigurationDataSet(TypedDict):
description: T.Optional[str]

@ -275,9 +275,6 @@ configure_file(
test('configure-file', test_file)
cdata = configuration_data()
cdata.set('invalid_value', ['array'])
# Dictionaries
cdata = configuration_data({

@ -6,13 +6,6 @@ assert(arr == ['bar', 'baz'], 'get_variable with array fallback is broken')
set_variable('arr', ['bar', 'baz'])
assert(arr == ['bar', 'baz'], 'set_variable(array) is broken')
conf = configuration_data()
conf.set('foo', ['bar', 'baz'])
assert(conf.get('foo') == ['bar', 'baz'], 'configuration_data.set(array) is broken')
arr = conf.get('does-not-exist', ['bar', 'baz'])
assert(arr == ['bar', 'baz'], 'configuration_data.get with array fallback is broken')
arr = meson.get_cross_property('does-not-exist', ['bar', 'baz'])
assert(arr == ['bar', 'baz'], 'meson.get_cross_property with array fallback is broken')
@ -27,5 +20,6 @@ assert(arr == ['bar', 'baz'], 'meson.get_external_property native:false with arr
# Test deprecated behaviour
conf = configuration_data()
conf.set(['foo', 'bar'])
message(conf.get('foo'))

@ -2306,7 +2306,6 @@ class AllPlatformTests(BasePlatformTests):
self.assertEqual(f.read().strip(), b'/* #undef FOO_BAR */')
with open(os.path.join(self.builddir, 'nosubst-nocopy2.txt'), 'rb') as f:
self.assertEqual(f.read().strip(), b'')
self.assertRegex(out, r"DEPRECATION:.*\['array'\] is invalid.*dict")
def test_dirs(self):
with tempfile.TemporaryDirectory() as containing:

Loading…
Cancel
Save