summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/build_environment.py13
-rw-r--r--lib/spack/spack/repository.py21
-rw-r--r--lib/spack/spack/spec.py35
-rw-r--r--lib/spack/spack/test/cmd/install.py3
-rw-r--r--lib/spack/spack/test/git_fetch.py2
-rw-r--r--lib/spack/spack/test/hg_fetch.py2
-rw-r--r--lib/spack/spack/test/packaging.py5
-rw-r--r--lib/spack/spack/test/svn_fetch.py2
-rw-r--r--lib/spack/spack/test/url_fetch.py4
9 files changed, 27 insertions, 60 deletions
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index b2a7e1f6d6..81626d7361 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -575,19 +575,6 @@ def setup_package(pkg, dirty):
spack_env = EnvironmentModifications()
run_env = EnvironmentModifications()
- # Before proceeding, ensure that specs and packages are consistent
- #
- # This is a confusing behavior due to how packages are
- # constructed. `setup_dependent_package` may set attributes on
- # specs in the DAG for use by other packages' install
- # method. However, spec.package will look up a package via
- # spack.repo, which defensively copies specs into packages. This
- # code ensures that all packages in the DAG have pieces of the
- # same spec object at build time.
- #
- for s in pkg.spec.traverse():
- assert s.package.spec is s
-
set_compiler_environment_variables(pkg, spack_env)
set_build_environment_variables(pkg, spack_env, dirty)
pkg.architecture.platform.setup_platform_environment(pkg, spack_env)
diff --git a/lib/spack/spack/repository.py b/lib/spack/spack/repository.py
index c9111e9b3d..ec5e7ddc44 100644
--- a/lib/spack/spack/repository.py
+++ b/lib/spack/spack/repository.py
@@ -819,7 +819,7 @@ class Repo(object):
% (self.config_file, self.root))
@_autospec
- def get(self, spec, new=False):
+ def get(self, spec):
if not self.exists(spec.name):
raise UnknownPackageError(spec.name)
@@ -828,18 +828,13 @@ class Repo(object):
"Repository %s does not contain package %s"
% (self.namespace, spec.fullname))
- key = hash(spec)
- if new or key not in self._instances:
- package_class = self.get_pkg_class(spec.name)
- try:
- copy = spec.copy() # defensive copy. Package owns its spec.
- self._instances[key] = package_class(copy)
- except Exception:
- if spack.debug:
- sys.excepthook(*sys.exc_info())
- raise FailedConstructorError(spec.fullname, *sys.exc_info())
-
- return self._instances[key]
+ package_class = self.get_pkg_class(spec.name)
+ try:
+ return package_class(spec)
+ except Exception:
+ if spack.debug:
+ sys.excepthook(*sys.exc_info())
+ raise FailedConstructorError(spec.fullname, *sys.exc_info())
@_autospec
def dump_provenance(self, spec, path):
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index b0eba7363d..61f127a66c 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -1197,7 +1197,9 @@ class Spec(object):
@property
def package(self):
- return spack.repo.get(self)
+ if not self._package:
+ self._package = spack.repo.get(self)
+ return self._package
@property
def package_class(self):
@@ -1773,17 +1775,8 @@ class Spec(object):
Some rigorous validation and checks are also performed on the spec.
Concretizing ensures that it is self-consistent and that it's
- consistent with requirements of its pacakges. See flatten() and
+ consistent with requirements of its packages. See flatten() and
normalize() for more details on this.
-
- It also ensures that:
-
- .. code-block:: python
-
- for x in self.traverse():
- assert x.package.spec == x
-
- which may not be true *during* the concretization step.
"""
if not self.name:
raise SpecError("Attempting to concretize anonymous spec")
@@ -1872,7 +1865,7 @@ class Spec(object):
# there are declared conflicts
matches = []
for x in self.traverse():
- for conflict_spec, when_list in x.package.conflicts.items():
+ for conflict_spec, when_list in x.package_class.conflicts.items():
if x.satisfies(conflict_spec, strict=True):
for when_spec, msg in when_list:
if x.satisfies(when_spec, strict=True):
@@ -1880,11 +1873,6 @@ class Spec(object):
if matches:
raise ConflictsInSpecError(self, matches)
- # At this point the spec-package mutual references should
- # be self-consistent
- for x in self.traverse():
- x.package.spec = x
-
def _mark_concrete(self, value=True):
"""Mark this spec and its dependencies as concrete.
@@ -1968,8 +1956,7 @@ class Spec(object):
If no conditions are True (and we don't depend on it), return
``(None, None)``.
"""
- pkg = spack.repo.get(self.fullname)
- conditions = pkg.dependencies[name]
+ conditions = self.package_class.dependencies[name]
substitute_abstract_variants(self)
# evaluate when specs to figure out constraints on the dependency.
@@ -2136,10 +2123,9 @@ class Spec(object):
any_change = False
changed = True
- pkg = spack.repo.get(self.fullname)
while changed:
changed = False
- for dep_name in pkg.dependencies:
+ for dep_name in self.package_class.dependencies:
# Do we depend on dep_name? If so pkg_dep is not None.
dep = self._evaluate_dependency_conditions(dep_name)
# If dep is a needed dependency, merge it.
@@ -2556,7 +2542,7 @@ class Spec(object):
# FIXME: concretization to store the order of patches somewhere.
# FIXME: Needs to be refactored in a cleaner way.
for sha256 in self.variants['patches']._patches_in_order_of_appearance:
- patch = self.package.lookup_patch(sha256)
+ patch = self.package_class.lookup_patch(sha256)
if patch:
patches.append(patch)
continue
@@ -2564,7 +2550,7 @@ class Spec(object):
# if not found in this package, check immediate dependents
# for dependency patches
for dep_spec in self._dependents.values():
- patch = dep_spec.parent.package.lookup_patch(sha256)
+ patch = dep_spec.parent.package_class.lookup_patch(sha256)
if patch:
patches.append(patch)
@@ -2610,6 +2596,8 @@ class Spec(object):
self.external_module != other.external_module and
self.compiler_flags != other.compiler_flags)
+ self._package = None
+
# Local node attributes get copied first.
self.name = other.name
self.versions = other.versions.copy()
@@ -3374,6 +3362,7 @@ class SpecParser(spack.parse.Parser):
spec._hash = None
spec._cmp_key_cache = None
+ spec._package = None
spec._normal = False
spec._concrete = False
diff --git a/lib/spack/spack/test/cmd/install.py b/lib/spack/spack/test/cmd/install.py
index 3720e9bd38..85e52f2daf 100644
--- a/lib/spack/spack/test/cmd/install.py
+++ b/lib/spack/spack/test/cmd/install.py
@@ -72,9 +72,6 @@ def test_install_package_and_dependency(
assert 'failures="0"' in content
assert 'errors="0"' in content
- s = Spec('libdwarf').concretized()
- assert not spack.repo.get(s).stage.created
-
@pytest.mark.usefixtures('noop_install', 'builtin_mock', 'config')
def test_install_runtests():
diff --git a/lib/spack/spack/test/git_fetch.py b/lib/spack/spack/test/git_fetch.py
index b28c553753..4ca8ce506f 100644
--- a/lib/spack/spack/test/git_fetch.py
+++ b/lib/spack/spack/test/git_fetch.py
@@ -89,7 +89,7 @@ def test_fetch(type_of_test,
# Construct the package under test
spec = Spec('git-test')
spec.concretize()
- pkg = spack.repo.get(spec, new=True)
+ pkg = spack.repo.get(spec)
pkg.versions[ver('git')] = t.args
# Enter the stage directory and check some properties
diff --git a/lib/spack/spack/test/hg_fetch.py b/lib/spack/spack/test/hg_fetch.py
index 6a22502e86..07e7840eaa 100644
--- a/lib/spack/spack/test/hg_fetch.py
+++ b/lib/spack/spack/test/hg_fetch.py
@@ -61,7 +61,7 @@ def test_fetch(
# Construct the package under test
spec = Spec('hg-test')
spec.concretize()
- pkg = spack.repo.get(spec, new=True)
+ pkg = spack.repo.get(spec)
pkg.versions[ver('hg')] = t.args
# Enter the stage directory and check some properties
diff --git a/lib/spack/spack/test/packaging.py b/lib/spack/spack/test/packaging.py
index 7cb8dfc1fe..df45d96189 100644
--- a/lib/spack/spack/test/packaging.py
+++ b/lib/spack/spack/test/packaging.py
@@ -93,7 +93,7 @@ echo $PATH"""
spec = Spec('trivial-install-test-package')
spec.concretize()
assert spec.concrete
- pkg = spack.repo.get(spec)
+ pkg = spec.package
fake_fetchify(mock_archive.url, pkg)
pkg.do_install()
pkghash = '/' + spec.dag_hash(7)
@@ -107,9 +107,8 @@ echo $PATH"""
# put it directly into the mirror
mirror_path = os.path.join(str(tmpdir), 'test-mirror')
- specs = [spec]
spack.mirror.create(
- mirror_path, specs, no_checksum=True
+ mirror_path, specs=[], no_checksum=True
)
# register mirror with spack config
diff --git a/lib/spack/spack/test/svn_fetch.py b/lib/spack/spack/test/svn_fetch.py
index f00b0b8259..7e107ec423 100644
--- a/lib/spack/spack/test/svn_fetch.py
+++ b/lib/spack/spack/test/svn_fetch.py
@@ -61,7 +61,7 @@ def test_fetch(
# Construct the package under test
spec = Spec('svn-test')
spec.concretize()
- pkg = spack.repo.get(spec, new=True)
+ pkg = spack.repo.get(spec)
pkg.versions[ver('svn')] = t.args
# Enter the stage directory and check some properties
diff --git a/lib/spack/spack/test/url_fetch.py b/lib/spack/spack/test/url_fetch.py
index 168bda5f64..83e184f196 100644
--- a/lib/spack/spack/test/url_fetch.py
+++ b/lib/spack/spack/test/url_fetch.py
@@ -60,7 +60,7 @@ def test_fetch(
spec = Spec('url-test')
spec.concretize()
- pkg = spack.repo.get('url-test', new=True)
+ pkg = spack.repo.get('url-test')
pkg.url = mock_archive.url
pkg.versions[ver('test')] = {checksum_type: checksum, 'url': pkg.url}
pkg.spec = spec
@@ -84,7 +84,7 @@ def test_fetch(
def test_from_list_url(builtin_mock, config):
- pkg = spack.repo.get('url-list-test', new=True)
+ pkg = spack.repo.get('url-list-test')
for ver_str in ['0.0.0', '1.0.0', '2.0.0',
'3.0', '4.5', '2.0.0b2',
'3.0a1', '4.5-rc5']: