From 84cfb3b7fea78f81af5c6c1345a3b3db2d59b9dd Mon Sep 17 00:00:00 2001 From: Scott Wittenburg Date: Mon, 28 Feb 2022 12:46:30 -0700 Subject: spec: fix infinite recursion when computing package hash Issue described in the following PR comment: https://github.com/spack/spack/pull/28504#issuecomment-1051835568 Solution described in subsequent comment: https://github.com/spack/spack/pull/28504#issuecomment-1053986132 --- lib/spack/spack/spec.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index ac9b034d07..a5a3ab9aed 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -1823,6 +1823,10 @@ class Spec(object): """Get the first bits of the DAG hash as an integer type.""" return spack.util.hash.base32_prefix_bits(self.dag_hash(), bits) + def process_hash_bit_prefix(self, bits): + """Get the first bits of the DAG hash as an integer type.""" + return spack.util.hash.base32_prefix_bits(self.process_hash(), bits) + def to_node_dict(self, hash=ht.dag_hash): """Create a dictionary representing the state of this Spec. @@ -4737,14 +4741,18 @@ class Spec(object): self._dunder_hash = None def __hash__(self): - # If the spec is concrete, we leverage the DAG hash and just use - # a 64-bit prefix of it. The DAG hash has the advantage that it's - # computed once per concrete spec, and it's saved -- so if we - # read concrete specs we don't need to recompute the whole hash. - # This is good for large, unchanging specs. + # If the spec is concrete, we leverage the process hash and just use + # a 64-bit prefix of it. The process hash has the advantage that it's + # computed once per concrete spec, and it's saved -- so if we read + # concrete specs we don't need to recompute the whole hash. This is + # good for large, unchanging specs. + # + # We use the process hash instead of the DAG hash here because the DAG + # hash includes the package hash, which can cause infinite recursion, + # and which isn't defined unless the spec has a known package. if self.concrete: if not self._dunder_hash: - self._dunder_hash = self.dag_hash_bit_prefix(64) + self._dunder_hash = self.process_hash_bit_prefix(64) return self._dunder_hash # This is the normal hash for lazy_lexicographic_ordering. It's -- cgit v1.2.3-70-g09d2