diff options
author | Greg Becker <becker33@llnl.gov> | 2020-12-15 14:44:58 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-15 14:44:58 -0800 |
commit | 352dc0624cea9ad013e2e403bd8d78f869cf79f4 (patch) | |
tree | 9b57f57998df6ead0c417e79b562b71f68e2ef0f | |
parent | c02625eb5393a98866c78b251364f5b595cae7ab (diff) | |
download | spack-352dc0624cea9ad013e2e403bd8d78f869cf79f4.tar.gz spack-352dc0624cea9ad013e2e403bd8d78f869cf79f4.tar.bz2 spack-352dc0624cea9ad013e2e403bd8d78f869cf79f4.tar.xz spack-352dc0624cea9ad013e2e403bd8d78f869cf79f4.zip |
Fix comparisons for abstract specs (#20341)
bug only relevant for python3
-rw-r--r-- | lib/spack/spack/spec.py | 7 | ||||
-rw-r--r-- | lib/spack/spack/test/spec_syntax.py | 25 |
2 files changed, 29 insertions, 3 deletions
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index 88516470fb..a424dc60c9 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -3517,8 +3517,11 @@ class Spec(object): def _cmp_node(self): """Comparison key for just *this node* and not its deps.""" - return (self.name, - self.namespace, + # Name or namespace None will lead to invalid comparisons for abstract + # specs. Replace them with the empty string, which is not a valid spec + # name nor namespace so it will not create spurious equalities. + return (self.name or '', + self.namespace or '', tuple(self.versions), self.variants, self.architecture, diff --git a/lib/spack/spack/test/spec_syntax.py b/lib/spack/spack/test/spec_syntax.py index edfe73f3e5..b59828206f 100644 --- a/lib/spack/spack/test/spec_syntax.py +++ b/lib/spack/spack/test/spec_syntax.py @@ -2,7 +2,7 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) - +import itertools import os import pytest import shlex @@ -806,3 +806,26 @@ class TestSpecSyntax(object): ]) def test_target_tokenization(self, expected_tokens, spec_string): self.check_lex(expected_tokens, spec_string) + + @pytest.mark.regression('20310') + def test_compare_abstract_specs(self): + """Spec comparisons must be valid for abstract specs. + + Check that the spec cmp_key appropriately handles comparing specs for + which some attributes are None in exactly one of two specs""" + # Add fields in order they appear in `Spec._cmp_node` + constraints = [ + None, + 'foo', + 'foo.foo', + 'foo.foo@foo', + 'foo.foo@foo+foo', + 'foo.foo@foo+foo arch=foo-foo-foo', + 'foo.foo@foo+foo arch=foo-foo-foo %foo', + 'foo.foo@foo+foo arch=foo-foo-foo %foo cflags=foo', + ] + specs = [Spec(s) for s in constraints] + + for a, b in itertools.product(specs, repeat=2): + # Check that we can compare without raising an error + assert a <= b or b < a |