diff --git a/lib/spack/spack/directives.py b/lib/spack/spack/directives.py index bac466ed213..7dddd652674 100644 --- a/lib/spack/spack/directives.py +++ b/lib/spack/spack/directives.py @@ -462,8 +462,7 @@ def _execute_extends(pkg): if dep_spec.name == "python" and not pkg.name == "python-venv": _depends_on(pkg, spack.spec.Spec("python-venv"), when=when, type=("build", "run")) - # TODO: the values of the extendees dictionary are not used. Remove in next refactor. - pkg.extendees[dep_spec.name] = (dep_spec, None) + pkg.extendees[dep_spec.name] = (dep_spec, when_spec) return _execute_extends diff --git a/lib/spack/spack/package_base.py b/lib/spack/spack/package_base.py index 395a563fc4c..b2ab47ed359 100644 --- a/lib/spack/spack/package_base.py +++ b/lib/spack/spack/package_base.py @@ -1288,12 +1288,13 @@ def extendee_spec(self): if not self.extendees: return None - deps = [] - # If the extendee is in the spec's deps already, return that. - for dep in self.spec.traverse(deptype=("link", "run")): - if dep.name in self.extendees: - deps.append(dep) + deps = [ + dep + for dep in self.spec.dependencies(deptype=("link", "run")) + for d, when in self.extendees.values() + if dep.satisfies(d) and self.spec.satisfies(when) + ] if deps: assert len(deps) == 1 diff --git a/lib/spack/spack/test/directives.py b/lib/spack/spack/test/directives.py index 47f8023d598..06d5f43ff84 100644 --- a/lib/spack/spack/test/directives.py +++ b/lib/spack/spack/test/directives.py @@ -67,6 +67,20 @@ def test_extends_spec(config, mock_packages): assert extender.package.extends(extendee) +@pytest.mark.regression("48024") +def test_conditionally_extends_transitive_dep(config, mock_packages): + spec = spack.spec.Spec("conditionally-extends-transitive-dep").concretized() + + assert not spec.package.extendee_spec + + +@pytest.mark.regression("48025") +def test_conditionally_extends_direct_dep(config, mock_packages): + spec = spack.spec.Spec("conditionally-extends-direct-dep").concretized() + + assert not spec.package.extendee_spec + + @pytest.mark.regression("34368") def test_error_on_anonymous_dependency(config, mock_packages): pkg = spack.repo.PATH.get_pkg_class("pkg-a") diff --git a/var/spack/repos/builtin.mock/packages/conditionally-extends-direct-dep/package.py b/var/spack/repos/builtin.mock/packages/conditionally-extends-direct-dep/package.py new file mode 100644 index 00000000000..8d134ea2860 --- /dev/null +++ b/var/spack/repos/builtin.mock/packages/conditionally-extends-direct-dep/package.py @@ -0,0 +1,18 @@ +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +from spack.package import * + + +class ConditionallyExtendsDirectDep(Package): + """Package that tests if the extends directive supports a spec.""" + + homepage = "http://www.example.com" + url = "http://www.example.com/example-1.0.tar.gz" + + version("1.0", md5="0123456789abcdef0123456789abcdef") + + extends("extendee", when="@2:") # will not satisfy version + depends_on("extendee") diff --git a/var/spack/repos/builtin.mock/packages/conditionally-extends-transitive-dep/package.py b/var/spack/repos/builtin.mock/packages/conditionally-extends-transitive-dep/package.py new file mode 100644 index 00000000000..071213dab41 --- /dev/null +++ b/var/spack/repos/builtin.mock/packages/conditionally-extends-transitive-dep/package.py @@ -0,0 +1,18 @@ +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +from spack.package import * + + +class ConditionallyExtendsTransitiveDep(Package): + """Package that tests if the extends directive supports a spec.""" + + homepage = "http://www.example.com" + url = "http://www.example.com/example-1.0.tar.gz" + + version("1.0", md5="0123456789abcdef0123456789abcdef") + + extends("extendee", when="@2:") # will not satisfy version + depends_on("extension1")