diff --git a/lib/spack/spack/package_base.py b/lib/spack/spack/package_base.py index 8f6669d10e7..af5a4b8515b 100644 --- a/lib/spack/spack/package_base.py +++ b/lib/spack/spack/package_base.py @@ -767,6 +767,9 @@ def __init__(self, spec): self.win_rpath = fsys.WindowsSimulatedRPath(self) super().__init__() + def __getitem__(self, key: str) -> "PackageBase": + return self.spec[key].package + @classmethod def dependency_names(cls): return _subkeys(cls.dependencies) diff --git a/lib/spack/spack/test/package_class.py b/lib/spack/spack/test/package_class.py index 255b8a67007..2730aad40c4 100644 --- a/lib/spack/spack/test/package_class.py +++ b/lib/spack/spack/test/package_class.py @@ -285,3 +285,16 @@ def compilers(compiler, arch_spec): error = capfd.readouterr()[1] assert "Skipping tests for package" in error assert "test requires missing compiler" in error + + +def test_package_subscript(default_mock_concretization): + """Tests that we can use the subscript notation on packages, and that it returns a package""" + root = default_mock_concretization("mpileaks") + root_pkg = root.package + + # Subscript of a virtual + assert isinstance(root_pkg["mpi"], spack.package_base.PackageBase) + + # Subscript on concrete + for d in root.traverse(): + assert isinstance(root_pkg[d.name], spack.package_base.PackageBase) diff --git a/var/spack/repos/builtin/packages/cp2k/package.py b/var/spack/repos/builtin/packages/cp2k/package.py index 6b91b0a3d6a..c80959d5990 100644 --- a/var/spack/repos/builtin/packages/cp2k/package.py +++ b/var/spack/repos/builtin/packages/cp2k/package.py @@ -790,7 +790,7 @@ def edit(self, pkg, spec, prefix): "# include Plumed.inc as recommended by" "PLUMED to include libraries and flags" ) - mkf.write("include {0}\n".format(spec["plumed"].package.plumed_inc)) + mkf.write("include {0}\n".format(self.pkg["plumed"].plumed_inc)) mkf.write("\n# COMPILER, LINKER, TOOLS\n\n") mkf.write( diff --git a/var/spack/repos/builtin/packages/glvis/package.py b/var/spack/repos/builtin/packages/glvis/package.py index 20cdc9208c4..4bd9e12a6fe 100644 --- a/var/spack/repos/builtin/packages/glvis/package.py +++ b/var/spack/repos/builtin/packages/glvis/package.py @@ -153,7 +153,7 @@ def common_args(self): "CC={0}".format(env["CC"]), "PREFIX={0}".format(self.spec.prefix.bin), "MFEM_DIR={0}".format(self.spec["mfem"].prefix), - "CONFIG_MK={0}".format(self.spec["mfem"].package.config_mk), + "CONFIG_MK={0}".format(self.pkg["mfem"].config_mk), ] # https://github.com/spack/spack/issues/42839 diff --git a/var/spack/repos/builtin/packages/gromacs/package.py b/var/spack/repos/builtin/packages/gromacs/package.py index 181224f8ccd..ea9af54c6cb 100644 --- a/var/spack/repos/builtin/packages/gromacs/package.py +++ b/var/spack/repos/builtin/packages/gromacs/package.py @@ -585,7 +585,7 @@ def patch(self): ) if self.spec.satisfies("+plumed"): - self.spec["plumed"].package.apply_patch(self) + self["plumed"].apply_patch(self) if self.spec.satisfies("%nvhpc"): # Disable obsolete workaround diff --git a/var/spack/repos/builtin/packages/laghos/package.py b/var/spack/repos/builtin/packages/laghos/package.py index b8194987676..1c9ca551279 100644 --- a/var/spack/repos/builtin/packages/laghos/package.py +++ b/var/spack/repos/builtin/packages/laghos/package.py @@ -58,8 +58,8 @@ def build_targets(self): spec = self.spec targets.append("MFEM_DIR=%s" % spec["mfem"].prefix) - targets.append("CONFIG_MK=%s" % spec["mfem"].package.config_mk) - targets.append("TEST_MK=%s" % spec["mfem"].package.test_mk) + targets.append("CONFIG_MK=%s" % self["mfem"].config_mk) + targets.append("TEST_MK=%s" % self["mfem"].test_mk) if spec.satisfies("@:2.0"): targets.append("CXX=%s" % spec["mpi"].mpicxx) if self.spec.satisfies("+ofast %gcc"): diff --git a/var/spack/repos/builtin/packages/mfem/package.py b/var/spack/repos/builtin/packages/mfem/package.py index 05a5239b897..d58e66eaf23 100644 --- a/var/spack/repos/builtin/packages/mfem/package.py +++ b/var/spack/repos/builtin/packages/mfem/package.py @@ -1309,7 +1309,7 @@ def libs(self): @property def config_mk(self): """Export the location of the config.mk file. - This property can be accessed using spec["mfem"].package.config_mk + This property can be accessed using pkg["mfem"].config_mk """ dirs = [self.prefix, self.prefix.share.mfem] for d in dirs: @@ -1321,7 +1321,7 @@ def config_mk(self): @property def test_mk(self): """Export the location of the test.mk file. - This property can be accessed using spec["mfem"].package.test_mk. + This property can be accessed using pkg["mfem"].test_mk. In version 3.3.2 and newer, the location of test.mk is also defined inside config.mk, variable MFEM_TEST_MK. """ diff --git a/var/spack/repos/builtin/packages/namd/package.py b/var/spack/repos/builtin/packages/namd/package.py index d9de65c72c1..ab8433bc7f0 100644 --- a/var/spack/repos/builtin/packages/namd/package.py +++ b/var/spack/repos/builtin/packages/namd/package.py @@ -147,11 +147,9 @@ def _copy_arch_file(self, lib): def _append_option(self, opts, lib): if lib != "python": self._copy_arch_file(lib) - spec = self.spec + lib_pkg = self[lib] lib_prefix = ( - spec[lib].package.component_prefix - if spec[lib].name == "intel-oneapi-mkl" - else spec[lib].prefix + lib_pkg.component_prefix if lib_pkg.name == "intel-oneapi-mkl" else lib_pkg.prefix ) opts.extend(["--with-{0}".format(lib), "--{0}-prefix".format(lib), lib_prefix]) diff --git a/var/spack/repos/builtin/packages/nfft/package.py b/var/spack/repos/builtin/packages/nfft/package.py index 4a599f30b4c..3bcd122d881 100644 --- a/var/spack/repos/builtin/packages/nfft/package.py +++ b/var/spack/repos/builtin/packages/nfft/package.py @@ -35,7 +35,7 @@ class Nfft(AutotoolsPackage): @property def fftw_selected_precisions(self): if not self._fftw_precisions: - self._fftw_precisions = self.spec["fftw"].package.selected_precisions + self._fftw_precisions = self["fftw"].selected_precisions return self._fftw_precisions def configure(self, spec, prefix): diff --git a/var/spack/repos/builtin/packages/openvdb/package.py b/var/spack/repos/builtin/packages/openvdb/package.py index e97930591fb..d9802f00769 100644 --- a/var/spack/repos/builtin/packages/openvdb/package.py +++ b/var/spack/repos/builtin/packages/openvdb/package.py @@ -84,10 +84,10 @@ def post_install(self): pyso = "pyopenvdb.dylib" else: pyso = "pyopenvdb.so" - pyver = "python{0}".format(spec["python"].package.version.up_to(2)) + pyver = f"python{self['python'].version.up_to(2)}" - src = prefix.lib.join(pyver).join(pyso) + src = self.prefix.lib.join(pyver).join(pyso) if not os.path.isfile(src): - src = prefix.lib64.join(pyver).join(pyso) + src = self.prefix.lib64.join(pyver).join(pyso) assert os.path.isfile(src) os.rename(src, os.path.join(python_platlib, pyso)) diff --git a/var/spack/repos/builtin/packages/osmesa/package.py b/var/spack/repos/builtin/packages/osmesa/package.py index 3b591a9874a..a08116dfae9 100644 --- a/var/spack/repos/builtin/packages/osmesa/package.py +++ b/var/spack/repos/builtin/packages/osmesa/package.py @@ -21,11 +21,11 @@ def home(self): @property def headers(self): - return self.spec["mesa"].package.libosmesa_headers + return self["mesa"].libosmesa_headers @property def libs(self): - return self.spec["mesa"].package.libosmesa_libs + return self["mesa"].libosmesa_libs @property def gl_headers(self): @@ -33,4 +33,4 @@ def gl_headers(self): @property def gl_libs(self): - return self.spec["mesa"].package.libosmesa_libs + return self["mesa"].libosmesa_libs diff --git a/var/spack/repos/builtin/packages/pnfft/package.py b/var/spack/repos/builtin/packages/pnfft/package.py index 2d920b31b54..20fe8a1f5f1 100644 --- a/var/spack/repos/builtin/packages/pnfft/package.py +++ b/var/spack/repos/builtin/packages/pnfft/package.py @@ -31,7 +31,7 @@ class Pnfft(AutotoolsPackage): @property def fftw_selected_precisions(self): if not self._fftw_precisions: - self._fftw_precisions = self.spec["fftw"].package.selected_precisions + self._fftw_precisions = self["fftw"].selected_precisions return self._fftw_precisions def configure(self, spec, prefix): diff --git a/var/spack/repos/builtin/packages/py-pyqt4/package.py b/var/spack/repos/builtin/packages/py-pyqt4/package.py index 1c2f6394cd5..347ef9d2ac1 100644 --- a/var/spack/repos/builtin/packages/py-pyqt4/package.py +++ b/var/spack/repos/builtin/packages/py-pyqt4/package.py @@ -43,7 +43,7 @@ def configure_args(self): "--sip", self.spec["py-sip"].prefix.bin.sip, "--sip-incdir", - join_path(self.spec["py-sip"].prefix, self.spec["python"].package.include), + join_path(self.spec["py-sip"].prefix, self["python"].include), "--bindir", self.prefix.bin, "--destdir", diff --git a/var/spack/repos/builtin/packages/py-sip/package.py b/var/spack/repos/builtin/packages/py-sip/package.py index f9913dfd4d1..428fc74973f 100644 --- a/var/spack/repos/builtin/packages/py-sip/package.py +++ b/var/spack/repos/builtin/packages/py-sip/package.py @@ -71,7 +71,7 @@ def install(self, spec, prefix): "--sip-module={0}".format(spec.variants["module"].value), "--bindir={0}".format(prefix.bin), "--destdir={0}".format(python_platlib), - "--incdir={0}".format(join_path(prefix, spec["python"].package.include)), + "--incdir={0}".format(join_path(prefix, self["python"].include)), "--sipdir={0}".format(prefix.share.sip), "--stubsdir={0}".format(python_platlib), ] diff --git a/var/spack/repos/builtin/packages/qgis/package.py b/var/spack/repos/builtin/packages/qgis/package.py index 613b4906e9c..cbc87e63618 100644 --- a/var/spack/repos/builtin/packages/qgis/package.py +++ b/var/spack/repos/builtin/packages/qgis/package.py @@ -217,9 +217,7 @@ def fix_qsci_sip(self): elif "^py-pyqt6" in self.spec: pyqtx = "PyQt6" - sip_inc_dir = join_path( - self.spec["qscintilla"].package.module.python_platlib, pyqtx, "bindings" - ) + sip_inc_dir = join_path(self["qscintilla"].module.python_platlib, pyqtx, "bindings") with open(join_path("python", "gui", "pyproject.toml.in"), "a") as tomlfile: tomlfile.write(f'\n[tool.sip.project]\nsip-include-dirs = ["{sip_inc_dir}"]\n') diff --git a/var/spack/repos/builtin/packages/qscintilla/package.py b/var/spack/repos/builtin/packages/qscintilla/package.py index 234e740e03a..f70f84817d2 100644 --- a/var/spack/repos/builtin/packages/qscintilla/package.py +++ b/var/spack/repos/builtin/packages/qscintilla/package.py @@ -101,9 +101,7 @@ def make_qsci_python(self): with working_dir(join_path(self.stage.source_path, "Python")): copy(ftoml, "pyproject.toml") - sip_inc_dir = join_path( - self.spec[py_pyqtx].package.module.python_platlib, pyqtx, "bindings" - ) + sip_inc_dir = join_path(self[py_pyqtx].module.python_platlib, pyqtx, "bindings") with open("pyproject.toml", "a") as tomlfile: # https://pyqt-builder.readthedocs.io/en/latest/pyproject_toml.html diff --git a/var/spack/repos/builtin/packages/remhos/package.py b/var/spack/repos/builtin/packages/remhos/package.py index 50481808f66..b365f9a5865 100644 --- a/var/spack/repos/builtin/packages/remhos/package.py +++ b/var/spack/repos/builtin/packages/remhos/package.py @@ -38,14 +38,11 @@ class Remhos(MakefilePackage): @property def build_targets(self): - targets = [] - spec = self.spec - - targets.append("MFEM_DIR=%s" % spec["mfem"].prefix) - targets.append("CONFIG_MK=%s" % spec["mfem"].package.config_mk) - targets.append("TEST_MK=%s" % spec["mfem"].package.test_mk) - - return targets + return [ + f"MFEM_DIR={self['mfem'].prefix}", + f"CONFIG_MK={self['mfem'].config_mk}", + f"TEST_MK={self['mfem'].test_mk}", + ] # See lib/spack/spack/build_systems/makefile.py def check(self): diff --git a/var/spack/repos/builtin/packages/tau/package.py b/var/spack/repos/builtin/packages/tau/package.py index 19067a3e7d9..6c3382ce001 100644 --- a/var/spack/repos/builtin/packages/tau/package.py +++ b/var/spack/repos/builtin/packages/tau/package.py @@ -323,8 +323,8 @@ def install(self, spec, prefix): env["F77"] = spec["mpi"].mpif77 env["FC"] = spec["mpi"].mpifc if spec["mpi"].name == "intel-oneapi-mpi": - options.append("-mpiinc=%s/include" % spec["mpi"].package.component_prefix) - options.append("-mpilib=%s/lib" % spec["mpi"].package.component_prefix) + options.append("-mpiinc=%s/include" % self["mpi"].component_prefix) + options.append("-mpilib=%s/lib" % self["mpi"].component_prefix) else: options.append("-mpiinc=%s" % spec["mpi"].prefix.include) options.append("-mpilib=%s" % spec["mpi"].prefix.lib)