summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2024-09-03 09:02:15 -0700
committerJussi Pakkanen <jpakkane@gmail.com>2025-02-05 17:45:38 +0200
commit8eba69cbaaa6498ecb0a43fac64e81b7f764d572 (patch)
tree249b6479c4b0793120cf4cb04439218dfd022b8a
parent177148686c8c207268619d2d58ee021b1d6fd082 (diff)
downloadmeson-8eba69cbaaa6498ecb0a43fac64e81b7f764d572.tar.gz
options: Add a function to compare different option choices
This allows us to hide type differences inside the options module, but still get accurate change information.
-rw-r--r--mesonbuild/coredata.py2
-rw-r--r--mesonbuild/options.py26
2 files changed, 26 insertions, 2 deletions
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 6b8cec63f..b9a6b6d5d 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -599,7 +599,7 @@ class CoreData:
oldval = self.optstore.get_value_object(key)
if type(oldval) is not type(value):
self.optstore.set_value(key, value.value)
- elif oldval.printable_choices() != value.printable_choices():
+ 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
# defaults but warn.
diff --git a/mesonbuild/options.py b/mesonbuild/options.py
index 87c31d21c..23dc5fc86 100644
--- a/mesonbuild/options.py
+++ b/mesonbuild/options.py
@@ -484,7 +484,31 @@ class UserFeatureOption(UserComboOption):
return self.value == 'auto'
-@dataclasses.dataclass(init=False)
+_U = T.TypeVar('_U', bound=UserOption)
+
+
+def choices_are_different(a: _U, b: _U) -> bool:
+ """Are the choices between two options the same?
+
+ :param a: A UserOption[T]
+ :param b: A second UserOption[T]
+ :return: True if the choices have changed, otherwise False
+ """
+ if isinstance(a, EnumeratedUserOption):
+ # We expect `a` and `b` to be of the same type, but can't really annotate it that way.
+ assert isinstance(b, EnumeratedUserOption), 'for mypy'
+ return a.choices != b.choices
+ elif isinstance(a, UserArrayOption):
+ # We expect `a` and `b` to be of the same type, but can't really annotate it that way.
+ assert isinstance(b, UserArrayOption), 'for mypy'
+ return a.choices != b.choices
+ elif isinstance(a, _UserIntegerBase):
+ assert isinstance(b, _UserIntegerBase), 'for mypy'
+ return a.max_value != b.max_value or a.min_value != b.min_value
+
+ return False
+
+
class UserStdOption(UserComboOption):
'''
UserOption specific to c_std and cpp_std options. User can set a list of