Skip to content

Commit

Permalink
[settings] subsettings from fake settings (#16642)
Browse files Browse the repository at this point in the history
* Testing

* Trying to avoid raising any error when compatibility check

* Added UTs. Covered all the logic by the try-catch section

* Added integration test and renamed parameter
  • Loading branch information
franramirez688 authored Jul 12, 2024
1 parent 0b5860e commit 8485417
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 10 deletions.
4 changes: 2 additions & 2 deletions conans/client/graph/compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,12 @@ def _compatible_infos(conanfile, compatibles):
compat_info = conanfile.original_info.clone()
settings = elem.get("settings")
if settings:
compat_info.settings.update_values(settings)
compat_info.settings.update_values(settings, raise_undefined=False)
options = elem.get("options")
if options:
compat_info.options.update(options_values=OrderedDict(options))
result.append(compat_info)
settings_target = elem.get("settings_target")
if settings_target and compat_info.settings_target:
compat_info.settings_target.update_values(settings_target)
compat_info.settings_target.update_values(settings_target, raise_undefined=False)
return result
17 changes: 9 additions & 8 deletions conans/model/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,23 +302,24 @@ def values_list(self):
def items(self):
return self.values_list

def update_values(self, vals):
""" receives a list of tuples (compiler.version, value)
This is more an updated than a setter
def update_values(self, values, raise_undefined=True):
"""
Receives a list of tuples (compiler.version, value)
This is more an updater than a setter.
"""
self._frozen = False # Could be restored at the end, but not really necessary
assert isinstance(vals, (list, tuple)), vals
for (name, value) in vals:
assert isinstance(values, (list, tuple)), values
for (name, value) in values:
list_settings = name.split(".")
attr = self
try:
for setting in list_settings[:-1]:
attr = getattr(attr, setting)
except ConanException: # fails if receiving settings doesn't have it defined
pass
else:
value = str(value) if value is not None else None
setattr(attr, list_settings[-1], value)
except ConanException: # fails if receiving settings doesn't have it defined
if raise_undefined:
raise

def constrained(self, constraint_def):
""" allows to restrict a given Settings object with the input of another Settings object
Expand Down
13 changes: 13 additions & 0 deletions test/integration/settings/test_non_defining_settings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import textwrap

from conan.test.assets.genconanfile import GenConanfile
from conan.test.utils.tools import TestClient


Expand Down Expand Up @@ -29,3 +30,15 @@ def package_id(self):
# It doesn't fail, even if settings not defined
c.run("install --requires=pkg/1.0 -pr=profile -s os=Linux -s arch=x86")
# It doesn't fail, even if settings different value


def test_settings_undefined():
client = TestClient()
client.save({
"conanfile.py": GenConanfile(name="hello", version="1.0")
})
# Undefined settings field
client.run("install . -s foo=None", assert_error=True)
assert "'settings.foo' doesn't exist for 'settings'" in client.out
client.run("install . -s foo.bar=None", assert_error=True)
assert "'settings.foo' doesn't exist for 'settings'" in client.out
22 changes: 22 additions & 0 deletions test/unittests/model/settings_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,3 +481,25 @@ def test_settings_intel_cppstd_03():
settings.compiler = "intel-cc"
# This doesn't crash, it used to crash due to "03" not quoted in setting.yml
settings.compiler.cppstd = "03"


def test_set_value_non_existing_values():
data = {
"compiler": {
"gcc": {
"version": ["4.8", "4.9"],
"arch": {"x86": {"speed": ["A", "B"]},
"x64": {"speed": ["C", "D"]}}}
},
"os": ["Windows", "Linux"]
}
settings = Settings(data)
with pytest.raises(ConanException) as cm:
settings.update_values([("foo", "A")])
assert "'settings.foo' doesn't exist for 'settings'" in str(cm.value)
with pytest.raises(ConanException) as cm:
settings.update_values([("foo.bar", "A")])
assert "'settings.foo' doesn't exist for 'settings'" in str(cm.value)
# it does not raise any error
settings.update_values([("foo", "A")], raise_undefined=False)
settings.update_values([("foo.bar", "A")], raise_undefined=False)

0 comments on commit 8485417

Please sign in to comment.