Fix regression in spec format string for indiviual variants (#46206)

Fix a regression in {variants.X} and {variants.X.value} spec format strings.
This commit is contained in:
Jordan Galby 2024-09-09 10:42:04 +02:00 committed by Harmen Stoppels
parent ef1eabe5b3
commit 1bdc30979d
2 changed files with 19 additions and 2 deletions

View file

@ -4420,9 +4420,12 @@ def format_attribute(match_object: Match) -> str:
if part.startswith("_"): if part.startswith("_"):
raise SpecFormatStringError("Attempted to format private attribute") raise SpecFormatStringError("Attempted to format private attribute")
else: else:
if part == "variants" and isinstance(current, vt.VariantMap): if isinstance(current, vt.VariantMap):
# subscript instead of getattr for variant names # subscript instead of getattr for variant names
current = current[part] try:
current = current[part]
except KeyError:
raise SpecFormatStringError(f"Variant '{part}' does not exist")
else: else:
# aliases # aliases
if part == "arch": if part == "arch":

View file

@ -672,6 +672,13 @@ def test_spec_formatting(self, default_mock_concretization):
("{/hash}", "/", lambda s: "/" + s.dag_hash()), ("{/hash}", "/", lambda s: "/" + s.dag_hash()),
] ]
variants_segments = [
("{variants.debug}", spec, "debug"),
("{variants.foo}", spec, "foo"),
("{^pkg-a.variants.bvv}", spec["pkg-a"], "bvv"),
("{^pkg-a.variants.foo}", spec["pkg-a"], "foo"),
]
other_segments = [ other_segments = [
("{spack_root}", spack.paths.spack_root), ("{spack_root}", spack.paths.spack_root),
("{spack_install}", spack.store.STORE.layout.root), ("{spack_install}", spack.store.STORE.layout.root),
@ -699,6 +706,12 @@ def check_prop(check_spec, fmt_str, prop, getter):
callpath, fmt_str = depify("callpath", named_str, sigil) callpath, fmt_str = depify("callpath", named_str, sigil)
assert spec.format(fmt_str) == getter(callpath) assert spec.format(fmt_str) == getter(callpath)
for named_str, test_spec, variant_name in variants_segments:
assert test_spec.format(named_str) == str(test_spec.variants[variant_name])
assert test_spec.format(named_str[:-1] + ".value}") == str(
test_spec.variants[variant_name].value
)
for named_str, expected in other_segments: for named_str, expected in other_segments:
actual = spec.format(named_str) actual = spec.format(named_str)
assert expected == actual assert expected == actual
@ -731,6 +744,7 @@ def test_spec_formatting_sigil_mismatches(self, default_mock_concretization, fmt
r"{dag_hash}", r"{dag_hash}",
r"{foo}", r"{foo}",
r"{+variants.debug}", r"{+variants.debug}",
r"{variants.this_variant_does_not_exist}",
], ],
) )
def test_spec_formatting_bad_formats(self, default_mock_concretization, fmt_str): def test_spec_formatting_bad_formats(self, default_mock_concretization, fmt_str):