diff options
author | Massimiliano Culpo <massimiliano.culpo@gmail.com> | 2021-02-23 04:09:43 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-22 19:09:43 -0800 |
commit | 7226bd64dc3b46a1ed361f1e9d7fb4a2a5b65200 (patch) | |
tree | 67868cdf09b469c2669653ae46c40f3424d34cfa /lib | |
parent | 56e57769bde417366a8aa2273e158a6841d9d9e5 (diff) | |
download | spack-7226bd64dc3b46a1ed361f1e9d7fb4a2a5b65200.tar.gz spack-7226bd64dc3b46a1ed361f1e9d7fb4a2a5b65200.tar.bz2 spack-7226bd64dc3b46a1ed361f1e9d7fb4a2a5b65200.tar.xz spack-7226bd64dc3b46a1ed361f1e9d7fb4a2a5b65200.zip |
Improve error message for inconsistencies in package.py (#21811)
* Improve error message for inconsistencies in package.py
Sometimes directives refer to variants that do not exist.
Make it such that:
1. The name of the variant
2. The name of the package which is supposed to have
such variant
3. The name of the package making this assumption
are all printed in the error message for easier debugging.
* Add unit tests
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/solver/asp.py | 33 | ||||
-rw-r--r-- | lib/spack/spack/test/concretize.py | 12 |
2 files changed, 40 insertions, 5 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 4d7b019ea6..3c00f4a968 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -647,11 +647,15 @@ class SpackSolverSetup(object): self.gen.fact(cond_fn(condition_id, pkg_name, dep_spec.name)) # conditions that trigger the condition - conditions = self.spec_clauses(named_cond, body=True) + conditions = self.checked_spec_clauses( + named_cond, body=True, required_from=pkg_name + ) for pred in conditions: self.gen.fact(require_fn(condition_id, pred.name, *pred.args)) - imposed_constraints = self.spec_clauses(dep_spec) + imposed_constraints = self.checked_spec_clauses( + dep_spec, required_from=pkg_name + ) for pred in imposed_constraints: # imposed "node"-like conditions are no-ops if pred.name in ("node", "virtual_node"): @@ -857,6 +861,20 @@ class SpackSolverSetup(object): self.gen.fact(fn.compiler_version_flag( compiler.name, compiler.version, name, flag)) + def checked_spec_clauses(self, *args, **kwargs): + """Wrap a call to spec clauses into a try/except block that raise + a comprehensible error message in case of failure. + """ + requestor = kwargs.pop('required_from', None) + try: + clauses = self.spec_clauses(*args, **kwargs) + except RuntimeError as exc: + msg = str(exc) + if requestor: + msg += ' [required from package "{0}"]'.format(requestor) + raise RuntimeError(msg) + return clauses + def spec_clauses(self, spec, body=False, transitive=True): """Return a list of clauses for a spec mandates are true. @@ -925,9 +943,14 @@ class SpackSolverSetup(object): # validate variant value reserved_names = spack.directives.reserved_names - if (not spec.virtual and vname not in reserved_names): - variant_def = spec.package.variants[vname] - variant_def.validate_or_raise(variant, spec.package) + if not spec.virtual and vname not in reserved_names: + try: + variant_def = spec.package.variants[vname] + except KeyError: + msg = 'variant "{0}" not found in package "{1}"' + raise RuntimeError(msg.format(vname, spec.name)) + else: + variant_def.validate_or_raise(variant, spec.package) clauses.append(f.variant_value(spec.name, vname, value)) diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index 283b9052cc..913a22432f 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -1098,3 +1098,15 @@ class TestConcretize(object): # dependency type declared to infer that the dependency holds. s = Spec('test-dep-with-imposed-conditions').concretized() assert 'c' not in s + + @pytest.mark.parametrize('spec_str', [ + 'wrong-variant-in-conflicts', + 'wrong-variant-in-depends-on' + ]) + def test_error_message_for_inconsistent_variants(self, spec_str): + if spack.config.get('config:concretizer') == 'original': + pytest.xfail('Known failure of the original concretizer') + + s = Spec(spec_str) + with pytest.raises(RuntimeError, match='not found in package'): + s.concretize() |