Skip to content

Commit

Permalink
options: merge set_value and set_option
Browse files Browse the repository at this point in the history
Which are basically the same, except for handling of deprecated options,
and various bugs that only existed in one implementation or the other.
  • Loading branch information
dcbaker committed Mar 5, 2025
1 parent 6e6d77d commit 0dffe9a
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 54 deletions.
18 changes: 9 additions & 9 deletions mesonbuild/coredata.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ def get_option_for_target(self, target: 'BuildTarget', key: T.Union[str, OptionK
def set_option(self, key: OptionKey, value, first_invocation: bool = False) -> bool:
dirty = False
try:
changed = self.optstore.set_value(key, value, first_invocation)
changed = self.optstore.set_option(key, value, first_invocation)
except KeyError:
raise MesonException(f'Tried to set unknown builtin option {str(key)}')
dirty |= changed
Expand Down Expand Up @@ -483,8 +483,8 @@ def _set_others_from_buildtype(self, value: str) -> bool:
assert value == 'custom'
return False

dirty |= self.optstore.set_value('optimization', opt)
dirty |= self.optstore.set_value('debug', debug)
dirty |= self.optstore.set_option(OptionKey('optimization'), opt)
dirty |= self.optstore.set_option(OptionKey('debug'), debug)

return dirty

Expand Down Expand Up @@ -515,7 +515,7 @@ def update_project_options(self, project_options: 'MutableKeyedOptionDictType',

oldval = self.optstore.get_value_object(key)
if type(oldval) is not type(value):
self.optstore.set_value(key, value.value)
self.optstore.set_option(key, value.value)
elif options.choices_are_different(oldval, value):
# If the choices have changed, use the new value, but attempt
# to keep the old options. If they are not valid keep the new
Expand Down Expand Up @@ -546,7 +546,7 @@ def copy_build_options_from_regular_ones(self, shut_up_pylint: bool = True) -> b
assert not self.is_cross_build()
for k in options.BUILTIN_OPTIONS_PER_MACHINE:
o = self.optstore.get_value_object_for(k.name)
dirty |= self.optstore.set_value(k, o.value, True)
dirty |= self.optstore.set_option(k, o.value, True)
for bk, bv in self.optstore.items():
if bk.machine is MachineChoice.BUILD:
hk = bk.as_host()
Expand Down Expand Up @@ -690,16 +690,16 @@ def process_compiler_options(self, lang: str, comp: Compiler, env: Environment,
if skey not in self.optstore:
self.optstore.add_system_option(skey, copy.deepcopy(compilers.BASE_OPTIONS[key]))
if skey in env.options:
self.optstore.set_value(skey, env.options[skey])
self.optstore.set_option(skey, env.options[skey])
elif subproject and key in env.options:
self.optstore.set_value(skey, env.options[key])
self.optstore.set_option(skey, env.options[key])
# FIXME
#if subproject and not self.optstore.has_option(key):
# self.optstore[key] = copy.deepcopy(self.optstore[skey])
elif skey in env.options:
self.optstore.set_value(skey, env.options[skey])
self.optstore.set_option(skey, env.options[skey])
elif subproject and key in env.options:
self.optstore.set_value(skey, env.options[key])
self.optstore.set_option(skey, env.options[key])
self.emit_base_options_warnings()

def emit_base_options_warnings(self) -> None:
Expand Down
65 changes: 20 additions & 45 deletions mesonbuild/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -941,53 +941,26 @@ def sanitize_dir_option_value(self, prefix: str, option: OptionKey, value: T.Any
# .as_posix() keeps the posix-like file separators Meson uses.
return value.as_posix()

def set_value(self, key: T.Union[OptionKey, str], new_value: 'T.Any', first_invocation: bool = False) -> bool:
key = self.ensure_and_validate_key(key)
if key.name == 'prefix':
new_value = self.sanitize_prefix(new_value)
elif self.is_builtin_option(key):
prefix = self.get_value_for('prefix')
assert isinstance(prefix, str)
new_value = self.sanitize_dir_option_value(prefix, key, new_value)
if key not in self.options:
raise MesonException(f'Unknown options: "{key.name}" not found.')

valobj = self.options[key]
old_value = valobj.value
changed = valobj.set_value(new_value)

if valobj.readonly and changed and not first_invocation:
raise MesonException(f'Tried to modify read only option {str(key)!r}')

if key.name == 'prefix' and first_invocation and changed:
assert isinstance(old_value, str)
self.reset_prefixed_options(old_value, new_value)

if changed:
self.set_dependents(key, new_value)

return changed

def set_dependents(self, key: OptionKey, value: str) -> None:
if key.name != 'buildtype':
return
def _set_dependents(self, key: OptionKey, value: str) -> None:
opt, debug = self.DEFAULT_DEPENDENTS[value]
dkey = key.evolve(name='debug')
optkey = key.evolve(name='optimization')
self.options[dkey].set_value(debug)
self.options[optkey].set_value(opt)

def set_option(self, key: OptionKey, new_value: str, first_invocation: bool = False) -> bool:
assert isinstance(key, OptionKey)
# FIXME, dupe of set_value
# Remove one of the two before merging to master.
def set_option(self, key: OptionKey, new_value: ElementaryOptionValues, first_invocation: bool = False) -> bool:
if key.name == 'prefix':
assert isinstance(new_value, str), 'for mypy'
new_value = self.sanitize_prefix(new_value)
elif self.is_builtin_option(key):
prefix = self.get_value_for('prefix')
assert isinstance(prefix, str)
assert isinstance(prefix, str), 'for mypy'
new_value = self.sanitize_dir_option_value(prefix, key, new_value)

if key not in self.options:
raise MesonException(f'Unknown options: "{key.name}" not found.')
opt = self.get_value_object_for(key)

if opt.deprecated is True:
mlog.deprecation(f'Option {key.name!r} is deprecated')
elif isinstance(opt.deprecated, list):
Expand All @@ -1014,15 +987,17 @@ def replace(v: T.Any) -> T.Any:
old_value = opt.value
changed = opt.set_value(new_value)

if opt.readonly and changed:
raise MesonException(f'Tried modify read only option {str(key)!r}')
if opt.readonly and changed and not first_invocation:
raise MesonException(f'Tried to modify read only option {str(key)!r}')

if key.name == 'prefix' and first_invocation and changed:
assert isinstance(old_value, str), 'for mypy'
assert isinstance(new_value, str), 'for mypy'
self.reset_prefixed_options(old_value, new_value)

if changed:
self.set_dependents(key, new_value)
if changed and key.name == 'buildtype':
assert isinstance(new_value, str), 'for mypy'
self._set_dependents(key, new_value)

return changed

Expand All @@ -1032,9 +1007,9 @@ def set_option_from_string(self, keystr: T.Union[OptionKey, str], new_value: str
else:
o = OptionKey.from_string(keystr)
if o in self.options:
return self.set_value(o, new_value)
return self.set_option(o, new_value)
o = o.as_root()
return self.set_value(o, new_value)
return self.set_option(o, new_value)

def set_from_configure_command(self, D_args: T.List[str], U_args: T.List[str]) -> bool:
dirty = False
Expand Down Expand Up @@ -1279,7 +1254,7 @@ def initialize_from_top_level_project_call(self,
augstr = str(key)
self.augments[augstr] = valstr
elif key in self.options:
self.set_value(key, valstr, first_invocation)
self.set_option(key, valstr, first_invocation)
else:
proj_key = key.as_root()
if proj_key in self.options:
Expand Down Expand Up @@ -1330,7 +1305,7 @@ def initialize_from_top_level_project_call(self,
if not self.is_cross and key.is_for_build():
continue
if key in self.options:
self.set_value(key, valstr, True)
self.set_option(key, valstr, True)
elif key.subproject is None:
projectkey = key.as_root()
if projectkey in self.options:
Expand Down Expand Up @@ -1371,7 +1346,7 @@ def initialize_from_subproject_call(self,
# If the key points to a project option, set the value from that.
# Otherwise set an augment.
if key in self.project_options:
self.set_value(key, valstr, is_first_invocation)
self.set_option(key, valstr, is_first_invocation)
else:
self.pending_project_options.pop(key, None)
aug_str = f'{subproject}:{keystr}'
Expand All @@ -1385,6 +1360,6 @@ def initialize_from_subproject_call(self,
continue
self.pending_project_options.pop(key, None)
if key in self.options:
self.set_value(key, valstr, is_first_invocation)
self.set_option(key, valstr, is_first_invocation)
else:
self.augments[str(key)] = valstr

0 comments on commit 0dffe9a

Please sign in to comment.