summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/spec.py12
-rw-r--r--lib/spack/spack/test/spec_list.py19
2 files changed, 26 insertions, 5 deletions
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 141f6c4b62..30a67a55a8 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -3568,7 +3568,9 @@ class Spec(object):
)
# Update with additional constraints from other spec
- for name in other.dep_difference(self):
+ # operate on direct dependencies only, because a concrete dep
+ # represented by hash may have structure that needs to be preserved
+ for name in other.direct_dep_difference(self):
dep_spec_copy = other._get_dependency(name)
dep_copy = dep_spec_copy.spec
deptypes = dep_spec_copy.deptypes
@@ -3589,10 +3591,10 @@ class Spec(object):
clone.constrain(other, deps)
return clone
- def dep_difference(self, other):
+ def direct_dep_difference(self, other):
"""Returns dependencies in self that are not in other."""
- mine = set(s.name for s in self.traverse(root=False))
- mine.difference_update(s.name for s in other.traverse(root=False))
+ mine = set(dname for dname in self._dependencies)
+ mine.difference_update(dname for dname in other._dependencies)
return mine
def _autospec(self, spec_like):
@@ -4871,7 +4873,7 @@ def merge_abstract_anonymous_specs(*abstract_specs):
merged_spec[name].constrain(current_spec_constraint[name], deps=False)
# Update with additional constraints from other spec
- for name in current_spec_constraint.dep_difference(merged_spec):
+ for name in current_spec_constraint.direct_dep_difference(merged_spec):
edge = next(iter(current_spec_constraint.edges_to_dependencies(name)))
merged_spec._add_dependency(edge.spec.copy(), edge.deptypes)
diff --git a/lib/spack/spack/test/spec_list.py b/lib/spack/spack/test/spec_list.py
index 487417dff1..8923f6e1f6 100644
--- a/lib/spack/spack/test/spec_list.py
+++ b/lib/spack/spack/test/spec_list.py
@@ -200,3 +200,22 @@ class TestSpecList(object):
]
speclist = SpecList("specs", matrix)
assert len(speclist.specs) == 1
+
+ @pytest.mark.regression("22991")
+ def test_spec_list_constraints_with_structure(
+ self, mock_packages, mock_fetch, install_mockery
+ ):
+ # Setup by getting hash and installing package with dep
+ libdwarf_spec = Spec("libdwarf").concretized()
+ libdwarf_spec.package.do_install()
+
+ # Create matrix
+ matrix = {
+ "matrix": [["mpileaks"], ["^callpath"], ["^libdwarf/%s" % libdwarf_spec.dag_hash()]]
+ }
+
+ # ensure the concrete spec was retained in the matrix entry of which
+ # it is a dependency
+ speclist = SpecList("specs", [matrix])
+ assert len(speclist.specs) == 1
+ assert libdwarf_spec in speclist.specs[0]