Restore virtuals normalization on edge construction (#40130)

Put back normalization of the "virtuals" input as a sorted tuple. 

Without this we might get edges that differ just for the order of 
virtuals, or that have lists, which are not hashable.

Add unit-tests to prevent regressions.
This commit is contained in:
Massimiliano Culpo 2023-09-21 17:02:34 +02:00 committed by GitHub
parent 4c0bc39054
commit abad16c198
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 1 deletions

View File

@ -740,7 +740,7 @@ def __init__(
self.parent = parent self.parent = parent
self.spec = spec self.spec = spec
self.depflag = depflag self.depflag = depflag
self.virtuals = virtuals self.virtuals = tuple(sorted(set(virtuals)))
def update_deptypes(self, depflag: dt.DepFlag) -> bool: def update_deptypes(self, depflag: dt.DepFlag) -> bool:
"""Update the current dependency types""" """Update the current dependency types"""

View File

@ -11,6 +11,7 @@
from spack.spec import ( from spack.spec import (
ArchSpec, ArchSpec,
CompilerSpec, CompilerSpec,
DependencySpec,
Spec, Spec,
SpecFormatSigilError, SpecFormatSigilError,
SpecFormatStringError, SpecFormatStringError,
@ -1326,3 +1327,15 @@ def assert_disjoint(a: Spec, b: Spec):
# disjoint concretization space # disjoint concretization space
assert_disjoint(abstract_none, concrete) assert_disjoint(abstract_none, concrete)
assert_disjoint(abstract_none, abstract_5) assert_disjoint(abstract_none, abstract_5)
def test_edge_equality_does_not_depend_on_virtual_order():
"""Tests that two edges that are constructed with just a different order of the virtuals in
the input parameters are equal to each other.
"""
parent, child = Spec("parent"), Spec("child")
edge1 = DependencySpec(parent, child, depflag=0, virtuals=("mpi", "lapack"))
edge2 = DependencySpec(parent, child, depflag=0, virtuals=("lapack", "mpi"))
assert edge1 == edge2
assert tuple(sorted(edge1.virtuals)) == edge1.virtuals
assert tuple(sorted(edge2.virtuals)) == edge1.virtuals

View File

@ -500,3 +500,8 @@ def test_load_json_specfiles(specfile, expected_hash, reader_cls):
openmpi_edges = s2.edges_to_dependencies(name="openmpi") openmpi_edges = s2.edges_to_dependencies(name="openmpi")
assert len(openmpi_edges) == 1 assert len(openmpi_edges) == 1
# The virtuals attribute must be a tuple, when read from a
# JSON or YAML file, not a list
for edge in s2.traverse_edges():
assert isinstance(edge.virtuals, tuple), edge