Skip to content

Commit

Permalink
explore nested ANY settings.yml (#15415)
Browse files Browse the repository at this point in the history
  • Loading branch information
memsharded authored Jan 11, 2024
1 parent 9fb047f commit 98d68db
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
9 changes: 7 additions & 2 deletions conans/model/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ def _get_child(self, item):
raise undefined_field(self._name, item, None, self._value)
if self._value is None:
raise ConanException("'%s' value not defined" % self._name)
return self._get_definition()

def _get_definition(self):
if self._value not in self._definition and "ANY" in self._definition:
return self._definition["ANY"]
return self._definition[self._value]

def __getattr__(self, item):
Expand Down Expand Up @@ -142,15 +147,15 @@ def values_list(self):
partial_name = ".".join(self._name.split(".")[1:])
result.append((partial_name, self._value))
if isinstance(self._definition, dict):
sub_config_dict = self._definition[self._value]
sub_config_dict = self._get_definition()
result.extend(sub_config_dict.values_list)
return result

def validate(self):
if self._value is None and None not in self._definition:
raise ConanException("'%s' value not defined" % self._name)
if isinstance(self._definition, dict):
self._definition[self._value].validate()
self._get_definition().validate()

def possible_values(self):
if isinstance(self._definition, list):
Expand Down
27 changes: 27 additions & 0 deletions conans/test/unittests/model/settings_test.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import textwrap
import unittest

import pytest
Expand Down Expand Up @@ -48,6 +49,32 @@ def test_none_any(self):
self.assertTrue(settings.os == "Windows")
self.assertEqual("os=Windows", settings.dumps())

def test_nested_any(self):
yml = textwrap.dedent("""\
os:
ANY:
version: [null, ANY]
Ubuntu:
version: ["18.04", "20.04"]
""")
settings = Settings.loads(yml)
settings.os = "Windows"
settings.validate()
self.assertTrue(settings.os == "Windows")
self.assertIn("os=Windows", settings.dumps())
settings.os.version = 2
self.assertTrue(settings.os == "Windows")
self.assertEqual("os=Windows\nos.version=2", settings.dumps())
settings.os = "Ubuntu"
with self.assertRaisesRegex(ConanException, "'settings.os.version' value not defined"):
settings.validate()
with self.assertRaisesRegex(ConanException,
"Invalid setting '3' is not a valid 'settings.os.version'"):
settings.os.version = 3
settings.os.version = "20.04"
self.assertEqual("os=Ubuntu\nos.version=20.04", settings.dumps())
self.assertTrue(settings.os.version == "20.04")

def test_getattr_none(self):
yml = "os: [None, Windows]"
settings = Settings.loads(yml)
Expand Down

0 comments on commit 98d68db

Please sign in to comment.