summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2022-04-23 01:46:45 +0200
committerGitHub <noreply@github.com>2022-04-22 16:46:45 -0700
commita9fbc0175d8a1a3e444febac9edc84d42500d79a (patch)
tree183562e71578da3bbd3a789a7ffcad375cc1b6de
parent58ee1647778f7dd799848119236e6831ba26daee (diff)
downloadspack-a9fbc0175d8a1a3e444febac9edc84d42500d79a.tar.gz
spack-a9fbc0175d8a1a3e444febac9edc84d42500d79a.tar.bz2
spack-a9fbc0175d8a1a3e444febac9edc84d42500d79a.tar.xz
spack-a9fbc0175d8a1a3e444febac9edc84d42500d79a.zip
Move "installed" and "installed_upstream" from PackageBase to Spec (#30191)
This PR moves the `installed` and `installed_upstream` properties from `PackageBase` to `Spec` and is a step towards being able to reuse specs for which we don't have a `package.py` available. It _should_ be sufficient to complete the concretization step and see the spec in the concretized DAG. To fully reuse a spec without a package.py though we need a way to serialize enough data to reconstruct the results of calls to: - `Spec.libs`, `Spec.headers` and `Spec.ommand` - `Package.setup_dependent_*_environment` and `Package.setup_run_environment` - [x] Add stub methods to packages with warnings - [x] Add a missing "root=False" in cmd/fetch.py - [x] Assert that a spec is concrete before checking installation status
-rw-r--r--lib/spack/spack/binary_distribution.py3
-rw-r--r--lib/spack/spack/cmd/dev_build.py4
-rw-r--r--lib/spack/spack/cmd/fetch.py12
-rw-r--r--lib/spack/spack/cmd/modules/__init__.py2
-rw-r--r--lib/spack/spack/environment/environment.py26
-rw-r--r--lib/spack/spack/installer.py6
-rw-r--r--lib/spack/spack/modules/common.py2
-rw-r--r--lib/spack/spack/package.py54
-rw-r--r--lib/spack/spack/report.py5
-rw-r--r--lib/spack/spack/rewiring.py4
-rw-r--r--lib/spack/spack/spec.py36
-rw-r--r--lib/spack/spack/test/cmd/env.py2
-rw-r--r--lib/spack/spack/test/concretize.py2
-rw-r--r--lib/spack/spack/test/database.py22
-rw-r--r--lib/spack/spack/test/install.py10
-rw-r--r--lib/spack/spack/test/installer.py6
-rw-r--r--lib/spack/spack/test/modules/common.py6
-rw-r--r--lib/spack/spack/test/spec_dag.py9
-rw-r--r--lib/spack/spack/test/test_activations.py3
-rw-r--r--lib/spack/spack/util/mock_package.py1
20 files changed, 121 insertions, 94 deletions
diff --git a/lib/spack/spack/binary_distribution.py b/lib/spack/spack/binary_distribution.py
index df687391ed..a3e1f77f84 100644
--- a/lib/spack/spack/binary_distribution.py
+++ b/lib/spack/spack/binary_distribution.py
@@ -1568,12 +1568,11 @@ def install_root_node(spec, allow_root, unsigned=False, force=False, sha256=None
sha256 (str): optional sha256 of the binary package, to be checked
before installation
"""
- package = spack.repo.get(spec)
# Early termination
if spec.external or spec.virtual:
warnings.warn("Skipping external or virtual package {0}".format(spec.format()))
return
- elif spec.concrete and package.installed and not force:
+ elif spec.concrete and spec.installed and not force:
warnings.warn("Package for spec {0} already installed.".format(spec.format()))
return
diff --git a/lib/spack/spack/cmd/dev_build.py b/lib/spack/spack/cmd/dev_build.py
index 0d4a440306..bb8c79f048 100644
--- a/lib/spack/spack/cmd/dev_build.py
+++ b/lib/spack/spack/cmd/dev_build.py
@@ -91,8 +91,8 @@ def dev_build(self, args):
spec.concretize()
package = spack.repo.get(spec)
- if package.installed:
- tty.error("Already installed in %s" % package.prefix)
+ if spec.installed:
+ tty.error("Already installed in %s" % spec.prefix)
tty.msg("Uninstall or try adding a version suffix for this dev build.")
sys.exit(1)
diff --git a/lib/spack/spack/cmd/fetch.py b/lib/spack/spack/cmd/fetch.py
index 85b2ab429e..8eb9fffa07 100644
--- a/lib/spack/spack/cmd/fetch.py
+++ b/lib/spack/spack/cmd/fetch.py
@@ -69,14 +69,10 @@ def fetch(parser, args):
for spec in specs:
if args.missing or args.dependencies:
- for s in spec.traverse():
- package = spack.repo.get(s)
-
+ for s in spec.traverse(root=False):
# Skip already-installed packages with --missing
- if args.missing and package.installed:
+ if args.missing and s.installed:
continue
- package.do_fetch()
-
- package = spack.repo.get(spec)
- package.do_fetch()
+ s.package.do_fetch()
+ spec.package.do_fetch()
diff --git a/lib/spack/spack/cmd/modules/__init__.py b/lib/spack/spack/cmd/modules/__init__.py
index e5c5f2ee2c..53b6ff2175 100644
--- a/lib/spack/spack/cmd/modules/__init__.py
+++ b/lib/spack/spack/cmd/modules/__init__.py
@@ -273,7 +273,7 @@ def refresh(module_type, specs, args):
return
if not args.upstream_modules:
- specs = list(s for s in specs if not s.package.installed_upstream)
+ specs = list(s for s in specs if not s.installed_upstream)
if not args.yes_to_all:
msg = 'You are about to regenerate {types} module files for:\n'
diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py
index 720819695b..ade4fd248c 100644
--- a/lib/spack/spack/environment/environment.py
+++ b/lib/spack/spack/environment/environment.py
@@ -302,7 +302,7 @@ def _is_dev_spec_and_has_changed(spec):
return False
# Now we can check whether the code changed since the last installation
- if not spec.package.installed:
+ if not spec.installed:
# Not installed -> nothing to compare against
return False
@@ -315,7 +315,7 @@ def _spec_needs_overwrite(spec, changed_dev_specs):
"""Check whether the current spec needs to be overwritten because either it has
changed itself or one of its dependencies have changed"""
# if it's not installed, we don't need to overwrite it
- if not spec.package.installed:
+ if not spec.installed:
return False
# If the spec itself has changed this is a trivial decision
@@ -330,7 +330,7 @@ def _spec_needs_overwrite(spec, changed_dev_specs):
# If any dep needs overwrite, or any dep is missing and is a dev build then
# overwrite this package
if any(
- ((not dep.package.installed) and dep.satisfies('dev_path=*')) or
+ ((not dep.installed) and dep.satisfies('dev_path=*')) or
_spec_needs_overwrite(dep, changed_dev_specs)
for dep in spec.traverse(root=False)
):
@@ -518,7 +518,7 @@ class ViewDescriptor(object):
# Filter selected, installed specs
with spack.store.db.read_transaction():
- specs = [s for s in specs if s in self and s.package.installed]
+ specs = [s for s in specs if s in self and s.installed]
return specs
@@ -1380,9 +1380,10 @@ class Environment(object):
# default view if they are installed.
for view_name, view in self.views.items():
for _, spec in self.concretized_specs():
- if spec in view and spec.package.installed:
- tty.debug(
- 'Spec %s in view %s' % (spec.name, view_name))
+ if spec in view and spec.package and spec.installed:
+ msg = '{0} in view "{1}"'
+ tty.debug(msg.format(spec.name, view_name))
+
except (spack.repo.UnknownPackageError,
spack.repo.UnknownNamespaceError) as e:
tty.warn(e)
@@ -1398,7 +1399,8 @@ class Environment(object):
errors = []
for _, root_spec in self.concretized_specs():
- if root_spec in self.default_view and root_spec.package.installed:
+ if (root_spec in self.default_view and
+ root_spec.installed and root_spec.package):
for spec in root_spec.traverse(deptype='run', root=True):
if spec.name in visited:
# It is expected that only one instance of the package
@@ -1537,7 +1539,7 @@ class Environment(object):
with spack.store.db.read_transaction():
for concretized_hash in self.concretized_order:
spec = self.specs_by_hash[concretized_hash]
- if not spec.package.installed or (
+ if not spec.installed or (
spec.satisfies('dev_path=*') or
spec.satisfies('^dev_path=*')
):
@@ -1572,7 +1574,7 @@ class Environment(object):
# ensure specs already installed are marked explicit
all_specs = specs or [cs for _, cs in self.concretized_specs()]
- specs_installed = [s for s in all_specs if s.package.installed]
+ specs_installed = [s for s in all_specs if s.installed]
with spack.store.db.write_transaction(): # do all in one transaction
for spec in specs_installed:
spack.store.db.update_explicit(spec, True)
@@ -1599,7 +1601,7 @@ class Environment(object):
finally:
# Ensure links are set appropriately
for spec in specs_to_install:
- if spec.package.installed:
+ if spec.installed:
self.new_installs.append(spec)
try:
self._install_log_links(spec)
@@ -1649,7 +1651,7 @@ class Environment(object):
concrete = concretized.get(spec)
if not concrete:
yield spec
- elif not concrete.package.installed:
+ elif not concrete.installed:
yield concrete
def concretized_specs(self):
diff --git a/lib/spack/spack/installer.py b/lib/spack/spack/installer.py
index 4cc1eedbe6..a43b0dea6a 100644
--- a/lib/spack/spack/installer.py
+++ b/lib/spack/spack/installer.py
@@ -140,7 +140,7 @@ def _handle_external_and_upstream(pkg, explicit):
.format(pkg.prefix, package_id(pkg)))
return True
- if pkg.installed_upstream:
+ if pkg.spec.installed_upstream:
tty.verbose('{0} is installed in an upstream Spack instance at {1}'
.format(package_id(pkg), pkg.spec.prefix))
_print_installed_pkg(pkg.prefix)
@@ -853,7 +853,7 @@ class PackageInstaller(object):
raise InstallError(err.format(request.pkg_id, msg))
# Flag external and upstream packages as being installed
- if dep_pkg.spec.external or dep_pkg.installed_upstream:
+ if dep_pkg.spec.external or dep_pkg.spec.installed_upstream:
self._flag_installed(dep_pkg)
continue
@@ -995,7 +995,7 @@ class PackageInstaller(object):
raise ExternalPackageError('{0} {1}'.format(pre, 'is external'))
# Upstream packages cannot be installed locally.
- if pkg.installed_upstream:
+ if pkg.spec.installed_upstream:
raise UpstreamPackageError('{0} {1}'.format(pre, 'is upstream'))
# The package must have a prefix lock at this stage.
diff --git a/lib/spack/spack/modules/common.py b/lib/spack/spack/modules/common.py
index 4b81b1a4b3..9bc904acad 100644
--- a/lib/spack/spack/modules/common.py
+++ b/lib/spack/spack/modules/common.py
@@ -370,7 +370,7 @@ def get_module(
available.
"""
try:
- upstream = spec.package.installed_upstream
+ upstream = spec.installed_upstream
except spack.repo.UnknownPackageError:
upstream, record = spack.store.db.query_by_spec_hash(spec.dag_hash())
if upstream:
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 9bd7669de9..27bdc6b459 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -26,6 +26,7 @@ import textwrap
import time
import traceback
import types
+import warnings
from typing import Any, Callable, Dict, List, Optional # novm
import six
@@ -790,15 +791,6 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
super(PackageBase, self).__init__()
- @property
- def installed_upstream(self):
- if not hasattr(self, '_installed_upstream'):
- upstream, record = spack.store.db.query_by_spec_hash(
- self.spec.dag_hash())
- self._installed_upstream = upstream
-
- return self._installed_upstream
-
@classmethod
def possible_dependencies(
cls, transitive=True, expand_virtuals=True, deptype='all',
@@ -1267,6 +1259,20 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
"""Return the install test root directory."""
return os.path.join(self.metadata_dir, 'test')
+ @property
+ def installed(self):
+ msg = ('the "PackageBase.installed" property is deprecated and will be '
+ 'removed in Spack v0.19, use "Spec.installed" instead')
+ warnings.warn(msg)
+ return self.spec.installed
+
+ @property
+ def installed_upstream(self):
+ msg = ('the "PackageBase.installed_upstream" property is deprecated and will '
+ 'be removed in Spack v0.19, use "Spec.installed_upstream" instead')
+ warnings.warn(msg)
+ return self.spec.installed_upstream
+
def _make_fetcher(self):
# Construct a composite fetcher that always contains at least
# one element (the root package). In case there are resources
@@ -1380,7 +1386,7 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
if not self.is_extension:
raise ValueError(
"is_activated called on package that is not an extension.")
- if self.extendee_spec.package.installed_upstream:
+ if self.extendee_spec.installed_upstream:
# If this extends an upstream package, it cannot be activated for
# it. This bypasses construction of the extension map, which can
# can fail when run in the context of a downstream Spack instance
@@ -1407,22 +1413,6 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
if any(self.spec.satisfies(c) for c in constraints)]
@property
- def installed(self):
- """Installation status of a package.
-
- Returns:
- True if the package has been installed, False otherwise.
- """
- try:
- # If the spec is in the DB, check the installed
- # attribute of the record
- return spack.store.db.get_record(self.spec).installed
- except KeyError:
- # If the spec is not in the DB, the method
- # above raises a Key error
- return False
-
- @property
def prefix(self):
"""Get the prefix into which this package should be installed."""
return self.spec.prefix
@@ -2143,21 +2133,21 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
to the staging build file until the software is successfully installed,
when it points to the file in the installation directory.
"""
- return self.install_log_path if self.installed else self.log_path
+ return self.install_log_path if self.spec.installed else self.log_path
@classmethod
def inject_flags(cls, name, flags):
"""
flag_handler that injects all flags through the compiler wrapper.
"""
- return (flags, None, None)
+ return flags, None, None
@classmethod
def env_flags(cls, name, flags):
"""
flag_handler that adds all flags to canonical environment variables.
"""
- return (None, flags, None)
+ return None, flags, None
@classmethod
def build_system_flags(cls, name, flags):
@@ -2168,7 +2158,7 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
implements it. Currently, AutotoolsPackage and CMakePackage
implement it.
"""
- return (None, None, flags)
+ return None, None, flags
def setup_build_environment(self, env):
"""Sets up the build environment for a package.
@@ -2465,10 +2455,10 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
extendee_package = self.extendee_spec.package
extendee_package._check_extendable()
- if not extendee_package.installed:
+ if not self.extendee_spec.installed:
raise ActivationError(
"Can only (de)activate extensions for installed packages.")
- if not self.installed:
+ if not self.spec.installed:
raise ActivationError("Extensions must first be installed.")
if self.extendee_spec.name not in self.extendees:
raise ActivationError("%s does not extend %s!" %
diff --git a/lib/spack/spack/report.py b/lib/spack/spack/report.py
index a31c011fc4..c8975a8f77 100644
--- a/lib/spack/spack/report.py
+++ b/lib/spack/spack/report.py
@@ -112,8 +112,7 @@ class InfoCollector(object):
# Check which specs are already installed and mark them as skipped
# only for install_task
if self.do_fn == '_install_task':
- for dep in filter(lambda x: x.package.installed,
- input_spec.traverse()):
+ for dep in filter(lambda x: x.installed, input_spec.traverse()):
package = {
'name': dep.name,
'id': dep.dag_hash(),
@@ -140,7 +139,7 @@ class InfoCollector(object):
raise Exception
# We accounted before for what is already installed
- installed_already = pkg.installed
+ installed_already = pkg.spec.installed
package = {
'name': pkg.name,
diff --git a/lib/spack/spack/rewiring.py b/lib/spack/spack/rewiring.py
index de7114dd97..feeb8d1a14 100644
--- a/lib/spack/spack/rewiring.py
+++ b/lib/spack/spack/rewiring.py
@@ -38,13 +38,13 @@ def rewire(spliced_spec):
nodes in the DAG of that spec."""
assert spliced_spec.spliced
for spec in spliced_spec.traverse(order='post', root=True):
- if not spec.build_spec.package.installed:
+ if not spec.build_spec.installed:
# TODO: May want to change this at least for the root spec...
# spec.build_spec.package.do_install(force=True)
raise PackageNotInstalledError(spliced_spec,
spec.build_spec,
spec)
- if spec.build_spec is not spec and not spec.package.installed:
+ if spec.build_spec is not spec and not spec.installed:
explicit = spec is spliced_spec
rewire_node(spec, explicit)
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index bf9bbaa789..e5505fb5a4 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -1197,6 +1197,7 @@ class Spec(object):
self._package_hash = None
self._dunder_hash = None
self._package = None
+ self._installed_upstream = None
# Most of these are internal implementation details that can be
# set by internal Spack calls in the constructor.
@@ -1554,6 +1555,33 @@ class Spec(object):
"""
return any(s.build_spec is not s for s in self.traverse(root=True))
+ @property
+ def installed(self):
+ """Installation status of a package.
+
+ Returns:
+ True if the package has been installed, False otherwise.
+ """
+ msg = "a spec must be concrete to be queried for installation status"
+ assert self.concrete, msg
+ try:
+ # If the spec is in the DB, check the installed
+ # attribute of the record
+ return spack.store.db.get_record(self).installed
+ except KeyError:
+ # If the spec is not in the DB, the method
+ # above raises a Key error
+ return False
+
+ @property
+ def installed_upstream(self):
+ msg = "a spec must be concrete to be queried for installation status"
+ assert self.concrete, msg
+ if getattr(self, '_installed_upstream', None) is None:
+ upstream, _ = spack.store.db.query_by_spec_hash(self.dag_hash())
+ self._installed_upstream = upstream
+ return self._installed_upstream
+
def traverse(self, **kwargs):
direction = kwargs.get('direction', 'children')
depth = kwargs.get('depth', False)
@@ -2880,7 +2908,7 @@ class Spec(object):
def _mark_root_concrete(self, value=True):
"""Mark just this spec (not dependencies) concrete."""
- if (not value) and self.concrete and self.package.installed:
+ if (not value) and self.concrete and self.installed:
return
self._normal = value
self._concrete = value
@@ -2894,7 +2922,7 @@ class Spec(object):
# if set to false, clear out all hashes (set to None or remove attr)
# may need to change references to respect None
for s in self.traverse():
- if (not value) and s.concrete and s.package.installed:
+ if (not value) and s.concrete and s.installed:
continue
elif not value:
s.clear_cached_hashes()
@@ -3159,7 +3187,7 @@ class Spec(object):
# Avoid recursively adding constraints for already-installed packages:
# these may include build dependencies which are not needed for this
# install (since this package is already installed).
- if self.concrete and self.package.installed:
+ if self.concrete and self.installed:
return False
# Combine constraints from package deps with constraints from
@@ -4529,7 +4557,7 @@ class Spec(object):
if status_fn:
status = status_fn(node)
- if node.package.installed_upstream:
+ if node.installed_upstream:
out += clr.colorize("@g{[^]} ", color=color)
elif status is None:
out += clr.colorize("@K{ - } ", color=color) # !installed
diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py
index 7f05e22545..cdd3e29cfb 100644
--- a/lib/spack/spack/test/cmd/env.py
+++ b/lib/spack/spack/test/cmd/env.py
@@ -162,7 +162,7 @@ def test_env_install_all(install_mockery, mock_fetch):
e.install_all()
env_specs = e._get_environment_specs()
spec = next(x for x in env_specs if x.name == 'cmake-client')
- assert spec.package.installed
+ assert spec.installed
def test_env_install_single_spec(install_mockery, mock_fetch):
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index adb8d05160..607ec85cd8 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -1422,7 +1422,7 @@ class TestConcretize(object):
# the answer set produced by clingo.
with spack.config.override("concretizer:reuse", True):
s = spack.spec.Spec(spec_str).concretized()
- assert s.package.installed is expect_installed
+ assert s.installed is expect_installed
assert s.satisfies(spec_str, strict=True)
@pytest.mark.regression('26721,19736')
diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py
index 4278aeb4f0..4a5071e1a3 100644
--- a/lib/spack/spack/test/database.py
+++ b/lib/spack/spack/test/database.py
@@ -726,11 +726,11 @@ def test_regression_issue_8036(mutable_database, usr_folder_exists):
# do_install.
s = spack.spec.Spec('externaltool@0.9')
s.concretize()
- assert not s.package.installed
+ assert not s.installed
# Now install the external package and check again the `installed` property
s.package.do_install(fake=True)
- assert s.package.installed
+ assert s.installed
@pytest.mark.regression('11118')
@@ -761,7 +761,7 @@ def test_old_external_entries_prefix(mutable_database):
def test_uninstall_by_spec(mutable_database):
with mutable_database.write_transaction():
for spec in mutable_database.query():
- if spec.package.installed:
+ if spec.installed:
spack.package.PackageBase.uninstall_by_spec(spec, force=True)
else:
mutable_database.remove(spec)
@@ -1023,3 +1023,19 @@ def test_consistency_of_dependents_upon_remove(mutable_database):
s = mutable_database.query_one('dyninst')
parents = s.dependents(name='callpath')
assert len(parents) == 2
+
+
+@pytest.mark.regression('30187')
+def test_query_installed_when_package_unknown(database):
+ """Test that we can query the installation status of a spec
+ when we don't know its package.py
+ """
+ with spack.repo.use_repositories(MockPackageMultiRepo()):
+ specs = database.query('mpileaks')
+ for s in specs:
+ # Assert that we can query the installation methods even though we
+ # don't have the package.py available
+ assert s.installed
+ assert not s.installed_upstream
+ with pytest.raises(spack.repo.UnknownNamespaceError):
+ s.package
diff --git a/lib/spack/spack/test/install.py b/lib/spack/spack/test/install.py
index 00276b379c..599087ac78 100644
--- a/lib/spack/spack/test/install.py
+++ b/lib/spack/spack/test/install.py
@@ -119,7 +119,7 @@ def test_partial_install_delete_prefix_and_stage(install_mockery, mock_fetch):
pkg.do_install(restage=True)
assert rm_prefix_checker.removed
assert pkg.stage.test_destroyed
- assert pkg.installed
+ assert pkg.spec.installed
finally:
pkg.remove_prefix = instance_rm_prefix
@@ -146,7 +146,7 @@ def test_failing_overwrite_install_should_keep_previous_installation(
with pytest.raises(Exception):
pkg.do_install(**kwargs)
- assert pkg.installed
+ assert pkg.spec.installed
assert os.path.exists(spec.prefix)
@@ -301,7 +301,7 @@ def test_installed_upstream(install_upstream, mock_fetch):
dependent = spack.spec.Spec('dependent-install').concretized()
new_dependency = dependent['dependency-install']
- assert new_dependency.package.installed_upstream
+ assert new_dependency.installed_upstream
assert (new_dependency.prefix ==
upstream_layout.path_for_spec(dependency))
@@ -333,7 +333,7 @@ def test_partial_install_keep_prefix(install_mockery, mock_fetch, monkeypatch):
pkg.succeed = True # make the build succeed
pkg.stage = MockStage(pkg.stage)
pkg.do_install(keep_prefix=True)
- assert pkg.installed
+ assert pkg.spec.installed
assert not pkg.stage.test_destroyed
@@ -344,7 +344,7 @@ def test_second_install_no_overwrite_first(install_mockery, mock_fetch, monkeypa
pkg.succeed = True
pkg.do_install()
- assert pkg.installed
+ assert pkg.spec.installed
# If Package.install is called after this point, it will fail
pkg.succeed = False
diff --git a/lib/spack/spack/test/installer.py b/lib/spack/spack/test/installer.py
index a7b0b1edd9..53f254d665 100644
--- a/lib/spack/spack/test/installer.py
+++ b/lib/spack/spack/test/installer.py
@@ -300,14 +300,14 @@ def test_installer_ensure_ready_errors(install_mockery):
# Force an upstream package error
spec.external_path, spec.external_modules = path, modules
- spec.package._installed_upstream = True
+ spec._installed_upstream = True
msg = fmt.format('is upstream')
with pytest.raises(inst.UpstreamPackageError, match=msg):
installer._ensure_install_ready(spec.package)
# Force an install lock error, which should occur naturally since
# we are calling an internal method prior to any lock-related setup
- spec.package._installed_upstream = False
+ spec._installed_upstream = False
assert len(installer.locks) == 0
with pytest.raises(inst.InstallLockError, match=fmt.format('not locked')):
installer._ensure_install_ready(spec.package)
@@ -638,7 +638,7 @@ def test_check_deps_status_upstream(install_mockery, monkeypatch):
request = installer.build_requests[0]
# Mock the known dependent, b, as installed upstream
- monkeypatch.setattr(spack.package.PackageBase, 'installed_upstream', True)
+ monkeypatch.setattr(spack.spec.Spec, 'installed_upstream', True)
installer._check_deps_status(request)
assert list(installer.installed)[0].startswith('b')
diff --git a/lib/spack/spack/test/modules/common.py b/lib/spack/spack/test/modules/common.py
index 401dc73877..39619ce741 100644
--- a/lib/spack/spack/test/modules/common.py
+++ b/lib/spack/spack/test/modules/common.py
@@ -2,8 +2,6 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
-import collections
import os
import stat
import sys
@@ -208,9 +206,7 @@ module_index:
)
upstream_index = UpstreamModuleIndex(mock_db, module_indices)
- MockPackage = collections.namedtuple('MockPackage', ['installed_upstream'])
- setattr(s1, "package", MockPackage(True))
-
+ setattr(s1, "installed_upstream", True)
try:
old_index = spack.modules.common.upstream_module_index
spack.modules.common.upstream_module_index = upstream_index
diff --git a/lib/spack/spack/test/spec_dag.py b/lib/spack/spack/test/spec_dag.py
index 046ff7aad2..dcf830fd78 100644
--- a/lib/spack/spack/test/spec_dag.py
+++ b/lib/spack/spack/test/spec_dag.py
@@ -84,7 +84,7 @@ w->y deptypes are (link, build), w->x and y->z deptypes are (test)
@pytest.mark.usefixtures('config')
-def test_installed_deps():
+def test_installed_deps(monkeypatch):
"""Preinstall a package P with a constrained build dependency D, then
concretize a dependent package which also depends on P and D, specifying
that the installed instance of P should be used. In this case, D should
@@ -120,9 +120,12 @@ def test_installed_deps():
assert c_spec['d'].version == spack.version.Version('2')
c_installed = spack.spec.Spec.from_dict(c_spec.to_dict())
- for spec in c_installed.traverse():
- setattr(spec.package, 'installed', True)
+ installed_names = [s.name for s in c_installed.traverse()]
+
+ def _mock_installed(self):
+ return self.name in installed_names
+ monkeypatch.setattr(Spec, 'installed', _mock_installed)
a_spec = Spec('a')
a_spec._add_dependency(c_installed, default)
a_spec.concretize()
diff --git a/lib/spack/spack/test/test_activations.py b/lib/spack/spack/test/test_activations.py
index 8eadfa837b..a832236c49 100644
--- a/lib/spack/spack/test/test_activations.py
+++ b/lib/spack/spack/test/test_activations.py
@@ -432,8 +432,7 @@ def test_is_activated_upstream_extendee(tmpdir, builtin_and_mock_packages,
# Set the prefix on the package's spec reference because that is a copy of
# the original spec
extendee_spec.package.spec.prefix = python_prefix
- monkeypatch.setattr(extendee_spec.package.__class__,
- 'installed_upstream', True)
+ monkeypatch.setattr(extendee_spec.__class__, 'installed_upstream', True)
ext_name = 'py-extension1'
tmpdir.ensure(ext_name, dir=True)
diff --git a/lib/spack/spack/util/mock_package.py b/lib/spack/spack/util/mock_package.py
index b5f942aedf..b89b989311 100644
--- a/lib/spack/spack/util/mock_package.py
+++ b/lib/spack/spack/util/mock_package.py
@@ -32,7 +32,6 @@ class MockPackageBase(object):
"""
self.spec = None
- self._installed_upstream = False
def provides(self, vname):
return vname in self.provided