Better error message when setting unknown variants during concretization (#13128)

fixes #13124
This commit is contained in:
Massimiliano Culpo 2019-12-10 20:21:45 +01:00 committed by Greg Becker
parent 34f0195de8
commit 59d222c172
3 changed files with 17 additions and 8 deletions

View File

@ -2661,7 +2661,7 @@ def validate_or_raise(self):
not_existing = set(spec.variants) - ( not_existing = set(spec.variants) - (
set(pkg_variants) | set(spack.directives.reserved_names)) set(pkg_variants) | set(spack.directives.reserved_names))
if not_existing: if not_existing:
raise UnknownVariantError(spec.name, not_existing) raise UnknownVariantError(spec, not_existing)
substitute_abstract_variants(spec) substitute_abstract_variants(spec)

View File

@ -9,7 +9,7 @@
from spack.spec import Spec, UnsatisfiableSpecError, SpecError from spack.spec import Spec, UnsatisfiableSpecError, SpecError
from spack.spec import substitute_abstract_variants from spack.spec import substitute_abstract_variants
from spack.spec import SpecFormatSigilError, SpecFormatStringError from spack.spec import SpecFormatSigilError, SpecFormatStringError
from spack.variant import InvalidVariantValueError from spack.variant import InvalidVariantValueError, UnknownVariantError
from spack.variant import MultipleValuesInExclusiveVariantError from spack.variant import MultipleValuesInExclusiveVariantError
import spack.architecture import spack.architecture
@ -981,3 +981,9 @@ def test_forwarding_of_architecture_attributes(self):
def test_target_constraints(self, spec, constraint, expected_result): def test_target_constraints(self, spec, constraint, expected_result):
s = Spec(spec) s = Spec(spec)
assert s.satisfies(constraint) is expected_result assert s.satisfies(constraint) is expected_result
@pytest.mark.regression('13124')
def test_error_message_unknown_variant(self):
s = Spec('mpileaks +unknown')
with pytest.raises(UnknownVariantError, match=r'package has no such'):
s.concretize()

View File

@ -600,7 +600,9 @@ def substitute_abstract_variants(spec):
for name, v in spec.variants.items(): for name, v in spec.variants.items():
if name in spack.directives.reserved_names: if name in spack.directives.reserved_names:
continue continue
pkg_variant = spec.package_class.variants[name] pkg_variant = spec.package_class.variants.get(name, None)
if not pkg_variant:
raise UnknownVariantError(spec, [name])
new_variant = pkg_variant.make_variant(v._original_value) new_variant = pkg_variant.make_variant(v._original_value)
pkg_variant.validate_or_raise(new_variant, spec.package_class) pkg_variant.validate_or_raise(new_variant, spec.package_class)
spec.variants.substitute(new_variant) spec.variants.substitute(new_variant)
@ -778,12 +780,13 @@ class DuplicateVariantError(error.SpecError):
class UnknownVariantError(error.SpecError): class UnknownVariantError(error.SpecError):
"""Raised when an unknown variant occurs in a spec.""" """Raised when an unknown variant occurs in a spec."""
def __init__(self, spec, variants):
def __init__(self, pkg, variants):
self.unknown_variants = variants self.unknown_variants = variants
super(UnknownVariantError, self).__init__( variant_str = 'variant' if len(variants) == 1 else 'variants'
'Package {0} has no variant {1}!'.format(pkg, comma_or(variants)) msg = ('trying to set {0} "{1}" in package "{2}", but the package'
) ' has no such {0} [happened during concretization of {3}]')
msg = msg.format(variant_str, comma_or(variants), spec.name, spec.root)
super(UnknownVariantError, self).__init__(msg)
class InconsistentValidationError(error.SpecError): class InconsistentValidationError(error.SpecError):