From 39105a3a6f2fe49376a2068a5885fcbdb4a5acbf Mon Sep 17 00:00:00 2001 From: Harmen Stoppels Date: Mon, 17 Oct 2022 18:14:12 +0200 Subject: installer.py: traverse_dependencies has local deptype (#33367) Currently `traverse_dependencies` fixes deptypes to traverse once and for all in the recursion, but this is incorrect, since deptypes depend on the node (e.g. if it's a dependency and cache-only, don't follow build type edges, even if the parent is build from sources and needs build deps.) --- lib/spack/spack/installer.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/spack/spack/installer.py b/lib/spack/spack/installer.py index 1de78e392b..ca53f87691 100644 --- a/lib/spack/spack/installer.py +++ b/lib/spack/spack/installer.py @@ -2426,21 +2426,31 @@ class BuildRequest(object): """The specification associated with the package.""" return self.pkg.spec - def traverse_dependencies(self): + def traverse_dependencies(self, spec=None, visited=None): """ Yield any dependencies of the appropriate type(s) Yields: (Spec) The next child spec in the DAG """ - get_spec = lambda s: s.spec - - deptypes = self.get_deptypes(self.pkg) - tty.debug("Processing dependencies for {0}: {1}".format(self.pkg_id, deptypes)) - for dspec in self.spec.traverse_edges( - deptype=deptypes, order="post", root=False, direction="children" - ): - yield get_spec(dspec) + # notice: deptype is not constant across nodes, so we cannot use + # spec.traverse_edges(deptype=...). + + if spec is None: + spec = self.spec + if visited is None: + visited = set() + deptype = self.get_deptypes(spec.package) + + for dep in spec.dependencies(deptype=deptype): + hash = dep.dag_hash() + if hash in visited: + continue + visited.add(hash) + # In Python 3: yield from self.traverse_dependencies(dep, visited) + for s in self.traverse_dependencies(dep, visited): + yield s + yield dep class InstallError(spack.error.SpackError): -- cgit v1.2.3-70-g09d2