From e7c591a8b87f09ba89bdc37b9f2946b3d7ff3361 Mon Sep 17 00:00:00 2001 From: Greg Becker Date: Wed, 15 Jan 2025 01:13:19 -0800 Subject: [PATCH] Deprecate Spec.concretize/Spec.concretized in favor of spack.concretize.concretize_one (#47971) The methods spack.spec.Spec.concretize and spack.spec.Spec.concretized are deprecated in favor of spack.concretize.concretize_one. This will resolve a circular dependency between the spack.spec and spack.concretize in the next Spack release. --- lib/spack/docs/developer_guide.rst | 4 +- lib/spack/spack/bootstrap/core.py | 7 +- lib/spack/spack/cmd/__init__.py | 6 +- lib/spack/spack/cmd/bootstrap.py | 4 +- lib/spack/spack/cmd/buildcache.py | 6 +- lib/spack/spack/cmd/deprecate.py | 3 +- lib/spack/spack/cmd/dev_build.py | 3 +- lib/spack/spack/cmd/install.py | 3 +- lib/spack/spack/cmd/make_installer.py | 5 +- lib/spack/spack/cmd/mirror.py | 2 +- lib/spack/spack/concretize.py | 69 ++- lib/spack/spack/solver/asp.py | 24 +- lib/spack/spack/spec.py | 65 +-- lib/spack/spack/test/abi_splicing.py | 45 +- lib/spack/spack/test/architecture.py | 2 +- lib/spack/spack/test/bindist.py | 24 +- lib/spack/spack/test/build_distribution.py | 4 +- lib/spack/spack/test/build_environment.py | 30 +- lib/spack/spack/test/build_systems.py | 20 +- lib/spack/spack/test/builder.py | 16 +- lib/spack/spack/test/buildrequest.py | 9 +- lib/spack/spack/test/buildtask.py | 9 +- lib/spack/spack/test/ci.py | 11 +- lib/spack/spack/test/cmd/bootstrap.py | 3 +- lib/spack/spack/test/cmd/buildcache.py | 18 +- lib/spack/spack/test/cmd/checksum.py | 4 +- lib/spack/spack/test/cmd/ci.py | 12 +- lib/spack/spack/test/cmd/clean.py | 16 - lib/spack/spack/test/cmd/config.py | 5 +- lib/spack/spack/test/cmd/deprecate.py | 19 +- lib/spack/spack/test/cmd/dev_build.py | 54 ++- lib/spack/spack/test/cmd/develop.py | 9 +- lib/spack/spack/test/cmd/diff.py | 14 +- lib/spack/spack/test/cmd/env.py | 37 +- lib/spack/spack/test/cmd/extensions.py | 8 +- lib/spack/spack/test/cmd/find.py | 13 +- lib/spack/spack/test/cmd/gc.py | 20 +- lib/spack/spack/test/cmd/install.py | 55 +-- lib/spack/spack/test/cmd/load.py | 8 +- lib/spack/spack/test/cmd/location.py | 4 +- lib/spack/spack/test/cmd/logs.py | 5 +- lib/spack/spack/test/cmd/mirror.py | 11 +- lib/spack/spack/test/cmd/module.py | 13 +- lib/spack/spack/test/cmd/tags.py | 4 +- lib/spack/spack/test/cmd/test.py | 8 +- lib/spack/spack/test/cmd/undevelop.py | 6 +- lib/spack/spack/test/cmd/verify.py | 4 +- lib/spack/spack/test/cmd/view.py | 4 +- .../test/concretization/compiler_runtimes.py | 7 +- lib/spack/spack/test/concretization/core.py | 428 +++++++++--------- lib/spack/spack/test/concretization/errors.py | 4 +- .../spack/test/concretization/flag_mixing.py | 23 +- .../spack/test/concretization/preferences.py | 50 +- .../spack/test/concretization/requirements.py | 127 +++--- lib/spack/spack/test/config_values.py | 6 +- lib/spack/spack/test/conftest.py | 7 +- lib/spack/spack/test/cvs_fetch.py | 4 +- lib/spack/spack/test/database.py | 45 +- lib/spack/spack/test/directives.py | 7 +- lib/spack/spack/test/directory_layout.py | 13 +- lib/spack/spack/test/flag_handlers.py | 28 +- lib/spack/spack/test/git_fetch.py | 6 +- lib/spack/spack/test/graph.py | 4 +- lib/spack/spack/test/hg_fetch.py | 4 +- lib/spack/spack/test/install.py | 73 ++- lib/spack/spack/test/installer.py | 63 ++- lib/spack/spack/test/mirror.py | 13 +- lib/spack/spack/test/modules/common.py | 9 +- lib/spack/spack/test/modules/conftest.py | 5 +- lib/spack/spack/test/modules/lmod.py | 9 +- lib/spack/spack/test/modules/tcl.py | 17 +- lib/spack/spack/test/multimethod.py | 12 +- lib/spack/spack/test/optional_deps.py | 10 +- lib/spack/spack/test/package_class.py | 7 +- lib/spack/spack/test/packages.py | 16 +- lib/spack/spack/test/packaging.py | 4 +- lib/spack/spack/test/patch.py | 42 +- lib/spack/spack/test/rewiring.py | 26 +- lib/spack/spack/test/spec_dag.py | 76 ++-- lib/spack/spack/test/spec_list.py | 5 +- lib/spack/spack/test/spec_semantics.py | 61 +-- lib/spack/spack/test/spec_syntax.py | 13 +- lib/spack/spack/test/spec_yaml.py | 25 +- lib/spack/spack/test/svn_fetch.py | 4 +- lib/spack/spack/test/test_suite.py | 39 +- lib/spack/spack/test/url_fetch.py | 8 +- lib/spack/spack/test/util/package_hash.py | 19 +- lib/spack/spack/test/variant.py | 10 +- lib/spack/spack/test/versions.py | 15 +- lib/spack/spack/test/views.py | 3 +- 90 files changed, 1038 insertions(+), 1034 deletions(-) diff --git a/lib/spack/docs/developer_guide.rst b/lib/spack/docs/developer_guide.rst index 51a6e6fc2b4..d90259f9336 100644 --- a/lib/spack/docs/developer_guide.rst +++ b/lib/spack/docs/developer_guide.rst @@ -543,10 +543,10 @@ With either interpreter you can run a single command: .. code-block:: console - $ spack python -c 'from spack.spec import Spec; Spec("python").concretized()' + $ spack python -c 'from spack.concretize import concretize_one; concretize_one("python")' ... - $ spack python -i ipython -c 'from spack.spec import Spec; Spec("python").concretized()' + $ spack python -i ipython -c 'from spack.concretize import concretize_one; concretize_one("python")' Out[1]: ... or a file: diff --git a/lib/spack/spack/bootstrap/core.py b/lib/spack/spack/bootstrap/core.py index 022dbc38493..5b144e4c824 100644 --- a/lib/spack/spack/bootstrap/core.py +++ b/lib/spack/spack/bootstrap/core.py @@ -34,6 +34,7 @@ from llnl.util.lang import GroupedExceptionHandler import spack.binary_distribution +import spack.concretize import spack.config import spack.detection import spack.mirrors.mirror @@ -270,10 +271,10 @@ def try_import(self, module: str, abstract_spec_str: str) -> bool: bootstrapper = ClingoBootstrapConcretizer(configuration=spack.config.CONFIG) concrete_spec = bootstrapper.concretize() else: - concrete_spec = spack.spec.Spec( + abstract_spec = spack.spec.Spec( abstract_spec_str + " ^" + spec_for_current_python() ) - concrete_spec.concretize() + concrete_spec = spack.concretize.concretize_one(abstract_spec) msg = "[BOOTSTRAP MODULE {0}] Try installing '{1}' from sources" tty.debug(msg.format(module, abstract_spec_str)) @@ -299,7 +300,7 @@ def try_search_path(self, executables: Tuple[str], abstract_spec_str: str) -> bo # might reduce compilation time by a fair amount _add_externals_if_missing() - concrete_spec = spack.spec.Spec(abstract_spec_str).concretized() + concrete_spec = spack.concretize.concretize_one(abstract_spec_str) msg = "[BOOTSTRAP] Try installing '{0}' from sources" tty.debug(msg.format(abstract_spec_str)) with spack.config.override(self.mirror_scope): diff --git a/lib/spack/spack/cmd/__init__.py b/lib/spack/spack/cmd/__init__.py index 5cee932504b..acb462e0580 100644 --- a/lib/spack/spack/cmd/__init__.py +++ b/lib/spack/spack/cmd/__init__.py @@ -202,7 +202,7 @@ def _concretize_spec_pairs( # Special case for concretizing a single spec if len(to_concretize) == 1: abstract, concrete = to_concretize[0] - return [concrete or abstract.concretized(tests=tests)] + return [concrete or spack.concretize.concretize_one(abstract, tests=tests)] # Special case if every spec is either concrete or has an abstract hash if all( @@ -254,9 +254,9 @@ def matching_spec_from_env(spec): """ env = ev.active_environment() if env: - return env.matching_spec(spec) or spec.concretized() + return env.matching_spec(spec) or spack.concretize.concretize_one(spec) else: - return spec.concretized() + return spack.concretize.concretize_one(spec) def matching_specs_from_env(specs): diff --git a/lib/spack/spack/cmd/bootstrap.py b/lib/spack/spack/cmd/bootstrap.py index d1f85c59a33..cf246555306 100644 --- a/lib/spack/spack/cmd/bootstrap.py +++ b/lib/spack/spack/cmd/bootstrap.py @@ -14,9 +14,9 @@ import spack.bootstrap import spack.bootstrap.config import spack.bootstrap.core +import spack.concretize import spack.config import spack.mirrors.utils -import spack.spec import spack.stage import spack.util.path import spack.util.spack_yaml @@ -397,7 +397,7 @@ def _mirror(args): llnl.util.tty.msg(msg.format(spec_str, mirror_dir)) # Suppress tty from the call below for terser messages llnl.util.tty.set_msg_enabled(False) - spec = spack.spec.Spec(spec_str).concretized() + spec = spack.concretize.concretize_one(spec_str) for node in spec.traverse(): spack.mirrors.utils.create(mirror_dir, [node]) llnl.util.tty.set_msg_enabled(True) diff --git a/lib/spack/spack/cmd/buildcache.py b/lib/spack/spack/cmd/buildcache.py index eb09d19ff66..a76cfa767f6 100644 --- a/lib/spack/spack/cmd/buildcache.py +++ b/lib/spack/spack/cmd/buildcache.py @@ -16,6 +16,7 @@ import spack.binary_distribution as bindist import spack.cmd +import spack.concretize import spack.config import spack.deptypes as dt import spack.environment as ev @@ -554,8 +555,7 @@ def check_fn(args: argparse.Namespace): tty.msg("No specs provided, exiting.") return - for spec in specs: - spec.concretize() + specs = [spack.concretize.concretize_one(s) for s in specs] # Next see if there are any configured binary mirrors configured_mirrors = spack.config.get("mirrors", scope=args.scope) @@ -623,7 +623,7 @@ def save_specfile_fn(args): root = specs[0] if not root.concrete: - root.concretize() + root = spack.concretize.concretize_one(root) save_dependency_specfiles( root, args.specfile_dir, dependencies=spack.cmd.parse_specs(args.specs) diff --git a/lib/spack/spack/cmd/deprecate.py b/lib/spack/spack/cmd/deprecate.py index c3dcc752adf..3468314cfbb 100644 --- a/lib/spack/spack/cmd/deprecate.py +++ b/lib/spack/spack/cmd/deprecate.py @@ -18,6 +18,7 @@ from llnl.util.symlink import symlink import spack.cmd +import spack.concretize import spack.environment as ev import spack.installer import spack.store @@ -103,7 +104,7 @@ def deprecate(parser, args): ) if args.install: - deprecator = specs[1].concretized() + deprecator = spack.concretize.concretize_one(specs[1]) else: deprecator = spack.cmd.disambiguate_spec(specs[1], env, local=True) diff --git a/lib/spack/spack/cmd/dev_build.py b/lib/spack/spack/cmd/dev_build.py index 26bc011672f..32bb8265964 100644 --- a/lib/spack/spack/cmd/dev_build.py +++ b/lib/spack/spack/cmd/dev_build.py @@ -10,6 +10,7 @@ import spack.build_environment import spack.cmd import spack.cmd.common.arguments +import spack.concretize import spack.config import spack.repo from spack.cmd.common import arguments @@ -114,7 +115,7 @@ def dev_build(self, args): # Forces the build to run out of the source directory. spec.constrain("dev_path=%s" % source_path) - spec.concretize() + spec = spack.concretize.concretize_one(spec) if spec.installed: tty.error("Already installed in %s" % spec.prefix) diff --git a/lib/spack/spack/cmd/install.py b/lib/spack/spack/cmd/install.py index bb731d33176..d71f67d8865 100644 --- a/lib/spack/spack/cmd/install.py +++ b/lib/spack/spack/cmd/install.py @@ -13,6 +13,7 @@ from llnl.util import lang, tty import spack.cmd +import spack.concretize import spack.config import spack.environment as ev import spack.paths @@ -450,7 +451,7 @@ def concrete_specs_from_file(args): else: s = spack.spec.Spec.from_json(f) - concretized = s.concretized() + concretized = spack.concretize.concretize_one(s) if concretized.dag_hash() != s.dag_hash(): msg = 'skipped invalid file "{0}". ' msg += "The file does not contain a concrete spec." diff --git a/lib/spack/spack/cmd/make_installer.py b/lib/spack/spack/cmd/make_installer.py index 6e96601d0fc..5cc0ff29d4b 100644 --- a/lib/spack/spack/cmd/make_installer.py +++ b/lib/spack/spack/cmd/make_installer.py @@ -7,9 +7,9 @@ from llnl.path import convert_to_posix_path +import spack.concretize import spack.paths import spack.util.executable -from spack.spec import Spec description = "generate Windows installer" section = "admin" @@ -65,8 +65,7 @@ def make_installer(parser, args): """ if sys.platform == "win32": output_dir = args.output_dir - cmake_spec = Spec("cmake") - cmake_spec.concretize() + cmake_spec = spack.concretize.concretize_one("cmake") cmake_path = os.path.join(cmake_spec.prefix, "bin", "cmake.exe") cpack_path = os.path.join(cmake_spec.prefix, "bin", "cpack.exe") spack_source = args.spack_source diff --git a/lib/spack/spack/cmd/mirror.py b/lib/spack/spack/cmd/mirror.py index 677549ef454..1b34c09d4c2 100644 --- a/lib/spack/spack/cmd/mirror.py +++ b/lib/spack/spack/cmd/mirror.py @@ -492,7 +492,7 @@ def extend_with_additional_versions(specs, num_versions): mirror_specs = spack.mirrors.utils.get_all_versions(specs) else: mirror_specs = spack.mirrors.utils.get_matching_versions(specs, num_versions=num_versions) - mirror_specs = [x.concretized() for x in mirror_specs] + mirror_specs = [spack.concretize.concretize_one(x) for x in mirror_specs] return mirror_specs diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py index 468e0309ecf..78a46a33ab8 100644 --- a/lib/spack/spack/concretize.py +++ b/lib/spack/spack/concretize.py @@ -37,13 +37,12 @@ def enable_compiler_existence_check(): SpecPairInput = Tuple[Spec, Optional[Spec]] SpecPair = Tuple[Spec, Spec] -SpecLike = Union[Spec, str] TestsType = Union[bool, Iterable[str]] -def concretize_specs_together( - abstract_specs: Sequence[SpecLike], tests: TestsType = False -) -> Sequence[Spec]: +def _concretize_specs_together( + abstract_specs: Sequence[Spec], tests: TestsType = False +) -> List[Spec]: """Given a number of specs as input, tries to concretize them together. Args: @@ -51,11 +50,10 @@ def concretize_specs_together( tests: list of package names for which to consider tests dependencies. If True, all nodes will have test dependencies. If False, test dependencies will be disregarded. """ - import spack.solver.asp + from spack.solver.asp import Solver allow_deprecated = spack.config.get("config:deprecated", False) - solver = spack.solver.asp.Solver() - result = solver.solve(abstract_specs, tests=tests, allow_deprecated=allow_deprecated) + result = Solver().solve(abstract_specs, tests=tests, allow_deprecated=allow_deprecated) return [s.copy() for s in result.specs] @@ -72,7 +70,7 @@ def concretize_together( """ to_concretize = [concrete if concrete else abstract for abstract, concrete in spec_list] abstract_specs = [abstract for abstract, _ in spec_list] - concrete_specs = concretize_specs_together(to_concretize, tests=tests) + concrete_specs = _concretize_specs_together(to_concretize, tests=tests) return list(zip(abstract_specs, concrete_specs)) @@ -90,7 +88,7 @@ def concretize_together_when_possible( tests: list of package names for which to consider tests dependencies. If True, all nodes will have test dependencies. If False, test dependencies will be disregarded. """ - import spack.solver.asp + from spack.solver.asp import Solver to_concretize = [concrete if concrete else abstract for abstract, concrete in spec_list] old_concrete_to_abstract = { @@ -98,9 +96,8 @@ def concretize_together_when_possible( } result_by_user_spec = {} - solver = spack.solver.asp.Solver() allow_deprecated = spack.config.get("config:deprecated", False) - for result in solver.solve_in_rounds( + for result in Solver().solve_in_rounds( to_concretize, tests=tests, allow_deprecated=allow_deprecated ): result_by_user_spec.update(result.specs_by_input) @@ -124,7 +121,7 @@ def concretize_separately( tests: list of package names for which to consider tests dependencies. If True, all nodes will have test dependencies. If False, test dependencies will be disregarded. """ - import spack.bootstrap + from spack.bootstrap import ensure_bootstrap_configuration, ensure_clingo_importable_or_raise to_concretize = [abstract for abstract, concrete in spec_list if not concrete] args = [ @@ -134,8 +131,8 @@ def concretize_separately( ] ret = [(i, abstract) for i, abstract in enumerate(to_concretize) if abstract.concrete] # Ensure we don't try to bootstrap clingo in parallel - with spack.bootstrap.ensure_bootstrap_configuration(): - spack.bootstrap.ensure_clingo_importable_or_raise() + with ensure_bootstrap_configuration(): + ensure_clingo_importable_or_raise() # Ensure all the indexes have been built or updated, since # otherwise the processes in the pool may timeout on waiting @@ -190,10 +187,52 @@ def _concretize_task(packed_arguments: Tuple[int, str, TestsType]) -> Tuple[int, index, spec_str, tests = packed_arguments with tty.SuppressOutput(msg_enabled=False): start = time.time() - spec = Spec(spec_str).concretized(tests=tests) + spec = concretize_one(Spec(spec_str), tests=tests) return index, spec, time.time() - start +def concretize_one(spec: Union[str, Spec], tests: TestsType = False) -> Spec: + """Return a concretized copy of the given spec. + + Args: + tests: if False disregard 'test' dependencies, if a list of names activate them for + the packages in the list, if True activate 'test' dependencies for all packages. + """ + from spack.solver.asp import Solver, SpecBuilder + + if isinstance(spec, str): + spec = Spec(spec) + spec = spec.lookup_hash() + + if spec.concrete: + return spec.copy() + + for node in spec.traverse(): + if not node.name: + raise spack.error.SpecError( + f"Spec {node} has no name; cannot concretize an anonymous spec" + ) + + allow_deprecated = spack.config.get("config:deprecated", False) + result = Solver().solve([spec], tests=tests, allow_deprecated=allow_deprecated) + + # take the best answer + opt, i, answer = min(result.answers) + name = spec.name + # TODO: Consolidate this code with similar code in solve.py + if spec.virtual: + providers = [s.name for s in answer.values() if s.package.provides(name)] + name = providers[0] + + node = SpecBuilder.make_node(pkg=name) + assert ( + node in answer + ), f"cannot find {name} in the list of specs {','.join([n.pkg for n in answer.keys()])}" + + concretized = answer[node] + return concretized + + class UnavailableCompilerVersionError(spack.error.SpackError): """Raised when there is no available compiler that satisfies a compiler spec.""" diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 88d69725b05..9fd85eaa7cc 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -67,7 +67,7 @@ GitOrStandardVersion = Union[spack.version.GitVersion, spack.version.StandardVersion] -TransformFunction = Callable[["spack.spec.Spec", List[AspFunction]], List[AspFunction]] +TransformFunction = Callable[[spack.spec.Spec, List[AspFunction]], List[AspFunction]] #: Enable the addition of a runtime node WITH_RUNTIME = sys.platform != "win32" @@ -127,8 +127,8 @@ def __str__(self): @contextmanager def named_spec( - spec: Optional["spack.spec.Spec"], name: Optional[str] -) -> Iterator[Optional["spack.spec.Spec"]]: + spec: Optional[spack.spec.Spec], name: Optional[str] +) -> Iterator[Optional[spack.spec.Spec]]: """Context manager to temporarily set the name of a spec""" if spec is None or name is None: yield spec @@ -747,11 +747,11 @@ def on_model(model): class KnownCompiler(NamedTuple): """Data class to collect information on compilers""" - spec: "spack.spec.Spec" + spec: spack.spec.Spec os: str target: str available: bool - compiler_obj: Optional["spack.compiler.Compiler"] + compiler_obj: Optional[spack.compiler.Compiler] def _key(self): return self.spec, self.os, self.target @@ -1386,7 +1386,7 @@ def effect_rules(self): def define_variant( self, - pkg: "Type[spack.package_base.PackageBase]", + pkg: Type[spack.package_base.PackageBase], name: str, when: spack.spec.Spec, variant_def: vt.Variant, @@ -1490,7 +1490,7 @@ def define_auto_variant(self, name: str, multi: bool): ) ) - def variant_rules(self, pkg: "Type[spack.package_base.PackageBase]"): + def variant_rules(self, pkg: Type[spack.package_base.PackageBase]): for name in pkg.variant_names(): self.gen.h3(f"Variant {name} in package {pkg.name}") for when, variant_def in pkg.variant_definitions(name): @@ -1681,8 +1681,8 @@ def dependency_holds(input_spec, requirements): def _gen_match_variant_splice_constraints( self, pkg, - cond_spec: "spack.spec.Spec", - splice_spec: "spack.spec.Spec", + cond_spec: spack.spec.Spec, + splice_spec: spack.spec.Spec, hash_asp_var: "AspVar", splice_node, match_variants: List[str], @@ -2977,7 +2977,7 @@ def _specs_from_requires(self, pkg_name, section): for s in spec_group[key]: yield _spec_with_default_name(s, pkg_name) - def pkg_class(self, pkg_name: str) -> typing.Type["spack.package_base.PackageBase"]: + def pkg_class(self, pkg_name: str) -> typing.Type[spack.package_base.PackageBase]: request = pkg_name if pkg_name in self.explicitly_required_namespaces: namespace = self.explicitly_required_namespaces[pkg_name] @@ -3096,7 +3096,7 @@ def __init__(self, configuration) -> None: self.compilers.add(candidate) - def with_input_specs(self, input_specs: List["spack.spec.Spec"]) -> "CompilerParser": + def with_input_specs(self, input_specs: List[spack.spec.Spec]) -> "CompilerParser": """Accounts for input specs when building the list of possible compilers. Args: @@ -3136,7 +3136,7 @@ def with_input_specs(self, input_specs: List["spack.spec.Spec"]) -> "CompilerPar return self - def add_compiler_from_concrete_spec(self, spec: "spack.spec.Spec") -> None: + def add_compiler_from_concrete_spec(self, spec: spack.spec.Spec) -> None: """Account for compilers that are coming from concrete specs, through reuse. Args: diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index 731ed343441..829039f13a9 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -86,7 +86,6 @@ import spack import spack.compiler import spack.compilers -import spack.config import spack.deptypes as dt import spack.error import spack.hash_types as ht @@ -94,7 +93,6 @@ import spack.platforms import spack.provider_index import spack.repo -import spack.solver import spack.spec_parser import spack.store import spack.traverse @@ -2949,44 +2947,16 @@ def ensure_no_deprecated(root): raise SpecDeprecatedError(msg) def concretize(self, tests: Union[bool, Iterable[str]] = False) -> None: - """Concretize the current spec. + from spack.concretize import concretize_one - Args: - tests: if False disregard 'test' dependencies, if a list of names activate them for - the packages in the list, if True activate 'test' dependencies for all packages. - """ - import spack.solver.asp + warnings.warn( + "`Spec.concretize` is deprecated and will be removed in version 1.0.0. Use " + "`spack.concretize.concretize_one` instead.", + category=spack.error.SpackAPIWarning, + stacklevel=2, + ) - self.replace_hash() - - for node in self.traverse(): - if not node.name: - raise spack.error.SpecError( - f"Spec {node} has no name; cannot concretize an anonymous spec" - ) - - if self._concrete: - return - - allow_deprecated = spack.config.get("config:deprecated", False) - solver = spack.solver.asp.Solver() - result = solver.solve([self], tests=tests, allow_deprecated=allow_deprecated) - - # take the best answer - opt, i, answer = min(result.answers) - name = self.name - # TODO: Consolidate this code with similar code in solve.py - if self.virtual: - providers = [spec.name for spec in answer.values() if spec.package.provides(name)] - name = providers[0] - - node = spack.solver.asp.SpecBuilder.make_node(pkg=name) - assert ( - node in answer - ), f"cannot find {name} in the list of specs {','.join([n.pkg for n in answer.keys()])}" - - concretized = answer[node] - self._dup(concretized) + self._dup(concretize_one(self, tests)) def _mark_root_concrete(self, value=True): """Mark just this spec (not dependencies) concrete.""" @@ -3076,19 +3046,16 @@ def _finalize_concretization(self): spec._cached_hash(ht.dag_hash) def concretized(self, tests: Union[bool, Iterable[str]] = False) -> "Spec": - """This is a non-destructive version of concretize(). + from spack.concretize import concretize_one - First clones, then returns a concrete version of this package - without modifying this package. + warnings.warn( + "`Spec.concretized` is deprecated and will be removed in version 1.0.0. Use " + "`spack.concretize.concretize_one` instead.", + category=spack.error.SpackAPIWarning, + stacklevel=2, + ) - Args: - tests (bool or list): if False disregard 'test' dependencies, - if a list of names activate them for the packages in the list, - if True activate 'test' dependencies for all packages. - """ - clone = self.copy() - clone.concretize(tests=tests) - return clone + return concretize_one(self, tests) def index(self, deptype="all"): """Return a dictionary that points to all the dependencies in this diff --git a/lib/spack/spack/test/abi_splicing.py b/lib/spack/spack/test/abi_splicing.py index c9bf198f6fb..d70dc09b377 100644 --- a/lib/spack/spack/test/abi_splicing.py +++ b/lib/spack/spack/test/abi_splicing.py @@ -7,6 +7,7 @@ import pytest +import spack.concretize import spack.config import spack.deptypes as dt import spack.solver.asp @@ -21,7 +22,7 @@ def __init__(self, specs: List[str]) -> None: self.concr_specs = [] def __enter__(self): - self.concr_specs = [Spec(s).concretized() for s in self.req_specs] + self.concr_specs = [spack.concretize.concretize_one(s) for s in self.req_specs] for s in self.concr_specs: PackageInstaller([s.package], fake=True, explicit=True).install() @@ -62,13 +63,13 @@ def _has_build_dependency(spec: Spec, name: str): def test_simple_reuse(splicing_setup): with CacheManager(["splice-z@1.0.0+compat"]): spack.config.set("packages", _make_specs_non_buildable(["splice-z"])) - assert Spec("splice-z").concretized().satisfies(Spec("splice-z")) + assert spack.concretize.concretize_one("splice-z").satisfies(Spec("splice-z")) def test_simple_dep_reuse(splicing_setup): with CacheManager(["splice-z@1.0.0+compat"]): spack.config.set("packages", _make_specs_non_buildable(["splice-z"])) - assert Spec("splice-h@1").concretized().satisfies(Spec("splice-h@1")) + assert spack.concretize.concretize_one("splice-h@1").satisfies(Spec("splice-h@1")) def test_splice_installed_hash(splicing_setup): @@ -81,9 +82,9 @@ def test_splice_installed_hash(splicing_setup): spack.config.set("packages", packages_config) goal_spec = Spec("splice-t@1 ^splice-h@1.0.2+compat ^splice-z@1.0.0") with pytest.raises(Exception): - goal_spec.concretized() + spack.concretize.concretize_one(goal_spec) _enable_splicing() - assert goal_spec.concretized().satisfies(goal_spec) + assert spack.concretize.concretize_one(goal_spec).satisfies(goal_spec) def test_splice_build_splice_node(splicing_setup): @@ -91,9 +92,9 @@ def test_splice_build_splice_node(splicing_setup): spack.config.set("packages", _make_specs_non_buildable(["splice-t"])) goal_spec = Spec("splice-t@1 ^splice-h@1.0.2+compat ^splice-z@1.0.0+compat") with pytest.raises(Exception): - goal_spec.concretized() + spack.concretize.concretize_one(goal_spec) _enable_splicing() - assert goal_spec.concretized().satisfies(goal_spec) + assert spack.concretize.concretize_one(goal_spec).satisfies(goal_spec) def test_double_splice(splicing_setup): @@ -107,9 +108,9 @@ def test_double_splice(splicing_setup): spack.config.set("packages", freeze_builds_config) goal_spec = Spec("splice-t@1 ^splice-h@1.0.2+compat ^splice-z@1.0.2+compat") with pytest.raises(Exception): - goal_spec.concretized() + spack.concretize.concretize_one(goal_spec) _enable_splicing() - assert goal_spec.concretized().satisfies(goal_spec) + assert spack.concretize.concretize_one(goal_spec).satisfies(goal_spec) # The next two tests are mirrors of one another @@ -126,10 +127,10 @@ def test_virtual_multi_splices_in(splicing_setup): spack.config.set("packages", _make_specs_non_buildable(["depends-on-virtual-with-abi"])) for gs in goal_specs: with pytest.raises(Exception): - Spec(gs).concretized() + spack.concretize.concretize_one(gs) _enable_splicing() for gs in goal_specs: - assert Spec(gs).concretized().satisfies(gs) + assert spack.concretize.concretize_one(gs).satisfies(gs) def test_virtual_multi_can_be_spliced(splicing_setup): @@ -143,12 +144,12 @@ def test_virtual_multi_can_be_spliced(splicing_setup): ] with CacheManager(cache): spack.config.set("packages", _make_specs_non_buildable(["depends-on-virtual-with-abi"])) - with pytest.raises(Exception): - for gs in goal_specs: - Spec(gs).concretized() + for gs in goal_specs: + with pytest.raises(Exception): + spack.concretize.concretize_one(gs) _enable_splicing() for gs in goal_specs: - assert Spec(gs).concretized().satisfies(gs) + assert spack.concretize.concretize_one(gs).satisfies(gs) def test_manyvariant_star_matching_variant_splice(splicing_setup): @@ -166,10 +167,10 @@ def test_manyvariant_star_matching_variant_splice(splicing_setup): spack.config.set("packages", freeze_build_config) for goal in goal_specs: with pytest.raises(Exception): - goal.concretized() + spack.concretize.concretize_one(goal) _enable_splicing() for goal in goal_specs: - assert goal.concretized().satisfies(goal) + assert spack.concretize.concretize_one(goal).satisfies(goal) def test_manyvariant_limited_matching(splicing_setup): @@ -188,10 +189,10 @@ def test_manyvariant_limited_matching(splicing_setup): spack.config.set("packages", freeze_build_config) for s in goal_specs: with pytest.raises(Exception): - s.concretized() + spack.concretize.concretize_one(s) _enable_splicing() for s in goal_specs: - assert s.concretized().satisfies(s) + assert spack.concretize.concretize_one(s).satisfies(s) def test_external_splice_same_name(splicing_setup): @@ -210,7 +211,7 @@ def test_external_splice_same_name(splicing_setup): spack.config.set("packages", packages_yaml) _enable_splicing() for s in goal_specs: - assert s.concretized().satisfies(s) + assert spack.concretize.concretize_one(s).satisfies(s) def test_spliced_build_deps_only_in_build_spec(splicing_setup): @@ -219,7 +220,7 @@ def test_spliced_build_deps_only_in_build_spec(splicing_setup): with CacheManager(cache): _enable_splicing() - concr_goal = goal_spec.concretized() + concr_goal = spack.concretize.concretize_one(goal_spec) build_spec = concr_goal._build_spec # Spec has been spliced assert build_spec is not None @@ -237,7 +238,7 @@ def test_spliced_transitive_dependency(splicing_setup): with CacheManager(cache): spack.config.set("packages", _make_specs_non_buildable(["splice-depends-on-t"])) _enable_splicing() - concr_goal = goal_spec.concretized() + concr_goal = spack.concretize.concretize_one(goal_spec) # Spec has been spliced assert concr_goal._build_spec is not None assert concr_goal["splice-t"]._build_spec is not None diff --git a/lib/spack/spack/test/architecture.py b/lib/spack/spack/test/architecture.py index 991cc3f8cb9..04e89fc80b5 100644 --- a/lib/spack/spack/test/architecture.py +++ b/lib/spack/spack/test/architecture.py @@ -133,5 +133,5 @@ def test_concretize_target_ranges(root_target_range, dep_target_range, result, m f"pkg-a %gcc@10 foobar=bar target={root_target_range} ^pkg-b target={dep_target_range}" ) with spack.concretize.disable_compiler_existence_check(): - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.target == spec["pkg-b"].target == result diff --git a/lib/spack/spack/test/bindist.py b/lib/spack/spack/test/bindist.py index a67ccc1632f..4b9659883b4 100644 --- a/lib/spack/spack/test/bindist.py +++ b/lib/spack/spack/test/bindist.py @@ -28,6 +28,7 @@ import spack.binary_distribution as bindist import spack.caches import spack.compilers +import spack.concretize import spack.config import spack.fetch_strategy import spack.hooks.sbang as sbang @@ -205,8 +206,9 @@ def test_default_rpaths_create_install_default_layout(temporary_mirror_dir): Test the creation and installation of buildcaches with default rpaths into the default directory layout scheme. """ - gspec, cspec = Spec("garply").concretized(), Spec("corge").concretized() - sy_spec = Spec("symly").concretized() + gspec = spack.concretize.concretize_one("garply") + cspec = spack.concretize.concretize_one("corge") + sy_spec = spack.concretize.concretize_one("symly") # Install 'corge' without using a cache install_cmd("--no-cache", cspec.name) @@ -253,9 +255,9 @@ def test_default_rpaths_install_nondefault_layout(temporary_mirror_dir): Test the creation and installation of buildcaches with default rpaths into the non-default directory layout scheme. """ - cspec = Spec("corge").concretized() + cspec = spack.concretize.concretize_one("corge") # This guy tests for symlink relocation - sy_spec = Spec("symly").concretized() + sy_spec = spack.concretize.concretize_one("symly") # Install some packages with dependent packages # test install in non-default install path scheme @@ -276,7 +278,8 @@ def test_relative_rpaths_install_default_layout(temporary_mirror_dir): Test the creation and installation of buildcaches with relative rpaths into the default directory layout scheme. """ - gspec, cspec = Spec("garply").concretized(), Spec("corge").concretized() + gspec = spack.concretize.concretize_one("garply") + cspec = spack.concretize.concretize_one("corge") # Install buildcache created with relativized rpaths buildcache_cmd("install", "-uf", cspec.name) @@ -305,7 +308,7 @@ def test_relative_rpaths_install_nondefault(temporary_mirror_dir): Test the installation of buildcaches with relativized rpaths into the non-default directory layout scheme. """ - cspec = Spec("corge").concretized() + cspec = spack.concretize.concretize_one("corge") # Test install in non-default install path scheme and relative path buildcache_cmd("install", "-uf", cspec.name) @@ -358,7 +361,8 @@ def test_built_spec_cache(temporary_mirror_dir): that cache from a buildcache index.""" buildcache_cmd("list", "-a", "-l") - gspec, cspec = Spec("garply").concretized(), Spec("corge").concretized() + gspec = spack.concretize.concretize_one("garply") + cspec = spack.concretize.concretize_one("corge") for s in [gspec, cspec]: results = bindist.get_mirrors_for_spec(s) @@ -381,7 +385,7 @@ def test_spec_needs_rebuild(monkeypatch, tmpdir): mirror_dir = tmpdir.join("mirror_dir") mirror_url = url_util.path_to_file_url(mirror_dir.strpath) - s = Spec("libdwarf").concretized() + s = spack.concretize.concretize_one("libdwarf") # Install a package install_cmd(s.name) @@ -410,7 +414,7 @@ def test_generate_index_missing(monkeypatch, tmpdir, mutable_config): mirror_url = url_util.path_to_file_url(mirror_dir.strpath) spack.config.set("mirrors", {"test": mirror_url}) - s = Spec("libdwarf").concretized() + s = spack.concretize.concretize_one("libdwarf") # Install a package install_cmd("--no-cache", s.name) @@ -494,7 +498,7 @@ def mock_list_url(url, recursive=False): def test_update_sbang(tmp_path, temporary_mirror, mock_fetch, install_mockery): """Test relocation of the sbang shebang line in a package script""" - s = Spec("old-sbang").concretized() + s = spack.concretize.concretize_one("old-sbang") PackageInstaller([s.package]).install() old_prefix, old_sbang_shebang = s.prefix, sbang.sbang_shebang_line() old_contents = f"""\ diff --git a/lib/spack/spack/test/build_distribution.py b/lib/spack/spack/test/build_distribution.py index dd6dedbc667..aad12c88181 100644 --- a/lib/spack/spack/test/build_distribution.py +++ b/lib/spack/spack/test/build_distribution.py @@ -8,15 +8,15 @@ import pytest import spack.binary_distribution as bd +import spack.concretize import spack.mirrors.mirror -import spack.spec from spack.installer import PackageInstaller pytestmark = pytest.mark.not_on_windows("does not run on windows") def test_build_tarball_overwrite(install_mockery, mock_fetch, monkeypatch, tmp_path): - spec = spack.spec.Spec("trivial-install-test-package").concretized() + spec = spack.concretize.concretize_one("trivial-install-test-package") PackageInstaller([spec.package], fake=True).install() specs = [spec] diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py index 83891a51be1..e4699f1f02f 100644 --- a/lib/spack/spack/test/build_environment.py +++ b/lib/spack/spack/test/build_environment.py @@ -16,6 +16,7 @@ import spack.build_environment import spack.compiler import spack.compilers +import spack.concretize import spack.config import spack.deptypes as dt import spack.package_base @@ -163,8 +164,7 @@ def test_static_to_shared_library(build_environment): @pytest.mark.regression("8345") @pytest.mark.usefixtures("config", "mock_packages") def test_cc_not_changed_by_modules(monkeypatch, working_env): - s = spack.spec.Spec("cmake") - s.concretize() + s = spack.concretize.concretize_one("cmake") pkg = s.package def _set_wrong_cc(x): @@ -184,7 +184,7 @@ def test_setup_dependent_package_inherited_modules( working_env, mock_packages, install_mockery, mock_fetch ): # This will raise on regression - s = spack.spec.Spec("cmake-client-inheritor").concretized() + s = spack.concretize.concretize_one("cmake-client-inheritor") PackageInstaller([s.package]).install() @@ -277,7 +277,7 @@ def platform_pathsep(pathlist): return convert_to_platform_path(pathlist) # Monkeypatch a pkg.compiler.environment with the required modifications - pkg = spack.spec.Spec("cmake").concretized().package + pkg = spack.concretize.concretize_one("cmake").package monkeypatch.setattr(pkg.compiler, "environment", modifications) # Trigger the modifications spack.build_environment.setup_package(pkg, False) @@ -301,7 +301,7 @@ def custom_env(pkg, env): env.prepend_path("PATH", test_path) env.append_flags("ENV_CUSTOM_CC_FLAGS", "--custom-env-flag1") - pkg = spack.spec.Spec("cmake").concretized().package + pkg = spack.concretize.concretize_one("cmake").package monkeypatch.setattr(pkg.compiler, "setup_custom_environment", custom_env) spack.build_environment.setup_package(pkg, False) @@ -322,7 +322,7 @@ def test_external_config_env(mock_packages, mutable_config, working_env): } spack.config.set("packages:cmake", cmake_config) - cmake_client = spack.spec.Spec("cmake-client").concretized() + cmake_client = spack.concretize.concretize_one("cmake-client") spack.build_environment.setup_package(cmake_client.package, False) assert os.environ["TEST_ENV_VAR_SET"] == "yes it's set" @@ -330,8 +330,7 @@ def test_external_config_env(mock_packages, mutable_config, working_env): @pytest.mark.regression("9107") def test_spack_paths_before_module_paths(config, mock_packages, monkeypatch, working_env): - s = spack.spec.Spec("cmake") - s.concretize() + s = spack.concretize.concretize_one("cmake") pkg = s.package module_path = os.path.join("path", "to", "module") @@ -352,8 +351,7 @@ def _set_wrong_cc(x): def test_package_inheritance_module_setup(config, mock_packages, working_env): - s = spack.spec.Spec("multimodule-inheritance") - s.concretize() + s = spack.concretize.concretize_one("multimodule-inheritance") pkg = s.package spack.build_environment.setup_package(pkg, False) @@ -387,8 +385,7 @@ def test_wrapper_variables( not in cuda_include_dirs ) - root = spack.spec.Spec("dt-diamond") - root.concretize() + root = spack.concretize.concretize_one("dt-diamond") for s in root.traverse(): s.prefix = "/{0}-prefix/".format(s.name) @@ -453,7 +450,7 @@ def test_external_prefixes_last(mutable_config, mock_packages, working_env, monk """ ) spack.config.set("packages", cfg_data) - top = spack.spec.Spec("dt-diamond").concretized() + top = spack.concretize.concretize_one("dt-diamond") def _trust_me_its_a_dir(path): return True @@ -500,8 +497,7 @@ def test_parallel_false_is_not_propagating(default_mock_concretization): ) def test_setting_dtags_based_on_config(config_setting, expected_flag, config, mock_packages): # Pick a random package to be able to set compiler's variables - s = spack.spec.Spec("cmake") - s.concretize() + s = spack.concretize.concretize_one("cmake") pkg = s.package env = EnvironmentModifications() @@ -533,7 +529,7 @@ def setup_dependent_package(module, dependent_spec): assert dependent_module.ninja is not None dependent_spec.package.test_attr = True - externaltool = spack.spec.Spec("externaltest").concretized() + externaltool = spack.concretize.concretize_one("externaltest") monkeypatch.setattr( externaltool["externaltool"].package, "setup_dependent_package", setup_dependent_package ) @@ -728,7 +724,7 @@ def test_build_system_globals_only_set_on_root_during_build(default_mock_concret But obviously it can lead to very hard to find bugs... We should get rid of those globals and define them instead as a property on the package instance. """ - root = spack.spec.Spec("mpileaks").concretized() + root = spack.concretize.concretize_one("mpileaks") build_variables = ("std_cmake_args", "std_meson_args", "std_pip_args") # See todo above, we clear out any properties that may have been set by the previous test. diff --git a/lib/spack/spack/test/build_systems.py b/lib/spack/spack/test/build_systems.py index 0b35a67005f..6ed44395b91 100644 --- a/lib/spack/spack/test/build_systems.py +++ b/lib/spack/spack/test/build_systems.py @@ -15,6 +15,7 @@ import spack.build_systems.autotools import spack.build_systems.cmake import spack.builder +import spack.concretize import spack.environment import spack.error import spack.paths @@ -146,7 +147,7 @@ def test_none_is_allowed(self, default_mock_concretization): def test_libtool_archive_files_are_deleted_by_default(self, mutable_database): # Install a package that creates a mock libtool archive - s = Spec("libtool-deletion").concretized() + s = spack.concretize.concretize_one("libtool-deletion") PackageInstaller([s.package], explicit=True).install() # Assert the libtool archive is not there and we have @@ -161,7 +162,7 @@ def test_libtool_archive_files_might_be_installed_on_demand( ): # Install a package that creates a mock libtool archive, # patch its package to preserve the installation - s = Spec("libtool-deletion").concretized() + s = spack.concretize.concretize_one("libtool-deletion") monkeypatch.setattr( type(spack.builder.create(s.package)), "install_libtool_archives", True ) @@ -175,7 +176,9 @@ def test_autotools_gnuconfig_replacement(self, mutable_database): Tests whether only broken config.sub and config.guess are replaced with files from working alternatives from the gnuconfig package. """ - s = Spec("autotools-config-replacement +patch_config_files +gnuconfig").concretized() + s = spack.concretize.concretize_one( + Spec("autotools-config-replacement +patch_config_files +gnuconfig") + ) PackageInstaller([s.package]).install() with open(os.path.join(s.prefix.broken, "config.sub"), encoding="utf-8") as f: @@ -194,7 +197,9 @@ def test_autotools_gnuconfig_replacement_disabled(self, mutable_database): """ Tests whether disabling patch_config_files """ - s = Spec("autotools-config-replacement ~patch_config_files +gnuconfig").concretized() + s = spack.concretize.concretize_one( + Spec("autotools-config-replacement ~patch_config_files +gnuconfig") + ) PackageInstaller([s.package]).install() with open(os.path.join(s.prefix.broken, "config.sub"), encoding="utf-8") as f: @@ -219,8 +224,9 @@ def test_autotools_gnuconfig_replacement_no_gnuconfig(self, mutable_database, mo enabled, but gnuconfig is not listed as a direct build dependency. """ monkeypatch.setattr(spack.platforms.test.Test, "default", "x86_64") - s = Spec("autotools-config-replacement +patch_config_files ~gnuconfig") - s.concretize() + s = spack.concretize.concretize_one( + Spec("autotools-config-replacement +patch_config_files ~gnuconfig") + ) msg = "Cannot patch config files: missing dependencies: gnuconfig" with pytest.raises(ChildError, match=msg): @@ -300,7 +306,7 @@ def test_define(self, default_mock_concretization): assert define("SINGLE", "red") == "-DSINGLE:STRING=red" def test_define_from_variant(self): - s = Spec("cmake-client multi=up,right ~truthy single=red").concretized() + s = spack.concretize.concretize_one("cmake-client multi=up,right ~truthy single=red") arg = s.package.define_from_variant("MULTI") assert arg == "-DMULTI:STRING=right;up" diff --git a/lib/spack/spack/test/builder.py b/lib/spack/spack/test/builder.py index c895e46ae74..1c611cab053 100644 --- a/lib/spack/spack/test/builder.py +++ b/lib/spack/spack/test/builder.py @@ -8,9 +8,9 @@ from llnl.util.filesystem import touch import spack.builder +import spack.concretize import spack.paths import spack.repo -import spack.spec @pytest.fixture() @@ -78,7 +78,7 @@ def builder_test_repository(): @pytest.mark.disable_clean_stage_check def test_callbacks_and_installation_procedure(spec_str, expected_values, working_env): """Test the correct execution of callbacks and installation procedures for packages.""" - s = spack.spec.Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) builder = spack.builder.create(s.package) for phase_fn in builder: phase_fn.execute() @@ -101,7 +101,7 @@ def test_callbacks_and_installation_procedure(spec_str, expected_values, working ], ) def test_old_style_compatibility_with_super(spec_str, method_name, expected): - s = spack.spec.Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) builder = spack.builder.create(s.package) value = getattr(builder, method_name)() assert value == expected @@ -112,7 +112,7 @@ def test_old_style_compatibility_with_super(spec_str, method_name, expected): @pytest.mark.usefixtures("builder_test_repository", "config", "working_env") @pytest.mark.disable_clean_stage_check def test_build_time_tests_are_executed_from_default_builder(): - s = spack.spec.Spec("old-style-autotools").concretized() + s = spack.concretize.concretize_one("old-style-autotools") builder = spack.builder.create(s.package) builder.pkg.run_tests = True for phase_fn in builder: @@ -126,7 +126,7 @@ def test_build_time_tests_are_executed_from_default_builder(): @pytest.mark.usefixtures("builder_test_repository", "config", "working_env") def test_monkey_patching_wrapped_pkg(): """Confirm 'run_tests' is accessible through wrappers.""" - s = spack.spec.Spec("old-style-autotools").concretized() + s = spack.concretize.concretize_one("old-style-autotools") builder = spack.builder.create(s.package) assert s.package.run_tests is False assert builder.pkg.run_tests is False @@ -141,7 +141,7 @@ def test_monkey_patching_wrapped_pkg(): @pytest.mark.usefixtures("builder_test_repository", "config", "working_env") def test_monkey_patching_test_log_file(): """Confirm 'test_log_file' is accessible through wrappers.""" - s = spack.spec.Spec("old-style-autotools").concretized() + s = spack.concretize.concretize_one("old-style-autotools") builder = spack.builder.create(s.package) s.package.tester.test_log_file = "/some/file" @@ -154,7 +154,7 @@ def test_monkey_patching_test_log_file(): @pytest.mark.not_on_windows("Does not run on windows") def test_install_time_test_callback(tmpdir, config, mock_packages, mock_stage): """Confirm able to run stand-alone test as a post-install callback.""" - s = spack.spec.Spec("py-test-callback").concretized() + s = spack.concretize.concretize_one("py-test-callback") builder = spack.builder.create(s.package) builder.pkg.run_tests = True s.package.tester.test_log_file = tmpdir.join("install_test.log") @@ -174,7 +174,7 @@ def test_mixins_with_builders(working_env): """Tests that run_after and run_before callbacks are accumulated correctly, when mixins are used with builders. """ - s = spack.spec.Spec("builder-and-mixins").concretized() + s = spack.concretize.concretize_one("builder-and-mixins") builder = spack.builder.create(s.package) # Check that callbacks added by the mixin are in the list diff --git a/lib/spack/spack/test/buildrequest.py b/lib/spack/spack/test/buildrequest.py index 41067d7f069..bea3badd45c 100644 --- a/lib/spack/spack/test/buildrequest.py +++ b/lib/spack/spack/test/buildrequest.py @@ -4,6 +4,7 @@ import pytest +import spack.concretize import spack.deptypes as dt import spack.installer as inst import spack.repo @@ -21,8 +22,7 @@ def test_build_request_errors(install_mockery): def test_build_request_basics(install_mockery): - spec = spack.spec.Spec("dependent-install") - spec.concretize() + spec = spack.concretize.concretize_one("dependent-install") assert spec.concrete # Ensure key properties match expectations @@ -39,8 +39,7 @@ def test_build_request_basics(install_mockery): def test_build_request_strings(install_mockery): """Tests of BuildRequest repr and str for coverage purposes.""" # Using a package with one dependency - spec = spack.spec.Spec("dependent-install") - spec.concretize() + spec = spack.concretize.concretize_one("dependent-install") assert spec.concrete # Ensure key properties match expectations @@ -72,7 +71,7 @@ def test_build_request_deptypes( package_deptypes, dependencies_deptypes, ): - s = spack.spec.Spec("dependent-install").concretized() + s = spack.concretize.concretize_one("dependent-install") build_request = inst.BuildRequest( s.package, diff --git a/lib/spack/spack/test/buildtask.py b/lib/spack/spack/test/buildtask.py index 9771c90071c..5eddd3e2ce1 100644 --- a/lib/spack/spack/test/buildtask.py +++ b/lib/spack/spack/test/buildtask.py @@ -4,6 +4,7 @@ import pytest +import spack.concretize import spack.error import spack.installer as inst import spack.repo @@ -24,7 +25,7 @@ def test_build_task_errors(install_mockery): inst.BuildTask(pkg_cls(spec), None) # Using a concretized package now means the request argument is checked. - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.concrete with pytest.raises(TypeError, match="is not a valid build request"): @@ -47,8 +48,7 @@ def test_build_task_errors(install_mockery): def test_build_task_basics(install_mockery): - spec = spack.spec.Spec("dependent-install") - spec.concretize() + spec = spack.concretize.concretize_one("dependent-install") assert spec.concrete # Ensure key properties match expectations @@ -69,8 +69,7 @@ def test_build_task_basics(install_mockery): def test_build_task_strings(install_mockery): """Tests of build_task repr and str for coverage purposes.""" # Using a package with one dependency - spec = spack.spec.Spec("dependent-install") - spec.concretize() + spec = spack.concretize.concretize_one("dependent-install") assert spec.concrete # Ensure key properties match expectations diff --git a/lib/spack/spack/test/ci.py b/lib/spack/spack/test/ci.py index c703510ee2f..f951c0664db 100644 --- a/lib/spack/spack/test/ci.py +++ b/lib/spack/spack/test/ci.py @@ -9,13 +9,12 @@ import llnl.util.filesystem as fs import spack.ci as ci +import spack.concretize import spack.environment as ev import spack.error import spack.paths as spack_paths import spack.repo as repo -import spack.spec import spack.util.git -from spack.spec import Spec pytestmark = [pytest.mark.usefixtures("mock_packages")] @@ -54,7 +53,7 @@ def test_pipeline_dag(config, tmpdir): builder.add_package("pkg-a", dependencies=[("pkg-b", None, None), ("pkg-c", None, None)]) with repo.use_repositories(builder.root): - spec_a = Spec("pkg-a").concretized() + spec_a = spack.concretize.concretize_one("pkg-a") key_a = ci.common.PipelineDag.key(spec_a) key_b = ci.common.PipelineDag.key(spec_a["pkg-b"]) @@ -449,7 +448,7 @@ def test_ci_run_standalone_tests_not_installed_junit( log_file = tmp_path / "junit.xml" args = { "log_file": str(log_file), - "job_spec": spack.spec.Spec("printing-package").concretized(), + "job_spec": spack.concretize.concretize_one("printing-package"), "repro_dir": str(repro_dir), "fail_fast": True, } @@ -468,7 +467,7 @@ def test_ci_run_standalone_tests_not_installed_cdash( log_file = tmp_path / "junit.xml" args = { "log_file": str(log_file), - "job_spec": spack.spec.Spec("printing-package").concretized(), + "job_spec": spack.concretize.concretize_one("printing-package"), "repro_dir": str(repro_dir), } @@ -501,7 +500,7 @@ def test_ci_run_standalone_tests_not_installed_cdash( def test_ci_skipped_report(tmpdir, mock_packages, config): """Test explicit skipping of report as well as CI's 'package' arg.""" pkg = "trivial-smoke-test" - spec = spack.spec.Spec(pkg).concretized() + spec = spack.concretize.concretize_one(pkg) ci_cdash = { "url": "file://fake", "build-group": "fake-group", diff --git a/lib/spack/spack/test/cmd/bootstrap.py b/lib/spack/spack/test/cmd/bootstrap.py index dd532a6ad7b..33166433833 100644 --- a/lib/spack/spack/test/cmd/bootstrap.py +++ b/lib/spack/spack/test/cmd/bootstrap.py @@ -10,6 +10,7 @@ import spack.bootstrap import spack.bootstrap.core +import spack.concretize import spack.config import spack.environment as ev import spack.main @@ -183,7 +184,7 @@ def test_bootstrap_mirror_metadata(mutable_config, linux_os, monkeypatch, tmpdir """ old_create = spack.mirrors.utils.create monkeypatch.setattr(spack.mirrors.utils, "create", lambda p, s: old_create(p, [])) - monkeypatch.setattr(spack.spec.Spec, "concretized", lambda p: p) + monkeypatch.setattr(spack.concretize, "concretize_one", lambda p: spack.spec.Spec(p)) # Create the mirror in a temporary folder compilers = [ diff --git a/lib/spack/spack/test/cmd/buildcache.py b/lib/spack/spack/test/cmd/buildcache.py index 82db4468375..52d2616cd68 100644 --- a/lib/spack/spack/test/cmd/buildcache.py +++ b/lib/spack/spack/test/cmd/buildcache.py @@ -12,6 +12,7 @@ import spack.binary_distribution import spack.cmd.buildcache +import spack.concretize import spack.environment as ev import spack.error import spack.main @@ -19,7 +20,6 @@ import spack.spec import spack.util.url from spack.installer import PackageInstaller -from spack.spec import Spec buildcache = spack.main.SpackCommand("buildcache") install = spack.main.SpackCommand("install") @@ -81,7 +81,7 @@ def tests_buildcache_create(install_mockery, mock_fetch, monkeypatch, tmpdir): buildcache("push", "--unsigned", str(tmpdir), pkg) - spec = Spec(pkg).concretized() + spec = spack.concretize.concretize_one(pkg) tarball_path = spack.binary_distribution.tarball_path_name(spec, ".spack") tarball = spack.binary_distribution.tarball_name(spec, ".spec.json") assert os.path.exists(os.path.join(str(tmpdir), "build_cache", tarball_path)) @@ -101,7 +101,7 @@ def tests_buildcache_create_env( buildcache("push", "--unsigned", str(tmpdir)) - spec = Spec(pkg).concretized() + spec = spack.concretize.concretize_one(pkg) tarball_path = spack.binary_distribution.tarball_path_name(spec, ".spack") tarball = spack.binary_distribution.tarball_name(spec, ".spec.json") assert os.path.exists(os.path.join(str(tmpdir), "build_cache", tarball_path)) @@ -145,7 +145,7 @@ def test_update_key_index( gpg("create", "Test Signing Key", "nobody@nowhere.com") - s = Spec("libdwarf").concretized() + s = spack.concretize.concretize_one("libdwarf") # Install a package install(s.name) @@ -175,7 +175,7 @@ def test_buildcache_autopush(tmp_path, install_mockery, mock_fetch): mirror("add", "--unsigned", "mirror", mirror_dir.as_uri()) mirror("add", "--autopush", "--unsigned", "mirror-autopush", mirror_autopush_dir.as_uri()) - s = Spec("libdwarf").concretized() + s = spack.concretize.concretize_one("libdwarf") # Install and generate build cache index PackageInstaller([s.package], explicit=True).install() @@ -219,7 +219,7 @@ def verify_mirror_contents(): assert False # Install a package and put it in the buildcache - s = Spec(out_env_pkg).concretized() + s = spack.concretize.concretize_one(out_env_pkg) install(s.name) buildcache("push", "-u", "-f", src_mirror_url, s.name) @@ -329,7 +329,7 @@ def test_buildcache_create_install( buildcache("push", "--unsigned", str(tmpdir), pkg) - spec = Spec(pkg).concretized() + spec = spack.concretize.concretize_one(pkg) tarball_path = spack.binary_distribution.tarball_path_name(spec, ".spack") tarball = spack.binary_distribution.tarball_name(spec, ".spec.json") assert os.path.exists(os.path.join(str(tmpdir), "build_cache", tarball_path)) @@ -450,7 +450,7 @@ def test_push_and_install_with_mirror_marked_unsigned_does_not_require_extra_fla def test_skip_no_redistribute(mock_packages, config): - specs = list(Spec("no-redistribute-dependent").concretized().traverse()) + specs = list(spack.concretize.concretize_one("no-redistribute-dependent").traverse()) filtered = spack.cmd.buildcache._skip_no_redistribute_for_public(specs) assert not any(s.name == "no-redistribute" for s in filtered) assert any(s.name == "no-redistribute-dependent" for s in filtered) @@ -490,7 +490,7 @@ def test_push_without_build_deps(tmp_path, temporary_store, mock_packages, mutab mirror("add", "--unsigned", "my-mirror", str(tmp_path)) - s = spack.spec.Spec("dtrun3").concretized() + s = spack.concretize.concretize_one("dtrun3") PackageInstaller([s.package], explicit=True, fake=True).install() s["dtbuild3"].package.do_uninstall() diff --git a/lib/spack/spack/test/cmd/checksum.py b/lib/spack/spack/test/cmd/checksum.py index b6b37358ca1..6ea333f286b 100644 --- a/lib/spack/spack/test/cmd/checksum.py +++ b/lib/spack/spack/test/cmd/checksum.py @@ -7,10 +7,10 @@ import pytest import spack.cmd.checksum +import spack.concretize import spack.error import spack.package_base import spack.repo -import spack.spec import spack.stage import spack.util.web from spack.main import SpackCommand @@ -308,7 +308,7 @@ def test_checksum_url(mock_packages, config): def test_checksum_verification_fails(default_mock_concretization, capsys, can_fetch_versions): - spec = spack.spec.Spec("zlib").concretized() + spec = spack.concretize.concretize_one("zlib") pkg = spec.package versions = list(pkg.versions.keys()) version_hashes = {versions[0]: "abadhash", Version("0.1"): "123456789"} diff --git a/lib/spack/spack/test/cmd/ci.py b/lib/spack/spack/test/cmd/ci.py index 919c322c2b0..a017e33a38b 100644 --- a/lib/spack/spack/test/cmd/ci.py +++ b/lib/spack/spack/test/cmd/ci.py @@ -18,6 +18,7 @@ import spack.ci as ci import spack.cmd import spack.cmd.ci +import spack.concretize import spack.environment as ev import spack.hash_types as ht import spack.main @@ -1056,7 +1057,7 @@ def test_ci_rebuild_index( with working_dir(tmp_path): env_cmd("create", "test", "./spack.yaml") with ev.read("test"): - concrete_spec = Spec("callpath").concretized() + concrete_spec = spack.concretize.concretize_one("callpath") with open(tmp_path / "spec.json", "w", encoding="utf-8") as f: f.write(concrete_spec.to_json(hash=ht.dag_hash)) @@ -1177,12 +1178,10 @@ def test_ci_generate_read_broken_specs_url( ci_base_environment, ): """Verify that `broken-specs-url` works as intended""" - spec_a = Spec("pkg-a") - spec_a.concretize() + spec_a = spack.concretize.concretize_one("pkg-a") a_dag_hash = spec_a.dag_hash() - spec_flattendeps = Spec("flatten-deps") - spec_flattendeps.concretize() + spec_flattendeps = spack.concretize.concretize_one("flatten-deps") flattendeps_dag_hash = spec_flattendeps.dag_hash() broken_specs_url = tmp_path.as_uri() @@ -1533,8 +1532,7 @@ def dynamic_mapping_setup(tmpdir): """ ) - spec_a = Spec("pkg-a") - spec_a.concretize() + spec_a = spack.concretize.concretize_one("pkg-a") return gitlab_generator.get_job_name(spec_a) diff --git a/lib/spack/spack/test/cmd/clean.py b/lib/spack/spack/test/cmd/clean.py index 01a8d3181f0..91482530560 100644 --- a/lib/spack/spack/test/cmd/clean.py +++ b/lib/spack/spack/test/cmd/clean.py @@ -10,10 +10,8 @@ import spack.caches import spack.cmd.clean -import spack.environment as ev import spack.main import spack.package_base -import spack.spec import spack.stage import spack.store @@ -69,20 +67,6 @@ def test_function_calls(command_line, effects, mock_calls_for_clean): assert mock_calls_for_clean[name] == (1 if name in effects else 0) -def test_env_aware_clean(mock_stage, install_mockery, mutable_mock_env_path, monkeypatch): - e = ev.create("test", with_view=False) - e.add("mpileaks") - e.concretize() - - def fail(*args, **kwargs): - raise Exception("This should not have been called") - - monkeypatch.setattr(spack.spec.Spec, "concretize", fail) - - with e: - clean("mpileaks") - - def test_remove_python_cache(tmpdir, monkeypatch): cache_files = ["file1.pyo", "file2.pyc"] source_file = "file1.py" diff --git a/lib/spack/spack/test/cmd/config.py b/lib/spack/spack/test/cmd/config.py index 1182ebd68f8..c30e8b3d7b4 100644 --- a/lib/spack/spack/test/cmd/config.py +++ b/lib/spack/spack/test/cmd/config.py @@ -8,12 +8,12 @@ import llnl.util.filesystem as fs +import spack.concretize import spack.config import spack.database import spack.environment as ev import spack.main import spack.schema.config -import spack.spec import spack.store import spack.util.spack_yaml as syaml @@ -593,8 +593,7 @@ def test_config_prefer_upstream( prepared_db = spack.database.Database(mock_db_root, layout=gen_mock_layout("/a/")) for spec in ["hdf5 +mpi", "hdf5 ~mpi", "boost+debug~icu+graph", "dependency-install", "patch"]: - dep = spack.spec.Spec(spec) - dep.concretize() + dep = spack.concretize.concretize_one(spec) prepared_db.add(dep) downstream_db_root = str(tmpdir_factory.mktemp("mock_downstream_db_root")) diff --git a/lib/spack/spack/test/cmd/deprecate.py b/lib/spack/spack/test/cmd/deprecate.py index 81da47b9759..68994a5c33b 100644 --- a/lib/spack/spack/test/cmd/deprecate.py +++ b/lib/spack/spack/test/cmd/deprecate.py @@ -4,6 +4,7 @@ import pytest +import spack.concretize import spack.spec import spack.store from spack.enums import InstallRecordStatus @@ -66,8 +67,8 @@ def test_deprecate_deps(mock_packages, mock_archive, mock_fetch, install_mockery install("libdwarf@20130729 ^libelf@0.8.13") install("libdwarf@20130207 ^libelf@0.8.10") - new_spec = spack.spec.Spec("libdwarf@20130729^libelf@0.8.13").concretized() - old_spec = spack.spec.Spec("libdwarf@20130207^libelf@0.8.10").concretized() + new_spec = spack.concretize.concretize_one("libdwarf@20130729^libelf@0.8.13") + old_spec = spack.concretize.concretize_one("libdwarf@20130207^libelf@0.8.10") all_installed = spack.store.STORE.db.query() @@ -107,12 +108,12 @@ def test_deprecate_already_deprecated(mock_packages, mock_archive, mock_fetch, i install("libelf@0.8.12") install("libelf@0.8.10") - deprecated_spec = spack.spec.Spec("libelf@0.8.10").concretized() + deprecated_spec = spack.concretize.concretize_one("libelf@0.8.10") deprecate("-y", "libelf@0.8.10", "libelf@0.8.12") deprecator = spack.store.STORE.db.deprecator(deprecated_spec) - assert deprecator == spack.spec.Spec("libelf@0.8.12").concretized() + assert deprecator == spack.concretize.concretize_one("libelf@0.8.12") deprecate("-y", "libelf@0.8.10", "libelf@0.8.13") @@ -122,7 +123,7 @@ def test_deprecate_already_deprecated(mock_packages, mock_archive, mock_fetch, i assert len(all_available) == 3 deprecator = spack.store.STORE.db.deprecator(deprecated_spec) - assert deprecator == spack.spec.Spec("libelf@0.8.13").concretized() + assert deprecator == spack.concretize.concretize_one("libelf@0.8.13") def test_deprecate_deprecator(mock_packages, mock_archive, mock_fetch, install_mockery): @@ -132,9 +133,9 @@ def test_deprecate_deprecator(mock_packages, mock_archive, mock_fetch, install_m install("libelf@0.8.12") install("libelf@0.8.10") - first_deprecated_spec = spack.spec.Spec("libelf@0.8.10").concretized() - second_deprecated_spec = spack.spec.Spec("libelf@0.8.12").concretized() - final_deprecator = spack.spec.Spec("libelf@0.8.13").concretized() + first_deprecated_spec = spack.concretize.concretize_one("libelf@0.8.10") + second_deprecated_spec = spack.concretize.concretize_one("libelf@0.8.12") + final_deprecator = spack.concretize.concretize_one("libelf@0.8.13") deprecate("-y", "libelf@0.8.10", "libelf@0.8.12") @@ -164,7 +165,7 @@ def test_concretize_deprecated(mock_packages, mock_archive, mock_fetch, install_ spec = spack.spec.Spec("libelf@0.8.10") with pytest.raises(spack.spec.SpecDeprecatedError): - spec.concretize() + spack.concretize.concretize_one(spec) @pytest.mark.usefixtures("mock_packages", "mock_archive", "mock_fetch", "install_mockery") diff --git a/lib/spack/spack/test/cmd/dev_build.py b/lib/spack/spack/test/cmd/dev_build.py index f5349e2015b..dc9102278ed 100644 --- a/lib/spack/spack/test/cmd/dev_build.py +++ b/lib/spack/spack/test/cmd/dev_build.py @@ -8,6 +8,7 @@ import llnl.util.filesystem as fs +import spack.concretize import spack.environment as ev import spack.error import spack.repo @@ -23,7 +24,9 @@ def test_dev_build_basics(tmpdir, install_mockery): - spec = spack.spec.Spec(f"dev-build-test-install@0.0.0 dev_path={tmpdir}").concretized() + spec = spack.concretize.concretize_one( + spack.spec.Spec(f"dev-build-test-install@0.0.0 dev_path={tmpdir}") + ) assert "dev_path" in spec.variants @@ -41,7 +44,9 @@ def test_dev_build_basics(tmpdir, install_mockery): def test_dev_build_before(tmpdir, install_mockery): - spec = spack.spec.Spec(f"dev-build-test-install@0.0.0 dev_path={tmpdir}").concretized() + spec = spack.concretize.concretize_one( + spack.spec.Spec(f"dev-build-test-install@0.0.0 dev_path={tmpdir}") + ) with tmpdir.as_cwd(): with open(spec.package.filename, "w", encoding="utf-8") as f: @@ -57,7 +62,9 @@ def test_dev_build_before(tmpdir, install_mockery): def test_dev_build_until(tmpdir, install_mockery): - spec = spack.spec.Spec(f"dev-build-test-install@0.0.0 dev_path={tmpdir}").concretized() + spec = spack.concretize.concretize_one( + spack.spec.Spec(f"dev-build-test-install@0.0.0 dev_path={tmpdir}") + ) with tmpdir.as_cwd(): with open(spec.package.filename, "w", encoding="utf-8") as f: @@ -75,7 +82,9 @@ def test_dev_build_until(tmpdir, install_mockery): def test_dev_build_until_last_phase(tmpdir, install_mockery): # Test that we ignore the last_phase argument if it is already last - spec = spack.spec.Spec(f"dev-build-test-install@0.0.0 dev_path={tmpdir}").concretized() + spec = spack.concretize.concretize_one( + spack.spec.Spec(f"dev-build-test-install@0.0.0 dev_path={tmpdir}") + ) with tmpdir.as_cwd(): with open(spec.package.filename, "w", encoding="utf-8") as f: @@ -93,7 +102,9 @@ def test_dev_build_until_last_phase(tmpdir, install_mockery): def test_dev_build_before_until(tmpdir, install_mockery): - spec = spack.spec.Spec(f"dev-build-test-install@0.0.0 dev_path={tmpdir}").concretized() + spec = spack.concretize.concretize_one( + spack.spec.Spec(f"dev-build-test-install@0.0.0 dev_path={tmpdir}") + ) with tmpdir.as_cwd(): with open(spec.package.filename, "w", encoding="utf-8") as f: @@ -129,8 +140,9 @@ def test_dev_build_drop_in(tmpdir, mock_packages, monkeypatch, install_mockery, def test_dev_build_fails_already_installed(tmpdir, install_mockery): - spec = spack.spec.Spec("dev-build-test-install@0.0.0 dev_path=%s" % tmpdir) - spec.concretize() + spec = spack.concretize.concretize_one( + spack.spec.Spec("dev-build-test-install@0.0.0 dev_path=%s" % tmpdir) + ) with tmpdir.as_cwd(): with open(spec.package.filename, "w", encoding="utf-8") as f: @@ -172,8 +184,9 @@ def test_dev_build_env(tmpdir, install_mockery, mutable_mock_env_path): """Test Spack does dev builds for packages in develop section of env.""" # setup dev-build-test-install package for dev build build_dir = tmpdir.mkdir("build") - spec = spack.spec.Spec("dev-build-test-install@0.0.0 dev_path=%s" % build_dir) - spec.concretize() + spec = spack.concretize.concretize_one( + spack.spec.Spec("dev-build-test-install@0.0.0 dev_path=%s" % build_dir) + ) with build_dir.as_cwd(): with open(spec.package.filename, "w", encoding="utf-8") as f: @@ -208,8 +221,9 @@ def test_dev_build_env_with_vars(tmpdir, install_mockery, mutable_mock_env_path, """Test Spack does dev builds for packages in develop section of env (path with variables).""" # setup dev-build-test-install package for dev build build_dir = tmpdir.mkdir("build") - spec = spack.spec.Spec(f"dev-build-test-install@0.0.0 dev_path={build_dir}") - spec.concretize() + spec = spack.concretize.concretize_one( + spack.spec.Spec(f"dev-build-test-install@0.0.0 dev_path={build_dir}") + ) # store the build path in an environment variable that will be used in the environment monkeypatch.setenv("CUSTOM_BUILD_PATH", build_dir) @@ -246,8 +260,9 @@ def test_dev_build_env_version_mismatch(tmpdir, install_mockery, mutable_mock_en """Test Spack constraints concretization by develop specs.""" # setup dev-build-test-install package for dev build build_dir = tmpdir.mkdir("build") - spec = spack.spec.Spec("dev-build-test-install@0.0.0 dev_path=%s" % tmpdir) - spec.concretize() + spec = spack.concretize.concretize_one( + spack.spec.Spec("dev-build-test-install@0.0.0 dev_path=%s" % tmpdir) + ) with build_dir.as_cwd(): with open(spec.package.filename, "w", encoding="utf-8") as f: @@ -327,8 +342,8 @@ def test_dev_build_multiple(tmpdir, install_mockery, mutable_mock_env_path, mock with ev.read("test"): # Do concretization inside environment for dev info # These specs are the source of truth to compare against the installs - leaf_spec.concretize() - root_spec.concretize() + leaf_spec = spack.concretize.concretize_one(leaf_spec) + root_spec = spack.concretize.concretize_one(root_spec) # Do install install() @@ -374,8 +389,8 @@ def test_dev_build_env_dependency(tmpdir, install_mockery, mock_fetch, mutable_m # concretize in the environment to get the dev build info # equivalent to setting dev_build and dev_path variants # on all specs above - spec.concretize() - dep_spec.concretize() + spec = spack.concretize.concretize_one(spec) + dep_spec = spack.concretize.concretize_one(dep_spec) install() # Ensure that both specs installed properly @@ -399,8 +414,9 @@ def test_dev_build_rebuild_on_source_changes( """ # setup dev-build-test-install package for dev build build_dir = tmpdir.mkdir("build") - spec = spack.spec.Spec("dev-build-test-install@0.0.0 dev_path=%s" % build_dir) - spec.concretize() + spec = spack.concretize.concretize_one( + spack.spec.Spec("dev-build-test-install@0.0.0 dev_path=%s" % build_dir) + ) def reset_string(): with build_dir.as_cwd(): diff --git a/lib/spack/spack/test/cmd/develop.py b/lib/spack/spack/test/cmd/develop.py index 9394987eb58..dd2195d259c 100644 --- a/lib/spack/spack/test/cmd/develop.py +++ b/lib/spack/spack/test/cmd/develop.py @@ -8,6 +8,7 @@ import llnl.util.filesystem as fs +import spack.concretize import spack.config import spack.environment as ev import spack.package_base @@ -138,7 +139,8 @@ def check_path(stage, dest): self.check_develop(e, spack.spec.Spec("mpich@=1.0"), path) # Check modifications actually worked - assert spack.spec.Spec("mpich@1.0").concretized().satisfies("dev_path=%s" % abspath) + result = spack.concretize.concretize_one("mpich@1.0") + assert result.satisfies("dev_path=%s" % abspath) def test_develop_canonicalize_path_no_args(self, monkeypatch): env("create", "test") @@ -165,7 +167,8 @@ def check_path(stage, dest): self.check_develop(e, spack.spec.Spec("mpich@=1.0"), path) # Check modifications actually worked - assert spack.spec.Spec("mpich@1.0").concretized().satisfies("dev_path=%s" % abspath) + result = spack.concretize.concretize_one("mpich@1.0") + assert result.satisfies("dev_path=%s" % abspath) def _git_commit_list(git_repo_dir): @@ -190,7 +193,7 @@ def test_develop_full_git_repo( spack.package_base.PackageBase, "git", "file://%s" % repo_path, raising=False ) - spec = spack.spec.Spec("git-test-commit@1.2").concretized() + spec = spack.concretize.concretize_one("git-test-commit@1.2") try: spec.package.do_stage() commits = _git_commit_list(spec.package.stage[0].source_path) diff --git a/lib/spack/spack/test/cmd/diff.py b/lib/spack/spack/test/cmd/diff.py index f07b91f0eca..9ef9acacc9f 100644 --- a/lib/spack/spack/test/cmd/diff.py +++ b/lib/spack/spack/test/cmd/diff.py @@ -5,9 +5,9 @@ import pytest import spack.cmd.diff +import spack.concretize import spack.main import spack.repo -import spack.spec import spack.util.spack_json as sjson from spack.test.conftest import create_test_repo @@ -133,8 +133,8 @@ def test_repo(_create_test_repo, monkeypatch, mock_stage): def test_diff_ignore(test_repo): - specA = spack.spec.Spec("p1+usev1").concretized() - specB = spack.spec.Spec("p1~usev1").concretized() + specA = spack.concretize.concretize_one("p1+usev1") + specB = spack.concretize.concretize_one("p1~usev1") c1 = spack.cmd.diff.compare_specs(specA, specB, to_string=False) @@ -154,8 +154,8 @@ def find(function_list, name, args): # Check ignoring changes on multiple packages - specA = spack.spec.Spec("p1+usev1 ^p3+p3var").concretized() - specA = spack.spec.Spec("p1~usev1 ^p3~p3var").concretized() + specA = spack.concretize.concretize_one("p1+usev1 ^p3+p3var") + specA = spack.concretize.concretize_one("p1~usev1 ^p3~p3var") c3 = spack.cmd.diff.compare_specs(specA, specB, to_string=False) assert find(c3["a_not_b"], "variant_value", ["p3", "p3var"]) @@ -168,8 +168,8 @@ def find(function_list, name, args): def test_diff_cmd(install_mockery, mock_fetch, mock_archive, mock_packages): """Test that we can install two packages and diff them""" - specA = spack.spec.Spec("mpileaks").concretized() - specB = spack.spec.Spec("mpileaks+debug").concretized() + specA = spack.concretize.concretize_one("mpileaks") + specB = spack.concretize.concretize_one("mpileaks+debug") # Specs should be the same as themselves c = spack.cmd.diff.compare_specs(specA, specA, to_string=True) diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py index 240b7cf5dce..0c0bcad7445 100644 --- a/lib/spack/spack/test/cmd/env.py +++ b/lib/spack/spack/test/cmd/env.py @@ -19,6 +19,7 @@ from llnl.util.symlink import readlink import spack.cmd.env +import spack.concretize import spack.config import spack.environment as ev import spack.environment.depfile as depfile @@ -957,7 +958,7 @@ def test_lockfile_spliced_specs(environment_from_manifest, install_mockery): """Test that an environment can round-trip a spliced spec.""" # Create a local install for zmpi to splice in # Default concretization is not using zmpi - zmpi = spack.spec.Spec("zmpi").concretized() + zmpi = spack.concretize.concretize_one("zmpi") PackageInstaller([zmpi.package], fake=True).install() e1 = environment_from_manifest( @@ -1320,39 +1321,43 @@ def test_config_change_existing(mutable_mock_env_path, tmp_path, mock_packages, with e: # List of requirements, flip a variant config("change", "packages:mpich:require:~debug") - test_spec = spack.spec.Spec("mpich").concretized() + test_spec = spack.concretize.concretize_one("mpich") assert test_spec.satisfies("@3.0.2~debug") # List of requirements, change the version (in a different scope) config("change", "packages:mpich:require:@3.0.3") - test_spec = spack.spec.Spec("mpich").concretized() + test_spec = spack.concretize.concretize_one("mpich") assert test_spec.satisfies("@3.0.3") # "require:" as a single string, also try specifying # a spec string that requires enclosing in quotes as # part of the config path config("change", 'packages:libelf:require:"@0.8.12:"') - spack.spec.Spec("libelf@0.8.12").concretized() + spack.concretize.concretize_one("libelf@0.8.12") # No need for assert, if there wasn't a failure, we # changed the requirement successfully. # Use change to add a requirement for a package that # has no requirements defined config("change", "packages:fftw:require:+mpi") - test_spec = spack.spec.Spec("fftw").concretized() + test_spec = spack.concretize.concretize_one("fftw") assert test_spec.satisfies("+mpi") config("change", "packages:fftw:require:~mpi") - test_spec = spack.spec.Spec("fftw").concretized() + test_spec = spack.concretize.concretize_one("fftw") assert test_spec.satisfies("~mpi") config("change", "packages:fftw:require:@1.0") - test_spec = spack.spec.Spec("fftw").concretized() + test_spec = spack.concretize.concretize_one("fftw") assert test_spec.satisfies("@1.0~mpi") # Use "--match-spec" to change one spec in a "one_of" # list config("change", "packages:bowtie:require:@1.2.2", "--match-spec", "@1.2.0") - spack.spec.Spec("bowtie@1.3.0").concretize() - spack.spec.Spec("bowtie@1.2.2").concretized() + # confirm that we can concretize to either value + spack.concretize.concretize_one("bowtie@1.3.0") + spack.concretize.concretize_one("bowtie@1.2.2") + # confirm that we cannot concretize to the old value + with pytest.raises(spack.solver.asp.UnsatisfiableSpecError): + spack.concretize.concretize_one("bowtie@1.2.0") def test_config_change_new(mutable_mock_env_path, tmp_path, mock_packages, mutable_config): @@ -1367,8 +1372,8 @@ def test_config_change_new(mutable_mock_env_path, tmp_path, mock_packages, mutab with ev.Environment(tmp_path): config("change", "packages:mpich:require:~debug") with pytest.raises(spack.solver.asp.UnsatisfiableSpecError): - spack.spec.Spec("mpich+debug").concretized() - spack.spec.Spec("mpich~debug").concretized() + spack.concretize.concretize_one("mpich+debug") + spack.concretize.concretize_one("mpich~debug") # Now check that we raise an error if we need to add a require: constraint # when preexisting config manually specified it as a singular spec @@ -1382,7 +1387,7 @@ def test_config_change_new(mutable_mock_env_path, tmp_path, mock_packages, mutab """ ) with ev.Environment(tmp_path): - assert spack.spec.Spec("mpich").concretized().satisfies("@3.0.3") + assert spack.concretize.concretize_one("mpich").satisfies("@3.0.3") with pytest.raises(spack.error.ConfigError, match="not a list"): config("change", "packages:mpich:require:~debug") @@ -1690,7 +1695,7 @@ def test_stage(mock_stage, mock_fetch, install_mockery): root = str(mock_stage) def check_stage(spec): - spec = Spec(spec).concretized() + spec = spack.concretize.concretize_one(spec) for dep in spec.traverse(): stage_name = f"{stage_prefix}{dep.name}-{dep.version}-{dep.dag_hash()}" assert os.path.isdir(os.path.join(root, stage_name)) @@ -1791,7 +1796,7 @@ def test_indirect_build_dep(tmp_path): with spack.repo.use_repositories(builder.root): x_spec = Spec("x") - x_concretized = x_spec.concretized() + x_concretized = spack.concretize.concretize_one(x_spec) _env_create("test", with_view=False) e = ev.read("test") @@ -1824,10 +1829,10 @@ def test_store_different_build_deps(tmp_path): with spack.repo.use_repositories(builder.root): y_spec = Spec("y ^z@3") - y_concretized = y_spec.concretized() + y_concretized = spack.concretize.concretize_one(y_spec) x_spec = Spec("x ^z@2") - x_concretized = x_spec.concretized() + x_concretized = spack.concretize.concretize_one(x_spec) # Even though x chose a different 'z', the y it chooses should be identical # *aside* from the dependency on 'z'. The dag_hash() will show the difference diff --git a/lib/spack/spack/test/cmd/extensions.py b/lib/spack/spack/test/cmd/extensions.py index e46439ceb64..be80ef9828c 100644 --- a/lib/spack/spack/test/cmd/extensions.py +++ b/lib/spack/spack/test/cmd/extensions.py @@ -5,16 +5,18 @@ import pytest +import spack.concretize from spack.installer import PackageInstaller from spack.main import SpackCommand, SpackCommandError -from spack.spec import Spec extensions = SpackCommand("extensions") @pytest.fixture def python_database(mock_packages, mutable_database): - specs = [Spec(s).concretized() for s in ["python", "py-extension1", "py-extension2"]] + specs = [ + spack.concretize.concretize_one(s) for s in ["python", "py-extension1", "py-extension2"] + ] PackageInstaller([s.package for s in specs], explicit=True, fake=True).install() yield @@ -22,7 +24,7 @@ def python_database(mock_packages, mutable_database): @pytest.mark.not_on_windows("All Fetchers Failed") @pytest.mark.db def test_extensions(mock_packages, python_database, capsys): - ext2 = Spec("py-extension2").concretized() + ext2 = spack.concretize.concretize_one("py-extension2") def check_output(ni): with capsys.disabled(): diff --git a/lib/spack/spack/test/cmd/find.py b/lib/spack/spack/test/cmd/find.py index 6c9efb0de7a..26e62ffc106 100644 --- a/lib/spack/spack/test/cmd/find.py +++ b/lib/spack/spack/test/cmd/find.py @@ -12,13 +12,13 @@ import spack.cmd as cmd import spack.cmd.find +import spack.concretize import spack.environment as ev import spack.repo import spack.store import spack.user_environment as uenv from spack.enums import InstallRecordStatus from spack.main import SpackCommand -from spack.spec import Spec from spack.test.conftest import create_test_repo from spack.test.utilities import SpackCommandArgs from spack.util.pattern import Bunch @@ -201,7 +201,8 @@ def test_find_json_deps(database): @pytest.mark.db def test_display_json(database, capsys): specs = [ - Spec(s).concretized() for s in ["mpileaks ^zmpi", "mpileaks ^mpich", "mpileaks ^mpich2"] + spack.concretize.concretize_one(s) + for s in ["mpileaks ^zmpi", "mpileaks ^mpich", "mpileaks ^mpich2"] ] cmd.display_specs_as_json(specs) @@ -216,7 +217,8 @@ def test_display_json(database, capsys): @pytest.mark.db def test_display_json_deps(database, capsys): specs = [ - Spec(s).concretized() for s in ["mpileaks ^zmpi", "mpileaks ^mpich", "mpileaks ^mpich2"] + spack.concretize.concretize_one(s) + for s in ["mpileaks ^zmpi", "mpileaks ^mpich", "mpileaks ^mpich2"] ] cmd.display_specs_as_json(specs, deps=True) @@ -275,7 +277,7 @@ def test_find_format_deps(database, config): def test_find_format_deps_paths(database, config): output = find("-dp", "--format", "{name}-{version}", "mpileaks", "^zmpi") - spec = Spec("mpileaks ^zmpi").concretized() + spec = spack.concretize.concretize_one("mpileaks ^zmpi") prefixes = [s.prefix for s in spec.traverse()] assert ( @@ -300,7 +302,8 @@ def test_find_very_long(database, config): output = find("-L", "--no-groups", "mpileaks") specs = [ - Spec(s).concretized() for s in ["mpileaks ^zmpi", "mpileaks ^mpich", "mpileaks ^mpich2"] + spack.concretize.concretize_one(s) + for s in ["mpileaks ^zmpi", "mpileaks ^mpich", "mpileaks ^mpich2"] ] assert set(output.strip().split("\n")) == set( diff --git a/lib/spack/spack/test/cmd/gc.py b/lib/spack/spack/test/cmd/gc.py index 8efdd8f2958..b557f5b57ff 100644 --- a/lib/spack/spack/test/cmd/gc.py +++ b/lib/spack/spack/test/cmd/gc.py @@ -5,6 +5,7 @@ import pytest +import spack.concretize import spack.deptypes as dt import spack.environment as ev import spack.main @@ -25,8 +26,7 @@ def test_gc_without_build_dependency(mutable_database): @pytest.mark.db def test_gc_with_build_dependency(mutable_database): - s = spack.spec.Spec("simple-inheritance") - s.concretize() + s = spack.concretize.concretize_one("simple-inheritance") PackageInstaller([s.package], explicit=True, fake=True).install() assert "There are no unused specs." in gc("-yb") @@ -36,8 +36,8 @@ def test_gc_with_build_dependency(mutable_database): @pytest.mark.db def test_gc_with_constraints(mutable_database): - s_cmake1 = spack.spec.Spec("simple-inheritance ^cmake@3.4.3").concretized() - s_cmake2 = spack.spec.Spec("simple-inheritance ^cmake@3.23.1").concretized() + s_cmake1 = spack.concretize.concretize_one("simple-inheritance ^cmake@3.4.3") + s_cmake2 = spack.concretize.concretize_one("simple-inheritance ^cmake@3.23.1") PackageInstaller([s_cmake1.package], explicit=True, fake=True).install() PackageInstaller([s_cmake2.package], explicit=True, fake=True).install() @@ -52,8 +52,7 @@ def test_gc_with_constraints(mutable_database): @pytest.mark.db def test_gc_with_environment(mutable_database, mutable_mock_env_path): - s = spack.spec.Spec("simple-inheritance") - s.concretize() + s = spack.concretize.concretize_one("simple-inheritance") PackageInstaller([s.package], explicit=True, fake=True).install() e = ev.create("test_gc") @@ -68,8 +67,7 @@ def test_gc_with_environment(mutable_database, mutable_mock_env_path): @pytest.mark.db def test_gc_with_build_dependency_in_environment(mutable_database, mutable_mock_env_path): - s = spack.spec.Spec("simple-inheritance") - s.concretize() + s = spack.concretize.concretize_one("simple-inheritance") PackageInstaller([s.package], explicit=True, fake=True).install() e = ev.create("test_gc") @@ -120,8 +118,7 @@ def test_gc_except_any_environments(mutable_database, mutable_mock_env_path): @pytest.mark.db def test_gc_except_specific_environments(mutable_database, mutable_mock_env_path): - s = spack.spec.Spec("simple-inheritance") - s.concretize() + s = spack.concretize.concretize_one("simple-inheritance") PackageInstaller([s.package], explicit=True, fake=True).install() assert mutable_database.query_local("zmpi") @@ -147,8 +144,7 @@ def test_gc_except_nonexisting_dir_env(mutable_database, mutable_mock_env_path, @pytest.mark.db def test_gc_except_specific_dir_env(mutable_database, mutable_mock_env_path, tmpdir): - s = spack.spec.Spec("simple-inheritance") - s.concretize() + s = spack.concretize.concretize_one("simple-inheritance") PackageInstaller([s.package], explicit=True, fake=True).install() assert mutable_database.query_local("zmpi") diff --git a/lib/spack/spack/test/cmd/install.py b/lib/spack/spack/test/cmd/install.py index 4723d1879ed..88ec80639ac 100644 --- a/lib/spack/spack/test/cmd/install.py +++ b/lib/spack/spack/test/cmd/install.py @@ -19,6 +19,7 @@ import spack.build_environment import spack.cmd.common.arguments import spack.cmd.install +import spack.concretize import spack.config import spack.environment as ev import spack.error @@ -134,7 +135,7 @@ def test_package_output(tmpdir, capsys, install_mockery, mock_fetch): # we can't use output capture here because it interferes with Spack's # logging. TODO: see whether we can get multiple log_outputs to work # when nested AND in pytest - spec = Spec("printing-package").concretized() + spec = spack.concretize.concretize_one("printing-package") pkg = spec.package PackageInstaller([pkg], explicit=True, verbose=True).install() @@ -174,7 +175,7 @@ def test_install_output_on_python_error(mock_packages, mock_archive, mock_fetch, def test_install_with_source(mock_packages, mock_archive, mock_fetch, install_mockery): """Verify that source has been copied into place.""" install("--source", "--keep-stage", "trivial-install-test-package") - spec = Spec("trivial-install-test-package").concretized() + spec = spack.concretize.concretize_one("trivial-install-test-package") src = os.path.join(spec.prefix.share, "trivial-install-test-package", "src") assert filecmp.cmp( os.path.join(mock_archive.path, "configure"), os.path.join(src, "configure") @@ -182,8 +183,7 @@ def test_install_with_source(mock_packages, mock_archive, mock_fetch, install_mo def test_install_env_variables(mock_packages, mock_archive, mock_fetch, install_mockery): - spec = Spec("libdwarf") - spec.concretize() + spec = spack.concretize.concretize_one("libdwarf") install("libdwarf") assert os.path.isfile(spec.package.install_env_path) @@ -204,8 +204,7 @@ def test_show_log_on_error(mock_packages, mock_archive, mock_fetch, install_mock def test_install_overwrite(mock_packages, mock_archive, mock_fetch, install_mockery): # Try to install a spec and then to reinstall it. - spec = Spec("libdwarf") - spec.concretize() + spec = spack.concretize.concretize_one("libdwarf") install("libdwarf") @@ -238,8 +237,7 @@ def test_install_overwrite(mock_packages, mock_archive, mock_fetch, install_mock def test_install_overwrite_not_installed(mock_packages, mock_archive, mock_fetch, install_mockery): # Try to install a spec and then to reinstall it. - spec = Spec("libdwarf") - spec.concretize() + spec = spack.concretize.concretize_one("libdwarf") assert not os.path.exists(spec.prefix) @@ -260,7 +258,7 @@ def test_install_commit(mock_git_version_info, install_mockery, mock_packages, m monkeypatch.setattr(spack.package_base.PackageBase, "git", file_url, raising=False) # Use the earliest commit in the respository - spec = Spec(f"git-test-commit@{commits[-1]}").concretized() + spec = spack.concretize.concretize_one(f"git-test-commit@{commits[-1]}") PackageInstaller([spec.package], explicit=True).install() # Ensure first commit file contents were written @@ -273,13 +271,11 @@ def test_install_commit(mock_git_version_info, install_mockery, mock_packages, m def test_install_overwrite_multiple(mock_packages, mock_archive, mock_fetch, install_mockery): # Try to install a spec and then to reinstall it. - libdwarf = Spec("libdwarf") - libdwarf.concretize() + libdwarf = spack.concretize.concretize_one("libdwarf") install("libdwarf") - cmake = Spec("cmake") - cmake.concretize() + cmake = spack.concretize.concretize_one("cmake") install("cmake") @@ -355,7 +351,7 @@ def test_install_invalid_spec(): ) def test_install_from_file(spec, concretize, error_code, tmpdir): if concretize: - spec.concretize() + spec = spack.concretize.concretize_one(spec) specfile = tmpdir.join("spec.yaml") @@ -485,8 +481,7 @@ def test_install_mix_cli_and_files(clispecs, filespecs, tmpdir): for spec in filespecs: filepath = tmpdir.join(spec + ".yaml") args = ["-f", str(filepath)] + args - s = Spec(spec) - s.concretize() + s = spack.concretize.concretize_one(spec) with filepath.open("w") as f: s.to_yaml(f) @@ -495,8 +490,7 @@ def test_install_mix_cli_and_files(clispecs, filespecs, tmpdir): def test_extra_files_are_archived(mock_packages, mock_archive, mock_fetch, install_mockery): - s = Spec("archive-files") - s.concretize() + s = spack.concretize.concretize_one("archive-files") install("archive-files") @@ -615,8 +609,7 @@ def test_cdash_install_from_spec_json( with capfd.disabled(), tmpdir.as_cwd(): spec_json_path = str(tmpdir.join("spec.json")) - pkg_spec = Spec("pkg-a") - pkg_spec.concretize() + pkg_spec = spack.concretize.concretize_one("pkg-a") with open(spec_json_path, "w", encoding="utf-8") as fd: fd.write(pkg_spec.to_json(hash=ht.dag_hash)) @@ -692,8 +685,8 @@ def test_cache_only_fails(tmpdir, mock_fetch, install_mockery, capfd): def test_install_only_dependencies(tmpdir, mock_fetch, install_mockery): - dep = Spec("dependency-install").concretized() - root = Spec("dependent-install").concretized() + dep = spack.concretize.concretize_one("dependency-install") + root = spack.concretize.concretize_one("dependent-install") install("--only", "dependencies", "dependent-install") @@ -714,8 +707,8 @@ def test_install_only_package(tmpdir, mock_fetch, install_mockery, capfd): def test_install_deps_then_package(tmpdir, mock_fetch, install_mockery): - dep = Spec("dependency-install").concretized() - root = Spec("dependent-install").concretized() + dep = spack.concretize.concretize_one("dependency-install") + root = spack.concretize.concretize_one("dependent-install") install("--only", "dependencies", "dependent-install") assert os.path.exists(dep.prefix) @@ -733,8 +726,8 @@ def test_install_only_dependencies_in_env( env("create", "test") with ev.read("test"): - dep = Spec("dependency-install").concretized() - root = Spec("dependent-install").concretized() + dep = spack.concretize.concretize_one("dependency-install") + root = spack.concretize.concretize_one("dependent-install") install("-v", "--only", "dependencies", "--add", "dependent-install") @@ -750,8 +743,8 @@ def test_install_only_dependencies_of_all_in_env( with ev.read("test"): roots = [ - Spec("dependent-install@1.0").concretized(), - Spec("dependent-install@2.0").concretized(), + spack.concretize.concretize_one("dependent-install@1.0"), + spack.concretize.concretize_one("dependent-install@2.0"), ] add("dependent-install@1.0") @@ -900,7 +893,7 @@ def test_cdash_configure_warning(tmpdir, mock_fetch, install_mockery, capfd): # Ensure that even on non-x86_64 architectures, there are no # dependencies installed - spec = Spec("configure-warning").concretized() + spec = spack.concretize.concretize_one("configure-warning") spec.clear_dependencies() specfile = "./spec.json" with open(specfile, "w", encoding="utf-8") as f: @@ -946,7 +939,7 @@ def test_install_env_with_tests_all( ): env("create", "test") with ev.read("test"): - test_dep = Spec("test-dependency").concretized() + test_dep = spack.concretize.concretize_one("test-dependency") add("depb") install("--test", "all") assert os.path.exists(test_dep.prefix) @@ -958,7 +951,7 @@ def test_install_env_with_tests_root( ): env("create", "test") with ev.read("test"): - test_dep = Spec("test-dependency").concretized() + test_dep = spack.concretize.concretize_one("test-dependency") add("depb") install("--test", "root") assert not os.path.exists(test_dep.prefix) diff --git a/lib/spack/spack/test/cmd/load.py b/lib/spack/spack/test/cmd/load.py index d39e246aee2..c0e1a03c799 100644 --- a/lib/spack/spack/test/cmd/load.py +++ b/lib/spack/spack/test/cmd/load.py @@ -7,7 +7,7 @@ import pytest -import spack.spec +import spack.concretize import spack.user_environment as uenv from spack.main import SpackCommand @@ -49,7 +49,7 @@ def test_load_shell(shell, set_command): """Test that `spack load` applies prefix inspections of its required runtime deps in topo-order""" install("mpileaks") - mpileaks_spec = spack.spec.Spec("mpileaks").concretized() + mpileaks_spec = spack.concretize.concretize_one("mpileaks") # Ensure our reference variable is clean. os.environ["CMAKE_PREFIX_PATH"] = "/hello" + os.pathsep + "/world" @@ -166,7 +166,7 @@ def test_unload( """Tests that any variables set in the user environment are undone by the unload command""" install("mpileaks") - mpileaks_spec = spack.spec.Spec("mpileaks").concretized() + mpileaks_spec = spack.concretize.concretize_one("mpileaks") # Set so unload has something to do os.environ["FOOBAR"] = "mpileaks" @@ -187,7 +187,7 @@ def test_unload_fails_no_shell( ): """Test that spack unload prints an error message without a shell.""" install("mpileaks") - mpileaks_spec = spack.spec.Spec("mpileaks").concretized() + mpileaks_spec = spack.concretize.concretize_one("mpileaks") os.environ[uenv.spack_loaded_hashes_var] = mpileaks_spec.dag_hash() out = unload("mpileaks", fail_on_error=False) diff --git a/lib/spack/spack/test/cmd/location.py b/lib/spack/spack/test/cmd/location.py index dcc013710b1..e37d1ab60da 100644 --- a/lib/spack/spack/test/cmd/location.py +++ b/lib/spack/spack/test/cmd/location.py @@ -8,9 +8,9 @@ from llnl.util.filesystem import mkdirp +import spack.concretize import spack.environment as ev import spack.paths -import spack.spec import spack.stage from spack.main import SpackCommand, SpackCommandError @@ -25,7 +25,7 @@ @pytest.fixture def mock_spec(): # Make it look like the source was actually expanded. - s = spack.spec.Spec("externaltest").concretized() + s = spack.concretize.concretize_one("externaltest") source_path = s.package.stage.source_path mkdirp(source_path) yield s, s.package diff --git a/lib/spack/spack/test/cmd/logs.py b/lib/spack/spack/test/cmd/logs.py index 1a5cf9932b9..274be40c7e6 100644 --- a/lib/spack/spack/test/cmd/logs.py +++ b/lib/spack/spack/test/cmd/logs.py @@ -13,6 +13,7 @@ import spack import spack.cmd.logs +import spack.concretize import spack.main import spack.spec from spack.main import SpackCommand @@ -53,7 +54,7 @@ def disable_capture(capfd): def test_logs_cmd_errors(install_mockery, mock_fetch, mock_archive, mock_packages): - spec = spack.spec.Spec("libelf").concretized() + spec = spack.concretize.concretize_one("libelf") assert not spec.installed with pytest.raises(spack.main.SpackCommandError, match="is not installed or staged"): @@ -82,7 +83,7 @@ def test_dump_logs(install_mockery, mock_fetch, mock_archive, mock_packages, dis decompress them. """ cmdline_spec = spack.spec.Spec("libelf") - concrete_spec = cmdline_spec.concretized() + concrete_spec = spack.concretize.concretize_one(cmdline_spec) # Sanity check, make sure this test is checking what we want: to # start with diff --git a/lib/spack/spack/test/cmd/mirror.py b/lib/spack/spack/test/cmd/mirror.py index 2780b31cb40..48bae87f66c 100644 --- a/lib/spack/spack/test/cmd/mirror.py +++ b/lib/spack/spack/test/cmd/mirror.py @@ -7,6 +7,7 @@ import pytest import spack.cmd.mirror +import spack.concretize import spack.config import spack.environment as ev import spack.error @@ -60,7 +61,7 @@ def test_mirror_from_env(tmp_path, mock_packages, mock_fetch, mutable_mock_env_p @pytest.fixture def source_for_pkg_with_hash(mock_packages, tmpdir): - s = spack.spec.Spec("trivial-pkg-with-valid-hash").concretized() + s = spack.concretize.concretize_one("trivial-pkg-with-valid-hash") local_url_basename = os.path.basename(s.package.url) local_path = os.path.join(str(tmpdir), local_url_basename) with open(local_path, "w", encoding="utf-8") as f: @@ -72,7 +73,9 @@ def source_for_pkg_with_hash(mock_packages, tmpdir): def test_mirror_skip_unstable(tmpdir_factory, mock_packages, config, source_for_pkg_with_hash): mirror_dir = str(tmpdir_factory.mktemp("mirror-dir")) - specs = [spack.spec.Spec(x).concretized() for x in ["git-test", "trivial-pkg-with-valid-hash"]] + specs = [ + spack.concretize.concretize_one(x) for x in ["git-test", "trivial-pkg-with-valid-hash"] + ] spack.mirrors.utils.create(mirror_dir, specs, skip_unstable_versions=True) assert set(os.listdir(mirror_dir)) - set(["_source-cache"]) == set( @@ -111,7 +114,7 @@ def test_exclude_specs(mock_packages, config): mirror_specs, _ = spack.cmd.mirror._specs_and_action(args) expected_include = set( - spack.spec.Spec(x).concretized() for x in ["mpich@3.0.3", "mpich@3.0.4", "mpich@3.0"] + spack.concretize.concretize_one(x) for x in ["mpich@3.0.3", "mpich@3.0.4", "mpich@3.0"] ) expected_exclude = set(spack.spec.Spec(x) for x in ["mpich@3.0.1", "mpich@3.0.2", "mpich@1.0"]) assert expected_include <= set(mirror_specs) @@ -145,7 +148,7 @@ def test_exclude_file(mock_packages, tmpdir, config): mirror_specs, _ = spack.cmd.mirror._specs_and_action(args) expected_include = set( - spack.spec.Spec(x).concretized() for x in ["mpich@3.0.3", "mpich@3.0.4", "mpich@3.0"] + spack.concretize.concretize_one(x) for x in ["mpich@3.0.3", "mpich@3.0.4", "mpich@3.0"] ) expected_exclude = set(spack.spec.Spec(x) for x in ["mpich@3.0.1", "mpich@3.0.2", "mpich@1.0"]) assert expected_include <= set(mirror_specs) diff --git a/lib/spack/spack/test/cmd/module.py b/lib/spack/spack/test/cmd/module.py index 6b8fd716b4d..0c68d619221 100644 --- a/lib/spack/spack/test/cmd/module.py +++ b/lib/spack/spack/test/cmd/module.py @@ -7,12 +7,12 @@ import pytest +import spack.concretize import spack.config import spack.main import spack.modules import spack.modules.lmod import spack.repo -import spack.spec import spack.store from spack.installer import PackageInstaller @@ -33,7 +33,7 @@ def ensure_module_files_are_there(mock_repo_path, mock_store, mock_configuration def _module_files(module_type, *specs): - specs = [spack.spec.Spec(x).concretized() for x in specs] + specs = [spack.concretize.concretize_one(x) for x in specs] writer_cls = spack.modules.module_types[module_type] return [writer_cls(spec, "default").layout.filename for spec in specs] @@ -184,12 +184,15 @@ def test_setdefault_command(mutable_database, mutable_config): # Install two different versions of pkg-a other_spec, preferred = "pkg-a@1.0", "pkg-a@2.0" - specs = [spack.spec.Spec(other_spec).concretized(), spack.spec.Spec(preferred).concretized()] + specs = [ + spack.concretize.concretize_one(other_spec), + spack.concretize.concretize_one(preferred), + ] PackageInstaller([s.package for s in specs], explicit=True, fake=True).install() writers = { - preferred: writer_cls(spack.spec.Spec(preferred).concretized(), "default"), - other_spec: writer_cls(spack.spec.Spec(other_spec).concretized(), "default"), + preferred: writer_cls(specs[1], "default"), + other_spec: writer_cls(specs[0], "default"), } # Create two module files for the same software diff --git a/lib/spack/spack/test/cmd/tags.py b/lib/spack/spack/test/cmd/tags.py index 04940560468..dd435f90316 100644 --- a/lib/spack/spack/test/cmd/tags.py +++ b/lib/spack/spack/test/cmd/tags.py @@ -2,9 +2,9 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import spack.concretize import spack.main import spack.repo -import spack.spec from spack.installer import PackageInstaller tags = spack.main.SpackCommand("tags") @@ -47,7 +47,7 @@ class tag_path: def test_tags_installed(install_mockery, mock_fetch): - s = spack.spec.Spec("mpich").concretized() + s = spack.concretize.concretize_one("mpich") PackageInstaller([s.package], explicit=True, fake=True).install() out = tags("-i") diff --git a/lib/spack/spack/test/cmd/test.py b/lib/spack/spack/test/cmd/test.py index 12165445a87..38abd1adf51 100644 --- a/lib/spack/spack/test/cmd/test.py +++ b/lib/spack/spack/test/cmd/test.py @@ -11,10 +11,10 @@ import spack.cmd.common.arguments import spack.cmd.test +import spack.concretize import spack.config import spack.install_test import spack.paths -import spack.spec from spack.install_test import TestStatus from spack.main import SpackCommand @@ -240,7 +240,7 @@ def test_read_old_results(mock_packages, mock_test_stage): def test_test_results_none(mock_packages, mock_test_stage): name = "trivial" - spec = spack.spec.Spec("trivial-smoke-test").concretized() + spec = spack.concretize.concretize_one("trivial-smoke-test") suite = spack.install_test.TestSuite([spec], name) suite.ensure_stage() spack.install_test.write_test_suite_file(suite) @@ -255,7 +255,7 @@ def test_test_results_none(mock_packages, mock_test_stage): def test_test_results_status(mock_packages, mock_test_stage, status): """Confirm 'spack test results' returns expected status.""" name = "trivial" - spec = spack.spec.Spec("trivial-smoke-test").concretized() + spec = spack.concretize.concretize_one("trivial-smoke-test") suite = spack.install_test.TestSuite([spec], name) suite.ensure_stage() spack.install_test.write_test_suite_file(suite) @@ -278,7 +278,7 @@ def test_test_results_status(mock_packages, mock_test_stage, status): def test_report_filename_for_cdash(install_mockery, mock_fetch): """Test that the temporary file used to write Testing.xml for CDash is not the upload URL""" name = "trivial" - spec = spack.spec.Spec("trivial-smoke-test").concretized() + spec = spack.concretize.concretize_one("trivial-smoke-test") suite = spack.install_test.TestSuite([spec], name) suite.ensure_stage() diff --git a/lib/spack/spack/test/cmd/undevelop.py b/lib/spack/spack/test/cmd/undevelop.py index 77bb84ec503..b21f48aa641 100644 --- a/lib/spack/spack/test/cmd/undevelop.py +++ b/lib/spack/spack/test/cmd/undevelop.py @@ -1,8 +1,8 @@ # Copyright Spack Project Developers. See COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import spack.concretize import spack.environment as ev -import spack.spec from spack.main import SpackCommand undevelop = SpackCommand("undevelop") @@ -30,9 +30,9 @@ def test_undevelop(tmpdir, mutable_config, mock_packages, mutable_mock_env_path) env("create", "test", "./spack.yaml") with ev.read("test"): - before = spack.spec.Spec("mpich").concretized() + before = spack.concretize.concretize_one("mpich") undevelop("mpich") - after = spack.spec.Spec("mpich").concretized() + after = spack.concretize.concretize_one("mpich") # Removing dev spec from environment changes concretization assert before.satisfies("dev_path=*") diff --git a/lib/spack/spack/test/cmd/verify.py b/lib/spack/spack/test/cmd/verify.py index de495ba377a..e9886e55657 100644 --- a/lib/spack/spack/test/cmd/verify.py +++ b/lib/spack/spack/test/cmd/verify.py @@ -7,7 +7,7 @@ import llnl.util.filesystem as fs -import spack.spec +import spack.concretize import spack.store import spack.util.spack_json as sjson import spack.verify @@ -65,7 +65,7 @@ def test_single_file_verify_cmd(tmpdir): def test_single_spec_verify_cmd(tmpdir, mock_packages, mock_archive, mock_fetch, install_mockery): # Test the verify command interface to verify a single spec install("libelf") - s = spack.spec.Spec("libelf").concretized() + s = spack.concretize.concretize_one("libelf") prefix = s.prefix hash = s.dag_hash() diff --git a/lib/spack/spack/test/cmd/view.py b/lib/spack/spack/test/cmd/view.py index f5eeba18333..bc774a3dbc7 100644 --- a/lib/spack/spack/test/cmd/view.py +++ b/lib/spack/spack/test/cmd/view.py @@ -9,10 +9,10 @@ from llnl.util.symlink import _windows_can_symlink +import spack.concretize import spack.util.spack_yaml as s_yaml from spack.installer import PackageInstaller from spack.main import SpackCommand -from spack.spec import Spec extensions = SpackCommand("extensions") install = SpackCommand("install") @@ -190,7 +190,7 @@ def test_view_fails_with_missing_projections_file(tmpdir): def test_view_files_not_ignored( tmpdir, mock_packages, mock_archive, mock_fetch, install_mockery, cmd, with_projection ): - spec = Spec("view-not-ignored").concretized() + spec = spack.concretize.concretize_one("view-not-ignored") pkg = spec.package PackageInstaller([pkg], explicit=True).install() pkg.assert_installed(spec.prefix) diff --git a/lib/spack/spack/test/concretization/compiler_runtimes.py b/lib/spack/spack/test/concretization/compiler_runtimes.py index cf8101daa59..12761587009 100644 --- a/lib/spack/spack/test/concretization/compiler_runtimes.py +++ b/lib/spack/spack/test/concretization/compiler_runtimes.py @@ -8,6 +8,7 @@ import archspec.cpu +import spack.concretize import spack.config import spack.paths import spack.repo @@ -20,7 +21,7 @@ def _concretize_with_reuse(*, root_str, reused_str): - reused_spec = spack.spec.Spec(reused_str).concretized() + reused_spec = spack.concretize.concretize_one(reused_str) setup = spack.solver.asp.SpackSolverSetup(tests=False) driver = spack.solver.asp.PyclingoDriver() result, _, _ = driver.solve(setup, [spack.spec.Spec(f"{root_str}")], reuse=[reused_spec]) @@ -44,7 +45,7 @@ def enable_runtimes(): def test_correct_gcc_runtime_is_injected_as_dependency(runtime_repo): - s = spack.spec.Spec("pkg-a%gcc@10.2.1 ^pkg-b%gcc@9.4.0").concretized() + s = spack.concretize.concretize_one("pkg-a%gcc@10.2.1 ^pkg-b%gcc@9.4.0") a, b = s["pkg-a"], s["pkg-b"] # Both a and b should depend on the same gcc-runtime directly @@ -61,7 +62,7 @@ def test_external_nodes_do_not_have_runtimes(runtime_repo, mutable_config, tmp_p packages_yaml = {"pkg-b": {"externals": [{"spec": "pkg-b@1.0", "prefix": f"{str(tmp_path)}"}]}} spack.config.set("packages", packages_yaml) - s = spack.spec.Spec("pkg-a%gcc@10.2.1").concretized() + s = spack.concretize.concretize_one("pkg-a%gcc@10.2.1") a, b = s["pkg-a"], s["pkg-b"] diff --git a/lib/spack/spack/test/concretization/core.py b/lib/spack/spack/test/concretization/core.py index 3f10a7e0eca..3a978a4ceb2 100644 --- a/lib/spack/spack/test/concretization/core.py +++ b/lib/spack/spack/test/concretization/core.py @@ -68,7 +68,7 @@ def check_spec(abstract, concrete): def check_concretize(abstract_spec): abstract = Spec(abstract_spec) - concrete = abstract.concretized() + concrete = spack.concretize.concretize_one(abstract) assert not abstract.concrete assert concrete.concrete check_spec(abstract, concrete) @@ -385,10 +385,12 @@ def test_different_compilers_get_different_flags( ): """Tests that nodes get the flags of the associated compiler.""" mutable_config.set("compilers", [clang12_with_flags, gcc11_with_flags]) - client = Spec( - "cmake-client %gcc@11.1.0 platform=test os=fe target=fe" - " ^cmake %clang@12.2.0 platform=test os=fe target=fe" - ).concretized() + client = spack.concretize.concretize_one( + Spec( + "cmake-client %gcc@11.1.0 platform=test os=fe target=fe" + " ^cmake %clang@12.2.0 platform=test os=fe target=fe" + ) + ) cmake = client["cmake"] assert set(client.compiler_flags["cflags"]) == {"-O0", "-g"} assert set(cmake.compiler_flags["cflags"]) == {"-O3"} @@ -403,7 +405,7 @@ def test_spec_flags_maintain_order(self, mutable_config, gcc11_with_flags): mutable_config.set("compilers", [gcc11_with_flags]) spec_str = "libelf %gcc@11.1.0 os=redhat6" for _ in range(3): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) assert all( s.compiler_flags[x] == ["-O0", "-g"] for x in ("cflags", "cxxflags", "fflags") ) @@ -422,7 +424,7 @@ def test_compiler_flags_differ_identical_compilers(self, mutable_config, clang12 different_dict["compiler"]["flags"] = {"cflags": "-O2"} with spack.config.override("compilers", [different_dict]): - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.satisfies("cflags=-O2") @pytest.mark.parametrize( @@ -457,7 +459,7 @@ def test_compiler_flags_differ_identical_compilers(self, mutable_config, clang12 ], ) def test_compiler_flag_propagation(self, spec_str, expected, not_expected): - root = Spec(spec_str).concretized() + root = spack.concretize.concretize_one(spec_str) for constraint in expected: assert root.satisfies(constraint) @@ -467,12 +469,12 @@ def test_compiler_flag_propagation(self, spec_str, expected, not_expected): def test_mixing_compilers_only_affects_subdag(self): spack.config.set("packages:all:compiler", ["clang", "gcc"]) - spec = Spec("dt-diamond%gcc ^dt-diamond-bottom%clang").concretized() + spec = spack.concretize.concretize_one("dt-diamond%gcc ^dt-diamond-bottom%clang") for dep in spec.traverse(): assert ("%clang" in dep) == (dep.name == "dt-diamond-bottom") def test_compiler_inherited_upwards(self): - spec = Spec("dt-diamond ^dt-diamond-bottom%clang").concretized() + spec = spack.concretize.concretize_one("dt-diamond ^dt-diamond-bottom%clang") for dep in spec.traverse(): assert "%clang" in dep @@ -486,50 +488,50 @@ def test_architecture_deep_inheritance(self, mock_targets, compiler_factory): del cnl_compiler["compiler"]["target"] with spack.config.override("compilers", [cnl_compiler]): spec_str = "mpileaks %gcc@4.5.0 os=CNL target=nocona ^dyninst os=CNL ^callpath os=CNL" - spec = Spec(spec_str).concretized() + spec = spack.concretize.concretize_one(spec_str) for s in spec.traverse(root=False): assert s.architecture.target == spec.architecture.target def test_compiler_flags_from_user_are_grouped(self): spec = Spec('pkg-a%gcc cflags="-O -foo-flag foo-val" platform=test') - spec.concretize() + spec = spack.concretize.concretize_one(spec) cflags = spec.compiler_flags["cflags"] assert any(x == "-foo-flag foo-val" for x in cflags) def concretize_multi_provider(self): s = Spec("mpileaks ^multi-provider-mpi@3.0") - s.concretize() + s = spack.concretize.concretize_one(s) assert s["mpi"].version == ver("1.10.3") def test_concretize_dependent_with_singlevalued_variant_type(self): s = Spec("singlevalue-variant-dependent-type") - s.concretize() + s = spack.concretize.concretize_one(s) @pytest.mark.parametrize("spec,version", [("dealii", "develop"), ("xsdk", "0.4.0")]) def concretize_difficult_packages(self, a, b): """Test a couple of large packages that are often broken due to current limitations in the concretizer""" s = Spec(a + "@" + b) - s.concretize() + s = spack.concretize.concretize_one(s) assert s[a].version == ver(b) def test_concretize_two_virtuals(self): """Test a package with multiple virtual dependencies.""" - Spec("hypre").concretize() + spack.concretize.concretize_one("hypre") def test_concretize_two_virtuals_with_one_bound(self, mutable_mock_repo): """Test a package with multiple virtual dependencies and one preset.""" - Spec("hypre ^openblas").concretize() + spack.concretize.concretize_one("hypre ^openblas") def test_concretize_two_virtuals_with_two_bound(self): """Test a package with multiple virtual deps and two of them preset.""" - Spec("hypre ^openblas ^netlib-lapack").concretize() + spack.concretize.concretize_one("hypre ^netlib-lapack") def test_concretize_two_virtuals_with_dual_provider(self): """Test a package with multiple virtual dependencies and force a provider that provides both. """ - Spec("hypre ^openblas-with-lapack").concretize() + spack.concretize.concretize_one("hypre ^openblas-with-lapack") def test_concretize_two_virtuals_with_dual_provider_and_a_conflict(self): """Test a package with multiple virtual dependencies and force a @@ -538,7 +540,7 @@ def test_concretize_two_virtuals_with_dual_provider_and_a_conflict(self): """ s = Spec("hypre ^openblas-with-lapack ^netlib-lapack") with pytest.raises(spack.error.SpackError): - s.concretize() + spack.concretize.concretize_one(s) @pytest.mark.parametrize( "spec_str,expected_propagation", @@ -559,7 +561,7 @@ def test_concretize_two_virtuals_with_dual_provider_and_a_conflict(self): ) def test_concretize_propagate_disabled_variant(self, spec_str, expected_propagation): """Tests various patterns of boolean variant propagation""" - spec = Spec(spec_str).concretized() + spec = spack.concretize.concretize_one(spec_str) for key, expected_satisfies in expected_propagation: spec[key].satisfies(expected_satisfies) @@ -567,7 +569,7 @@ def test_concretize_propagate_variant_not_dependencies(self): """Test that when propagating a variant it is not propagated to dependencies that do not have that variant""" spec = Spec("quantum-espresso~~invino") - spec.concretize() + spec = spack.concretize.concretize_one(spec) for dep in spec.traverse(root=False): assert "invino" not in dep.variants.keys() @@ -577,21 +579,21 @@ def test_concretize_propagate_variant_exclude_dependency_fail(self): the source package's dependencies""" spec = Spec("hypre ~~shared ^openblas +shared") with pytest.raises(spack.error.UnsatisfiableSpecError): - spec.concretize() + spec = spack.concretize.concretize_one(spec) def test_concretize_propagate_same_variant_from_direct_dep_fail(self): """Test that when propagating a variant from the source package and a direct dependency also propagates the same variant with a different value. Raises error""" spec = Spec("ascent +adios2 ++shared ^adios2 ~~shared") with pytest.raises(spack.error.UnsatisfiableSpecError): - spec.concretize() + spec = spack.concretize.concretize_one(spec) def test_concretize_propagate_same_variant_in_dependency_fail(self): """Test that when propagating a variant from the source package, none of it's dependencies can propagate that variant with a different value. Raises error.""" spec = Spec("ascent +adios2 ++shared ^bzip2 ~~shared") with pytest.raises(spack.error.UnsatisfiableSpecError): - spec.concretize() + spec = spack.concretize.concretize_one(spec) def test_concretize_propagate_same_variant_virtual_dependency_fail(self): """Test that when propagating a variant from the source package and a direct @@ -599,19 +601,19 @@ def test_concretize_propagate_same_variant_virtual_dependency_fail(self): different value. Raises error""" spec = Spec("hypre ++shared ^openblas ~~shared") with pytest.raises(spack.error.UnsatisfiableSpecError): - spec.concretize() + spec = spack.concretize.concretize_one(spec) def test_concretize_propagate_same_variant_multiple_sources_diamond_dep_fail(self): """Test that fails when propagating the same variant with different values from multiple sources that share a dependency""" spec = Spec("parent-foo-bar ^dependency-foo-bar++bar ^direct-dep-foo-bar~~bar") with pytest.raises(spack.error.UnsatisfiableSpecError): - spec.concretize() + spec = spack.concretize.concretize_one(spec) def test_concretize_propagate_specified_variant(self): """Test that only the specified variant is propagated to the dependencies""" spec = Spec("parent-foo-bar ~~foo") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.satisfies("^dependency-foo-bar~foo") assert spec.satisfies("^second-dependency-foo-bar-fee~foo") @@ -624,7 +626,7 @@ def test_concretize_propagate_specified_variant(self): def test_concretize_propagate_one_variant(self): """Test that you can specify to propagate one variant and not all""" spec = Spec("parent-foo-bar ++bar ~foo") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.satisfies("~foo") and not spec.satisfies("^dependency-foo-bar~foo") assert spec.satisfies("+bar") and spec.satisfies("^dependency-foo-bar+bar") @@ -633,7 +635,7 @@ def test_concretize_propagate_through_first_level_deps(self): """Test that boolean valued variants can be propagated past first level dependecies even if the first level dependency does have the variant""" spec = Spec("parent-foo-bar-fee ++fee") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.satisfies("+fee") and not spec.satisfies("dependency-foo-bar+fee") assert spec.satisfies("^second-dependency-foo-bar-fee+fee") @@ -642,7 +644,7 @@ def test_concretize_propagate_multiple_variants(self): """Test that multiple boolean valued variants can be propagated from the same source package""" spec = Spec("parent-foo-bar-fee ~~foo ++bar") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.satisfies("~foo") and spec.satisfies("+bar") assert spec.satisfies("^dependency-foo-bar ~foo +bar") @@ -652,7 +654,7 @@ def test_concretize_propagate_multiple_variants_mulitple_sources(self): """Test the propagates multiple different variants for multiple sources in a diamond dependency""" spec = Spec("parent-foo-bar ^dependency-foo-bar++bar ^direct-dep-foo-bar~~foo") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.satisfies("^second-dependency-foo-bar-fee+bar") assert spec.satisfies("^second-dependency-foo-bar-fee~foo") @@ -662,7 +664,7 @@ def test_concretize_propagate_multiple_variants_mulitple_sources(self): def test_concretize_propagate_single_valued_variant(self): """Test propagation for single valued variants""" spec = Spec("multivalue-variant libs==static") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.satisfies("libs=static") assert spec.satisfies("^pkg-a libs=static") @@ -671,7 +673,7 @@ def test_concretize_propagate_multivalue_variant(self): """Test that multivalue variants are propagating the specified value(s) to their dependecies. The dependencies should not have the default value""" spec = Spec("multivalue-variant foo==baz,fee") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.satisfies("^pkg-a foo=baz,fee") assert spec.satisfies("^pkg-b foo=baz,fee") @@ -682,7 +684,7 @@ def test_concretize_propagate_multiple_multivalue_variant(self): """Tests propagating the same mulitvalued variant from different sources allows the dependents to accept all propagated values""" spec = Spec("multivalue-variant foo==bar ^pkg-a foo==baz") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.satisfies("multivalue-variant foo=bar") assert spec.satisfies("^pkg-a foo=bar,baz") @@ -692,7 +694,7 @@ def test_concretize_propagate_variant_not_in_source(self): """Test that variant is still propagated even if the source pkg doesn't have the variant""" spec = Spec("callpath++debug") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.satisfies("^mpich+debug") assert not spec.satisfies("callpath+debug") @@ -702,7 +704,7 @@ def test_concretize_propagate_variant_multiple_deps_not_in_source(self): """Test that a variant can be propagated to multiple dependencies when the variant is not in the source package""" spec = Spec("netlib-lapack++shared") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.satisfies("^openblas+shared") assert spec.satisfies("^perl+shared") @@ -713,7 +715,7 @@ def test_concretize_propagate_variant_second_level_dep_not_in_source(self): when the variant is not in the source package or any of the first level dependencies""" spec = Spec("parent-foo-bar ++fee") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec.satisfies("^second-dependency-foo-bar-fee +fee") assert not spec.satisfies("parent-foo-bar +fee") @@ -723,12 +725,12 @@ def test_no_matching_compiler_specs(self, mock_low_high_config): with spack.concretize.enable_compiler_existence_check(): s = Spec("pkg-a %gcc@=0.0.0") with pytest.raises(spack.concretize.UnavailableCompilerVersionError): - s.concretize() + s = spack.concretize.concretize_one(s) def test_no_compilers_for_arch(self): s = Spec("pkg-a arch=linux-rhel0-x86_64") with pytest.raises(spack.error.SpackError): - s.concretize() + s = spack.concretize.concretize_one(s) def test_virtual_is_fully_expanded_for_callpath(self): # force dependence on fake "zmpi" by asking for MPI 10.0 @@ -736,7 +738,7 @@ def test_virtual_is_fully_expanded_for_callpath(self): assert len(spec.dependencies(name="mpi")) == 1 assert "fake" not in spec - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert len(spec.dependencies(name="zmpi")) == 1 assert all(not d.dependencies(name="mpi") for d in spec.traverse()) assert all(x in spec for x in ("zmpi", "mpi")) @@ -750,7 +752,7 @@ def test_virtual_is_fully_expanded_for_mpileaks(self): assert len(spec.dependencies(name="mpi")) == 1 assert "fake" not in spec - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert len(spec.dependencies(name="zmpi")) == 1 assert len(spec.dependencies(name="callpath")) == 1 @@ -766,13 +768,13 @@ def test_virtual_is_fully_expanded_for_mpileaks(self): @pytest.mark.parametrize("compiler_str", ["clang", "gcc", "gcc@10.2.1", "clang@:15.0.0"]) def test_compiler_inheritance(self, compiler_str): spec_str = "mpileaks %{0}".format(compiler_str) - spec = Spec(spec_str).concretized() + spec = spack.concretize.concretize_one(spec_str) assert spec["libdwarf"].compiler.satisfies(compiler_str) assert spec["libelf"].compiler.satisfies(compiler_str) def test_external_package(self): spec = Spec("externaltool%gcc") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec["externaltool"].external_path == os.path.sep + os.path.join( "path", "to", "external_tool" ) @@ -785,12 +787,12 @@ def test_nobuild_package(self): """ spec = Spec("externaltool%clang") with pytest.raises(spack.error.SpecError): - spec.concretize() + spec = spack.concretize.concretize_one(spec) def test_external_and_virtual(self, mutable_config): mutable_config.set("packages:stuff", {"buildable": False}) spec = Spec("externaltest") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert spec["externaltool"].external_path == os.path.sep + os.path.join( "path", "to", "external_tool" ) @@ -802,26 +804,26 @@ def test_external_and_virtual(self, mutable_config): def test_compiler_child(self): s = Spec("mpileaks%clang target=x86_64 ^dyninst%gcc") - s.concretize() + s = spack.concretize.concretize_one(s) assert s["mpileaks"].satisfies("%clang") assert s["dyninst"].satisfies("%gcc") def test_conflicts_in_spec(self, conflict_spec): s = Spec(conflict_spec) with pytest.raises(spack.error.SpackError): - s.concretize() + s = spack.concretize.concretize_one(s) def test_conflicts_show_cores(self, conflict_spec, monkeypatch): s = Spec(conflict_spec) with pytest.raises(spack.error.SpackError) as e: - s.concretize() + s = spack.concretize.concretize_one(s) assert "conflict" in e.value.message def test_conflict_in_all_directives_true(self): s = Spec("when-directives-true") with pytest.raises(spack.error.SpackError): - s.concretize() + s = spack.concretize.concretize_one(s) @pytest.mark.parametrize("spec_str", ["conflict@10.0%clang+foo"]) def test_no_conflict_in_external_specs(self, spec_str): @@ -830,7 +832,7 @@ def test_no_conflict_in_external_specs(self, spec_str): ext = Spec(spec_str) data = {"externals": [{"spec": spec_str, "prefix": "/fake/path"}]} spack.config.set("packages::{0}".format(ext.name), data) - ext.concretize() # failure raises exception + ext = spack.concretize.concretize_one(ext) # failure raises exception def test_regression_issue_4492(self): # Constructing a spec which has no dependencies, but is otherwise @@ -839,7 +841,7 @@ def test_regression_issue_4492(self): # cache values. s = Spec("mpileaks") - s.concretize() + s = spack.concretize.concretize_one(s) # Check that now the Spec is concrete, store the hash assert s.concrete @@ -857,7 +859,7 @@ def test_regression_issue_7239(self): # Normal Spec s = Spec("mpileaks") - s.concretize() + s = spack.concretize.concretize_one(s) assert llnl.util.lang.ObjectWrapper not in s.__class__.__mro__ @@ -874,7 +876,7 @@ def test_regression_issue_7705(self): # spec.package.provides(name) doesn't account for conditional # constraints in the concretized spec s = Spec("simple-inheritance~openblas") - s.concretize() + s = spack.concretize.concretize_one(s) assert not s.package.provides("lapack") @@ -886,8 +888,8 @@ def test_regression_issue_7941(self): s = Spec("pkg-a foobar=bar ^pkg-b") t = Spec(str(s)) - s.concretize() - t.concretize() + s = spack.concretize.concretize_one(s) + t = spack.concretize.concretize_one(t) assert s.dag_hash() == t.dag_hash() @@ -908,7 +910,7 @@ def test_regression_issue_7941(self): ) def test_simultaneous_concretization_of_specs(self, abstract_specs): abstract_specs = [Spec(x) for x in abstract_specs] - concrete_specs = spack.concretize.concretize_specs_together(abstract_specs) + concrete_specs = spack.concretize._concretize_specs_together(abstract_specs) # Check there's only one configuration of each package in the DAG names = set(dep.name for spec in concrete_specs for dep in spec.traverse()) @@ -929,7 +931,7 @@ def test_simultaneous_concretization_of_specs(self, abstract_specs): def test_noversion_pkg(self, spec): """Test concretization failures for no-version packages.""" with pytest.raises(spack.error.SpackError): - Spec(spec).concretized() + spack.concretize.concretize_one(spec) @pytest.mark.not_on_windows("Not supported on Windows (yet)") # Include targets to prevent regression on 20537 @@ -949,29 +951,33 @@ def test_adjusting_default_target_based_on_compiler( best_achievable = archspec.cpu.TARGETS[best_achievable] expected = best_achievable if best_achievable < current_host else current_host with spack.concretize.disable_compiler_existence_check(): - s = Spec(spec).concretized() + s = spack.concretize.concretize_one(spec) assert str(s.architecture.target) == str(expected) def test_compiler_version_matches_any_entry_in_compilers_yaml(self): # The behavior here has changed since #8735 / #14730. Now %gcc@10.2 is an abstract # compiler spec, and it should first find a matching compiler gcc@=10.2.1 - assert Spec("mpileaks %gcc@10.2").concretized().compiler == CompilerSpec("gcc@=10.2.1") - assert Spec("mpileaks %gcc@10.2:").concretized().compiler == CompilerSpec("gcc@=10.2.1") + assert spack.concretize.concretize_one( + Spec("mpileaks %gcc@10.2") + ).compiler == CompilerSpec("gcc@=10.2.1") + assert spack.concretize.concretize_one( + Spec("mpileaks %gcc@10.2:") + ).compiler == CompilerSpec("gcc@=10.2.1") # This compiler does not exist with pytest.raises(spack.concretize.UnavailableCompilerVersionError): - Spec("mpileaks %gcc@=10.2").concretized() + spack.concretize.concretize_one("mpileaks %gcc@=10.2") def test_concretize_anonymous(self): with pytest.raises(spack.error.SpackError): s = Spec("+variant") - s.concretize() + s = spack.concretize.concretize_one(s) @pytest.mark.parametrize("spec_str", ["mpileaks ^%gcc", "mpileaks ^cflags=-g"]) def test_concretize_anonymous_dep(self, spec_str): with pytest.raises(spack.error.SpackError): s = Spec(spec_str) - s.concretize() + s = spack.concretize.concretize_one(s) @pytest.mark.parametrize( "spec_str,expected_str", @@ -988,7 +994,7 @@ def test_compiler_conflicts_in_package_py( self, spec_str, expected_str, clang12_with_flags, gcc11_with_flags ): with spack.config.override("compilers", [clang12_with_flags, gcc11_with_flags]): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) assert s.satisfies(expected_str) @pytest.mark.parametrize( @@ -1009,7 +1015,7 @@ def test_compiler_conflicts_in_package_py( ], ) def test_conditional_variants(self, spec_str, expected, unexpected): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) for var in expected: assert s.satisfies("%s=*" % var) @@ -1029,7 +1035,7 @@ def test_conditional_variants_fail(self, bad_spec): with pytest.raises( (spack.error.UnsatisfiableSpecError, spack.spec.InvalidVariantForSpecError) ): - _ = Spec("conditional-variant-pkg" + bad_spec).concretized() + _ = spack.concretize.concretize_one("conditional-variant-pkg" + bad_spec) @pytest.mark.parametrize( "spec_str,expected,unexpected", @@ -1050,7 +1056,7 @@ def test_conditional_dependencies(self, spec_str, expected, unexpected, fuzz_dep """ fuzz_dep_order("py-extension3") # test forwards and backwards - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) for dep in expected: msg = '"{0}" is not in "{1}" and was expected' @@ -1074,7 +1080,7 @@ def test_conditional_dependencies(self, spec_str, expected, unexpected, fuzz_dep ], ) def test_patching_dependencies(self, spec_str, patched_deps): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) for dep, num_patches in patched_deps: assert s[dep].satisfies("patches=*") @@ -1102,7 +1108,7 @@ def test_patching_dependencies(self, spec_str, patched_deps): ], ) def test_working_around_conflicting_defaults(self, spec_str, expected): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) assert s.concrete for constraint in expected: @@ -1122,7 +1128,7 @@ def test_external_package_and_compiler_preferences(self, spec_str, expected, mut }, } mutable_config.set("packages", packages_yaml) - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) assert s.external for condition in expected: @@ -1138,13 +1144,13 @@ def test_package_with_constraint_not_met_by_external(self): spack.config.set("packages", packages_yaml) # quantum-espresso+veritas requires libelf@:0.8.12 - s = Spec("quantum-espresso+veritas").concretized() + s = spack.concretize.concretize_one("quantum-espresso+veritas") assert s.satisfies("^libelf@0.8.12") assert not s["libelf"].external @pytest.mark.regression("9744") def test_cumulative_version_ranges_with_different_length(self): - s = Spec("cumulative-vrange-root").concretized() + s = spack.concretize.concretize_one("cumulative-vrange-root") assert s.concrete assert s.satisfies("^cumulative-vrange-bottom@2.2") @@ -1154,15 +1160,15 @@ def test_dependency_conditional_on_another_dependency_state(self): dep_str = "variant-on-dependency-condition-a" spec_str = "{0} ^{1}".format(root_str, dep_str) - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) assert s.concrete assert s.satisfies("^variant-on-dependency-condition-b") - s = Spec(spec_str + "+x").concretized() + s = spack.concretize.concretize_one(spec_str + "+x") assert s.concrete assert s.satisfies("^variant-on-dependency-condition-b") - s = Spec(spec_str + "~x").concretized() + s = spack.concretize.concretize_one(spec_str + "~x") assert s.concrete assert not s.satisfies("^variant-on-dependency-condition-b") @@ -1176,7 +1182,7 @@ def test_compiler_constraint_with_external_package(self, spec_str, expected): } spack.config.set("packages", packages_yaml) - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) assert s.external assert s.satisfies(expected) @@ -1213,12 +1219,12 @@ def test_compiler_in_nonbuildable_external_package( } spack.config.set("packages", packages_yaml) - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) assert s.satisfies(expected) assert "external-common-perl" not in [d.name for d in s.dependencies()] def test_external_that_would_require_a_virtual_dependency(self): - s = Spec("requires-virtual").concretized() + s = spack.concretize.concretize_one("requires-virtual") assert s.external assert "stuff" not in s @@ -1226,7 +1232,7 @@ def test_external_that_would_require_a_virtual_dependency(self): def test_transitive_conditional_virtual_dependency(self, mutable_config): """Test that an external is used as provider if the virtual is non-buildable""" mutable_config.set("packages:stuff", {"buildable": False}) - s = Spec("transitive-conditional-virtual-dependency").concretized() + s = spack.concretize.concretize_one("transitive-conditional-virtual-dependency") # Test that the default +stuff~mpi is maintained, and the right provider is selected assert s.satisfies("^conditional-virtual-dependency +stuff~mpi") @@ -1236,7 +1242,7 @@ def test_transitive_conditional_virtual_dependency(self, mutable_config): def test_conditional_provides_or_depends_on(self): # Check that we can concretize correctly a spec that can either # provide a virtual or depend on it based on the value of a variant - s = Spec("conditional-provider +disable-v1").concretized() + s = spack.concretize.concretize_one("conditional-provider +disable-v1") assert "v1-provider" in s assert s["v1"].name == "v1-provider" assert s["v2"].name == "conditional-provider" @@ -1258,7 +1264,7 @@ def test_conditional_provides_or_depends_on(self): ], ) def test_activating_test_dependencies(self, spec_str, tests_arg, with_dep, without_dep): - s = Spec(spec_str).concretized(tests=tests_arg) + s = spack.concretize.concretize_one(spec_str, tests=tests_arg) for pkg_name in with_dep: msg = "Cannot find test dependency in package '{0}'" @@ -1280,22 +1286,24 @@ def test_compiler_match_is_preferred_to_newer_version(self, compiler_factory): "compilers", [compiler_factory(spec="gcc@10.1.0", operating_system="redhat6")] ): spec_str = "simple-inheritance+openblas %gcc@10.1.0 os=redhat6" - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) assert "openblas@0.2.15" in s assert s["openblas"].satisfies("%gcc@10.1.0") @pytest.mark.regression("19981") def test_target_ranges_in_conflicts(self): with pytest.raises(spack.error.SpackError): - Spec("impossible-concretization").concretized() + spack.concretize.concretize_one("impossible-concretization") def test_target_compatibility(self): with pytest.raises(spack.error.SpackError): - Spec("libdwarf target=x86_64 ^libelf target=x86_64_v2").concretized() + spack.concretize.concretize_one( + Spec("libdwarf target=x86_64 ^libelf target=x86_64_v2") + ) @pytest.mark.regression("20040") def test_variant_not_default(self): - s = Spec("ecp-viz-sdk").concretized() + s = spack.concretize.concretize_one("ecp-viz-sdk") # Check default variant value for the package assert "+dep" in s["conditional-constrained-dependencies"] @@ -1310,7 +1318,7 @@ def test_custom_compiler_version(self, mutable_config, compiler_factory, monkeyp "compilers", [compiler_factory(spec="gcc@10foo", operating_system="redhat6")] ) monkeypatch.setattr(spack.compiler.Compiler, "real_version", "10.2.1") - s = Spec("pkg-a %gcc@10foo os=redhat6").concretized() + s = spack.concretize.concretize_one("pkg-a %gcc@10foo os=redhat6") assert "%gcc@10foo" in s def test_all_patches_applied(self): @@ -1321,11 +1329,11 @@ def test_all_patches_applied(self): ) localpatch = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" spec = Spec("conditionally-patch-dependency+jasper") - spec.concretize() + spec = spack.concretize.concretize_one(spec) assert (uuidpatch, localpatch) == spec["libelf"].variants["patches"].value def test_dont_select_version_that_brings_more_variants_in(self): - s = Spec("dep-with-variants-if-develop-root").concretized() + s = spack.concretize.concretize_one("dep-with-variants-if-develop-root") assert s["dep-with-variants-if-develop"].satisfies("@1.0") @pytest.mark.regression("20244,20736") @@ -1352,7 +1360,7 @@ def test_dont_select_version_that_brings_more_variants_in(self): ], ) def test_external_package_versions(self, spec_str, is_external, expected): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) assert s.external == is_external assert s.satisfies(expected) @@ -1381,7 +1389,7 @@ def test_reuse_does_not_overwrite_dev_specs( second_spec = spec if dev_first else dev_spec # concretize and setup spack to reuse in the appropriate manner - first_spec.concretize() + first_spec = spack.concretize.concretize_one(first_spec) def mock_fn(*args, **kwargs): return [first_spec] @@ -1393,7 +1401,7 @@ def mock_fn(*args, **kwargs): # concretize and ensure we did not reuse with spack.config.override("concretizer:reuse", True): - second_spec.concretize() + second_spec = spack.concretize.concretize_one(second_spec) assert first_spec.dag_hash() != second_spec.dag_hash() @pytest.mark.regression("20292") @@ -1412,7 +1420,7 @@ def test_reuse_installed_packages_when_package_def_changes( spack.config.set("concretizer:reuse", False) # Install a spec - root = Spec("root").concretized() + root = spack.concretize.concretize_one("root") dependency = root["changing"].copy() PackageInstaller([root.package], fake=True, explicit=True).install() @@ -1420,9 +1428,11 @@ def test_reuse_installed_packages_when_package_def_changes( repo_with_changing_recipe.change(context) # Try to concretize with the spec installed previously - new_root_with_reuse = Spec("root ^/{0}".format(dependency.dag_hash())).concretized() + new_root_with_reuse = spack.concretize.concretize_one( + Spec("root ^/{0}".format(dependency.dag_hash())) + ) - new_root_without_reuse = Spec("root").concretized() + new_root_without_reuse = spack.concretize.concretize_one("root") # validate that the graphs are the same with reuse, but not without assert ht.build_hash(root) == ht.build_hash(new_root_with_reuse) @@ -1439,23 +1449,23 @@ def test_no_reuse_when_variant_condition_does_not_hold(self, mutable_database, m spack.config.set("concretizer:reuse", True) # Install a spec for which the `version_based` variant condition does not hold - old = Spec("conditional-variant-pkg @1").concretized() + old = spack.concretize.concretize_one("conditional-variant-pkg @1") PackageInstaller([old.package], fake=True, explicit=True).install() # Then explicitly require a spec with `+version_based`, which shouldn't reuse previous spec - new1 = Spec("conditional-variant-pkg +version_based").concretized() + new1 = spack.concretize.concretize_one("conditional-variant-pkg +version_based") assert new1.satisfies("@2 +version_based") - new2 = Spec("conditional-variant-pkg +two_whens").concretized() + new2 = spack.concretize.concretize_one("conditional-variant-pkg +two_whens") assert new2.satisfies("@2 +two_whens +version_based") def test_reuse_with_flags(self, mutable_database, mutable_config): spack.config.set("concretizer:reuse", True) - spec = Spec("pkg-a cflags=-g cxxflags=-g").concretized() + spec = spack.concretize.concretize_one("pkg-a cflags=-g cxxflags=-g") PackageInstaller([spec.package], fake=True, explicit=True).install() testspec = Spec("pkg-a cflags=-g") - testspec.concretize() + testspec = spack.concretize.concretize_one(testspec) assert testspec == spec @pytest.mark.regression("20784") @@ -1463,7 +1473,7 @@ def test_concretization_of_test_dependencies(self): # With clingo we emit dependency_conditions regardless of the type # of the dependency. We need to ensure that there's at least one # dependency type declared to infer that the dependency holds. - s = Spec("test-dep-with-imposed-conditions").concretized() + s = spack.concretize.concretize_one("test-dep-with-imposed-conditions") assert "c" not in s @pytest.mark.parametrize( @@ -1472,7 +1482,7 @@ def test_concretization_of_test_dependencies(self): def test_error_message_for_inconsistent_variants(self, spec_str): s = Spec(spec_str) with pytest.raises(vt.UnknownVariantError): - s.concretize() + s = spack.concretize.concretize_one(s) @pytest.mark.regression("22533") @pytest.mark.parametrize( @@ -1487,7 +1497,7 @@ def test_error_message_for_inconsistent_variants(self, spec_str): ], ) def test_mv_variants_disjoint_sets_from_spec(self, spec_str, variant_name, expected_values): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) assert set(expected_values) == set(s.variants[variant_name].value) @pytest.mark.regression("22533") @@ -1500,14 +1510,14 @@ def test_mv_variants_disjoint_sets_from_packages_yaml(self): } spack.config.set("packages", external_mvapich2) - s = Spec("mvapich2").concretized() + s = spack.concretize.concretize_one("mvapich2") assert set(s.variants["file_systems"].value) == set(["ufs", "nfs"]) @pytest.mark.regression("22596") def test_external_with_non_default_variant_as_dependency(self): # This package depends on another that is registered as an external # with 'buildable: true' and a variant with a non-default value set - s = Spec("trigger-external-non-default-variant").concretized() + s = spack.concretize.concretize_one("trigger-external-non-default-variant") assert "~foo" in s["external-non-default-variant"] assert "~bar" in s["external-non-default-variant"] @@ -1531,7 +1541,7 @@ def test_os_selection_when_multiple_choices_are_possible( with spack.config.override( "compilers", [compiler_factory(spec="gcc@10.2.1", operating_system="redhat6")] ): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) for node in s.traverse(): if node.name == "glibc": continue @@ -1543,7 +1553,7 @@ def test_os_selection_when_multiple_choices_are_possible( [("mpileaks", "%gcc@10.2.1"), ("mpileaks ^mpich%clang@15.0.0", "%clang@15.0.0")], ) def test_compiler_is_unique(self, spec_str, expected_compiler): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) for node in s.traverse(): assert node.satisfies(expected_compiler) @@ -1558,7 +1568,7 @@ def test_compiler_is_unique(self, spec_str, expected_compiler): ], ) def test_multivalued_variants_from_cli(self, spec_str, expected_dict): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) for constraint, value in expected_dict.items(): assert s.satisfies(constraint) == value @@ -1575,7 +1585,7 @@ def test_multivalued_variants_from_cli(self, spec_str, expected_dict): ) def test_deprecated_versions_not_selected(self, spec_str, expected): with spack.config.override("config:deprecated", True): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) s.satisfies(expected) @pytest.mark.regression("24196") @@ -1584,7 +1594,7 @@ def test_version_badness_more_important_than_default_mv_variants(self): # a transitive dependency with a multi-valued variant, that old # version was preferred because of the order of our optimization # criteria. - s = Spec("root").concretized() + s = spack.concretize.concretize_one("root") assert s["gmt"].satisfies("@2.0") @pytest.mark.regression("24205") @@ -1593,7 +1603,7 @@ def test_provider_must_meet_requirements(self): # requirements are met. s = Spec("unsat-virtual-dependency") with pytest.raises((RuntimeError, spack.error.UnsatisfiableSpecError)): - s.concretize() + s = spack.concretize.concretize_one(s) @pytest.mark.regression("23951") def test_newer_dependency_adds_a_transitive_virtual(self): @@ -1605,7 +1615,7 @@ def test_newer_dependency_adds_a_transitive_virtual(self): # root@1.0 <- middle@1.0 <- leaf@1.0 # # and "blas" is pulled in only by newer versions of "leaf" - s = Spec("root-adds-virtual").concretized() + s = spack.concretize.concretize_one("root-adds-virtual") assert s["leaf-adds-virtual"].satisfies("@2.0") assert "blas" in s @@ -1613,12 +1623,12 @@ def test_newer_dependency_adds_a_transitive_virtual(self): def test_versions_in_virtual_dependencies(self): # Ensure that a package that needs a given version of a virtual # package doesn't end up using a later implementation - s = Spec("hpcviewer@2019.02").concretized() + s = spack.concretize.concretize_one("hpcviewer@2019.02") assert s["java"].satisfies("virtual-with-versions@1.8.0") @pytest.mark.regression("26866") def test_non_default_provider_of_multiple_virtuals(self): - s = Spec("many-virtual-consumer ^low-priority-provider").concretized() + s = spack.concretize.concretize_one("many-virtual-consumer ^low-priority-provider") assert s["mpi"].name == "low-priority-provider" assert s["lapack"].name == "low-priority-provider" @@ -1641,7 +1651,7 @@ def test_concrete_specs_are_not_modified_on_reuse( # like additional constraints being added to concrete specs in # the answer set produced by clingo. with spack.config.override("concretizer:reuse", True): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) assert s.installed is expect_installed assert s.satisfies(spec_str) @@ -1652,12 +1662,12 @@ def test_sticky_variant_in_package(self): # to have +allow-gcc set to be concretized with %gcc and clingo is not allowed # to change the default ~allow-gcc with pytest.raises(spack.error.SpackError): - Spec("sticky-variant %gcc").concretized() + spack.concretize.concretize_one("sticky-variant %gcc") - s = Spec("sticky-variant+allow-gcc %gcc").concretized() + s = spack.concretize.concretize_one("sticky-variant+allow-gcc %gcc") assert s.satisfies("%gcc") and s.satisfies("+allow-gcc") - s = Spec("sticky-variant %clang").concretized() + s = spack.concretize.concretize_one("sticky-variant %clang") assert s.satisfies("%clang") and s.satisfies("~allow-gcc") @pytest.mark.regression("42172") @@ -1676,7 +1686,7 @@ def test_sticky_variant_in_external(self, spec, allow_gcc): maybe = llnl.util.lang.nullcontext if allow_gcc else pytest.raises with maybe(spack.error.SpackError): - s = Spec("sticky-variant-dependent%gcc").concretized() + s = spack.concretize.concretize_one("sticky-variant-dependent%gcc") if allow_gcc: assert s.satisfies("%gcc") @@ -1686,10 +1696,10 @@ def test_sticky_variant_in_external(self, spec, allow_gcc): def test_do_not_invent_new_concrete_versions_unless_necessary(self): # ensure we select a known satisfying version rather than creating # a new '2.7' version. - assert ver("=2.7.11") == Spec("python@2.7").concretized().version + assert ver("=2.7.11") == spack.concretize.concretize_one("python@2.7").version # Here there is no known satisfying version - use the one on the spec. - assert ver("=2.7.21") == Spec("python@=2.7.21").concretized().version + assert ver("=2.7.21") == spack.concretize.concretize_one("python@=2.7.21").version @pytest.mark.parametrize( "spec_str,valid", @@ -1708,14 +1718,14 @@ def test_conditional_values_in_variants(self, spec_str, valid): s = Spec(spec_str) raises = pytest.raises((RuntimeError, spack.error.UnsatisfiableSpecError)) with llnl.util.lang.nullcontext() if valid else raises: - s.concretize() + s = spack.concretize.concretize_one(s) def test_conditional_values_in_conditional_variant(self): """Test that conditional variants play well with conditional possible values""" - s = Spec("conditional-values-in-variant@1.50.0").concretized() + s = spack.concretize.concretize_one("conditional-values-in-variant@1.50.0") assert "cxxstd" not in s.variants - s = Spec("conditional-values-in-variant@1.60.0").concretized() + s = spack.concretize.concretize_one("conditional-values-in-variant@1.60.0") assert "cxxstd" in s.variants def test_target_granularity(self): @@ -1724,9 +1734,9 @@ def test_target_granularity(self): default_target = spack.platforms.test.Test.default generic_target = archspec.cpu.TARGETS[default_target].generic.name s = Spec("python") - assert s.concretized().satisfies("target=%s" % default_target) + assert spack.concretize.concretize_one(s).satisfies("target=%s" % default_target) with spack.config.override("concretizer:targets", {"granularity": "generic"}): - assert s.concretized().satisfies("target=%s" % generic_target) + assert spack.concretize.concretize_one(s).satisfies("target=%s" % generic_target) def test_host_compatible_concretization(self): # Check that after setting "host_compatible" to false we cannot concretize. @@ -1735,16 +1745,16 @@ def test_host_compatible_concretization(self): # is that the defaults for the test platform are very old, so there's no # compiler supporting e.g. icelake etc. s = Spec("python target=k10") - assert s.concretized() + assert spack.concretize.concretize_one(s) with spack.config.override("concretizer:targets", {"host_compatible": True}): with pytest.raises(spack.error.SpackError): - s.concretized() + spack.concretize.concretize_one(s) def test_add_microarchitectures_on_explicit_request(self): # Check that if we consider only "generic" targets, we can still solve for # specific microarchitectures on explicit requests with spack.config.override("concretizer:targets", {"granularity": "generic"}): - s = Spec("python target=k10").concretized() + s = spack.concretize.concretize_one("python target=k10") assert s.satisfies("target=k10") @pytest.mark.regression("29201") @@ -1752,12 +1762,12 @@ def test_delete_version_and_reuse(self, mutable_database, repo_with_changing_rec """Test that we can reuse installed specs with versions not declared in package.py """ - root = Spec("root").concretized() + root = spack.concretize.concretize_one("root") PackageInstaller([root.package], fake=True, explicit=True).install() repo_with_changing_recipe.change({"delete_version": True}) with spack.config.override("concretizer:reuse", True): - new_root = Spec("root").concretized() + new_root = spack.concretize.concretize_one("root") assert root.dag_hash() == new_root.dag_hash() @@ -1770,12 +1780,12 @@ def test_installed_version_is_selected_only_for_reuse( """ # Install a dependency that cannot be reused with "root" # because of a conflict in a variant, then delete its version - dependency = Spec("changing@1.0~foo").concretized() + dependency = spack.concretize.concretize_one("changing@1.0~foo") PackageInstaller([dependency.package], fake=True, explicit=True).install() repo_with_changing_recipe.change({"delete_version": True}) with spack.config.override("concretizer:reuse", True): - new_root = Spec("root").concretized() + new_root = spack.concretize.concretize_one("root") assert not new_root["changing"].satisfies("@1.0") @@ -1784,12 +1794,12 @@ def test_reuse_with_unknown_namespace_dont_raise( self, temporary_store, mock_custom_repository ): with spack.repo.use_repositories(mock_custom_repository, override=False): - s = Spec("pkg-c").concretized() + s = spack.concretize.concretize_one("pkg-c") assert s.namespace != "builtin.mock" PackageInstaller([s.package], fake=True, explicit=True).install() with spack.config.override("concretizer:reuse", True): - s = Spec("pkg-c").concretized() + s = spack.concretize.concretize_one("pkg-c") assert s.namespace == "builtin.mock" @pytest.mark.regression("45538") @@ -1797,12 +1807,12 @@ def test_reuse_from_other_namespace_no_raise(self, tmpdir, temporary_store, monk myrepo = spack.repo.MockRepositoryBuilder(tmpdir.mkdir("mock.repo"), namespace="myrepo") myrepo.add_package("zlib") - builtin = Spec("zlib").concretized() + builtin = spack.concretize.concretize_one("zlib") PackageInstaller([builtin.package], fake=True, explicit=True).install() with spack.repo.use_repositories(myrepo.root, override=False): with spack.config.override("concretizer:reuse", True): - myrepo = Spec("myrepo.zlib").concretized() + myrepo = spack.concretize.concretize_one("myrepo.zlib") assert myrepo.namespace == "myrepo" @@ -1811,7 +1821,7 @@ def test_reuse_with_unknown_package_dont_raise(self, tmpdir, temporary_store, mo builder = spack.repo.MockRepositoryBuilder(tmpdir.mkdir("mock.repo"), namespace="myrepo") builder.add_package("pkg-c") with spack.repo.use_repositories(builder.root, override=False): - s = Spec("pkg-c").concretized() + s = spack.concretize.concretize_one("pkg-c") assert s.namespace == "myrepo" PackageInstaller([s.package], fake=True, explicit=True).install() @@ -1822,7 +1832,7 @@ def test_reuse_with_unknown_package_dont_raise(self, tmpdir, temporary_store, mo # TODO (INJECT CONFIGURATION): unclear why the cache needs to be invalidated explicitly repos.repos[0]._pkg_checker.invalidate() with spack.config.override("concretizer:reuse", True): - s = Spec("pkg-c").concretized() + s = spack.concretize.concretize_one("pkg-c") assert s.namespace == "builtin.mock" @pytest.mark.parametrize( @@ -1916,7 +1926,7 @@ def test_solve_in_rounds_all_unsolved(self, monkeypatch, mock_packages): def test_coconcretize_reuse_and_virtuals(self): reusable_specs = [] for s in ["mpileaks ^mpich", "zmpi"]: - reusable_specs.extend(Spec(s).concretized().traverse(root=True)) + reusable_specs.extend(spack.concretize.concretize_one(s).traverse(root=True)) root_specs = [Spec("mpileaks"), Spec("zmpi")] @@ -1933,7 +1943,7 @@ def test_misleading_error_message_on_version(self, mutable_database): # For this bug to be triggered we need a reusable dependency # that is not optimal in terms of optimization scores. # We pick an old version of "b" - reusable_specs = [Spec("non-existing-conditional-dep@1.0").concretized()] + reusable_specs = [spack.concretize.concretize_one("non-existing-conditional-dep@1.0")] root_spec = Spec("non-existing-conditional-dep@2.0") with spack.config.override("concretizer:reuse", True): @@ -1947,7 +1957,9 @@ def test_misleading_error_message_on_version(self, mutable_database): @pytest.mark.regression("31148") def test_version_weight_and_provenance(self): """Test package preferences during coconcretization.""" - reusable_specs = [Spec(spec_str).concretized() for spec_str in ("pkg-b@0.9", "pkg-b@1.0")] + reusable_specs = [ + spack.concretize.concretize_one(spec_str) for spec_str in ("pkg-b@0.9", "pkg-b@1.0") + ] root_spec = Spec("pkg-a foobar=bar") with spack.config.override("concretizer:reuse", True): @@ -1978,7 +1990,7 @@ def test_version_weight_and_provenance(self): def test_reuse_succeeds_with_config_compatible_os(self): root_spec = Spec("pkg-b") - s = root_spec.concretized() + s = spack.concretize.concretize_one(root_spec) other_os = s.copy() mock_os = "ubuntu2204" other_os.architecture = spack.spec.ArchSpec( @@ -1997,13 +2009,13 @@ def test_reuse_succeeds_with_config_compatible_os(self): def test_git_hash_assigned_version_is_preferred(self): hash = "a" * 40 s = Spec("develop-branch-version@%s=develop" % hash) - c = s.concretized() + c = spack.concretize.concretize_one(s) assert hash in str(c) @pytest.mark.parametrize("git_ref", ("a" * 40, "0.2.15", "main")) def test_git_ref_version_is_equivalent_to_specified_version(self, git_ref): s = Spec("develop-branch-version@git.%s=develop" % git_ref) - c = s.concretized() + c = spack.concretize.concretize_one(s) assert git_ref in str(c) print(str(c)) assert s.satisfies("@develop") @@ -2013,7 +2025,7 @@ def test_git_ref_version_is_equivalent_to_specified_version(self, git_ref): def test_git_ref_version_succeeds_with_unknown_version(self, git_ref): # main is not defined in the package.py for this file s = Spec("develop-branch-version@git.%s=main" % git_ref) - s.concretize() + s = spack.concretize.concretize_one(s) assert s.satisfies("develop-branch-version@main") @pytest.mark.regression("31484") @@ -2030,7 +2042,7 @@ def test_installed_externals_are_reused( spack.config.set("packages", external_conf) # Install the external spec - external1 = Spec("changing@1.0").concretized() + external1 = spack.concretize.concretize_one("changing@1.0") PackageInstaller([external1.package], fake=True, explicit=True).install() assert external1.external @@ -2039,12 +2051,12 @@ def test_installed_externals_are_reused( # Try to concretize the external without reuse and confirm the hash changed with spack.config.override("concretizer:reuse", False): - external2 = Spec("changing@1.0").concretized() + external2 = spack.concretize.concretize_one("changing@1.0") assert external2.dag_hash() != external1.dag_hash() # ... while with reuse we have the same hash with spack.config.override("concretizer:reuse", True): - external3 = Spec("changing@1.0").concretized() + external3 = spack.concretize.concretize_one("changing@1.0") assert external3.dag_hash() == external1.dag_hash() @pytest.mark.regression("31484") @@ -2061,18 +2073,18 @@ def test_user_can_select_externals_with_require(self, mutable_database, tmp_path # mpich and others are installed, so check that # fresh use the external, reuse does not with spack.config.override("concretizer:reuse", False): - mpi_spec = Spec("mpi").concretized() + mpi_spec = spack.concretize.concretize_one("mpi") assert mpi_spec.name == "multi-provider-mpi" with spack.config.override("concretizer:reuse", True): - mpi_spec = Spec("mpi").concretized() + mpi_spec = spack.concretize.concretize_one("mpi") assert mpi_spec.name != "multi-provider-mpi" external_conf["mpi"]["require"] = "multi-provider-mpi" spack.config.set("packages", external_conf) with spack.config.override("concretizer:reuse", True): - mpi_spec = Spec("mpi").concretized() + mpi_spec = spack.concretize.concretize_one("mpi") assert mpi_spec.name == "multi-provider-mpi" @pytest.mark.regression("31484") @@ -2086,12 +2098,12 @@ def test_installed_specs_disregard_conflicts(self, mutable_database, monkeypatch # If we concretize with --fresh the conflict is taken into account with spack.config.override("concretizer:reuse", False): - s = Spec("mpich").concretized() + s = spack.concretize.concretize_one("mpich") assert s.satisfies("+debug") # If we concretize with --reuse it is not, since "mpich~debug" was already installed with spack.config.override("concretizer:reuse", True): - s = Spec("mpich").concretized() + s = spack.concretize.concretize_one("mpich") assert s.installed assert s.satisfies("~debug"), s @@ -2103,7 +2115,7 @@ def test_require_targets_are_allowed(self, mutable_database): spack.config.set("packages", external_conf) with spack.config.override("concretizer:reuse", False): - spec = Spec("mpich").concretized() + spec = spack.concretize.concretize_one("mpich") for s in spec.traverse(): assert s.satisfies("target=%s" % spack.platforms.test.Test.front_end) @@ -2120,7 +2132,7 @@ def test_external_python_extensions_have_dependency(self): } spack.config.set("packages", external_conf) - spec = Spec("py-extension2").concretized() + spec = spack.concretize.concretize_one("py-extension2") assert "python" in spec["py-extension1"] assert spec["python"] == spec["py-extension1"]["python"] @@ -2148,7 +2160,7 @@ def test_external_python_extension_find_dependency_from_config(self, python_spec } spack.config.set("packages", external_conf) - spec = Spec("py-extension1").concretized() + spec = spack.concretize.concretize_one("py-extension1") assert "python" in spec["py-extension1"] assert spec["python"].prefix == fake_path @@ -2172,7 +2184,7 @@ def test_external_python_extension_find_dependency_from_installed(self, monkeypa spack.config.set("packages", external_conf) # install python external - python = Spec("python").concretized() + python = spack.concretize.concretize_one("python") def query(*args, **kwargs): return [python] @@ -2183,7 +2195,7 @@ def query(*args, **kwargs): external_conf.pop("python") spack.config.set("packages", external_conf) - spec = Spec("py-extension1").concretized() + spec = spack.concretize.concretize_one("py-extension1") assert "python" in spec["py-extension1"] assert spec["python"].prefix == fake_path @@ -2212,7 +2224,7 @@ def find_fake_python(classes, path_hints): } spack.config.set("packages", external_conf) - spec = Spec("py-extension1").concretized() + spec = spack.concretize.concretize_one("py-extension1") assert "python" in spec["py-extension1"] assert spec["python"].prefix == prefix @@ -2230,7 +2242,7 @@ def test_external_python_extension_find_unified_python(self): spack.config.set("packages", external_conf) abstract_specs = [Spec(s) for s in ["py-extension1", "python"]] - specs = spack.concretize.concretize_specs_together(abstract_specs) + specs = spack.concretize._concretize_specs_together(abstract_specs) assert specs[0]["python"] == specs[1]["python"] @pytest.mark.regression("36190") @@ -2278,7 +2290,7 @@ def test_clear_error_when_unknown_compiler_requested(self, mock_packages): with pytest.raises( spack.error.UnsatisfiableSpecError, match="Cannot set the required compiler: pkg-a%foo" ): - Spec("pkg-a %foo").concretized() + spack.concretize.concretize_one("pkg-a %foo") @pytest.mark.regression("36339") def test_compiler_match_constraints_when_selected(self): @@ -2314,7 +2326,7 @@ def test_compiler_match_constraints_when_selected(self): }, ] spack.config.set("compilers", compiler_configuration) - s = Spec("pkg-a %gcc@:11").concretized() + s = spack.concretize.concretize_one("pkg-a %gcc@:11") assert s.compiler.version == ver("=11.1.0"), s @pytest.mark.regression("36339") @@ -2336,7 +2348,7 @@ def test_compiler_with_custom_non_numeric_version(self, mock_executable): } ] spack.config.set("compilers", compiler_configuration) - s = Spec("pkg-a %gcc@foo").concretized() + s = spack.concretize.concretize_one("pkg-a %gcc@foo") assert s.compiler.version == ver("=foo") @pytest.mark.regression("36628") @@ -2362,13 +2374,13 @@ def test_concretization_with_compilers_supporting_target_any(self): ] with spack.config.override("compilers", compiler_configuration): - s = Spec("pkg-a").concretized() + s = spack.concretize.concretize_one("pkg-a") assert s.satisfies("%gcc@12.1.0") @pytest.mark.parametrize("spec_str", ["mpileaks", "mpileaks ^mpich"]) def test_virtuals_are_annotated_on_edges(self, spec_str): """Tests that information on virtuals is annotated on DAG edges""" - spec = Spec(spec_str).concretized() + spec = spack.concretize.concretize_one(spec_str) mpi_provider = spec["mpi"].name edges = spec.edges_to_dependencies(name=mpi_provider) @@ -2388,7 +2400,7 @@ def test_explicit_splices( } spack.config.CONFIG.set("concretizer", {"splice": {"explicit": [splice_info]}}) - spec = spack.spec.Spec("hdf5 ^zmpi").concretized() + spec = spack.concretize.concretize_one("hdf5 ^zmpi") assert spec.satisfies(f"^mpich@{mpich_spec.version}") assert spec.build_spec.dependencies(name="zmpi", deptype="link") @@ -2406,14 +2418,14 @@ def test_explicit_splice_fails_nonexistent(mutable_config, mock_packages, mock_s spack.config.CONFIG.set("concretizer", {"splice": {"explicit": [splice_info]}}) with pytest.raises(spack.spec.InvalidHashError): - _ = spack.spec.Spec("hdf5^zmpi").concretized() + _ = spack.concretize.concretize_one("hdf5^zmpi") def test_explicit_splice_fails_no_hash(mutable_config, mock_packages, mock_store): splice_info = {"target": "mpi", "replacement": "mpich"} spack.config.CONFIG.set("concretizer", {"splice": {"explicit": [splice_info]}}) with pytest.raises(spack.solver.asp.InvalidSpliceError, match="must be specified by hash"): - _ = spack.spec.Spec("hdf5^zmpi").concretized() + _ = spack.concretize.concretize_one("hdf5^zmpi") def test_explicit_splice_non_match_nonexistent_succeeds( mutable_config, mock_packages, mock_store @@ -2421,7 +2433,7 @@ def test_explicit_splice_non_match_nonexistent_succeeds( """When we have a nonexistent splice configured but are not using it, don't fail.""" splice_info = {"target": "will_not_match", "replacement": "nonexistent/doesnotexist"} spack.config.CONFIG.set("concretizer", {"splice": {"explicit": [splice_info]}}) - spec = spack.spec.Spec("zlib").concretized() + spec = spack.concretize.concretize_one("zlib") # the main test is that it does not raise assert not spec.spliced @@ -2433,7 +2445,7 @@ def test_explicit_splice_non_match_nonexistent_succeeds( def test_virtuals_are_reconstructed_on_reuse(self, spec_str, mpi_name, mutable_database): """Tests that when we reuse a spec, virtual on edges are reconstructed correctly""" with spack.config.override("concretizer:reuse", True): - spec = Spec(spec_str).concretized() + spec = spack.concretize.concretize_one(spec_str) assert spec.installed mpi_edges = spec.edges_to_dependencies(mpi_name) assert len(mpi_edges) == 1 @@ -2444,7 +2456,7 @@ def test_dont_define_new_version_from_input_if_checksum_required(self, working_e with pytest.raises(spack.error.UnsatisfiableSpecError): # normally spack concretizes to @=3.0 if it's not defined in package.py, except # when checksums are required - Spec("pkg-a@=3.0").concretized() + spack.concretize.concretize_one("pkg-a@=3.0") @pytest.mark.regression("39570") @pytest.mark.db @@ -2452,15 +2464,15 @@ def test_reuse_python_from_cli_and_extension_from_db(self, mutable_database): """Tests that reusing python with and explicit request on the command line, when the spec also reuses a python extension from the DB, doesn't fail. """ - s = Spec("py-extension1").concretized() + s = spack.concretize.concretize_one("py-extension1") python_hash = s["python"].dag_hash() PackageInstaller([s.package], fake=True, explicit=True).install() with spack.config.override("concretizer:reuse", True): - with_reuse = Spec(f"py-extension2 ^/{python_hash}").concretized() + with_reuse = spack.concretize.concretize_one(f"py-extension2 ^/{python_hash}") with spack.config.override("concretizer:reuse", False): - without_reuse = Spec("py-extension2").concretized() + without_reuse = spack.concretize.concretize_one("py-extension2") assert with_reuse.dag_hash() == without_reuse.dag_hash() @@ -2484,7 +2496,7 @@ def test_select_lower_priority_package_from_repository_stack( # 'builtin.mock" and "duplicates.test" share a 'gmake' package additional_repo = os.path.join(spack.paths.repos_path, "duplicates.test") with spack.repo.use_repositories(additional_repo, override=False): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) for name, namespace in expected_namespaces.items(): assert s[name].concrete @@ -2501,13 +2513,13 @@ def test_reuse_specs_from_non_available_compilers(self, mutable_config, mutable_ mutable_config.set("concretizer:reuse", True) # mpileaks is in the database, it will be reused with gcc@=10.2.1 - root = Spec("mpileaks").concretized() + root = spack.concretize.concretize_one("mpileaks") for s in root.traverse(): assert s.satisfies("%gcc@10.2.1") # fftw is not in the database, therefore the root will be compiled with gcc@=9.4.0, # while the mpi is reused from the database and is compiled with gcc@=10.2.1 - root = Spec("fftw").concretized() + root = spack.concretize.concretize_one("fftw") assert root.satisfies("%gcc@=9.4.0") for s in root.traverse(root=False): assert s.satisfies("%gcc@10.2.1") @@ -2522,7 +2534,7 @@ def test_externals_with_platform_explicitly_set(self, tmp_path): } } spack.config.set("packages", external_conf) - s = Spec("mpich").concretized() + s = spack.concretize.concretize_one("mpich") assert s.external @pytest.mark.regression("43267") @@ -2533,10 +2545,10 @@ def test_spec_with_build_dep_from_json(self, tmp_path): The bug was triggered by missing virtuals on edges that were trimmed from pure build dependencies. """ - build_dep = Spec("dttop").concretized() + build_dep = spack.concretize.concretize_one("dttop") json_file = tmp_path / "build.json" json_file.write_text(build_dep.to_json()) - s = Spec(f"dtuse ^{str(json_file)}").concretized() + s = spack.concretize.concretize_one(f"dtuse ^{str(json_file)}") assert s["dttop"].dag_hash() == build_dep.dag_hash() @pytest.mark.regression("44040") @@ -2563,14 +2575,14 @@ def test_exclude_specs_from_reuse(self, monkeypatch): """ # Prepare a mock mirror that returns an old version of dyninst request_str = "callpath ^mpich" - reused = Spec(f"{request_str} ^dyninst@8.1.1").concretized() + reused = spack.concretize.concretize_one(f"{request_str} ^dyninst@8.1.1") monkeypatch.setattr(spack.solver.asp, "_specs_from_mirror", lambda: [reused]) # Exclude dyninst from reuse, so we expect that the old version is not taken into account with spack.config.override( "concretizer:reuse", {"from": [{"type": "buildcache", "exclude": ["dyninst"]}]} ): - result = Spec(request_str).concretized() + result = spack.concretize.concretize_one(request_str) assert result.dag_hash() != reused.dag_hash() assert result["mpich"].dag_hash() == reused["mpich"].dag_hash() @@ -2607,7 +2619,7 @@ def test_include_specs_from_externals_and_libcs( with spack.config.override( "concretizer:reuse", {"from": [{"type": "external", "include": included_externals}]} ): - result = Spec(request_str).concretized() + result = spack.concretize.concretize_one(request_str) assert result["deprecated-versions"].satisfies("@1.1.0") @@ -2616,7 +2628,7 @@ def test_include_specs_from_externals_and_libcs( "concretizer:reuse", {"from": [{"type": "external", "exclude": ["deprecated-versions"]}]}, ): - result = Spec(request_str).concretized() + result = spack.concretize.concretize_one(request_str) assert result["deprecated-versions"].satisfies("@1.0.0") @@ -2630,7 +2642,7 @@ def test_can_reuse_concrete_externals_for_dependents(self, mutable_config, tmp_p } mutable_config.set("packages", packages_yaml) # Concretize with gcc@9 to get a suboptimal spec, since we have gcc@10 available - external_spec = Spec("externaltool@2 %gcc@9").concretized() + external_spec = spack.concretize.concretize_one("externaltool@2 %gcc@9") assert external_spec.external root_specs = [Spec("sombrero")] @@ -2651,11 +2663,11 @@ def test_cannot_reuse_host_incompatible_libc(self): # We install b@1 ^glibc@2.30, and b@0 ^glibc@2.28. The former is not host compatible, the # latter is. - fst = Spec("pkg-b@1").concretized() + fst = spack.concretize.concretize_one("pkg-b@1") fst._mark_concrete(False) fst.dependencies("glibc")[0].versions = VersionList(["=2.30"]) fst._mark_concrete(True) - snd = Spec("pkg-b@0").concretized() + snd = spack.concretize.concretize_one("pkg-b@0") # The spec b@1 ^glibc@2.30 is "more optimal" than b@0 ^glibc@2.28, but due to glibc # incompatibility, it should not be reused. @@ -2684,7 +2696,7 @@ def test_corrupted_external_does_not_halt_concretization(self, corrupted_str, mu } mutable_config.set("packages", packages_yaml) # Assert we don't raise due to the corrupted external entry above - s = Spec("pkg-a").concretized() + s = spack.concretize.concretize_one("pkg-a") assert s.concrete @pytest.mark.regression("44828") @@ -2707,7 +2719,7 @@ def test_correct_external_is_selected_from_packages_yaml(self, mutable_config): mutable_config.set("packages", packages_yaml) mutable_config.set("concretizer", concretizer_yaml) - s = Spec("cmake").concretized() + s = spack.concretize.concretize_one("cmake") # Check that we got the properties from the right external assert s.external @@ -2740,7 +2752,7 @@ def test_two_gmake(self, strategy): """ spack.config.CONFIG.set("concretizer:duplicates:strategy", strategy) - s = Spec("hdf5").concretized() + s = spack.concretize.concretize_one("hdf5") # Check that hdf5 depends on gmake@=4.1 hdf5_gmake = s["hdf5"].dependencies(name="gmake", deptype="build") @@ -2772,7 +2784,7 @@ def test_two_setuptools(self, strategy): """ spack.config.CONFIG.set("concretizer:duplicates:strategy", strategy) - s = Spec("py-shapely").concretized() + s = spack.concretize.concretize_one("py-shapely") # Requirements on py-shapely setuptools = s["py-shapely"].dependencies(name="py-setuptools", deptype="build") assert len(setuptools) == 1 and setuptools[0].satisfies("@=60") @@ -2791,11 +2803,11 @@ def test_solution_without_cycles(self): """Tests that when we concretize a spec with cycles, a fallback kicks in to recompute a solution without cycles. """ - s = Spec("cycle-a").concretized() + s = spack.concretize.concretize_one("cycle-a") assert s["cycle-a"].satisfies("+cycle") assert s["cycle-b"].satisfies("~cycle") - s = Spec("cycle-b").concretized() + s = spack.concretize.concretize_one("cycle-b") assert s["cycle-a"].satisfies("~cycle") assert s["cycle-b"].satisfies("+cycle") @@ -2811,7 +2823,7 @@ def test_pure_build_virtual_dependency(self, strategy): """ spack.config.CONFIG.set("concretizer:duplicates:strategy", strategy) - s = Spec("virtual-build").concretized() + s = spack.concretize.concretize_one("virtual-build") assert s["pkgconfig"].name == "pkg-config" @pytest.mark.regression("40595") @@ -2843,7 +2855,7 @@ def test_no_multiple_solutions_with_different_edges_same_nodes(self): """ spec_str = "py-floating" - root = spack.spec.Spec(spec_str).concretized() + root = spack.concretize.concretize_one(spec_str) assert root["py-shapely"].satisfies("^py-setuptools@=60") assert root["py-numpy"].satisfies("^py-setuptools@=59") @@ -2922,7 +2934,7 @@ def test_adding_specs(self, input_specs, default_mock_concretization): objects in memory. """ container = spack.solver.asp.ConcreteSpecsByHash() - input_specs = [Spec(s).concretized() for s in input_specs] + input_specs = [spack.concretize.concretize_one(s) for s in input_specs] for s in input_specs: container.add(s) @@ -2960,7 +2972,7 @@ def test_condition_triggered_by_edge_property( self, spec_str, expected_satisfies, expected_not_satisfies ): """Tests that we can enforce constraints based on edge attributes""" - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) for expected in expected_satisfies: assert s.satisfies(expected), str(expected) @@ -2977,7 +2989,7 @@ def test_virtuals_provided_together_but_only_one_required_in_dag(self): o openblas (provides blas and lapack together) """ - s = Spec("blas-only-client ^openblas").concretized() + s = spack.concretize.concretize_one("blas-only-client ^openblas") assert s.satisfies("^[virtuals=blas] openblas") assert not s.satisfies("^[virtuals=blas,lapack] openblas") @@ -3167,18 +3179,22 @@ def test_spec_filters(specs, include, exclude, expected): @pytest.mark.regression("38484") def test_git_ref_version_can_be_reused(install_mockery, do_not_check_runtimes_on_reuse): - first_spec = spack.spec.Spec("git-ref-package@git.2.1.5=2.1.5~opt").concretized() + first_spec = spack.concretize.concretize_one( + spack.spec.Spec("git-ref-package@git.2.1.5=2.1.5~opt") + ) PackageInstaller([first_spec.package], fake=True, explicit=True).install() with spack.config.override("concretizer:reuse", True): # reproducer of the issue is that spack will solve when there is a change to the base spec - second_spec = spack.spec.Spec("git-ref-package@git.2.1.5=2.1.5+opt").concretized() + second_spec = spack.concretize.concretize_one( + spack.spec.Spec("git-ref-package@git.2.1.5=2.1.5+opt") + ) assert second_spec.dag_hash() != first_spec.dag_hash() # we also want to confirm that reuse actually works so leave variant off to # let solver reuse third_spec = spack.spec.Spec("git-ref-package@git.2.1.5=2.1.5") assert first_spec.satisfies(third_spec) - third_spec.concretize() + third_spec = spack.concretize.concretize_one(third_spec) assert third_spec.dag_hash() == first_spec.dag_hash() @@ -3191,14 +3207,16 @@ def test_reuse_prefers_standard_over_git_versions( but we want to prefer the standard version over git ref based versions so install git ref last and ensure it is not picked up by reuse """ - standard_spec = spack.spec.Spec(f"git-ref-package@{standard_version}").concretized() + standard_spec = spack.concretize.concretize_one( + spack.spec.Spec(f"git-ref-package@{standard_version}") + ) PackageInstaller([standard_spec.package], fake=True, explicit=True).install() - git_spec = spack.spec.Spec("git-ref-package@git.2.1.5=2.1.5").concretized() + git_spec = spack.concretize.concretize_one("git-ref-package@git.2.1.5=2.1.5") PackageInstaller([git_spec.package], fake=True, explicit=True).install() with spack.config.override("concretizer:reuse", True): - test_spec = spack.spec.Spec("git-ref-package@2").concretized() + test_spec = spack.concretize.concretize_one("git-ref-package@2") assert git_spec.dag_hash() != test_spec.dag_hash() assert standard_spec.dag_hash() == test_spec.dag_hash() diff --git a/lib/spack/spack/test/concretization/errors.py b/lib/spack/spack/test/concretization/errors.py index 7a118fec047..f86ed6d187e 100644 --- a/lib/spack/spack/test/concretization/errors.py +++ b/lib/spack/spack/test/concretization/errors.py @@ -4,9 +4,9 @@ import pytest +import spack.concretize import spack.config import spack.solver.asp -import spack.spec version_error_messages = [ "Cannot satisfy 'fftw@:1.0' and 'fftw@1.1:", @@ -57,7 +57,7 @@ def test_error_messages(error_messages, config_set, spec, mock_packages, mutable spack.config.set(path, conf) with pytest.raises(spack.solver.asp.UnsatisfiableSpecError) as e: - _ = spack.spec.Spec(spec).concretized() + _ = spack.concretize.concretize_one(spec) for em in error_messages: assert em in str(e.value) diff --git a/lib/spack/spack/test/concretization/flag_mixing.py b/lib/spack/spack/test/concretization/flag_mixing.py index 62187dd39f9..29899a98f18 100644 --- a/lib/spack/spack/test/concretization/flag_mixing.py +++ b/lib/spack/spack/test/concretization/flag_mixing.py @@ -11,7 +11,6 @@ import spack.paths import spack.repo import spack.util.spack_yaml as syaml -from spack.spec import Spec """ These tests include the following package DAGs: @@ -63,12 +62,12 @@ def test_mix_spec_and_requirements(concretize_scope, test_repo): """ update_concretize_scope(conf_str, "packages") - s1 = Spec('y cflags="-a"').concretized() + s1 = spack.concretize.concretize_one('y cflags="-a"') assert s1.satisfies('cflags="-a -c"') def test_mix_spec_and_dependent(concretize_scope, test_repo): - s1 = Spec('x ^y cflags="-a"').concretized() + s1 = spack.concretize.concretize_one('x ^y cflags="-a"') assert s1["y"].satisfies('cflags="-a -d1"') @@ -93,7 +92,7 @@ def test_mix_spec_and_compiler_cfg(concretize_scope, test_repo): conf_str = _compiler_cfg_one_entry_with_cflags("-Wall") update_concretize_scope(conf_str, "compilers") - s1 = Spec('y %gcc@12.100.100 cflags="-O2"').concretized() + s1 = spack.concretize.concretize_one('y %gcc@12.100.100 cflags="-O2"') assert s1.satisfies('cflags="-Wall -O2"') @@ -160,7 +159,7 @@ def test_flag_order_and_grouping( if cmd_flags: spec_str += f' cflags="{cmd_flags}"' - root_spec = Spec(spec_str).concretized() + root_spec = spack.concretize.concretize_one(spec_str) spec = root_spec["y"] satisfy_flags = " ".join(x for x in [cmd_flags, req_flags, cmp_flags, expected_dflags] if x) assert spec.satisfies(f'cflags="{satisfy_flags}"') @@ -168,11 +167,11 @@ def test_flag_order_and_grouping( def test_two_dependents_flag_mixing(concretize_scope, test_repo): - root_spec1 = Spec("w~moveflaglater").concretized() + root_spec1 = spack.concretize.concretize_one("w~moveflaglater") spec1 = root_spec1["y"] assert spec1.compiler_flags["cflags"] == "-d0 -d1 -d2".split() - root_spec2 = Spec("w+moveflaglater").concretized() + root_spec2 = spack.concretize.concretize_one("w+moveflaglater") spec2 = root_spec2["y"] assert spec2.compiler_flags["cflags"] == "-d3 -d1 -d2".split() @@ -181,7 +180,7 @@ def test_propagate_and_compiler_cfg(concretize_scope, test_repo): conf_str = _compiler_cfg_one_entry_with_cflags("-f2") update_concretize_scope(conf_str, "compilers") - root_spec = Spec("v %gcc@12.100.100 cflags=='-f1'").concretized() + root_spec = spack.concretize.concretize_one("v %gcc@12.100.100 cflags=='-f1'") assert root_spec["y"].satisfies("cflags='-f1 -f2'") @@ -190,7 +189,7 @@ def test_propagate_and_compiler_cfg(concretize_scope, test_repo): def test_propagate_and_pkg_dep(concretize_scope, test_repo): - root_spec1 = Spec("x ~activatemultiflag cflags=='-f1'").concretized() + root_spec1 = spack.concretize.concretize_one("x ~activatemultiflag cflags=='-f1'") assert root_spec1["y"].satisfies("cflags='-f1 -d1'") @@ -202,7 +201,7 @@ def test_propagate_and_require(concretize_scope, test_repo): """ update_concretize_scope(conf_str, "packages") - root_spec1 = Spec("v cflags=='-f1'").concretized() + root_spec1 = spack.concretize.concretize_one("v cflags=='-f1'") assert root_spec1["y"].satisfies("cflags='-f1 -f2'") # Next, check that a requirement does not "undo" a request for @@ -214,7 +213,7 @@ def test_propagate_and_require(concretize_scope, test_repo): """ update_concretize_scope(conf_str, "packages") - root_spec2 = Spec("v cflags=='-f1'").concretized() + root_spec2 = spack.concretize.concretize_one("v cflags=='-f1'") assert root_spec2["y"].satisfies("cflags='-f1'") # Note: requirements cannot enforce propagation: any attempt to do @@ -258,7 +257,7 @@ def test_diamond_dep_flag_mixing(concretize_scope, test_repo): nodes of the diamond always appear in the same order). `Spec.traverse` is responsible for handling both of these needs. """ - root_spec1 = Spec("t").concretized() + root_spec1 = spack.concretize.concretize_one("t") spec1 = root_spec1["y"] assert spec1.satisfies('cflags="-c1 -c2 -d1 -d2 -e1 -e2"') assert spec1.compiler_flags["cflags"] == "-c1 -c2 -e1 -e2 -d1 -d2".split() diff --git a/lib/spack/spack/test/concretization/preferences.py b/lib/spack/spack/test/concretization/preferences.py index 255bc021011..fa9f85c037f 100644 --- a/lib/spack/spack/test/concretization/preferences.py +++ b/lib/spack/spack/test/concretization/preferences.py @@ -7,6 +7,7 @@ import pytest +import spack.concretize import spack.config import spack.package_prefs import spack.repo @@ -46,7 +47,7 @@ def configure_permissions(): def concretize(abstract_spec): - return Spec(abstract_spec).concretized() + return spack.concretize.concretize_one(abstract_spec) def update_packages(pkgname, section, value): @@ -111,7 +112,7 @@ def test_preferred_variants_from_wildcard(self): def test_preferred_compilers(self, compiler_str, spec_str): """Test preferred compilers are applied correctly""" update_packages("all", "compiler", [compiler_str]) - spec = spack.spec.Spec(spec_str).concretized() + spec = spack.concretize.concretize_one(spec_str) assert spec.compiler == CompilerSpec(compiler_str) def test_preferred_target(self, mutable_mock_repo): @@ -213,15 +214,13 @@ def test_config_set_pkg_property_new(self, mock_repo_path): def test_preferred(self): """ "Test packages with some version marked as preferred=True""" - spec = Spec("python") - spec.concretize() + spec = spack.concretize.concretize_one("python") assert spec.version == Version("2.7.11") # now add packages.yaml with versions other than preferred # ensure that once config is in place, non-preferred version is used update_packages("python", "version", ["3.5.0"]) - spec = Spec("python") - spec.concretize() + spec = spack.concretize.concretize_one("python") assert spec.version == Version("3.5.0") def test_preferred_undefined_raises(self): @@ -229,7 +228,7 @@ def test_preferred_undefined_raises(self): update_packages("python", "version", ["3.5.0.1"]) spec = Spec("python") with pytest.raises(ConfigError): - spec.concretize() + spack.concretize.concretize_one(spec) def test_preferred_truncated(self): """Versions without "=" are treated as version ranges: if there is @@ -237,35 +236,29 @@ def test_preferred_truncated(self): (don't define a new version). """ update_packages("python", "version", ["3.5"]) - spec = Spec("python") - spec.concretize() + spec = spack.concretize.concretize_one("python") assert spec.satisfies("@3.5.1") def test_develop(self): """Test concretization with develop-like versions""" - spec = Spec("develop-test") - spec.concretize() + spec = spack.concretize.concretize_one("develop-test") assert spec.version == Version("0.2.15") - spec = Spec("develop-test2") - spec.concretize() + spec = spack.concretize.concretize_one("develop-test2") assert spec.version == Version("0.2.15") # now add packages.yaml with develop-like versions # ensure that once config is in place, develop-like version is used update_packages("develop-test", "version", ["develop"]) - spec = Spec("develop-test") - spec.concretize() + spec = spack.concretize.concretize_one("develop-test") assert spec.version == Version("develop") update_packages("develop-test2", "version", ["0.2.15.develop"]) - spec = Spec("develop-test2") - spec.concretize() + spec = spack.concretize.concretize_one("develop-test2") assert spec.version == Version("0.2.15.develop") def test_external_mpi(self): # make sure this doesn't give us an external first. - spec = Spec("mpi") - spec.concretize() + spec = spack.concretize.concretize_one("mpi") assert not spec["mpi"].external # load config @@ -284,8 +277,7 @@ def test_external_mpi(self): spack.config.set("packages", conf, scope="concretize") # ensure that once config is in place, external is used - spec = Spec("mpi") - spec.concretize() + spec = spack.concretize.concretize_one("mpi") assert spec["mpich"].external_path == os.path.sep + os.path.join("dummy", "path") def test_external_module(self, monkeypatch): @@ -300,8 +292,7 @@ def mock_module(cmd, module): monkeypatch.setattr(spack.util.module_cmd, "module", mock_module) - spec = Spec("mpi") - spec.concretize() + spec = spack.concretize.concretize_one("mpi") assert not spec["mpi"].external # load config @@ -320,8 +311,7 @@ def mock_module(cmd, module): spack.config.set("packages", conf, scope="concretize") # ensure that once config is in place, external is used - spec = Spec("mpi") - spec.concretize() + spec = spack.concretize.concretize_one("mpi") assert spec["mpich"].external_path == os.path.sep + os.path.join("dummy", "path") def test_buildable_false(self): @@ -467,7 +457,7 @@ def test_variant_not_flipped_to_pull_externals(self): """Test that a package doesn't prefer pulling in an external to using the default value of a variant. """ - s = Spec("vdefault-or-external-root").concretized() + s = spack.concretize.concretize_one("vdefault-or-external-root") assert "~external" in s["vdefault-or-external"] assert "externaltool" not in s @@ -479,7 +469,7 @@ def test_dependencies_cant_make_version_parent_score_better(self): that makes the overall version score even or better and maybe has a better score in some lower priority criteria. """ - s = Spec("version-test-root").concretized() + s = spack.concretize.concretize_one("version-test-root") assert s.satisfies("^version-test-pkg@2.4.6") assert "version-test-dependency-preferred" not in s @@ -497,13 +487,13 @@ def test_multivalued_variants_are_lower_priority_than_providers(self): with spack.config.override( "packages:all", {"providers": {"somevirtual": ["some-virtual-preferred"]}} ): - s = Spec("somevirtual").concretized() + s = spack.concretize.concretize_one("somevirtual") assert s.name == "some-virtual-preferred" @pytest.mark.regression("26721,19736") def test_sticky_variant_accounts_for_packages_yaml(self): with spack.config.override("packages:sticky-variant", {"variants": "+allow-gcc"}): - s = Spec("sticky-variant %gcc").concretized() + s = spack.concretize.concretize_one("sticky-variant %gcc") assert s.satisfies("%gcc") and s.satisfies("+allow-gcc") @pytest.mark.regression("41134") @@ -512,5 +502,5 @@ def test_default_preference_variant_different_type_does_not_error(self): packages.yaml doesn't fail with an error. """ with spack.config.override("packages:all", {"variants": "+foo"}): - s = Spec("pkg-a").concretized() + s = spack.concretize.concretize_one("pkg-a") assert s.satisfies("foo=bar") diff --git a/lib/spack/spack/test/concretization/requirements.py b/lib/spack/spack/test/concretization/requirements.py index 495943c4938..a7a3be14d13 100644 --- a/lib/spack/spack/test/concretization/requirements.py +++ b/lib/spack/spack/test/concretization/requirements.py @@ -6,6 +6,7 @@ import pytest +import spack.concretize import spack.config import spack.error import spack.package_base @@ -42,7 +43,7 @@ def test_one_package_multiple_reqs(concretize_scope, test_repo): - "~shared" """ update_packages_config(conf_str) - y_spec = Spec("y").concretized() + y_spec = spack.concretize.concretize_one("y") assert y_spec.satisfies("@2.4~shared") @@ -57,7 +58,7 @@ def test_requirement_isnt_optional(concretize_scope, test_repo): """ update_packages_config(conf_str) with pytest.raises(UnsatisfiableSpecError): - Spec("x@1.1").concretize() + spack.concretize.concretize_one("x@1.1") def test_require_undefined_version(concretize_scope, test_repo): @@ -74,7 +75,7 @@ def test_require_undefined_version(concretize_scope, test_repo): """ update_packages_config(conf_str) with pytest.raises(spack.error.ConfigError): - Spec("x").concretize() + spack.concretize.concretize_one("x") def test_require_truncated(concretize_scope, test_repo): @@ -89,7 +90,7 @@ def test_require_truncated(concretize_scope, test_repo): require: "@1" """ update_packages_config(conf_str) - xspec = Spec("x").concretized() + xspec = spack.concretize.concretize_one("x") assert xspec.satisfies("@1.1") @@ -159,7 +160,7 @@ def test_requirement_adds_new_version( ) update_packages_config(conf_str) - s1 = Spec("v").concretized() + s1 = spack.concretize.concretize_one("v") assert s1.satisfies("@2.2") # Make sure the git commit info is retained assert isinstance(s1.version, spack.version.GitVersion) @@ -180,7 +181,7 @@ def test_requirement_adds_version_satisfies( ) # Sanity check: early version of T does not include U - s0 = Spec("t@2.0").concretized() + s0 = spack.concretize.concretize_one("t@2.0") assert not ("u" in s0) conf_str = """\ @@ -192,7 +193,7 @@ def test_requirement_adds_version_satisfies( ) update_packages_config(conf_str) - s1 = Spec("t").concretized() + s1 = spack.concretize.concretize_one("t") assert "u" in s1 assert s1.satisfies("@2.2") @@ -218,7 +219,7 @@ def test_requirement_adds_git_hash_version( """ update_packages_config(conf_str) - s1 = Spec("v").concretized() + s1 = spack.concretize.concretize_one("v") assert isinstance(s1.version, spack.version.GitVersion) assert s1.satisfies(f"v@{a_commit_hash}") @@ -239,8 +240,8 @@ def test_requirement_adds_multiple_new_versions( """ update_packages_config(conf_str) - assert Spec("v").concretized().satisfies(f"@{commits[0]}=2.2") - assert Spec("v@2.3").concretized().satisfies(f"v@{commits[1]}=2.3") + assert spack.concretize.concretize_one("v").satisfies(f"@{commits[0]}=2.2") + assert spack.concretize.concretize_one("v@2.3").satisfies(f"v@{commits[1]}=2.3") # TODO: this belongs in the concretize_preferences test module but uses @@ -263,11 +264,11 @@ def test_preference_adds_new_version( """ update_packages_config(conf_str) - assert Spec("v").concretized().satisfies(f"@{commits[0]}=2.2") - assert Spec("v@2.3").concretized().satisfies(f"@{commits[1]}=2.3") + assert spack.concretize.concretize_one("v").satisfies(f"@{commits[0]}=2.2") + assert spack.concretize.concretize_one("v@2.3").satisfies(f"@{commits[1]}=2.3") # When installing by hash, a lookup is triggered, so it's not mapped to =2.3. - s3 = Spec(f"v@{commits[1]}").concretized() + s3 = spack.concretize.concretize_one(f"v@{commits[1]}") assert s3.satisfies(f"v@{commits[1]}") assert not s3.satisfies("@2.3") @@ -287,7 +288,7 @@ def test_external_adds_new_version_that_is_preferred(concretize_scope, test_repo """ update_packages_config(conf_str) - spec = Spec("x").concretized() + spec = spack.concretize.concretize_one("x") assert spec["y"].satisfies("@2.7") assert spack.version.Version("2.7") not in spec["y"].package.versions @@ -296,7 +297,7 @@ def test_requirement_is_successfully_applied(concretize_scope, test_repo): """If a simple requirement can be satisfied, make sure the concretization succeeds and the requirement spec is applied. """ - s1 = Spec("x").concretized() + s1 = spack.concretize.concretize_one("x") # Without any requirements/preferences, the later version is preferred assert s1.satisfies("@1.1") @@ -306,7 +307,7 @@ def test_requirement_is_successfully_applied(concretize_scope, test_repo): require: "@1.0" """ update_packages_config(conf_str) - s2 = Spec("x").concretized() + s2 = spack.concretize.concretize_one("x") # The requirement forces choosing the eariler version assert s2.satisfies("@1.0") @@ -323,7 +324,7 @@ def test_multiple_packages_requirements_are_respected(concretize_scope, test_rep require: "@2.4" """ update_packages_config(conf_str) - spec = Spec("x").concretized() + spec = spack.concretize.concretize_one("x") assert spec["x"].satisfies("@1.0") assert spec["y"].satisfies("@2.4") @@ -339,7 +340,7 @@ def test_oneof(concretize_scope, test_repo): - one_of: ["@2.4", "~shared"] """ update_packages_config(conf_str) - spec = Spec("x").concretized() + spec = spack.concretize.concretize_one("x") # The concretizer only has to satisfy one of @2.4/~shared, and @2.4 # comes first so it is prioritized assert spec["y"].satisfies("@2.4+shared") @@ -358,10 +359,10 @@ def test_one_package_multiple_oneof_groups(concretize_scope, test_repo): """ update_packages_config(conf_str) - s1 = Spec("y@2.5").concretized() + s1 = spack.concretize.concretize_one("y@2.5") assert s1.satisfies("%clang~shared") - s2 = Spec("y@2.4").concretized() + s2 = spack.concretize.concretize_one("y@2.4") assert s2.satisfies("%gcc+shared") @@ -377,10 +378,10 @@ def test_require_cflags(concretize_scope, mock_packages): """ update_packages_config(conf_str) - spec_mpich2 = Spec("mpich2").concretized() + spec_mpich2 = spack.concretize.concretize_one("mpich2") assert spec_mpich2.satisfies("cflags=-g") - spec_mpi = Spec("mpi").concretized() + spec_mpi = spack.concretize.concretize_one("mpi") assert spec_mpi.satisfies("mpich cflags=-O1") @@ -403,7 +404,7 @@ def test_requirements_for_package_that_is_not_needed(concretize_scope, test_repo """ update_packages_config(conf_str) - s1 = Spec("v").concretized() + s1 = spack.concretize.concretize_one("v") assert s1.satisfies("@2.1") @@ -420,10 +421,10 @@ def test_oneof_ordering(concretize_scope, test_repo): """ update_packages_config(conf_str) - s1 = Spec("y").concretized() + s1 = spack.concretize.concretize_one("y") assert s1.satisfies("@2.4") - s2 = Spec("y@2.5").concretized() + s2 = spack.concretize.concretize_one("y@2.5") assert s2.satisfies("@2.5") @@ -437,14 +438,14 @@ def test_reuse_oneof(concretize_scope, test_repo, tmp_path, mock_fetch): store_dir = tmp_path / "store" with spack.store.use_store(str(store_dir)): - s1 = Spec("y@2.5 ~shared").concretized() + s1 = spack.concretize.concretize_one("y@2.5~shared") PackageInstaller([s1.package], fake=True, explicit=True).install() update_packages_config(conf_str) with spack.config.override("concretizer:reuse", True): - s2 = Spec("y").concretized() - assert not s2.satisfies("@2.5 ~shared") + s2 = spack.concretize.concretize_one("y") + assert not s2.satisfies("@2.5~shared") @pytest.mark.parametrize( @@ -472,7 +473,7 @@ def test_requirements_and_deprecated_versions( update_packages_config(conf_str) with spack.config.override("config:deprecated", allow_deprecated): - s1 = Spec("y").concretized() + s1 = spack.concretize.concretize_one("y") for constrain in expected: assert s1.satisfies(constrain) @@ -490,7 +491,7 @@ def test_default_requirements_with_all(spec_str, requirement_str, concretize_sco """ update_packages_config(conf_str) - spec = Spec(spec_str).concretized() + spec = spack.concretize.concretize_one(spec_str) for s in spec.traverse(): assert s.satisfies(requirement_str) @@ -499,7 +500,7 @@ def test_default_requirements_with_all(spec_str, requirement_str, concretize_sco "requirements,expectations", [ (("%gcc", "%clang"), ("%gcc", "%clang")), - (("%gcc ~shared", "@1.0"), ("%gcc ~shared", "@1.0 +shared")), + (("%gcc~shared", "@1.0"), ("%gcc~shared", "@1.0+shared")), ], ) def test_default_and_package_specific_requirements( @@ -517,7 +518,7 @@ def test_default_and_package_specific_requirements( """ update_packages_config(conf_str) - spec = Spec("x").concretized() + spec = spack.concretize.concretize_one("x") assert spec.satisfies(specific_exp) for s in spec.traverse(root=False): assert s.satisfies(generic_exp) @@ -532,7 +533,7 @@ def test_requirements_on_virtual(mpi_requirement, concretize_scope, mock_package """ update_packages_config(conf_str) - spec = Spec("callpath").concretized() + spec = spack.concretize.concretize_one("callpath") assert "mpi" in spec assert mpi_requirement in spec @@ -553,7 +554,7 @@ def test_requirements_on_virtual_and_on_package( """ update_packages_config(conf_str) - spec = Spec("callpath").concretized() + spec = spack.concretize.concretize_one("callpath") assert "mpi" in spec assert mpi_requirement in spec assert spec["mpi"].satisfies(specific_requirement) @@ -567,10 +568,10 @@ def test_incompatible_virtual_requirements_raise(concretize_scope, mock_packages """ update_packages_config(conf_str) - spec = Spec("callpath ^zmpi") + spec = Spec("callpath^zmpi") # TODO (multiple nodes): recover a better error message later with pytest.raises((UnsatisfiableSpecError, InternalConcretizerError)): - spec.concretize() + spack.concretize.concretize_one(spec) def test_non_existing_variants_under_all(concretize_scope, mock_packages): @@ -582,7 +583,7 @@ def test_non_existing_variants_under_all(concretize_scope, mock_packages): """ update_packages_config(conf_str) - spec = Spec("callpath ^zmpi").concretized() + spec = spack.concretize.concretize_one("callpath^zmpi") assert "~foo" not in spec @@ -657,7 +658,7 @@ def test_conditional_requirements_from_packages_yaml( and optional when the condition is not met. """ update_packages_config(packages_yaml) - spec = Spec(spec_str).concretized() + spec = spack.concretize.concretize_one(spec_str) for match_str, expected in expected_satisfies: assert spec.satisfies(match_str) is expected @@ -733,7 +734,7 @@ def test_requirements_fail_with_custom_message( """ update_packages_config(packages_yaml) with pytest.raises(spack.error.SpackError, match=expected_message): - Spec(spec_str).concretized() + spack.concretize.concretize_one(spec_str) def test_skip_requirement_when_default_requirement_condition_cannot_be_met( @@ -752,9 +753,9 @@ def test_skip_requirement_when_default_requirement_condition_cannot_be_met( when: "+shared" """ update_packages_config(packages_yaml) - s = Spec("mpileaks").concretized() + s = spack.concretize.concretize_one("mpileaks") - assert s.satisfies("%clang +shared") + assert s.satisfies("%clang+shared") # Sanity checks that 'callpath' doesn't have the shared variant, but that didn't # cause failures during concretization. assert "shared" not in s["callpath"].variants @@ -781,12 +782,12 @@ def test_requires_directive(concretize_scope, mock_packages): spack.config.CONFIG.clear_caches() # This package requires either clang or gcc - s = Spec("requires_clang_or_gcc").concretized() + s = spack.concretize.concretize_one("requires_clang_or_gcc") assert s.satisfies("%gcc@12.0.0") # This package can only be compiled with clang with pytest.raises(spack.error.SpackError, match="can only be compiled with Clang"): - Spec("requires_clang").concretized() + spack.concretize.concretize_one("requires_clang") @pytest.mark.parametrize( @@ -839,20 +840,20 @@ def test_default_requirements_semantic(packages_yaml, concretize_scope, mock_pac """ update_packages_config(packages_yaml) - # Regular zlib concretize to +shared - s = Spec("zlib").concretized() + # Regular zlib concretize to+shared + s = spack.concretize.concretize_one("zlib") assert s.satisfies("+shared") # If we specify the variant we can concretize only the one matching the constraint - s = Spec("zlib +shared").concretized() + s = spack.concretize.concretize_one("zlib+shared") assert s.satisfies("+shared") with pytest.raises(UnsatisfiableSpecError): - Spec("zlib ~shared").concretized() + spack.concretize.concretize_one("zlib~shared") # A spec without the shared variant still concretize - s = Spec("pkg-a").concretized() - assert not s.satisfies("pkg-a +shared") - assert not s.satisfies("pkg-a ~shared") + s = spack.concretize.concretize_one("pkg-a") + assert not s.satisfies("pkg-a+shared") + assert not s.satisfies("pkg-a~shared") @pytest.mark.parametrize( @@ -896,7 +897,7 @@ def test_default_requirements_semantic(packages_yaml, concretize_scope, mock_pac """ packages: all: - require: "libs=static +feefoo" + require: "libs=static+feefoo" """, "multivalue-variant", ["libs=shared"], @@ -911,7 +912,7 @@ def test_default_requirements_semantic_with_mv_variants( from MV variants. """ update_packages_config(packages_yaml) - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) for constraint in expected: assert s.satisfies(constraint), constraint @@ -936,7 +937,7 @@ def test_requiring_package_on_multiple_virtuals(concretize_scope, mock_packages) require: intel-parallel-studio """ ) - s = Spec("dla-future").concretized() + s = spack.concretize.concretize_one("dla-future") assert s["blas"].name == "intel-parallel-studio" assert s["lapack"].name == "intel-parallel-studio" @@ -989,7 +990,7 @@ def test_strong_preferences_packages_yaml( ): """Tests that "preferred" specs are stronger than usual preferences, but can be overridden.""" update_packages_config(packages_yaml) - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) for constraint in expected: assert s.satisfies(constraint), constraint @@ -1038,29 +1039,29 @@ def test_conflict_packages_yaml(packages_yaml, spec_str, concretize_scope, mock_ """Tests conflicts that are specified from configuration files.""" update_packages_config(packages_yaml) with pytest.raises(UnsatisfiableSpecError): - Spec(spec_str).concretized() + spack.concretize.concretize_one(spec_str) @pytest.mark.parametrize( "spec_str,expected,not_expected", [ ( - "forward-multi-value +cuda cuda_arch=10 ^dependency-mv~cuda", + "forward-multi-value+cuda cuda_arch=10^dependency-mv~cuda", ["cuda_arch=10", "^dependency-mv~cuda"], ["cuda_arch=11", "^dependency-mv cuda_arch=10", "^dependency-mv cuda_arch=11"], ), ( - "forward-multi-value +cuda cuda_arch=10 ^dependency-mv+cuda", + "forward-multi-value+cuda cuda_arch=10^dependency-mv+cuda", ["cuda_arch=10", "^dependency-mv cuda_arch=10"], ["cuda_arch=11", "^dependency-mv cuda_arch=11"], ), ( - "forward-multi-value +cuda cuda_arch=11 ^dependency-mv+cuda", + "forward-multi-value+cuda cuda_arch=11^dependency-mv+cuda", ["cuda_arch=11", "^dependency-mv cuda_arch=11"], ["cuda_arch=10", "^dependency-mv cuda_arch=10"], ), ( - "forward-multi-value +cuda cuda_arch=10,11 ^dependency-mv+cuda", + "forward-multi-value+cuda cuda_arch=10,11^dependency-mv+cuda", ["cuda_arch=10,11", "^dependency-mv cuda_arch=10,11"], [], ), @@ -1073,9 +1074,9 @@ def test_forward_multi_valued_variant_using_requires( `requires` directives of the form: for _val in ("shared", "static"): - requires(f"^some-virtual-mv libs={_val}", when=f"libs={_val} ^some-virtual-mv") + requires(f"^some-virtual-mv libs={_val}", when=f"libs={_val}^some-virtual-mv") """ - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) for constraint in expected: assert s.satisfies(constraint) @@ -1086,7 +1087,7 @@ def test_forward_multi_valued_variant_using_requires( def test_strong_preferences_higher_priority_than_reuse(concretize_scope, mock_packages): """Tests that strong preferences have a higher priority than reusing specs.""" - reused_spec = Spec("adios2~bzip2").concretized() + reused_spec = spack.concretize.concretize_one("adios2~bzip2") reuse_nodes = list(reused_spec.traverse()) root_specs = [Spec("ascent+adios2")] @@ -1121,7 +1122,7 @@ def test_strong_preferences_higher_priority_than_reuse(concretize_scope, mock_pa solver = spack.solver.asp.Solver() setup = spack.solver.asp.SpackSolverSetup() result, _, _ = solver.driver.solve( - setup, [Spec("ascent+adios2 ^adios2~bzip2")], reuse=reuse_nodes + setup, [Spec("ascent+adios2^adios2~bzip2")], reuse=reuse_nodes ) ascent = result.specs[0] assert ascent["adios2"].dag_hash() == reused_spec.dag_hash(), ascent diff --git a/lib/spack/spack/test/config_values.py b/lib/spack/spack/test/config_values.py index 0af1c50dfdb..70b9b10f96a 100644 --- a/lib/spack/spack/test/config_values.py +++ b/lib/spack/spack/test/config_values.py @@ -4,7 +4,7 @@ import pytest -import spack.spec +import spack.concretize import spack.store @@ -13,7 +13,7 @@ def test_set_install_hash_length(hash_length, mutable_config, tmpdir): mutable_config.set("config:install_hash_length", hash_length) with spack.store.use_store(str(tmpdir)): - spec = spack.spec.Spec("libelf").concretized() + spec = spack.concretize.concretize_one("libelf") prefix = spec.prefix hash_str = prefix.rsplit("-")[-1] assert len(hash_str) == hash_length @@ -23,7 +23,7 @@ def test_set_install_hash_length(hash_length, mutable_config, tmpdir): def test_set_install_hash_length_upper_case(mutable_config, tmpdir): mutable_config.set("config:install_hash_length", 5) with spack.store.use_store(str(tmpdir), extra_data={"projections": {"all": "{name}-{HASH}"}}): - spec = spack.spec.Spec("libelf").concretized() + spec = spack.concretize.concretize_one("libelf") prefix = spec.prefix hash_str = prefix.rsplit("-")[-1] assert len(hash_str) == 5 diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py index 2b4ee83f913..510c9f154f6 100644 --- a/lib/spack/spack/test/conftest.py +++ b/lib/spack/spack/test/conftest.py @@ -36,6 +36,7 @@ import spack.caches import spack.compiler import spack.compilers +import spack.concretize import spack.config import spack.directives_meta import spack.environment as ev @@ -849,7 +850,7 @@ def _populate(mock_db): """ def _install(spec): - s = spack.spec.Spec(spec).concretized() + s = spack.concretize.concretize_one(spec) PackageInstaller([s.package], fake=True, explicit=True).install() _install("mpileaks ^mpich") @@ -1983,7 +1984,9 @@ def default_mock_concretization(config, mock_packages, concretized_specs_cache): def _func(spec_str, tests=False): key = spec_str, tests if key not in concretized_specs_cache: - concretized_specs_cache[key] = spack.spec.Spec(spec_str).concretized(tests=tests) + concretized_specs_cache[key] = spack.concretize.concretize_one( + spack.spec.Spec(spec_str), tests=tests + ) return concretized_specs_cache[key].copy() return _func diff --git a/lib/spack/spack/test/cvs_fetch.py b/lib/spack/spack/test/cvs_fetch.py index 61d3c11ee61..0e7c02ebd50 100644 --- a/lib/spack/spack/test/cvs_fetch.py +++ b/lib/spack/spack/test/cvs_fetch.py @@ -8,8 +8,8 @@ from llnl.util.filesystem import mkdirp, touch, working_dir +import spack.concretize from spack.fetch_strategy import CvsFetchStrategy -from spack.spec import Spec from spack.stage import Stage from spack.util.executable import which from spack.version import Version @@ -37,7 +37,7 @@ def test_fetch(type_of_test, mock_cvs_repository, config, mutable_mock_repo): get_date = mock_cvs_repository.get_date # Construct the package under test - spec = Spec("cvs-test").concretized() + spec = spack.concretize.concretize_one("cvs-test") spec.package.versions[Version("cvs")] = test.args # Enter the stage directory and check some properties diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py index b1fb160b6b2..c07c8034cd5 100644 --- a/lib/spack/spack/test/database.py +++ b/lib/spack/spack/test/database.py @@ -28,6 +28,7 @@ import llnl.util.lock as lk from llnl.util.tty.colify import colify +import spack.concretize import spack.database import spack.deptypes as dt import spack.package_base @@ -108,8 +109,8 @@ def test_query_by_install_tree( up_db, down_db = upstream_and_downstream_db # Set the upstream DB to contain "pkg-c" and downstream to contain "pkg-b") - b = spack.spec.Spec("pkg-b").concretized() - c = spack.spec.Spec("pkg-c").concretized() + b = spack.concretize.concretize_one("pkg-b") + c = spack.concretize.concretize_one("pkg-c") with writable(up_db): up_db.add(c) up_db._read() @@ -127,7 +128,7 @@ def test_spec_installed_upstream( # a known installed spec should say that it's installed with spack.repo.use_repositories(mock_custom_repository): - spec = spack.spec.Spec("pkg-c").concretized() + spec = spack.concretize.concretize_one("pkg-c") assert not spec.installed assert not spec.installed_upstream @@ -157,7 +158,7 @@ def test_installed_upstream(upstream_and_downstream_db, tmpdir): builder.add_package("w", dependencies=[("x", None, None), ("y", None, None)]) with spack.repo.use_repositories(builder.root): - spec = spack.spec.Spec("w").concretized() + spec = spack.concretize.concretize_one("w") with writable(upstream_db): for dep in spec.traverse(root=False): upstream_db.add(dep) @@ -169,7 +170,7 @@ def test_installed_upstream(upstream_and_downstream_db, tmpdir): with pytest.raises(spack.database.ForbiddenLockError): upstream_db.get_by_hash(dep.dag_hash()) - new_spec = spack.spec.Spec("w").concretized() + new_spec = spack.concretize.concretize_one("w") downstream_db.add(new_spec) for dep in new_spec.traverse(root=False): upstream, record = downstream_db.query_by_spec_hash(dep.dag_hash()) @@ -191,7 +192,7 @@ def test_removed_upstream_dep(upstream_and_downstream_db, tmpdir, capsys, config builder.add_package("y", dependencies=[("z", None, None)]) with spack.repo.use_repositories(builder): - y = spack.spec.Spec("y").concretized() + y = spack.concretize.concretize_one("y") z = y["z"] # add dependency to upstream, dependents to downstream @@ -225,7 +226,7 @@ def test_add_to_upstream_after_downstream(upstream_and_downstream_db, tmpdir): builder.add_package("x") with spack.repo.use_repositories(builder.root): - spec = spack.spec.Spec("x").concretized() + spec = spack.concretize.concretize_one("x") downstream_db.add(spec) with writable(upstream_db): @@ -258,7 +259,7 @@ def test_cannot_write_upstream(tmp_path, mock_packages, config): db = spack.database.Database(str(tmp_path), is_upstream=True) with pytest.raises(spack.database.ForbiddenLockError): - db.add(spack.spec.Spec("pkg-a").concretized()) + db.add(spack.concretize.concretize_one("pkg-a")) @pytest.mark.usefixtures("config", "temporary_store") @@ -272,7 +273,7 @@ def test_recursive_upstream_dbs(tmpdir, gen_mock_layout): builder.add_package("x", dependencies=[("y", None, None)]) with spack.repo.use_repositories(builder.root): - spec = spack.spec.Spec("x").concretized() + spec = spack.concretize.concretize_one("x") db_c = spack.database.Database(roots[2], layout=layouts[2]) db_c.add(spec["z"]) @@ -422,7 +423,7 @@ def _check_remove_and_add_package(database: spack.database.Database, spec): def _mock_install(spec: str): - s = spack.spec.Spec(spec).concretized() + s = spack.concretize.concretize_one(spec) PackageInstaller([s.package], fake=True, explicit=True).install() @@ -767,8 +768,7 @@ def test_regression_issue_8036(mutable_database, usr_folder_exists): # existing. Even when the package prefix exists, the package should # not be considered installed until it is added to the database by # the installer with install(). - s = spack.spec.Spec("externaltool@0.9") - s.concretize() + s = spack.concretize.concretize_one("externaltool@0.9") assert not s.installed # Now install the external package and check again the `installed` property @@ -783,8 +783,7 @@ def test_old_external_entries_prefix(mutable_database): jsonschema.validate(db_obj, schema) - s = spack.spec.Spec("externaltool") - s.concretize() + s = spack.concretize.concretize_one("externaltool") db_obj["database"]["installs"][s.dag_hash()]["path"] = "None" @@ -813,8 +812,7 @@ def test_uninstall_by_spec(mutable_database): def test_query_unused_specs(mutable_database): # This spec installs a fake cmake as a build only dependency - s = spack.spec.Spec("simple-inheritance") - s.concretize() + s = spack.concretize.concretize_one("simple-inheritance") PackageInstaller([s.package], fake=True, explicit=True).install() si = s.dag_hash() @@ -856,8 +854,7 @@ def check_unused(roots, deptype, expected): def test_query_spec_with_conditional_dependency(mutable_database): # The issue is triggered by having dependencies that are # conditional on a Boolean variant - s = spack.spec.Spec("hdf5~mpi") - s.concretize() + s = spack.concretize.concretize_one("hdf5~mpi") PackageInstaller([s.package], fake=True, explicit=True).install() results = spack.store.STORE.db.query_local("hdf5 ^mpich") @@ -897,7 +894,7 @@ def _is(self, spec): # Pretend the spec has been failure locked monkeypatch.setattr(spack.database.FailureTracker, "lock_taken", _is) - s = spack.spec.Spec("pkg-a").concretized() + s = spack.concretize.concretize_one("pkg-a") spack.store.STORE.failure_tracker.clear(s) out = capfd.readouterr()[0] assert "Retaining failure marking" in out @@ -915,7 +912,7 @@ def _is(self, spec): # Ensure raise OSError when try to remove the non-existent marking monkeypatch.setattr(spack.database.FailureTracker, "persistent_mark", _is) - s = spack.spec.Spec("pkg-a").concretized() + s = spack.concretize.concretize_one("pkg-a") spack.store.STORE.failure_tracker.clear(s, force=True) out = capfd.readouterr()[1] assert "Removing failure marking despite lock" in out @@ -930,7 +927,7 @@ def _raise_exc(lock): raise lk.LockTimeoutError("write", "/mock-lock", 1.234, 10) with tmpdir.as_cwd(): - s = spack.spec.Spec("pkg-a").concretized() + s = spack.concretize.concretize_one("pkg-a") # Ensure attempt to acquire write lock on the mark raises the exception monkeypatch.setattr(lk.Lock, "acquire_write", _raise_exc) @@ -946,7 +943,7 @@ def _raise_exc(lock): def test_prefix_failed(mutable_database, monkeypatch): """Add coverage to failed operation.""" - s = spack.spec.Spec("pkg-a").concretized() + s = spack.concretize.concretize_one("pkg-a") # Confirm the spec is not already marked as failed assert not spack.store.STORE.failure_tracker.has_failed(s) @@ -970,7 +967,7 @@ def test_prefix_write_lock_error(mutable_database, monkeypatch): def _raise(db, spec): raise lk.LockError("Mock lock error") - s = spack.spec.Spec("pkg-a").concretized() + s = spack.concretize.concretize_one("pkg-a") # Ensure subsequent lock operations fail monkeypatch.setattr(lk.Lock, "acquire_write", _raise) @@ -1178,7 +1175,7 @@ def test_reindex_with_upstreams(tmp_path, monkeypatch, mock_packages, config): # we install `mpileaks` locally with dependencies in the upstream. And we even install # `mpileaks` with the same hash in the upstream. After reindexing, `mpileaks` should still be # in the local db, and `callpath` should not. - mpileaks = spack.spec.Spec("mpileaks").concretized() + mpileaks = spack.concretize.concretize_one("mpileaks") callpath = mpileaks.dependencies("callpath")[0] upstream_store = spack.store.create( diff --git a/lib/spack/spack/test/directives.py b/lib/spack/spack/test/directives.py index 055ef4b4094..def797b0ab9 100644 --- a/lib/spack/spack/test/directives.py +++ b/lib/spack/spack/test/directives.py @@ -5,6 +5,7 @@ import pytest +import spack.concretize import spack.directives import spack.repo import spack.spec @@ -59,8 +60,8 @@ def test_constraints_from_context_are_merged(mock_packages): @pytest.mark.regression("27754") def test_extends_spec(config, mock_packages): - extender = spack.spec.Spec("extends-spec").concretized() - extendee = spack.spec.Spec("extendee").concretized() + extender = spack.concretize.concretize_one("extends-spec") + extendee = spack.concretize.concretize_one("extendee") assert extender.dependencies assert extender.package.extends(extendee) @@ -206,7 +207,7 @@ def test_repo(_create_test_repo, monkeypatch, mock_stage): def test_redistribute_directive(test_repo, spec_str, distribute_src, distribute_bin): spec = spack.spec.Spec(spec_str) assert spec.package_class.redistribute_source(spec) == distribute_src - concretized_spec = spec.concretized() + concretized_spec = spack.concretize.concretize_one(spec) assert concretized_spec.package.redistribute_binary == distribute_bin diff --git a/lib/spack/spack/test/directory_layout.py b/lib/spack/spack/test/directory_layout.py index 81aafc297bb..533700de9d7 100644 --- a/lib/spack/spack/test/directory_layout.py +++ b/lib/spack/spack/test/directory_layout.py @@ -13,6 +13,7 @@ from llnl.path import path_to_os_path +import spack.concretize import spack.hash_types import spack.paths import spack.repo @@ -59,7 +60,7 @@ def test_yaml_directory_layout_parameters(tmpdir, default_mock_concretization): assert package7 == path_package7 # Test separation of architecture or namespace - spec2 = Spec("libelf").concretized() + spec2 = spack.concretize.concretize_one("libelf") arch_scheme = ( "{architecture.platform}/{architecture.target}/{architecture.os}/{name}/{version}/{hash:7}" @@ -97,7 +98,7 @@ def test_read_and_write_spec(temporary_store, config, mock_packages): # If a spec fails to concretize, just skip it. If it is a # real error, it will be caught by concretization tests. try: - spec = spack.spec.Spec(name).concretized() + spec = spack.concretize.concretize_one(name) except Exception: continue @@ -136,7 +137,7 @@ def test_read_and_write_spec(temporary_store, config, mock_packages): assert norm.eq_dag(spec_from_file) # TODO: revise this when build deps are in dag_hash - conc = read_separately.concretized().copy(deps=stored_deptypes) + conc = spack.concretize.concretize_one(read_separately).copy(deps=stored_deptypes) assert conc == spec_from_file assert conc.eq_dag(spec_from_file) @@ -172,12 +173,10 @@ def test_handle_unknown_package(temporary_store, config, mock_packages, tmp_path # Create all the packages that are not in mock. installed_specs = {} for pkg_name in packages: - spec = spack.spec.Spec(pkg_name) - # If a spec fails to concretize, just skip it. If it is a # real error, it will be caught by concretization tests. try: - spec.concretize() + spec = spack.concretize.concretize_one(pkg_name) except Exception: continue @@ -209,7 +208,7 @@ def test_find(temporary_store, config, mock_packages): if name.startswith("external"): # External package tests cannot be installed continue - spec = spack.spec.Spec(name).concretized() + spec = spack.concretize.concretize_one(name) installed_specs[spec.name] = spec layout.create_install_directory(spec) diff --git a/lib/spack/spack/test/flag_handlers.py b/lib/spack/spack/test/flag_handlers.py index 8fbd0e0184c..796b351ee3c 100644 --- a/lib/spack/spack/test/flag_handlers.py +++ b/lib/spack/spack/test/flag_handlers.py @@ -7,7 +7,7 @@ import pytest import spack.build_environment -import spack.spec +import spack.concretize from spack.package import build_system_flags, env_flags, inject_flags @@ -30,10 +30,10 @@ def add_o3_to_build_system_cflags(pkg, name, flags): class TestFlagHandlers: def test_no_build_system_flags(self, temp_env): # Test that both autotools and cmake work getting no build_system flags - s1 = spack.spec.Spec("cmake-client").concretized() + s1 = spack.concretize.concretize_one("cmake-client") spack.build_environment.setup_package(s1.package, False) - s2 = spack.spec.Spec("patchelf").concretized() + s2 = spack.concretize.concretize_one("patchelf") spack.build_environment.setup_package(s2.package, False) # Use cppflags as a canary @@ -43,28 +43,28 @@ def test_no_build_system_flags(self, temp_env): def test_unbound_method(self, temp_env): # Other tests test flag_handlers set as bound methods and functions. # This tests an unbound method in python2 (no change in python3). - s = spack.spec.Spec("mpileaks cppflags=-g").concretized() + s = spack.concretize.concretize_one("mpileaks cppflags=-g") s.package.flag_handler = s.package.__class__.inject_flags spack.build_environment.setup_package(s.package, False) assert os.environ["SPACK_CPPFLAGS"] == "-g" assert "CPPFLAGS" not in os.environ def test_inject_flags(self, temp_env): - s = spack.spec.Spec("mpileaks cppflags=-g").concretized() + s = spack.concretize.concretize_one("mpileaks cppflags=-g") s.package.flag_handler = inject_flags spack.build_environment.setup_package(s.package, False) assert os.environ["SPACK_CPPFLAGS"] == "-g" assert "CPPFLAGS" not in os.environ def test_env_flags(self, temp_env): - s = spack.spec.Spec("mpileaks cppflags=-g").concretized() + s = spack.concretize.concretize_one("mpileaks cppflags=-g") s.package.flag_handler = env_flags spack.build_environment.setup_package(s.package, False) assert os.environ["CPPFLAGS"] == "-g" assert "SPACK_CPPFLAGS" not in os.environ def test_build_system_flags_cmake(self, temp_env): - s = spack.spec.Spec("cmake-client cppflags=-g").concretized() + s = spack.concretize.concretize_one("cmake-client cppflags=-g") s.package.flag_handler = build_system_flags spack.build_environment.setup_package(s.package, False) assert "SPACK_CPPFLAGS" not in os.environ @@ -76,7 +76,7 @@ def test_build_system_flags_cmake(self, temp_env): } def test_build_system_flags_autotools(self, temp_env): - s = spack.spec.Spec("patchelf cppflags=-g").concretized() + s = spack.concretize.concretize_one("patchelf cppflags=-g") s.package.flag_handler = build_system_flags spack.build_environment.setup_package(s.package, False) assert "SPACK_CPPFLAGS" not in os.environ @@ -85,7 +85,7 @@ def test_build_system_flags_autotools(self, temp_env): def test_build_system_flags_not_implemented(self, temp_env): """Test the command line flags method raises a NotImplementedError""" - s = spack.spec.Spec("mpileaks cppflags=-g").concretized() + s = spack.concretize.concretize_one("mpileaks cppflags=-g") s.package.flag_handler = build_system_flags try: spack.build_environment.setup_package(s.package, False) @@ -94,7 +94,7 @@ def test_build_system_flags_not_implemented(self, temp_env): assert True def test_add_build_system_flags_autotools(self, temp_env): - s = spack.spec.Spec("patchelf cppflags=-g").concretized() + s = spack.concretize.concretize_one("patchelf cppflags=-g") s.package.flag_handler = add_o3_to_build_system_cflags spack.build_environment.setup_package(s.package, False) assert "-g" in os.environ["SPACK_CPPFLAGS"] @@ -102,7 +102,7 @@ def test_add_build_system_flags_autotools(self, temp_env): assert s.package.configure_flag_args == ["CFLAGS=-O3"] def test_add_build_system_flags_cmake(self, temp_env): - s = spack.spec.Spec("cmake-client cppflags=-g").concretized() + s = spack.concretize.concretize_one("cmake-client cppflags=-g") s.package.flag_handler = add_o3_to_build_system_cflags spack.build_environment.setup_package(s.package, False) assert "-g" in os.environ["SPACK_CPPFLAGS"] @@ -110,7 +110,7 @@ def test_add_build_system_flags_cmake(self, temp_env): assert s.package.cmake_flag_args == ["-DCMAKE_C_FLAGS=-O3"] def test_ld_flags_cmake(self, temp_env): - s = spack.spec.Spec("cmake-client ldflags=-mthreads").concretized() + s = spack.concretize.concretize_one("cmake-client ldflags=-mthreads") s.package.flag_handler = build_system_flags spack.build_environment.setup_package(s.package, False) assert "SPACK_LDFLAGS" not in os.environ @@ -122,7 +122,7 @@ def test_ld_flags_cmake(self, temp_env): } def test_ld_libs_cmake(self, temp_env): - s = spack.spec.Spec("cmake-client ldlibs=-lfoo").concretized() + s = spack.concretize.concretize_one("cmake-client ldlibs=-lfoo") s.package.flag_handler = build_system_flags spack.build_environment.setup_package(s.package, False) assert "SPACK_LDLIBS" not in os.environ @@ -138,7 +138,7 @@ def test_flag_handler(self, name, flags): flags.append("-foo") return (flags, None, None) - s = spack.spec.Spec("cmake-client").concretized() + s = spack.concretize.concretize_one("cmake-client") s.package.flag_handler = test_flag_handler spack.build_environment.setup_package(s.package, False) diff --git a/lib/spack/spack/test/git_fetch.py b/lib/spack/spack/test/git_fetch.py index 7118340cb59..8ee447aca3e 100644 --- a/lib/spack/spack/test/git_fetch.py +++ b/lib/spack/spack/test/git_fetch.py @@ -10,6 +10,7 @@ from llnl.util.filesystem import mkdirp, touch, working_dir +import spack.concretize import spack.config import spack.error import spack.fetch_strategy @@ -185,8 +186,9 @@ def test_adhoc_version_submodules( monkeypatch.setitem(pkg_class.versions, Version("git"), t.args) monkeypatch.setattr(pkg_class, "git", "file://%s" % mock_git_repository.path, raising=False) - spec = Spec("git-test@{0}".format(mock_git_repository.unversioned_commit)) - spec.concretize() + spec = spack.concretize.concretize_one( + Spec("git-test@{0}".format(mock_git_repository.unversioned_commit)) + ) spec.package.do_stage() collected_fnames = set() for root, dirs, files in os.walk(spec.package.stage.source_path): diff --git a/lib/spack/spack/test/graph.py b/lib/spack/spack/test/graph.py index 2708c320b91..1de96712234 100644 --- a/lib/spack/spack/test/graph.py +++ b/lib/spack/spack/test/graph.py @@ -3,8 +3,8 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) import io +import spack.concretize import spack.graph -import spack.spec def test_dynamic_dot_graph_mpileaks(default_mock_concretization): @@ -38,7 +38,7 @@ def test_dynamic_dot_graph_mpileaks(default_mock_concretization): def test_ascii_graph_mpileaks(config, mock_packages, monkeypatch): monkeypatch.setattr(spack.graph.AsciiGraph, "_node_label", lambda self, node: node.name) - s = spack.spec.Spec("mpileaks").concretized() + s = spack.concretize.concretize_one("mpileaks") stream = io.StringIO() graph = spack.graph.AsciiGraph() diff --git a/lib/spack/spack/test/hg_fetch.py b/lib/spack/spack/test/hg_fetch.py index 59baaf8fa86..9e7145a547b 100644 --- a/lib/spack/spack/test/hg_fetch.py +++ b/lib/spack/spack/test/hg_fetch.py @@ -8,9 +8,9 @@ from llnl.util.filesystem import mkdirp, touch, working_dir +import spack.concretize import spack.config from spack.fetch_strategy import HgFetchStrategy -from spack.spec import Spec from spack.stage import Stage from spack.util.executable import which from spack.version import Version @@ -40,7 +40,7 @@ def test_fetch(type_of_test, secure, mock_hg_repository, config, mutable_mock_re h = mock_hg_repository.hash # Construct the package under test - s = Spec("hg-test").concretized() + s = spack.concretize.concretize_one("hg-test") monkeypatch.setitem(s.package.versions, Version("hg"), t.args) # Enter the stage directory and check some properties diff --git a/lib/spack/spack/test/install.py b/lib/spack/spack/test/install.py index 05d5144fae5..f299e2fc277 100644 --- a/lib/spack/spack/test/install.py +++ b/lib/spack/spack/test/install.py @@ -11,6 +11,7 @@ import llnl.util.filesystem as fs import spack.build_environment +import spack.concretize import spack.config import spack.database import spack.error @@ -41,7 +42,7 @@ def find_nothing(*args): def test_install_and_uninstall(install_mockery, mock_fetch, monkeypatch): - spec = Spec("trivial-install-test-package").concretized() + spec = spack.concretize.concretize_one("trivial-install-test-package") PackageInstaller([spec.package], explicit=True).install() assert spec.installed @@ -53,7 +54,7 @@ def test_install_and_uninstall(install_mockery, mock_fetch, monkeypatch): @pytest.mark.regression("11870") def test_uninstall_non_existing_package(install_mockery, mock_fetch, monkeypatch): """Ensure that we can uninstall a package that has been deleted from the repo""" - spec = Spec("trivial-install-test-package").concretized() + spec = spack.concretize.concretize_one("trivial-install-test-package") PackageInstaller([spec.package], explicit=True).install() assert spec.installed @@ -71,8 +72,7 @@ def test_uninstall_non_existing_package(install_mockery, mock_fetch, monkeypatch def test_pkg_attributes(install_mockery, mock_fetch, monkeypatch): # Get a basic concrete spec for the dummy package. - spec = Spec("attributes-foo-app ^attributes-foo") - spec.concretize() + spec = spack.concretize.concretize_one("attributes-foo-app ^attributes-foo") assert spec.concrete pkg = spec.package @@ -127,7 +127,7 @@ def remove_prefix(self): def test_partial_install_delete_prefix_and_stage(install_mockery, mock_fetch, working_env): - s = Spec("canfail").concretized() + s = spack.concretize.concretize_one("canfail") instance_rm_prefix = s.package.remove_prefix @@ -157,7 +157,7 @@ def test_failing_overwrite_install_should_keep_previous_installation( the original install prefix instead of cleaning it. """ # Do a successful install - s = Spec("canfail").concretized() + s = spack.concretize.concretize_one("canfail") s.package.set_install_succeed() # Do a failing overwrite install @@ -173,13 +173,11 @@ def test_failing_overwrite_install_should_keep_previous_installation( def test_dont_add_patches_to_installed_package(install_mockery, mock_fetch, monkeypatch): - dependency = Spec("dependency-install") - dependency.concretize() + dependency = spack.concretize.concretize_one("dependency-install") PackageInstaller([dependency.package], explicit=True).install() dependency_hash = dependency.dag_hash() - dependent = Spec("dependent-install ^/" + dependency_hash) - dependent.concretize() + dependent = spack.concretize.concretize_one("dependent-install ^/" + dependency_hash) monkeypatch.setitem( dependency.package.patches, @@ -191,20 +189,18 @@ def test_dont_add_patches_to_installed_package(install_mockery, mock_fetch, monk def test_installed_dependency_request_conflicts(install_mockery, mock_fetch, mutable_mock_repo): - dependency = Spec("dependency-install") - dependency.concretize() + dependency = spack.concretize.concretize_one("dependency-install") PackageInstaller([dependency.package], explicit=True).install() dependency_hash = dependency.dag_hash() dependent = Spec("conflicting-dependent ^/" + dependency_hash) with pytest.raises(spack.error.UnsatisfiableSpecError): - dependent.concretize() + spack.concretize.concretize_one(dependent) def test_install_dependency_symlinks_pkg(install_mockery, mock_fetch, mutable_mock_repo): """Test dependency flattening/symlinks mock package.""" - spec = Spec("flatten-deps") - spec.concretize() + spec = spack.concretize.concretize_one("flatten-deps") pkg = spec.package PackageInstaller([pkg], explicit=True).install() @@ -215,7 +211,7 @@ def test_install_dependency_symlinks_pkg(install_mockery, mock_fetch, mutable_mo def test_install_times(install_mockery, mock_fetch, mutable_mock_repo): """Test install times added.""" - spec = Spec("dev-build-test-install-phases").concretized() + spec = spack.concretize.concretize_one("dev-build-test-install-phases") PackageInstaller([spec.package], explicit=True).install() # Ensure dependency directory exists after the installation. @@ -236,8 +232,7 @@ def test_flatten_deps(install_mockery, mock_fetch, mutable_mock_repo): """Explicitly test the flattening code for coverage purposes.""" # Unfortunately, executing the 'flatten-deps' spec's installation does # not affect code coverage results, so be explicit here. - spec = Spec("dependent-install") - spec.concretize() + spec = spack.concretize.concretize_one("dependent-install") pkg = spec.package PackageInstaller([pkg], explicit=True).install() @@ -272,7 +267,7 @@ def install_upstream(tmpdir_factory, gen_mock_layout, install_mockery): def _install_upstream(*specs): for spec_str in specs: - prepared_db.add(Spec(spec_str).concretized()) + prepared_db.add(spack.concretize.concretize_one(spec_str)) downstream_root = str(tmpdir_factory.mktemp("mock_downstream_db_root")) return downstream_root, upstream_layout @@ -285,8 +280,7 @@ def test_installed_upstream_external(install_upstream, mock_fetch): """ store_root, _ = install_upstream("externaltool") with spack.store.use_store(store_root): - dependent = Spec("externaltest") - dependent.concretize() + dependent = spack.concretize.concretize_one("externaltest") new_dependency = dependent["externaltool"] assert new_dependency.external @@ -304,8 +298,8 @@ def test_installed_upstream(install_upstream, mock_fetch): """ store_root, upstream_layout = install_upstream("dependency-install") with spack.store.use_store(store_root): - dependency = Spec("dependency-install").concretized() - dependent = Spec("dependent-install").concretized() + dependency = spack.concretize.concretize_one("dependency-install") + dependent = spack.concretize.concretize_one("dependent-install") new_dependency = dependent["dependency-install"] assert new_dependency.installed_upstream @@ -319,7 +313,7 @@ def test_installed_upstream(install_upstream, mock_fetch): @pytest.mark.disable_clean_stage_check def test_partial_install_keep_prefix(install_mockery, mock_fetch, monkeypatch, working_env): - s = Spec("canfail").concretized() + s = spack.concretize.concretize_one("canfail") # If remove_prefix is called at any point in this test, that is an error monkeypatch.setattr(spack.package_base.PackageBase, "remove_prefix", mock_remove_prefix) @@ -336,7 +330,7 @@ def test_partial_install_keep_prefix(install_mockery, mock_fetch, monkeypatch, w def test_second_install_no_overwrite_first(install_mockery, mock_fetch, monkeypatch): - s = Spec("canfail").concretized() + s = spack.concretize.concretize_one("canfail") monkeypatch.setattr(spack.package_base.PackageBase, "remove_prefix", mock_remove_prefix) s.package.set_install_succeed() @@ -356,8 +350,8 @@ def test_install_prefix_collision_fails(config, mock_fetch, mock_packages, tmpdi projections = {"projections": {"all": "one-prefix-per-package-{name}"}} with spack.store.use_store(str(tmpdir), extra_data=projections): with spack.config.override("config:checksum", False): - pkg_a = Spec("libelf@0.8.13").concretized().package - pkg_b = Spec("libelf@0.8.12").concretized().package + pkg_a = spack.concretize.concretize_one("libelf@0.8.13").package + pkg_b = spack.concretize.concretize_one("libelf@0.8.12").package PackageInstaller([pkg_a], explicit=True, fake=True).install() with pytest.raises(InstallError, match="Install prefix collision"): @@ -365,14 +359,14 @@ def test_install_prefix_collision_fails(config, mock_fetch, mock_packages, tmpdi def test_store(install_mockery, mock_fetch): - spec = Spec("cmake-client").concretized() + spec = spack.concretize.concretize_one("cmake-client") pkg = spec.package PackageInstaller([pkg], fake=True, explicit=True).install() @pytest.mark.disable_clean_stage_check def test_failing_build(install_mockery, mock_fetch, capfd): - spec = Spec("failing-build").concretized() + spec = spack.concretize.concretize_one("failing-build") pkg = spec.package with pytest.raises(spack.build_environment.ChildError, match="Expected failure"): @@ -387,8 +381,7 @@ def test_uninstall_by_spec_errors(mutable_database): """Test exceptional cases with the uninstall command.""" # Try to uninstall a spec that has not been installed - spec = Spec("dependent-install") - spec.concretize() + spec = spack.concretize.concretize_one("dependent-install") with pytest.raises(InstallError, match="is not installed"): PackageBase.uninstall_by_spec(spec) @@ -401,7 +394,7 @@ def test_uninstall_by_spec_errors(mutable_database): @pytest.mark.disable_clean_stage_check def test_nosource_pkg_install(install_mockery, mock_fetch, mock_packages, capfd, ensure_debug): """Test install phases with the nosource package.""" - spec = Spec("nosource").concretized() + spec = spack.concretize.concretize_one("nosource") pkg = spec.package # Make sure install works even though there is no associated code. @@ -418,7 +411,7 @@ def test_nosource_bundle_pkg_install( install_mockery, mock_fetch, mock_packages, capfd, ensure_debug ): """Test install phases with the nosource-bundle package.""" - spec = Spec("nosource-bundle").concretized() + spec = spack.concretize.concretize_one("nosource-bundle") pkg = spec.package # Make sure install works even though there is no associated code. @@ -432,7 +425,7 @@ def test_nosource_bundle_pkg_install( def test_nosource_pkg_install_post_install(install_mockery, mock_fetch, mock_packages): """Test install phases with the nosource package with post-install.""" - spec = Spec("nosource-install").concretized() + spec = spack.concretize.concretize_one("nosource-install") pkg = spec.package # Make sure both the install and post-install package methods work. @@ -449,14 +442,14 @@ def test_nosource_pkg_install_post_install(install_mockery, mock_fetch, mock_pac def test_pkg_build_paths(install_mockery): # Get a basic concrete spec for the trivial install package. - spec = Spec("trivial-install-test-package").concretized() + spec = spack.concretize.concretize_one("trivial-install-test-package") assert spec.package.log_path.endswith(_spack_build_logfile) assert spec.package.env_path.endswith(_spack_build_envfile) def test_pkg_install_paths(install_mockery): # Get a basic concrete spec for the trivial install package. - spec = Spec("trivial-install-test-package").concretized() + spec = spack.concretize.concretize_one("trivial-install-test-package") log_path = os.path.join(spec.prefix, ".spack", _spack_build_logfile + ".gz") assert spec.package.install_log_path == log_path @@ -493,7 +486,7 @@ def test_pkg_install_paths(install_mockery): def test_log_install_without_build_files(install_mockery): """Test the installer log function when no build files are present.""" # Get a basic concrete spec for the trivial install package. - spec = Spec("trivial-install-test-package").concretized() + spec = spack.concretize.concretize_one("trivial-install-test-package") # Attempt installing log without the build log file with pytest.raises(IOError, match="No such file or directory"): @@ -515,7 +508,7 @@ def _install(src, dest): monkeypatch.setattr(fs, "install", _install) - spec = Spec("trivial-install-test-package").concretized() + spec = spack.concretize.concretize_one("trivial-install-test-package") # Set up mock build files and try again to include archive failure log_path = spec.package.log_path @@ -587,7 +580,7 @@ def test_empty_install_sanity_check_prefix( monkeypatch, install_mockery, mock_fetch, mock_packages ): """Test empty install triggers sanity_check_prefix.""" - spec = Spec("failing-empty-install").concretized() + spec = spack.concretize.concretize_one("failing-empty-install") with pytest.raises(spack.build_environment.ChildError, match="Nothing was installed"): PackageInstaller([spec.package], explicit=True).install() @@ -599,7 +592,7 @@ def test_install_from_binary_with_missing_patch_succeeds( pushing the package to a binary cache, installation from that binary cache shouldn't error out because of the missing patch.""" # Create a spec s with non-existing patches - s = Spec("trivial-install-test-package").concretized() + s = spack.concretize.concretize_one("trivial-install-test-package") patches = ["a" * 64] s_dict = s.to_dict() s_dict["spec"]["nodes"][0]["patches"] = patches diff --git a/lib/spack/spack/test/installer.py b/lib/spack/spack/test/installer.py index af9ba26fef6..776d27873e9 100644 --- a/lib/spack/spack/test/installer.py +++ b/lib/spack/spack/test/installer.py @@ -16,6 +16,7 @@ import llnl.util.tty as tty import spack.binary_distribution +import spack.concretize import spack.database import spack.deptypes as dt import spack.error @@ -81,7 +82,7 @@ def create_installer( ) -> inst.PackageInstaller: """Create an installer instance for a list of specs or package names that will be concretized.""" - _specs = [spack.spec.Spec(s).concretized() if isinstance(s, str) else s for s in specs] + _specs = [spack.concretize.concretize_one(s) if isinstance(s, str) else s for s in specs] _install_args = {} if install_args is None else install_args return inst.PackageInstaller([spec.package for spec in _specs], **_install_args) @@ -96,8 +97,7 @@ def test_hms(sec, result): def test_get_dependent_ids(install_mockery, mock_packages): # Concretize the parent package, which handle dependency too - spec = spack.spec.Spec("pkg-a") - spec.concretize() + spec = spack.concretize.concretize_one("pkg-a") assert spec.concrete pkg_id = inst.package_id(spec) @@ -133,8 +133,7 @@ def test_install_msg(monkeypatch): def test_install_from_cache_errors(install_mockery): """Test to ensure cover install from cache errors.""" - spec = spack.spec.Spec("trivial-install-test-package") - spec.concretize() + spec = spack.concretize.concretize_one("trivial-install-test-package") assert spec.concrete # Check with cache-only @@ -153,8 +152,7 @@ def test_install_from_cache_errors(install_mockery): def test_install_from_cache_ok(install_mockery, monkeypatch): """Test to ensure cover _install_from_cache to the return.""" - spec = spack.spec.Spec("trivial-install-test-package") - spec.concretize() + spec = spack.concretize.concretize_one("trivial-install-test-package") monkeypatch.setattr(inst, "_try_install_from_binary_cache", _true) monkeypatch.setattr(spack.hooks, "post_install", _noop) @@ -163,8 +161,7 @@ def test_install_from_cache_ok(install_mockery, monkeypatch): def test_process_external_package_module(install_mockery, monkeypatch, capfd): """Test to simply cover the external module message path.""" - spec = spack.spec.Spec("trivial-install-test-package") - spec.concretize() + spec = spack.concretize.concretize_one("trivial-install-test-package") assert spec.concrete # Ensure take the external module path WITHOUT any changes to the database @@ -191,7 +188,7 @@ def _spec(spec, unsigned=False, mirrors_for_spec=None): # Skip database updates monkeypatch.setattr(spack.database.Database, "add", _noop) - spec = spack.spec.Spec("pkg-a").concretized() + spec = spack.concretize.concretize_one("pkg-a") assert inst._process_binary_cache_tarball(spec.package, explicit=False, unsigned=False) out = capfd.readouterr()[0] @@ -201,8 +198,7 @@ def _spec(spec, unsigned=False, mirrors_for_spec=None): def test_try_install_from_binary_cache(install_mockery, mock_packages, monkeypatch): """Test return false when no match exists in the mirror""" - spec = spack.spec.Spec("mpich") - spec.concretize() + spec = spack.concretize.concretize_one("mpich") result = inst._try_install_from_binary_cache(spec.package, False, False) assert not result @@ -274,7 +270,7 @@ def _mock_installed(self): def test_check_before_phase_error(install_mockery): - s = spack.spec.Spec("trivial-install-test-package").concretized() + s = spack.concretize.concretize_one("trivial-install-test-package") s.package.stop_before_phase = "beforephase" with pytest.raises(inst.BadInstallPhase) as exc_info: inst._check_last_phase(s.package) @@ -285,7 +281,7 @@ def test_check_before_phase_error(install_mockery): def test_check_last_phase_error(install_mockery): - s = spack.spec.Spec("trivial-install-test-package").concretized() + s = spack.concretize.concretize_one("trivial-install-test-package") s.package.stop_before_phase = None s.package.last_phase = "badphase" with pytest.raises(inst.BadInstallPhase) as exc_info: @@ -420,15 +416,13 @@ def test_package_id_err(install_mockery): def test_package_id_ok(install_mockery): - spec = spack.spec.Spec("trivial-install-test-package") - spec.concretize() + spec = spack.concretize.concretize_one("trivial-install-test-package") assert spec.concrete assert spec.name in inst.package_id(spec) def test_fake_install(install_mockery): - spec = spack.spec.Spec("trivial-install-test-package") - spec.concretize() + spec = spack.concretize.concretize_one("trivial-install-test-package") assert spec.concrete pkg = spec.package @@ -440,7 +434,7 @@ def test_dump_packages_deps_ok(install_mockery, tmpdir, mock_packages): """Test happy path for dump_packages with dependencies.""" spec_name = "simple-inheritance" - spec = spack.spec.Spec(spec_name).concretized() + spec = spack.concretize.concretize_one(spec_name) inst.dump_packages(spec, str(tmpdir)) repo = mock_packages.repos[0] @@ -471,7 +465,7 @@ def _repoerr(repo, name): # the try-except block monkeypatch.setattr(spack.store.STORE.layout, "build_packages_path", bpp_path) - spec = spack.spec.Spec("simple-inheritance").concretized() + spec = spack.concretize.concretize_one("simple-inheritance") path = str(tmpdir) # The call to install_tree will raise the exception since not mocking @@ -581,7 +575,7 @@ def test_check_deps_status_install_failure(install_mockery): """Tests that checking the dependency status on a request to install 'a' fails, if we mark the dependency as failed. """ - s = spack.spec.Spec("pkg-a").concretized() + s = spack.concretize.concretize_one("pkg-a") for dep in s.traverse(root=False): spack.store.STORE.failure_tracker.mark(dep) @@ -654,8 +648,8 @@ def test_installer_init_requests(install_mockery): @pytest.mark.parametrize("transitive", [True, False]) def test_install_spliced(install_mockery, mock_fetch, monkeypatch, capsys, transitive): """Test installing a spliced spec""" - spec = spack.spec.Spec("splice-t").concretized() - dep = spack.spec.Spec("splice-h+foo").concretized() + spec = spack.concretize.concretize_one("splice-t") + dep = spack.concretize.concretize_one("splice-h+foo") # Do the splice. out = spec.splice(dep, transitive) @@ -669,8 +663,8 @@ def test_install_spliced(install_mockery, mock_fetch, monkeypatch, capsys, trans @pytest.mark.parametrize("transitive", [True, False]) def test_install_spliced_build_spec_installed(install_mockery, capfd, mock_fetch, transitive): """Test installing a spliced spec with the build spec already installed""" - spec = spack.spec.Spec("splice-t").concretized() - dep = spack.spec.Spec("splice-h+foo").concretized() + spec = spack.concretize.concretize_one("splice-t") + dep = spack.concretize.concretize_one("splice-h+foo") # Do the splice. out = spec.splice(dep, transitive) @@ -696,8 +690,8 @@ def test_install_splice_root_from_binary( ): """Test installing a spliced spec with the root available in binary cache""" # Test splicing and rewiring a spec with the same name, different hash. - original_spec = spack.spec.Spec(root_str).concretized() - spec_to_splice = spack.spec.Spec("splice-h+foo").concretized() + original_spec = spack.concretize.concretize_one(root_str) + spec_to_splice = spack.concretize.concretize_one("splice-h+foo") PackageInstaller([original_spec.package, spec_to_splice.package]).install() @@ -853,7 +847,7 @@ def _chgrp(path, group, follow_symlinks=True): monkeypatch.setattr(fs, "chgrp", _chgrp) build_task = create_build_task( - spack.spec.Spec("trivial-install-test-package").concretized().package + spack.concretize.concretize_one("trivial-install-test-package").package ) spec = build_task.request.pkg.spec @@ -1024,7 +1018,8 @@ def test_install_fail_multi(install_mockery, mock_fetch, monkeypatch): def test_install_fail_fast_on_detect(install_mockery, monkeypatch, capsys): """Test fail_fast install when an install failure is detected.""" - b, c = spack.spec.Spec("pkg-b").concretized(), spack.spec.Spec("pkg-c").concretized() + b = spack.concretize.concretize_one("pkg-b") + c = spack.concretize.concretize_one("pkg-c") b_id, c_id = inst.package_id(b), inst.package_id(c) installer = create_installer([b, c], {"fail_fast": True}) @@ -1093,7 +1088,7 @@ def _requeued(installer, task, install_status): def test_install_lock_installed_requeue(install_mockery, monkeypatch, capfd): """Cover basic install handling for installed package.""" - b = spack.spec.Spec("pkg-b").concretized() + b = spack.concretize.concretize_one("pkg-b") b_pkg_id = inst.package_id(b) installer = create_installer([b]) @@ -1279,7 +1274,7 @@ def test_term_status_line(): @pytest.mark.parametrize("explicit", [True, False]) def test_single_external_implicit_install(install_mockery, explicit): pkg = "trivial-install-test-package" - s = spack.spec.Spec(pkg).concretized() + s = spack.concretize.concretize_one(pkg) s.external_path = "/usr" args = {"explicit": [s.dag_hash()] if explicit else []} create_installer([s], args).install() @@ -1288,7 +1283,7 @@ def test_single_external_implicit_install(install_mockery, explicit): def test_overwrite_install_does_install_build_deps(install_mockery, mock_fetch): """When overwrite installing something from sources, build deps should be installed.""" - s = spack.spec.Spec("dtrun3").concretized() + s = spack.concretize.concretize_one("dtrun3") create_installer([s]).install() # Verify there is a pure build dep @@ -1310,7 +1305,7 @@ def test_overwrite_install_does_install_build_deps(install_mockery, mock_fetch): def test_print_install_test_log_skipped(install_mockery, mock_packages, capfd, run_tests): """Confirm printing of install log skipped if not run/no failures.""" name = "trivial-install-test-package" - s = spack.spec.Spec(name).concretized() + s = spack.concretize.concretize_one(name) pkg = s.package pkg.run_tests = run_tests @@ -1324,7 +1319,7 @@ def test_print_install_test_log_failures( ): """Confirm expected outputs when there are test failures.""" name = "trivial-install-test-package" - s = spack.spec.Spec(name).concretized() + s = spack.concretize.concretize_one(name) pkg = s.package # Missing test log is an error diff --git a/lib/spack/spack/test/mirror.py b/lib/spack/spack/test/mirror.py index db162ba369b..a0c6458719d 100644 --- a/lib/spack/spack/test/mirror.py +++ b/lib/spack/spack/test/mirror.py @@ -11,6 +11,7 @@ from llnl.util.symlink import resolve_link_target_relative_to_the_link import spack.caches +import spack.concretize import spack.config import spack.fetch_strategy import spack.mirrors.layout @@ -43,7 +44,7 @@ def set_up_package(name, repository, url_attr): 2. Point the package's version args at that repo. """ # Set up packages to point at mock repos. - s = Spec(name).concretized() + s = spack.concretize.concretize_one(name) repos[name] = repository # change the fetch args of the first (only) version. @@ -60,7 +61,7 @@ def check_mirror(): mirrors = {"spack-mirror-test": url_util.path_to_file_url(mirror_root)} with spack.config.override("mirrors", mirrors): with spack.config.override("config:checksum", False): - specs = [Spec(x).concretized() for x in repos] + specs = [spack.concretize.concretize_one(x) for x in repos] spack.mirrors.utils.create(mirror_root, specs) # Stage directory exists @@ -77,7 +78,7 @@ def check_mirror(): # Now try to fetch each package. for name, mock_repo in repos.items(): - spec = Spec(name).concretized() + spec = spack.concretize.concretize_one(name) pkg = spec.package with spack.config.override("config:checksum", False): @@ -212,13 +213,15 @@ def test_invalid_json_mirror_collection(invalid_json, error_message): def test_mirror_archive_paths_no_version(mock_packages, mock_archive): - spec = Spec("trivial-install-test-package@=nonexistingversion").concretized() + spec = spack.concretize.concretize_one( + Spec("trivial-install-test-package@=nonexistingversion") + ) fetcher = spack.fetch_strategy.URLFetchStrategy(url=mock_archive.url) spack.mirrors.layout.default_mirror_layout(fetcher, "per-package-ref", spec) def test_mirror_with_url_patches(mock_packages, monkeypatch): - spec = Spec("patch-several-dependencies").concretized() + spec = spack.concretize.concretize_one("patch-several-dependencies") files_cached_in_mirror = set() def record_store(_class, fetcher, relative_dst, cosmetic_path=None): diff --git a/lib/spack/spack/test/modules/common.py b/lib/spack/spack/test/modules/common.py index 423200ef50b..76f64a22f52 100644 --- a/lib/spack/spack/test/modules/common.py +++ b/lib/spack/spack/test/modules/common.py @@ -9,6 +9,7 @@ from llnl.util.symlink import readlink import spack.cmd.modules +import spack.concretize import spack.config import spack.error import spack.modules @@ -17,10 +18,8 @@ import spack.package_base import spack.package_prefs import spack.repo -import spack.spec from spack.installer import PackageInstaller from spack.modules.common import UpstreamModuleIndex -from spack.spec import Spec pytestmark = [ pytest.mark.not_on_windows("does not run on windows"), @@ -60,7 +59,7 @@ def mock_package_perms(monkeypatch): def test_modules_written_with_proper_permissions( mock_module_filename, mock_package_perms, mock_packages, config ): - spec = spack.spec.Spec("mpileaks").concretized() + spec = spack.concretize.concretize_one("mpileaks") # The code tested is common to all module types, but has to be tested from # one. Tcl picked at random @@ -74,7 +73,7 @@ def test_modules_written_with_proper_permissions( def test_modules_default_symlink( module_type, mock_packages, mock_module_filename, mock_module_defaults, config ): - spec = spack.spec.Spec("mpileaks@2.3").concretized() + spec = spack.concretize.concretize_one("mpileaks@2.3") mock_module_defaults(spec.format("{name}{@version}"), True) generator_cls = spack.modules.module_types[module_type] @@ -180,7 +179,7 @@ def test_get_module_upstream(): @pytest.mark.regression("14347") def test_load_installed_package_not_in_repo(install_mockery, mock_fetch, monkeypatch): """Test that installed packages that have been removed are still loadable""" - spec = Spec("trivial-install-test-package").concretized() + spec = spack.concretize.concretize_one("trivial-install-test-package") PackageInstaller([spec.package], explicit=True).install() spack.modules.module_types["tcl"](spec, "default", True).write() diff --git a/lib/spack/spack/test/modules/conftest.py b/lib/spack/spack/test/modules/conftest.py index d4dbf342a6c..eb43d42489d 100644 --- a/lib/spack/spack/test/modules/conftest.py +++ b/lib/spack/spack/test/modules/conftest.py @@ -5,6 +5,7 @@ import pytest +import spack.concretize import spack.modules.lmod import spack.modules.tcl import spack.spec @@ -18,7 +19,7 @@ def modulefile_content(request): def _impl(spec_like, module_set_name="default", explicit=True): if isinstance(spec_like, str): spec_like = spack.spec.Spec(spec_like) - spec = spec_like.concretized() + spec = spack.concretize.concretize_one(spec_like) generator = writer_cls(spec, module_set_name, explicit) generator.write(overwrite=True) written_module = pathlib.Path(generator.layout.filename) @@ -35,7 +36,7 @@ def factory(request, mock_modules_root): writer_cls = getattr(request.module, "writer_cls") def _mock(spec_string, module_set_name="default", explicit=True): - spec = spack.spec.Spec(spec_string).concretized() + spec = spack.concretize.concretize_one(spec_string) return writer_cls(spec, module_set_name, explicit), spec return _mock diff --git a/lib/spack/spack/test/modules/lmod.py b/lib/spack/spack/test/modules/lmod.py index c90884573bf..5bd0d73cd15 100644 --- a/lib/spack/spack/test/modules/lmod.py +++ b/lib/spack/spack/test/modules/lmod.py @@ -8,6 +8,7 @@ import archspec.cpu +import spack.concretize import spack.config import spack.environment as ev import spack.main @@ -435,7 +436,7 @@ def test_modules_relative_to_view( module_configuration("with_view") install("--add", "cmake") - spec = spack.spec.Spec("cmake").concretized() + spec = spack.concretize.concretize_one("cmake") content = modulefile_content("cmake") expected = e.default_view.get_projection_for_spec(spec) @@ -455,7 +456,7 @@ def test_hide_implicits(self, module_configuration, temporary_store): """Tests the addition and removal of hide command in modulerc.""" module_configuration("hide_implicits") - spec = spack.spec.Spec("mpileaks@2.3").concretized() + spec = spack.concretize.concretize_one("mpileaks@2.3") # mpileaks is defined as implicit, thus hide command should appear in modulerc writer = writer_cls(spec, "default", False) @@ -507,8 +508,8 @@ def test_hide_implicits(self, module_configuration, temporary_store): # three versions of mpileaks are implicit writer = writer_cls(spec, "default", False) writer.write(overwrite=True) - spec_alt1 = spack.spec.Spec("mpileaks@2.2").concretized() - spec_alt2 = spack.spec.Spec("mpileaks@2.1").concretized() + spec_alt1 = spack.concretize.concretize_one("mpileaks@2.2") + spec_alt2 = spack.concretize.concretize_one("mpileaks@2.1") writer_alt1 = writer_cls(spec_alt1, "default", False) writer_alt1.write(overwrite=True) writer_alt2 = writer_cls(spec_alt2, "default", False) diff --git a/lib/spack/spack/test/modules/tcl.py b/lib/spack/spack/test/modules/tcl.py index 8cc6b25493b..ada1d789aae 100644 --- a/lib/spack/spack/test/modules/tcl.py +++ b/lib/spack/spack/test/modules/tcl.py @@ -8,9 +8,9 @@ import archspec.cpu +import spack.concretize import spack.modules.common import spack.modules.tcl -import spack.spec mpich_spec_string = "mpich@3.0.4" mpileaks_spec_string = "mpileaks" @@ -393,8 +393,7 @@ def test_setup_environment(self, modulefile_content, module_configuration): assert len([x for x in content if "setenv FOOBAR" in x]) == 1 assert len([x for x in content if "setenv FOOBAR {mpileaks}" in x]) == 1 - spec = spack.spec.Spec("mpileaks") - spec.concretize() + spec = spack.concretize.concretize_one("mpileaks") content = modulefile_content(spec["callpath"]) assert len([x for x in content if "setenv FOOBAR" in x]) == 1 @@ -468,14 +467,12 @@ def test_hide_implicits_with_arg(self, module_configuration): module_configuration("exclude_implicits") # mpileaks is defined as explicit with explicit argument set on writer - mpileaks_spec = spack.spec.Spec("mpileaks") - mpileaks_spec.concretize() + mpileaks_spec = spack.concretize.concretize_one("mpileaks") writer = writer_cls(mpileaks_spec, "default", True) assert not writer.conf.excluded # callpath is defined as implicit with explicit argument set on writer - callpath_spec = spack.spec.Spec("callpath") - callpath_spec.concretize() + callpath_spec = spack.concretize.concretize_one("callpath") writer = writer_cls(callpath_spec, "default", False) assert writer.conf.excluded @@ -510,7 +507,7 @@ def test_hide_implicits(self, module_configuration, temporary_store): """Tests the addition and removal of hide command in modulerc.""" module_configuration("hide_implicits") - spec = spack.spec.Spec("mpileaks@2.3").concretized() + spec = spack.concretize.concretize_one("mpileaks@2.3") # mpileaks is defined as implicit, thus hide command should appear in modulerc writer = writer_cls(spec, "default", False) @@ -557,8 +554,8 @@ def test_hide_implicits(self, module_configuration, temporary_store): # three versions of mpileaks are implicit writer = writer_cls(spec, "default", False) writer.write(overwrite=True) - spec_alt1 = spack.spec.Spec("mpileaks@2.2").concretized() - spec_alt2 = spack.spec.Spec("mpileaks@2.1").concretized() + spec_alt1 = spack.concretize.concretize_one("mpileaks@2.2") + spec_alt2 = spack.concretize.concretize_one("mpileaks@2.1") writer_alt1 = writer_cls(spec_alt1, "default", False) writer_alt1.write(overwrite=True) writer_alt2 = writer_cls(spec_alt2, "default", False) diff --git a/lib/spack/spack/test/multimethod.py b/lib/spack/spack/test/multimethod.py index 24408ad9bc2..a9996b3b625 100644 --- a/lib/spack/spack/test/multimethod.py +++ b/lib/spack/spack/test/multimethod.py @@ -6,9 +6,9 @@ import pytest +import spack.concretize import spack.config import spack.platforms -import spack.spec from spack.multimethod import NoSuchMethodError pytestmark = [ @@ -28,7 +28,7 @@ def pkg_name(request): def test_no_version_match(pkg_name): - spec = spack.spec.Spec(pkg_name + "@2.0").concretized() + spec = spack.concretize.concretize_one(pkg_name + "@2.0") with pytest.raises(NoSuchMethodError): spec.package.no_version_2() @@ -74,7 +74,7 @@ def test_multimethod_calls( with spack.config.override( "compilers", [compiler_factory(spec="apple-clang@9.1.0", operating_system="elcapitan")] ): - s = spack.spec.Spec(pkg_name + constraint_str).concretized() + s = spack.concretize.concretize_one(pkg_name + constraint_str) msg = f"Method {method_name} from {s} is giving a wrong result" assert getattr(s.package, method_name)() == expected_result, msg @@ -83,10 +83,10 @@ def test_target_match(pkg_name): platform = spack.platforms.host() targets = list(platform.targets.values()) for target in targets[:-1]: - s = spack.spec.Spec(pkg_name + " target=" + target.name).concretized() + s = spack.concretize.concretize_one(pkg_name + " target=" + target.name) assert s.package.different_by_target() == target.name - s = spack.spec.Spec(pkg_name + " target=" + targets[-1].name).concretized() + s = spack.concretize.concretize_one(pkg_name + " target=" + targets[-1].name) if len(targets) == 1: assert s.package.different_by_target() == targets[-1].name else: @@ -116,5 +116,5 @@ def test_target_match(pkg_name): ], ) def test_multimethod_calls_and_inheritance(spec_str, method_name, expected_result): - s = spack.spec.Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) assert getattr(s.package, method_name)() == expected_result diff --git a/lib/spack/spack/test/optional_deps.py b/lib/spack/spack/test/optional_deps.py index ceba2f6ed11..ea44da42b79 100644 --- a/lib/spack/spack/test/optional_deps.py +++ b/lib/spack/spack/test/optional_deps.py @@ -4,6 +4,7 @@ import pytest +import spack.concretize from spack.spec import Spec @@ -72,14 +73,11 @@ def spec_and_expected(request): def test_default_variant(config, mock_packages): - spec = Spec("optional-dep-test-3") - spec.concretize() + spec = spack.concretize.concretize_one("optional-dep-test-3") assert "pkg-a" in spec - spec = Spec("optional-dep-test-3~var") - spec.concretize() + spec = spack.concretize.concretize_one("optional-dep-test-3~var") assert "pkg-a" in spec - spec = Spec("optional-dep-test-3+var") - spec.concretize() + spec = spack.concretize.concretize_one("optional-dep-test-3+var") assert "pkg-b" in spec diff --git a/lib/spack/spack/test/package_class.py b/lib/spack/spack/test/package_class.py index 2730aad40c4..46de370e4e3 100644 --- a/lib/spack/spack/test/package_class.py +++ b/lib/spack/spack/test/package_class.py @@ -17,6 +17,7 @@ import llnl.util.filesystem as fs import spack.compilers +import spack.concretize import spack.deptypes as dt import spack.error import spack.install_test @@ -166,8 +167,7 @@ def setup_install_test(source_paths, test_root): ) def test_cache_extra_sources(install_mockery, spec, sources, extras, expect): """Test the package's cache extra test sources helper function.""" - s = spack.spec.Spec(spec).concretized() - s.package.spec.concretize() + s = spack.concretize.concretize_one(spec) source_path = s.package.stage.source_path srcs = [fs.join_path(source_path, src) for src in sources] @@ -205,8 +205,7 @@ def test_cache_extra_sources(install_mockery, spec, sources, extras, expect): def test_cache_extra_sources_fails(install_mockery): - s = spack.spec.Spec("pkg-a").concretized() - s.package.spec.concretize() + s = spack.concretize.concretize_one("pkg-a") with pytest.raises(InstallError) as exc_info: spack.install_test.cache_extra_test_sources(s.package, ["/a/b", "no-such-file"]) diff --git a/lib/spack/spack/test/packages.py b/lib/spack/spack/test/packages.py index 302dbe8df81..9c4b1142a78 100644 --- a/lib/spack/spack/test/packages.py +++ b/lib/spack/spack/test/packages.py @@ -7,6 +7,7 @@ import pytest import spack.build_systems.cmake as cmake +import spack.concretize import spack.directives import spack.error import spack.fetch_strategy @@ -75,13 +76,13 @@ def test_inheritance_of_directives(self): assert len(pkg_cls.provided) == 2 # Check that Spec instantiation behaves as we expect - s = Spec("simple-inheritance").concretized() + s = spack.concretize.concretize_one("simple-inheritance") assert "^cmake" in s assert "^openblas" in s assert "+openblas" in s assert "mpi" in s - s = Spec("simple-inheritance~openblas").concretized() + s = spack.concretize.concretize_one("simple-inheritance~openblas") assert "^cmake" in s assert "^openblas" not in s assert "~openblas" in s @@ -89,9 +90,8 @@ def test_inheritance_of_directives(self): @pytest.mark.regression("11844") def test_inheritance_of_patches(self): - s = Spec("patch-inheritance") # Will error if inheritor package cannot find inherited patch files - s.concretize() + _ = spack.concretize.concretize_one("patch-inheritance") def test_import_class_from_package(self): from spack.pkg.builtin.mock.mpich import Mpich # noqa: F401 @@ -115,7 +115,7 @@ def test_import_namespace_container_modules(self): def test_urls_for_versions(mock_packages, config): """Version directive without a 'url' argument should use default url.""" for spec_str in ("url_override@0.9.0", "url_override@1.0.0"): - s = Spec(spec_str).concretized() + s = spack.concretize.concretize_one(spec_str) url = s.package.url_for_version("0.9.0") assert url == "http://www.anothersite.org/uo-0.9.0.tgz" @@ -137,7 +137,7 @@ def test_url_for_version_with_no_urls(mock_packages, config): def test_custom_cmake_prefix_path(mock_packages, config): - spec = Spec("depends-on-define-cmake-prefix-paths").concretized() + spec = spack.concretize.concretize_one("depends-on-define-cmake-prefix-paths") assert cmake.get_cmake_prefix_path(spec.package) == [ spec["define-cmake-prefix-paths"].prefix.test @@ -145,7 +145,7 @@ def test_custom_cmake_prefix_path(mock_packages, config): def test_url_for_version_with_only_overrides(mock_packages, config): - s = Spec("url-only-override").concretized() + s = spack.concretize.concretize_one("url-only-override") # these exist and should just take the URL provided in the package assert s.package.url_for_version("1.0.0") == "http://a.example.com/url_override-1.0.0.tar.gz" @@ -160,7 +160,7 @@ def test_url_for_version_with_only_overrides(mock_packages, config): def test_url_for_version_with_only_overrides_with_gaps(mock_packages, config): - s = Spec("url-only-override-with-gaps").concretized() + s = spack.concretize.concretize_one("url-only-override-with-gaps") # same as for url-only-override -- these are specific assert s.package.url_for_version("1.0.0") == "http://a.example.com/url_override-1.0.0.tar.gz" diff --git a/lib/spack/spack/test/packaging.py b/lib/spack/spack/test/packaging.py index 4b5f41ade6b..0038fabd4fa 100644 --- a/lib/spack/spack/test/packaging.py +++ b/lib/spack/spack/test/packaging.py @@ -20,6 +20,7 @@ import spack.binary_distribution as bindist import spack.cmd.buildcache as buildcache +import spack.concretize import spack.config import spack.error import spack.fetch_strategy @@ -32,7 +33,6 @@ from spack.installer import PackageInstaller from spack.paths import mock_gpg_keys_path from spack.relocate import macho_find_paths, relocate_links, relocate_text -from spack.spec import Spec pytestmark = pytest.mark.not_on_windows("does not run on windows") @@ -40,7 +40,7 @@ @pytest.mark.usefixtures("install_mockery", "mock_gnupghome") def test_buildcache(mock_archive, tmp_path, monkeypatch, mutable_config): # Install a test package - spec = Spec("trivial-install-test-package").concretized() + spec = spack.concretize.concretize_one("trivial-install-test-package") monkeypatch.setattr(spec.package, "fetcher", URLFetchStrategy(url=mock_archive.url)) PackageInstaller([spec.package], explicit=True).install() pkghash = "/" + str(spec.dag_hash(7)) diff --git a/lib/spack/spack/test/patch.py b/lib/spack/spack/test/patch.py index 24d2759ac6f..4d0d4a15cb4 100644 --- a/lib/spack/spack/test/patch.py +++ b/lib/spack/spack/test/patch.py @@ -12,6 +12,7 @@ from llnl.util.filesystem import mkdirp, touch, working_dir +import spack.concretize import spack.error import spack.fetch_strategy import spack.patch @@ -91,7 +92,7 @@ def mock_patch_stage(tmpdir_factory, monkeypatch): def test_url_patch(mock_patch_stage, filename, sha256, archive_sha256, config): # Make a patch object url = url_util.path_to_file_url(filename) - s = Spec("patch").concretized() + s = spack.concretize.concretize_one("patch") # make a stage with Stage(url) as stage: # TODO: url isn't used; maybe refactor Stage @@ -145,8 +146,7 @@ def test_url_patch(mock_patch_stage, filename, sha256, archive_sha256, config): def test_patch_in_spec(mock_packages, config): """Test whether patches in a package appear in the spec.""" - spec = Spec("patch") - spec.concretize() + spec = spack.concretize.concretize_one("patch") assert "patches" in list(spec.variants.keys()) # Here the order is bar, foo, baz. Note that MV variants order @@ -164,18 +164,15 @@ def test_patch_mixed_versions_subset_constraint(mock_packages, config): a patch applied to a version range of x.y.z versions is not applied to an x.y version. """ - spec1 = Spec("patch@1.0.1") - spec1.concretize() + spec1 = spack.concretize.concretize_one("patch@1.0.1") assert biz_sha256 in spec1.variants["patches"].value - spec2 = Spec("patch@=1.0") - spec2.concretize() + spec2 = spack.concretize.concretize_one("patch@=1.0") assert biz_sha256 not in spec2.variants["patches"].value def test_patch_order(mock_packages, config): - spec = Spec("dep-diamond-patch-top") - spec.concretize() + spec = spack.concretize.concretize_one("dep-diamond-patch-top") mid2_sha256 = ( "mid21234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234" @@ -233,8 +230,7 @@ def test_nested_directives(mock_packages): @pytest.mark.not_on_windows("Test requires Autotools") def test_patched_dependency(mock_packages, install_mockery, mock_fetch): """Test whether patched dependencies work.""" - spec = Spec("patch-a-dependency") - spec.concretize() + spec = spack.concretize.concretize_one("patch-a-dependency") assert "patches" in list(spec["libelf"].variants.keys()) # make sure the patch makes it into the dependency spec @@ -274,8 +270,7 @@ def test_patch_failure_develop_spec_exits_gracefully( ): """ensure that a failing patch does not trigger exceptions for develop specs""" - spec = Spec(f"patch-a-dependency ^libelf dev_path={tmpdir}") - spec.concretize() + spec = spack.concretize.concretize_one(f"patch-a-dependency ^libelf dev_path={tmpdir}") libelf = spec["libelf"] assert "patches" in list(libelf.variants.keys()) pkg = libelf.package @@ -291,8 +286,7 @@ def test_patch_failure_restages(mock_packages, install_mockery, mock_fetch): ensure that a failing patch does not trigger exceptions for non-develop specs and the source gets restaged """ - spec = Spec("patch-a-dependency") - spec.concretize() + spec = spack.concretize.concretize_one("patch-a-dependency") pkg = spec["libelf"].package with pkg.stage: bad_patch_indicator = trigger_bad_patch(pkg) @@ -303,8 +297,7 @@ def test_patch_failure_restages(mock_packages, install_mockery, mock_fetch): def test_multiple_patched_dependencies(mock_packages, config): """Test whether multiple patched dependencies work.""" - spec = Spec("patch-several-dependencies") - spec.concretize() + spec = spack.concretize.concretize_one("patch-several-dependencies") # basic patch on libelf assert "patches" in list(spec["libelf"].variants.keys()) @@ -319,8 +312,7 @@ def test_multiple_patched_dependencies(mock_packages, config): def test_conditional_patched_dependencies(mock_packages, config): """Test whether conditional patched dependencies work.""" - spec = Spec("patch-several-dependencies @1.0") - spec.concretize() + spec = spack.concretize.concretize_one("patch-several-dependencies @1.0") # basic patch on libelf assert "patches" in list(spec["libelf"].variants.keys()) @@ -396,8 +388,9 @@ def get_patch(spec, ending): def test_conditional_patched_deps_with_conditions(mock_packages, config): """Test whether conditional patched dependencies with conditions work.""" - spec = Spec("patch-several-dependencies @1.0 ^libdwarf@20111030") - spec.concretize() + spec = spack.concretize.concretize_one( + Spec("patch-several-dependencies @1.0 ^libdwarf@20111030") + ) libelf = spec["libelf"] libdwarf = spec["libdwarf"] @@ -412,8 +405,9 @@ def test_write_and_read_sub_dags_with_patched_deps(mock_packages, config): """Test whether patched dependencies are still correct after writing and reading a sub-DAG of a concretized Spec. """ - spec = Spec("patch-several-dependencies @1.0 ^libdwarf@20111030") - spec.concretize() + spec = spack.concretize.concretize_one( + Spec("patch-several-dependencies @1.0 ^libdwarf@20111030") + ) # write to YAML and read back in -- new specs will *only* contain # their sub-DAGs, and won't contain the dependent that patched them @@ -474,7 +468,7 @@ def test_equality(): def test_sha256_setter(mock_patch_stage, config): path = os.path.join(data_path, "foo.patch") - s = Spec("patch").concretized() + s = spack.concretize.concretize_one("patch") patch = spack.patch.FilePatch(s.package, path, level=1, working_dir=".") patch.sha256 = "abc" diff --git a/lib/spack/spack/test/rewiring.py b/lib/spack/spack/test/rewiring.py index 33d7f46dce7..282e16a8f1b 100644 --- a/lib/spack/spack/test/rewiring.py +++ b/lib/spack/spack/test/rewiring.py @@ -8,11 +8,11 @@ import pytest +import spack.concretize import spack.deptypes as dt import spack.rewiring import spack.store from spack.installer import PackageInstaller -from spack.spec import Spec from spack.test.relocate import text_in_bin if sys.platform == "darwin": @@ -37,8 +37,8 @@ def check_spliced_spec_prefixes(spliced_spec): @pytest.mark.parametrize("transitive", [True, False]) def test_rewire_db(mock_fetch, install_mockery, transitive): """Tests basic rewiring without binary executables.""" - spec = Spec("splice-t^splice-h~foo").concretized() - dep = Spec("splice-h+foo").concretized() + spec = spack.concretize.concretize_one("splice-t^splice-h~foo") + dep = spack.concretize.concretize_one("splice-h+foo") PackageInstaller([spec.package, dep.package], explicit=True).install() spliced_spec = spec.splice(dep, transitive=transitive) assert spec.dag_hash() != spliced_spec.dag_hash() @@ -61,8 +61,8 @@ def test_rewire_db(mock_fetch, install_mockery, transitive): @pytest.mark.parametrize("transitive", [True, False]) def test_rewire_bin(mock_fetch, install_mockery, transitive): """Tests basic rewiring with binary executables.""" - spec = Spec("quux").concretized() - dep = Spec("garply cflags=-g").concretized() + spec = spack.concretize.concretize_one("quux") + dep = spack.concretize.concretize_one("garply cflags=-g") PackageInstaller([spec.package, dep.package], explicit=True).install() spliced_spec = spec.splice(dep, transitive=transitive) @@ -90,8 +90,8 @@ def test_rewire_bin(mock_fetch, install_mockery, transitive): def test_rewire_writes_new_metadata(mock_fetch, install_mockery): """Tests that new metadata was written during a rewire. Accuracy of metadata is left to other tests.""" - spec = Spec("quux").concretized() - dep = Spec("garply cflags=-g").concretized() + spec = spack.concretize.concretize_one("quux") + dep = spack.concretize.concretize_one("garply cflags=-g") PackageInstaller([spec.package, dep.package], explicit=True).install() spliced_spec = spec.splice(dep, transitive=True) spack.rewiring.rewire(spliced_spec) @@ -134,8 +134,8 @@ def test_rewire_writes_new_metadata(mock_fetch, install_mockery): @pytest.mark.parametrize("transitive", [True, False]) def test_uninstall_rewired_spec(mock_fetch, install_mockery, transitive): """Test that rewired packages can be uninstalled as normal.""" - spec = Spec("quux").concretized() - dep = Spec("garply cflags=-g").concretized() + spec = spack.concretize.concretize_one("quux") + dep = spack.concretize.concretize_one("garply cflags=-g") PackageInstaller([spec.package, dep.package], explicit=True).install() spliced_spec = spec.splice(dep, transitive=transitive) spack.rewiring.rewire(spliced_spec) @@ -148,8 +148,8 @@ def test_uninstall_rewired_spec(mock_fetch, install_mockery, transitive): def test_rewire_not_installed_fails(mock_fetch, install_mockery): """Tests error when an attempt is made to rewire a package that was not previously installed.""" - spec = Spec("quux").concretized() - dep = Spec("garply cflags=-g").concretized() + spec = spack.concretize.concretize_one("quux") + dep = spack.concretize.concretize_one("garply cflags=-g") spliced_spec = spec.splice(dep, False) with pytest.raises( spack.rewiring.PackageNotInstalledError, @@ -163,8 +163,8 @@ def test_rewire_virtual(mock_fetch, install_mockery): dep = "splice-a" alt_dep = "splice-h" - spec = Spec(f"splice-vt^{dep}").concretized() - alt_spec = Spec(alt_dep).concretized() + spec = spack.concretize.concretize_one(f"splice-vt^{dep}") + alt_spec = spack.concretize.concretize_one(alt_dep) PackageInstaller([spec.package, alt_spec.package]).install() diff --git a/lib/spack/spack/test/spec_dag.py b/lib/spack/spack/test/spec_dag.py index 5de2bd87f6e..5f366b44f61 100644 --- a/lib/spack/spack/test/spec_dag.py +++ b/lib/spack/spack/test/spec_dag.py @@ -6,6 +6,7 @@ """ import pytest +import spack.concretize import spack.deptypes as dt import spack.error import spack.repo @@ -74,7 +75,7 @@ def test_test_deptype(tmpdir): builder.add_package("w", dependencies=[("x", "test", None), ("y", None, None)]) with spack.repo.use_repositories(builder.root): - spec = Spec("w").concretized(tests=("w",)) + spec = spack.concretize.concretize_one("w", tests=("w",)) assert "x" in spec assert "z" not in spec @@ -106,8 +107,7 @@ def test_installed_deps(monkeypatch, mock_packages): # BUT d is only a build dependency of C, so it won't constrain # link/run dependents of C when C is depended on as an existing # (concrete) installation. - c_spec = Spec(c) - c_spec.concretize() + c_spec = spack.concretize.concretize_one(c) assert c_spec[d].version == spack.version.Version("2") installed_names = [s.name for s in c_spec.traverse()] @@ -122,7 +122,7 @@ def _mock_installed(self): # *if* we're doing a fresh installation. a_spec = Spec(a) a_spec._add_dependency(c_spec, depflag=dt.BUILD | dt.LINK, virtuals=()) - a_spec.concretize() + a_spec = spack.concretize.concretize_one(a_spec) assert spack.version.Version("2") == a_spec[c][d].version assert spack.version.Version("2") == a_spec[e].version assert spack.version.Version("3") == a_spec[b][d].version @@ -140,12 +140,12 @@ def test_specify_preinstalled_dep(tmpdir, monkeypatch): builder.add_package("pkg-a", dependencies=[("pkg-b", None, None)]) with spack.repo.use_repositories(builder.root): - b_spec = Spec("pkg-b").concretized() + b_spec = spack.concretize.concretize_one("pkg-b") monkeypatch.setattr(Spec, "installed", property(lambda x: x.name != "pkg-a")) a_spec = Spec("pkg-a") a_spec._add_dependency(b_spec, depflag=dt.BUILD | dt.LINK, virtuals=()) - a_spec.concretize() + a_spec = spack.concretize.concretize_one(a_spec) assert {x.name for x in a_spec.traverse()} == {"pkg-a", "pkg-b", "pkg-c"} @@ -167,7 +167,7 @@ def test_conditional_dep_with_user_constraints(tmpdir, spec_str, expr_str, expec builder.add_package("x", dependencies=[("y", None, "x@2:")]) with spack.repo.use_repositories(builder.root): - spec = Spec(spec_str).concretized() + spec = spack.concretize.concretize_one(spec_str) result = expr_str in spec assert result is expected, "{0} in {1}".format(expr_str, spec) @@ -181,10 +181,10 @@ def test_conflicting_package_constraints(self, set_dependency): spec = Spec("mpileaks ^mpich ^callpath ^dyninst ^libelf ^libdwarf") with pytest.raises(spack.error.UnsatisfiableSpecError): - spec.concretize() + spack.concretize.concretize_one(spec) def test_preorder_node_traversal(self): - dag = Spec("mpileaks ^zmpi").concretized() + dag = spack.concretize.concretize_one("mpileaks ^zmpi") names = ["mpileaks", "callpath", "dyninst", "libdwarf", "libelf", "zmpi", "fake"] pairs = list(zip([0, 1, 2, 3, 4, 2, 3], names)) @@ -196,7 +196,7 @@ def test_preorder_node_traversal(self): assert [(x, y.name) for x, y in traversal] == pairs def test_preorder_edge_traversal(self): - dag = Spec("mpileaks ^zmpi").concretized() + dag = spack.concretize.concretize_one("mpileaks ^zmpi") names = [ "mpileaks", @@ -218,7 +218,7 @@ def test_preorder_edge_traversal(self): assert [(x, y.name) for x, y in traversal] == pairs def test_preorder_path_traversal(self): - dag = Spec("mpileaks ^zmpi").concretized() + dag = spack.concretize.concretize_one("mpileaks ^zmpi") names = [ "mpileaks", @@ -241,7 +241,7 @@ def test_preorder_path_traversal(self): assert [(x, y.name) for x, y in traversal] == pairs def test_postorder_node_traversal(self): - dag = Spec("mpileaks ^zmpi").concretized() + dag = spack.concretize.concretize_one("mpileaks ^zmpi") names = ["libelf", "libdwarf", "dyninst", "fake", "zmpi", "callpath", "mpileaks"] pairs = list(zip([4, 3, 2, 3, 2, 1, 0], names)) @@ -253,7 +253,7 @@ def test_postorder_node_traversal(self): assert [(x, y.name) for x, y in traversal] == pairs def test_postorder_edge_traversal(self): - dag = Spec("mpileaks ^zmpi").concretized() + dag = spack.concretize.concretize_one("mpileaks ^zmpi") names = [ "libelf", @@ -275,7 +275,7 @@ def test_postorder_edge_traversal(self): assert [(x, y.name) for x, y in traversal] == pairs def test_postorder_path_traversal(self): - dag = Spec("mpileaks ^zmpi").concretized() + dag = spack.concretize.concretize_one("mpileaks ^zmpi") names = [ "libelf", @@ -310,8 +310,8 @@ def test_dependents_and_dependencies_are_correct(self): } ) check_links(spec) - spec.concretize() - check_links(spec) + concrete = spack.concretize.concretize_one(spec) + check_links(concrete) @pytest.mark.parametrize( "constraint_str,spec_str", @@ -328,7 +328,7 @@ def test_unsatisfiable_cases(self, set_dependency, constraint_str, spec_str): """ set_dependency("mpileaks", constraint_str) with pytest.raises(spack.error.UnsatisfiableSpecError): - Spec(spec_str).concretize() + spack.concretize.concretize_one(spec_str) @pytest.mark.parametrize( "spec_str", ["libelf ^mpich", "libelf ^libdwarf", "mpich ^dyninst ^libelf"] @@ -336,7 +336,7 @@ def test_unsatisfiable_cases(self, set_dependency, constraint_str, spec_str): def test_invalid_dep(self, spec_str): spec = Spec(spec_str) with pytest.raises(spack.error.SpecError): - spec.concretize() + spack.concretize.concretize_one(spec) def test_equal(self): # Different spec structures to test for equality @@ -398,8 +398,7 @@ def test_copy_simple(self): assert not orig_ids.intersection(copy_ids) def test_copy_concretized(self): - orig = Spec("mpileaks") - orig.concretize() + orig = spack.concretize.concretize_one("mpileaks") copy = orig.copy() check_links(copy) @@ -417,7 +416,7 @@ def test_copy_through_spec_build_interface(self): """Check that copying dependencies using id(node) as a fast identifier of the node works when the spec is wrapped in a SpecBuildInterface object. """ - s = Spec("mpileaks").concretized() + s = spack.concretize.concretize_one("mpileaks") c0 = s.copy() assert c0 == s @@ -500,7 +499,7 @@ def test_copy_through_spec_build_interface(self): ], ) def test_deptype_traversal(self, spec_str, deptypes, expected): - dag = Spec(spec_str).concretized() + dag = spack.concretize.concretize_one(spec_str) traversal = dag.traverse(deptype=deptypes) assert [x.name for x in traversal] == expected @@ -620,20 +619,18 @@ def check_diamond_deptypes(self, spec): def test_concretize_deptypes(self): """Ensure that dependency types are preserved after concretization.""" - s = Spec("dt-diamond") - s.concretize() + s = spack.concretize.concretize_one("dt-diamond") self.check_diamond_deptypes(s) def test_copy_deptypes(self): """Ensure that dependency types are preserved by spec copy.""" - s1 = Spec("dt-diamond").concretized() + s1 = spack.concretize.concretize_one("dt-diamond") self.check_diamond_deptypes(s1) s2 = s1.copy() self.check_diamond_deptypes(s2) def test_getitem_query(self): - s = Spec("mpileaks") - s.concretize() + s = spack.concretize.concretize_one("mpileaks") # Check a query to a non-virtual package a = s["callpath"] @@ -663,8 +660,7 @@ def test_getitem_query(self): assert query.isvirtual def test_getitem_exceptional_paths(self): - s = Spec("mpileaks") - s.concretize() + s = spack.concretize.concretize_one("mpileaks") # Needed to get a proxy object q = s["mpileaks"] @@ -735,7 +731,7 @@ def test_invalid_literal_spec(self): def test_spec_tree_respect_deptypes(self): # Version-test-root uses version-test-pkg as a build dependency - s = Spec("version-test-root").concretized() + s = spack.concretize.concretize_one("version-test-root") out = s.tree(deptypes="all") assert "version-test-pkg" in out out = s.tree(deptypes=("link", "run")) @@ -819,9 +815,9 @@ def test_synthetic_construction_of_split_dependencies_from_same_package(mock_pac # # To demonstrate that a spec can now hold two direct # dependencies from the same package - root = Spec("pkg-b").concretized() - link_run_spec = Spec("pkg-c@=1.0").concretized() - build_spec = Spec("pkg-c@=2.0").concretized() + root = spack.concretize.concretize_one("pkg-b") + link_run_spec = spack.concretize.concretize_one("pkg-c@=1.0") + build_spec = spack.concretize.concretize_one("pkg-c@=2.0") root.add_dependency_edge(link_run_spec, depflag=dt.LINK, virtuals=()) root.add_dependency_edge(link_run_spec, depflag=dt.RUN, virtuals=()) @@ -848,8 +844,8 @@ def test_synthetic_construction_bootstrapping(mock_packages, config): # | build # pkg-b@1.0 # - root = Spec("pkg-b@=2.0").concretized() - bootstrap = Spec("pkg-b@=1.0").concretized() + root = spack.concretize.concretize_one("pkg-b@=2.0") + bootstrap = spack.concretize.concretize_one("pkg-b@=1.0") root.add_dependency_edge(bootstrap, depflag=dt.BUILD, virtuals=()) @@ -866,8 +862,8 @@ def test_addition_of_different_deptypes_in_multiple_calls(mock_packages, config) # pkg-b@1.0 # # with three calls and check we always have a single edge - root = Spec("pkg-b@=2.0").concretized() - bootstrap = Spec("pkg-b@=1.0").concretized() + root = spack.concretize.concretize_one("pkg-b@=2.0") + bootstrap = spack.concretize.concretize_one("pkg-b@=1.0") for current_depflag in (dt.BUILD, dt.LINK, dt.RUN): root.add_dependency_edge(bootstrap, depflag=current_depflag, virtuals=()) @@ -894,9 +890,9 @@ def test_addition_of_different_deptypes_in_multiple_calls(mock_packages, config) def test_adding_same_deptype_with_the_same_name_raises( mock_packages, config, c1_depflag, c2_depflag ): - p = Spec("pkg-b@=2.0").concretized() - c1 = Spec("pkg-b@=1.0").concretized() - c2 = Spec("pkg-b@=2.0").concretized() + p = spack.concretize.concretize_one("pkg-b@=2.0") + c1 = spack.concretize.concretize_one("pkg-b@=1.0") + c2 = spack.concretize.concretize_one("pkg-b@=2.0") p.add_dependency_edge(c1, depflag=c1_depflag, virtuals=()) with pytest.raises(spack.error.SpackError): diff --git a/lib/spack/spack/test/spec_list.py b/lib/spack/spack/test/spec_list.py index 7571657368c..275d267fa69 100644 --- a/lib/spack/spack/test/spec_list.py +++ b/lib/spack/spack/test/spec_list.py @@ -5,6 +5,7 @@ import pytest +import spack.concretize from spack.installer import PackageInstaller from spack.spec import Spec from spack.spec_list import SpecList @@ -198,8 +199,8 @@ def test_spec_list_matrix_exclude(self, mock_packages): def test_spec_list_exclude_with_abstract_hashes(self, mock_packages, install_mockery): # Put mpich in the database so it can be referred to by hash. - mpich_1 = Spec("mpich+debug").concretized() - mpich_2 = Spec("mpich~debug").concretized() + mpich_1 = spack.concretize.concretize_one("mpich+debug") + mpich_2 = spack.concretize.concretize_one("mpich~debug") PackageInstaller([mpich_1.package, mpich_2.package], explicit=True, fake=True).install() # Create matrix and exclude +debug, which excludes the first mpich after its abstract hash diff --git a/lib/spack/spack/test/spec_semantics.py b/lib/spack/spack/test/spec_semantics.py index b0ee3709f30..406a63518f9 100644 --- a/lib/spack/spack/test/spec_semantics.py +++ b/lib/spack/spack/test/spec_semantics.py @@ -6,6 +6,7 @@ import pytest +import spack.concretize import spack.deptypes as dt import spack.directives import spack.error @@ -589,8 +590,7 @@ def test_satisfies_single_valued_variant(self): https://github.com/spack/spack/pull/2386#issuecomment-282147639 is handled correctly. """ - a = Spec("pkg-a foobar=bar") - a.concretize() + a = spack.concretize.concretize_one("pkg-a foobar=bar") assert a.satisfies("foobar=bar") assert a.satisfies("foobar=*") @@ -609,21 +609,18 @@ def test_satisfies_single_valued_variant(self): assert "^pkg-b" in a def test_unsatisfied_single_valued_variant(self): - a = Spec("pkg-a foobar=baz") - a.concretize() + a = spack.concretize.concretize_one("pkg-a foobar=baz") assert "^pkg-b" not in a - mv = Spec("multivalue-variant") - mv.concretize() + mv = spack.concretize.concretize_one("multivalue-variant") assert "pkg-a@1.0" not in mv def test_indirect_unsatisfied_single_valued_variant(self): - spec = Spec("singlevalue-variant-dependent") - spec.concretize() + spec = spack.concretize.concretize_one("singlevalue-variant-dependent") assert "pkg-a@1.0" not in spec def test_satisfied_namespace(self): - spec = Spec("zlib").concretized() + spec = spack.concretize.concretize_one("zlib") assert spec.satisfies("namespace=builtin.mock") assert not spec.satisfies("namespace=builtin") @@ -683,7 +680,7 @@ def test_unsatisfiable_multi_value_variant(self, default_mock_concretization): # ...but will fail during concretization if there are # values in the variant that are not allowed with pytest.raises(InvalidVariantValueError): - a.concretize() + spack.concretize.concretize_one(a) # This time we'll try to set a single-valued variant a = Spec('multivalue-variant fee="bar"') @@ -700,11 +697,10 @@ def test_unsatisfiable_multi_value_variant(self, default_mock_concretization): # ...but will fail during concretization if there are # multiple values set with pytest.raises(MultipleValuesInExclusiveVariantError): - a.concretize() + spack.concretize.concretize_one(a) def test_copy_satisfies_transitive(self): - spec = Spec("dttop") - spec.concretize() + spec = spack.concretize.concretize_one("dttop") copy = spec.copy() for s in spec.traverse(): assert s.satisfies(copy[s.name]) @@ -727,7 +723,7 @@ def test_intersects_virtual_providers(self): def test_intersectable_concrete_specs_must_have_the_same_hash(self): """Ensure that concrete specs are matched *exactly* by hash.""" - s1 = Spec("mpileaks").concretized() + s1 = spack.concretize.concretize_one("mpileaks") s2 = s1.copy() assert s1.satisfies(s2) @@ -767,17 +763,10 @@ def test_dep_index(self, default_mock_concretization): @pytest.mark.usefixtures("config") def test_virtual_index(self): - s = Spec("callpath") - s.concretize() - - s_mpich = Spec("callpath ^mpich") - s_mpich.concretize() - - s_mpich2 = Spec("callpath ^mpich2") - s_mpich2.concretize() - - s_zmpi = Spec("callpath ^zmpi") - s_zmpi.concretize() + s = spack.concretize.concretize_one("callpath") + s_mpich = spack.concretize.concretize_one("callpath ^mpich") + s_mpich2 = spack.concretize.concretize_one("callpath ^mpich2") + s_zmpi = spack.concretize.concretize_one("callpath ^zmpi") assert s["mpi"].name != "mpi" assert s_mpich["mpi"].name == "mpich" @@ -1047,7 +1036,7 @@ def test_abstract_spec_prefix_error(self): spec.prefix def test_forwarding_of_architecture_attributes(self): - spec = Spec("libelf target=x86_64").concretized() + spec = spack.concretize.concretize_one("libelf target=x86_64") # Check that we can still access each member through # the architecture attribute @@ -1372,7 +1361,7 @@ def test_target_constraints(self, spec, constraint, expected_result): def test_error_message_unknown_variant(self): s = Spec("mpileaks +unknown") with pytest.raises(UnknownVariantError): - s.concretize() + spack.concretize.concretize_one(s) @pytest.mark.regression("18527") def test_satisfies_dependencies_ordered(self): @@ -1399,8 +1388,7 @@ def test_splice_swap_names_mismatch_virtuals(self, default_mock_concretization, def test_spec_override(self): init_spec = Spec("pkg-a foo=baz foobar=baz cflags=-O3 cxxflags=-O1") change_spec = Spec("pkg-a foo=fee cflags=-O2") - new_spec = Spec.override(init_spec, change_spec) - new_spec.concretize() + new_spec = spack.concretize.concretize_one(Spec.override(init_spec, change_spec)) assert "foo=fee" in new_spec # This check fails without concretizing: apparently if both specs are # abstract, then the spec will always be considered to satisfy @@ -1419,8 +1407,7 @@ def test_spec_override_with_nonexisting_variant(self): def test_spec_override_with_variant_not_in_init_spec(self): init_spec = Spec("pkg-a foo=baz foobar=baz cflags=-O3 cxxflags=-O1") change_spec = Spec("pkg-a +bvv ~lorem_ipsum") - new_spec = Spec.override(init_spec, change_spec) - new_spec.concretize() + new_spec = spack.concretize.concretize_one(Spec.override(init_spec, change_spec)) assert "+bvv" in new_spec assert "~lorem_ipsum" in new_spec @@ -1513,7 +1500,7 @@ def test_virtual_deps_bindings(self, default_mock_concretization, spec_str, spec ) def test_unsatisfiable_virtual_deps_bindings(self, spec_str): with pytest.raises(spack.solver.asp.UnsatisfiableSpecError): - Spec(spec_str).concretized() + spack.concretize.concretize_one(spec_str) @pytest.mark.parametrize( @@ -1611,7 +1598,7 @@ def test_spec_format_path_posix(spec_str, format_str, expected, mock_git_test_pa def test_is_extension_after_round_trip_to_dict(config, mock_packages, spec_str): # x is constructed directly from string, y from a # round-trip to dict representation - x = Spec(spec_str).concretized() + x = spack.concretize.concretize_one(spec_str) y = Spec.from_dict(x.to_dict()) # Using 'y' since the round-trip make us lose build dependencies @@ -1712,7 +1699,7 @@ def test_call_dag_hash_on_old_dag_hash_spec(mock_packages, default_mock_concreti def test_spec_trim(mock_packages, config): - top = Spec("dt-diamond").concretized() + top = spack.concretize.concretize_one("dt-diamond") top.trim("dt-diamond-left") remaining = set(x.name for x in top.traverse()) assert set(["dt-diamond", "dt-diamond-right", "dt-diamond-bottom"]) == remaining @@ -1725,7 +1712,7 @@ def test_spec_trim(mock_packages, config): @pytest.mark.regression("30861") def test_concretize_partial_old_dag_hash_spec(mock_packages, config): # create an "old" spec with no package hash - bottom = Spec("dt-diamond-bottom").concretized() + bottom = spack.concretize.concretize_one("dt-diamond-bottom") delattr(bottom, "_package_hash") dummy_hash = "zd4m26eis2wwbvtyfiliar27wkcv3ehk" @@ -1736,7 +1723,7 @@ def test_concretize_partial_old_dag_hash_spec(mock_packages, config): top.add_dependency_edge(bottom, depflag=0, virtuals=()) # concretize with the already-concrete dependency - top.concretize() + top = spack.concretize.concretize_one(top) for spec in top.traverse(): assert spec.concrete @@ -1954,7 +1941,7 @@ def test_edge_equality_does_not_depend_on_virtual_order(): def test_old_format_strings_trigger_error(default_mock_concretization): - s = Spec("pkg-a").concretized() + s = spack.concretize.concretize_one("pkg-a") with pytest.raises(SpecFormatStringError): s.format("${PACKAGE}-${VERSION}-${HASH}") diff --git a/lib/spack/spack/test/spec_syntax.py b/lib/spack/spack/test/spec_syntax.py index 842c2f72470..e00fb3a7eee 100644 --- a/lib/spack/spack/test/spec_syntax.py +++ b/lib/spack/spack/test/spec_syntax.py @@ -10,6 +10,7 @@ import spack.binary_distribution import spack.cmd +import spack.concretize import spack.platforms.test import spack.repo import spack.spec @@ -776,7 +777,7 @@ def test_spec_by_hash_tokens(text, tokens): @pytest.mark.db def test_spec_by_hash(database, monkeypatch, config): mpileaks = database.query_one("mpileaks ^zmpi") - b = spack.spec.Spec("pkg-b").concretized() + b = spack.concretize.concretize_one("pkg-b") monkeypatch.setattr(spack.binary_distribution, "update_cache_and_get_specs", lambda: [b]) hash_str = f"/{mpileaks.dag_hash()}" @@ -873,7 +874,7 @@ def test_ambiguous_hash(mutable_database): In the past this ambiguity error would happen during parse time.""" # This is a very sketchy as manually setting hashes easily breaks invariants - x1 = spack.spec.Spec("pkg-a").concretized() + x1 = spack.concretize.concretize_one("pkg-a") x2 = x1.copy() x1._hash = "xyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" x1._process_hash = "xyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" @@ -947,8 +948,8 @@ def test_nonexistent_hash(database, config): ], ) def test_disambiguate_hash_by_spec(spec1, spec2, constraint, mock_packages, monkeypatch, config): - spec1_concrete = spack.spec.Spec(spec1).concretized() - spec2_concrete = spack.spec.Spec(spec2).concretized() + spec1_concrete = spack.concretize.concretize_one(spec1) + spec2_concrete = spack.concretize.concretize_one(spec2) spec1_concrete._hash = "spec1" spec2_concrete._hash = "spec2" @@ -1139,7 +1140,7 @@ def test_parse_filename_missing_slash_as_spec(specfile_for, tmpdir, filename): # Check that if we concretize this spec, we get a good error # message that mentions we might've meant a file. with pytest.raises(spack.repo.UnknownEntityError) as exc_info: - spec.concretize() + spack.concretize.concretize_one(spec) assert exc_info.value.long_message assert ( "Did you mean to specify a filename with './libelf.yaml'?" in exc_info.value.long_message @@ -1147,7 +1148,7 @@ def test_parse_filename_missing_slash_as_spec(specfile_for, tmpdir, filename): # make sure that only happens when the spec ends in yaml with pytest.raises(spack.repo.UnknownPackageError) as exc_info: - SpecParser("builtin.mock.doesnotexist").next_spec().concretize() + spack.concretize.concretize_one(SpecParser("builtin.mock.doesnotexist").next_spec()) assert not exc_info.value.long_message or ( "Did you mean to specify a filename with" not in exc_info.value.long_message ) diff --git a/lib/spack/spack/test/spec_yaml.py b/lib/spack/spack/test/spec_yaml.py index 78901f90348..59fe217b67d 100644 --- a/lib/spack/spack/test/spec_yaml.py +++ b/lib/spack/spack/test/spec_yaml.py @@ -20,6 +20,7 @@ import pytest import ruamel.yaml +import spack.concretize import spack.hash_types as ht import spack.paths import spack.repo @@ -107,8 +108,7 @@ def test_roundtrip_concrete_specs(abstract_spec, default_mock_concretization): def test_yaml_subdag(config, mock_packages): - spec = Spec("mpileaks^mpich+debug") - spec.concretize() + spec = spack.concretize.concretize_one("mpileaks^mpich+debug") yaml_spec = Spec.from_yaml(spec.to_yaml()) json_spec = Spec.from_json(spec.to_json()) @@ -153,8 +153,7 @@ def test_ordered_read_not_required_for_consistent_dag_hash(config, mock_packages """ specs = ["mpileaks ^zmpi", "dttop", "dtuse"] for spec in specs: - spec = Spec(spec) - spec.concretize() + spec = spack.concretize.concretize_one(spec) # # Dict & corresponding YAML & JSON from the original spec. @@ -214,11 +213,15 @@ def test_ordered_read_not_required_for_consistent_dag_hash(config, mock_packages assert spec.dag_hash() == round_trip_reversed_json_spec.dag_hash() # dag_hash is equal after round-trip by dag_hash - spec.concretize() - round_trip_yaml_spec.concretize() - round_trip_json_spec.concretize() - round_trip_reversed_yaml_spec.concretize() - round_trip_reversed_json_spec.concretize() + spec = spack.concretize.concretize_one(spec) + round_trip_yaml_spec = spack.concretize.concretize_one(round_trip_yaml_spec) + round_trip_json_spec = spack.concretize.concretize_one(round_trip_json_spec) + round_trip_reversed_yaml_spec = spack.concretize.concretize_one( + round_trip_reversed_yaml_spec + ) + round_trip_reversed_json_spec = spack.concretize.concretize_one( + round_trip_reversed_json_spec + ) assert spec.dag_hash() == round_trip_yaml_spec.dag_hash() assert spec.dag_hash() == round_trip_json_spec.dag_hash() assert spec.dag_hash() == round_trip_reversed_yaml_spec.dag_hash() @@ -322,7 +325,7 @@ def test_save_dependency_spec_jsons_subset(tmpdir, config): builder.add_package("pkg-a", dependencies=[("pkg-b", None, None), ("pkg-c", None, None)]) with spack.repo.use_repositories(builder.root): - spec_a = Spec("pkg-a").concretized() + spec_a = spack.concretize.concretize_one("pkg-a") b_spec = spec_a["pkg-b"] c_spec = spec_a["pkg-c"] @@ -389,7 +392,7 @@ def test_legacy_yaml(tmpdir, install_mockery, mock_packages): build_hash: iaapywazxgetn6gfv2cfba353qzzqvhy """ spec = Spec.from_yaml(yaml) - concrete_spec = spec.concretized() + concrete_spec = spack.concretize.concretize_one(spec) assert concrete_spec.eq_dag(spec) diff --git a/lib/spack/spack/test/svn_fetch.py b/lib/spack/spack/test/svn_fetch.py index ac3be1558f9..b8d0853d717 100644 --- a/lib/spack/spack/test/svn_fetch.py +++ b/lib/spack/spack/test/svn_fetch.py @@ -8,9 +8,9 @@ from llnl.util.filesystem import mkdirp, touch, working_dir +import spack.concretize import spack.config from spack.fetch_strategy import SvnFetchStrategy -from spack.spec import Spec from spack.stage import Stage from spack.util.executable import which from spack.version import Version @@ -40,7 +40,7 @@ def test_fetch(type_of_test, secure, mock_svn_repository, config, mutable_mock_r h = mock_svn_repository.hash # Construct the package under test - s = Spec("svn-test").concretized() + s = spack.concretize.concretize_one("svn-test") monkeypatch.setitem(s.package.versions, Version("svn"), t.args) # Enter the stage directory and check some properties diff --git a/lib/spack/spack/test/test_suite.py b/lib/spack/spack/test/test_suite.py index a6ae7037ac1..5b6ef111cc6 100644 --- a/lib/spack/spack/test/test_suite.py +++ b/lib/spack/spack/test/test_suite.py @@ -9,6 +9,7 @@ from llnl.util.filesystem import join_path, mkdirp, touch +import spack.concretize import spack.config import spack.install_test import spack.spec @@ -39,7 +40,7 @@ def ensure_results(filename, expected, present=True): def test_test_log_name(mock_packages, config): """Ensure test log path is reasonable.""" - spec = spack.spec.Spec("libdwarf").concretized() + spec = spack.concretize.concretize_one("libdwarf") test_name = "test_name" @@ -52,7 +53,7 @@ def test_test_log_name(mock_packages, config): def test_test_ensure_stage(mock_test_stage, mock_packages): """Make sure test stage directory is properly set up.""" - spec = spack.spec.Spec("libdwarf").concretized() + spec = spack.concretize.concretize_one("libdwarf") test_name = "test_name" @@ -65,7 +66,7 @@ def test_test_ensure_stage(mock_test_stage, mock_packages): def test_write_test_result(mock_packages, mock_test_stage): """Ensure test results written to a results file.""" - spec = spack.spec.Spec("libdwarf").concretized() + spec = spack.concretize.concretize_one("libdwarf") result = "TEST" test_name = "write-test" @@ -85,7 +86,7 @@ def test_write_test_result(mock_packages, mock_test_stage): def test_test_not_installed(mock_packages, install_mockery, mock_test_stage): """Attempt to perform stand-alone test for not_installed package.""" - spec = spack.spec.Spec("trivial-smoke-test").concretized() + spec = spack.concretize.concretize_one("trivial-smoke-test") test_suite = spack.install_test.TestSuite([spec]) test_suite() @@ -102,7 +103,7 @@ def test_test_external( mock_packages, install_mockery, mock_test_stage, monkeypatch, arguments, status, msg ): name = "trivial-smoke-test" - spec = spack.spec.Spec(name).concretized() + spec = spack.concretize.concretize_one(name) spec.external_path = "/path/to/external/{0}".format(name) monkeypatch.setattr(spack.spec.Spec, "installed", _true) @@ -123,7 +124,7 @@ def ensure_current_cache_fail(test_suite): with pytest.raises(spack.install_test.TestSuiteSpecError): _ = test_suite.current_test_data_dir - spec = spack.spec.Spec("libelf").concretized() + spec = spack.concretize.concretize_one("libelf") test_suite = spack.install_test.TestSuite([spec], "test-cache") # Check no current specs yield failure @@ -141,7 +142,7 @@ def ensure_current_cache_fail(test_suite): def test_test_spec_run_once(mock_packages, install_mockery, mock_test_stage): - spec = spack.spec.Spec("libelf").concretized() + spec = spack.concretize.concretize_one("libelf") test_suite = spack.install_test.TestSuite([spec], "test-dups") (test_suite.specs[0]).package.test_suite = test_suite @@ -151,7 +152,7 @@ def test_test_spec_run_once(mock_packages, install_mockery, mock_test_stage): @pytest.mark.not_on_windows("Cannot find echo executable") def test_test_spec_passes(mock_packages, install_mockery, mock_test_stage, monkeypatch): - spec = spack.spec.Spec("simple-standalone-test").concretized() + spec = spack.concretize.concretize_one("simple-standalone-test") monkeypatch.setattr(spack.spec.Spec, "installed", _true) test_suite = spack.install_test.TestSuite([spec]) test_suite() @@ -177,7 +178,7 @@ def test_get_test_suite_too_many(mock_packages, mock_test_stage): name = "duplicate-alias" def add_suite(package): - spec = spack.spec.Spec(package).concretized() + spec = spack.concretize.concretize_one(package) suite = spack.install_test.TestSuite([spec], name) suite.ensure_stage() spack.install_test.write_test_suite_file(suite) @@ -199,7 +200,7 @@ def add_suite(package): ) def test_test_function_names(mock_packages, install_mockery, virtuals, expected): """Confirm test_function_names works as expected with/without virtuals.""" - spec = spack.spec.Spec("mpich").concretized() + spec = spack.concretize.concretize_one("mpich") tests = spack.install_test.test_function_names(spec.package, add_virtuals=virtuals) assert sorted(tests) == sorted(expected) @@ -212,7 +213,7 @@ def test_test_functions_fails(): def test_test_functions_pkgless(mock_packages, install_mockery, ensure_debug, capsys): """Confirm works for package providing a package-less virtual.""" - spec = spack.spec.Spec("simple-standalone-test").concretized() + spec = spack.concretize.concretize_one("simple-standalone-test") fns = spack.install_test.test_functions(spec.package, add_virtuals=True) out = capsys.readouterr() assert len(fns) == 2, "Expected two test functions" @@ -295,7 +296,7 @@ def test_process_test_parts(mock_packages): def test_test_part_fail(tmpdir, install_mockery, mock_fetch, mock_test_stage): """Confirm test_part with a ProcessError results in FAILED status.""" - s = spack.spec.Spec("trivial-smoke-test").concretized() + s = spack.concretize.concretize_one("trivial-smoke-test") pkg = s.package pkg.tester.test_log_file = str(tmpdir.join("test-log.txt")) touch(pkg.tester.test_log_file) @@ -311,7 +312,7 @@ def test_test_part_fail(tmpdir, install_mockery, mock_fetch, mock_test_stage): def test_test_part_pass(install_mockery, mock_fetch, mock_test_stage): """Confirm test_part that succeeds results in PASSED status.""" - s = spack.spec.Spec("trivial-smoke-test").concretized() + s = spack.concretize.concretize_one("trivial-smoke-test") pkg = s.package name = "test_echo" @@ -330,7 +331,7 @@ def test_test_part_pass(install_mockery, mock_fetch, mock_test_stage): def test_test_part_skip(install_mockery, mock_fetch, mock_test_stage): """Confirm test_part that raises SkipTest results in test status SKIPPED.""" - s = spack.spec.Spec("trivial-smoke-test").concretized() + s = spack.concretize.concretize_one("trivial-smoke-test") pkg = s.package name = "test_skip" @@ -344,7 +345,7 @@ def test_test_part_skip(install_mockery, mock_fetch, mock_test_stage): def test_test_part_missing_exe_fail_fast(tmpdir, install_mockery, mock_fetch, mock_test_stage): """Confirm test_part with fail fast enabled raises exception.""" - s = spack.spec.Spec("trivial-smoke-test").concretized() + s = spack.concretize.concretize_one("trivial-smoke-test") pkg = s.package pkg.tester.test_log_file = str(tmpdir.join("test-log.txt")) touch(pkg.tester.test_log_file) @@ -365,7 +366,7 @@ def test_test_part_missing_exe_fail_fast(tmpdir, install_mockery, mock_fetch, mo def test_test_part_missing_exe(tmpdir, install_mockery, mock_fetch, mock_test_stage): """Confirm test_part with missing executable fails.""" - s = spack.spec.Spec("trivial-smoke-test").concretized() + s = spack.concretize.concretize_one("trivial-smoke-test") pkg = s.package pkg.tester.test_log_file = str(tmpdir.join("test-log.txt")) touch(pkg.tester.test_log_file) @@ -401,7 +402,7 @@ def test_embedded_test_part_status( ): """Check to ensure the status of the enclosing test part reflects summary of embedded parts.""" - s = spack.spec.Spec("trivial-smoke-test").concretized() + s = spack.concretize.concretize_one("trivial-smoke-test") pkg = s.package base_name = "test_example" part_name = f"{pkg.__class__.__name__}::{base_name}" @@ -428,7 +429,7 @@ def test_write_tested_status( tmpdir, install_mockery, mock_fetch, mock_test_stage, statuses, expected ): """Check to ensure the status of the enclosing test part reflects summary of embedded parts.""" - s = spack.spec.Spec("trivial-smoke-test").concretized() + s = spack.concretize.concretize_one("trivial-smoke-test") pkg = s.package for i, status in enumerate(statuses): pkg.tester.test_parts[f"test_{i}"] = status @@ -444,7 +445,7 @@ def test_write_tested_status( @pytest.mark.regression("37840") def test_write_tested_status_no_repeats(tmpdir, install_mockery, mock_fetch, mock_test_stage): """Emulate re-running the same stand-alone tests a second time.""" - s = spack.spec.Spec("trivial-smoke-test").concretized() + s = spack.concretize.concretize_one("trivial-smoke-test") pkg = s.package statuses = [TestStatus.PASSED, TestStatus.PASSED] for i, status in enumerate(statuses): diff --git a/lib/spack/spack/test/url_fetch.py b/lib/spack/spack/test/url_fetch.py index c487633f510..3e16596302c 100644 --- a/lib/spack/spack/test/url_fetch.py +++ b/lib/spack/spack/test/url_fetch.py @@ -13,6 +13,7 @@ import llnl.util.tty as tty from llnl.util.filesystem import is_exe, working_dir +import spack.concretize import spack.config import spack.error import spack.fetch_strategy as fs @@ -21,7 +22,6 @@ import spack.util.executable import spack.util.web as web_util import spack.version -from spack.spec import Spec from spack.stage import Stage from spack.util.executable import which @@ -192,7 +192,7 @@ def test_from_list_url(mock_packages, config, spec, url, digest, _fetch_method): have checksums in the package. """ with spack.config.override("config:url_fetch_method", _fetch_method): - s = Spec(spec).concretized() + s = spack.concretize.concretize_one(spec) fetch_strategy = fs.from_list_url(s.package) assert isinstance(fetch_strategy, fs.URLFetchStrategy) assert os.path.basename(fetch_strategy.url) == url @@ -218,7 +218,7 @@ def test_new_version_from_list_url( ): """Test non-specific URLs from the url-list-test package.""" with spack.config.override("config:url_fetch_method", _fetch_method): - s = Spec(f"url-list-test @{requested_version}").concretized() + s = spack.concretize.concretize_one(f"url-list-test @{requested_version}") fetch_strategy = fs.from_list_url(s.package) assert isinstance(fetch_strategy, fs.URLFetchStrategy) @@ -232,7 +232,7 @@ def test_new_version_from_list_url( def test_nosource_from_list_url(mock_packages, config): """This test confirms BundlePackages do not have list url.""" - s = Spec("nosource").concretized() + s = spack.concretize.concretize_one("nosource") fetch_strategy = fs.from_list_url(s.package) assert fetch_strategy is None diff --git a/lib/spack/spack/test/util/package_hash.py b/lib/spack/spack/test/util/package_hash.py index 9d46ff5c252..991339bd17a 100644 --- a/lib/spack/spack/test/util/package_hash.py +++ b/lib/spack/spack/test/util/package_hash.py @@ -7,6 +7,7 @@ import pytest +import spack.concretize import spack.directives import spack.directives_meta import spack.paths @@ -91,8 +92,8 @@ def test_all_same_but_install(mock_packages, config): def test_content_hash_all_same_but_patch_contents(mock_packages, config): - spec1 = Spec("hash-test1@1.1").concretized() - spec2 = Spec("hash-test2@1.1").concretized() + spec1 = spack.concretize.concretize_one("hash-test1@1.1") + spec2 = spack.concretize.concretize_one("hash-test2@1.1") compare_hash_sans_name(False, spec1, spec2) @@ -117,8 +118,8 @@ def test_content_hash_not_concretized(mock_packages, config): def test_content_hash_different_variants(mock_packages, config): - spec1 = Spec("hash-test1@1.2 +variantx").concretized() - spec2 = Spec("hash-test2@1.2 ~variantx").concretized() + spec1 = spack.concretize.concretize_one("hash-test1@1.2 +variantx") + spec2 = spack.concretize.concretize_one("hash-test2@1.2 ~variantx") compare_hash_sans_name(True, spec1, spec2) @@ -132,19 +133,19 @@ def test_content_hash_cannot_get_details_from_ast(mock_packages, config): differ where Spack includes a phase on account of AST-examination failure. """ - spec3 = Spec("hash-test1@1.7").concretized() - spec4 = Spec("hash-test3@1.7").concretized() + spec3 = spack.concretize.concretize_one("hash-test1@1.7") + spec4 = spack.concretize.concretize_one("hash-test3@1.7") compare_hash_sans_name(False, spec3, spec4) def test_content_hash_all_same_but_archive_hash(mock_packages, config): - spec1 = Spec("hash-test1@1.3").concretized() - spec2 = Spec("hash-test2@1.3").concretized() + spec1 = spack.concretize.concretize_one("hash-test1@1.3") + spec2 = spack.concretize.concretize_one("hash-test2@1.3") compare_hash_sans_name(False, spec1, spec2) def test_content_hash_parse_dynamic_function_call(mock_packages, config): - spec = Spec("hash-test4").concretized() + spec = spack.concretize.concretize_one("hash-test4") spec.package.content_hash() diff --git a/lib/spack/spack/test/variant.py b/lib/spack/spack/test/variant.py index 7e9f327cdfc..8f0ac0aa4cd 100644 --- a/lib/spack/spack/test/variant.py +++ b/lib/spack/spack/test/variant.py @@ -5,6 +5,7 @@ import pytest +import spack.concretize import spack.error import spack.repo import spack.spec @@ -686,12 +687,11 @@ def test_str(self) -> None: def test_concrete(self, mock_packages, config) -> None: spec = Spec("pkg-a") - vm = VariantMap(spec) - assert not vm.concrete + assert not VariantMap(spec).concrete # concrete if associated spec is concrete - spec.concretize() - assert vm.concrete + spec = spack.concretize.concretize_one(spec) + assert VariantMap(spec).concrete # concrete if all variants are present (even if spec not concrete) spec._mark_concrete(False) @@ -910,7 +910,7 @@ def test_concretize_variant_default_with_multiple_defs( pkg = spack.repo.PATH.get_pkg_class(pkg_name) pkg_defs = [vdef for _, vdef in pkg.variant_definitions("v")] - spec = spack.spec.Spec(f"{pkg_name}{spec}").concretized() + spec = spack.concretize.concretize_one(f"{pkg_name}{spec}") assert spec.satisfies(satisfies) assert spec.package.get_variant("v") is pkg_defs[def_id] diff --git a/lib/spack/spack/test/versions.py b/lib/spack/spack/test/versions.py index 44d2623b7fb..66d21564e60 100644 --- a/lib/spack/spack/test/versions.py +++ b/lib/spack/spack/test/versions.py @@ -13,6 +13,7 @@ from llnl.util.filesystem import working_dir +import spack.concretize import spack.package_base import spack.spec import spack.version @@ -707,7 +708,9 @@ def test_git_hash_comparisons( spack.package_base.PackageBase, "git", pathlib.Path(repo_path).as_uri(), raising=False ) - spec = spack.spec.Spec(f"git-test-commit@{commits[commit_idx]}").concretized() + spec = spack.concretize.concretize_one( + spack.spec.Spec(f"git-test-commit@{commits[commit_idx]}") + ) for item in expected_satisfies: assert spec.satisfies(item) @@ -723,15 +726,13 @@ def test_git_ref_comparisons(mock_git_version_info, install_mockery, mock_packag ) # Spec based on tag v1.0 - spec_tag = spack.spec.Spec("git-test-commit@git.v1.0") - spec_tag.concretize() + spec_tag = spack.concretize.concretize_one("git-test-commit@git.v1.0") assert spec_tag.satisfies("@1.0") assert not spec_tag.satisfies("@1.1:") assert str(spec_tag.version) == "git.v1.0=1.0" # Spec based on branch 1.x - spec_branch = spack.spec.Spec("git-test-commit@git.1.x") - spec_branch.concretize() + spec_branch = spack.concretize.concretize_one("git-test-commit@git.1.x") assert spec_branch.satisfies("@1.2") assert spec_branch.satisfies("@1.1:1.3") assert str(spec_branch.version) == "git.1.x=1.2" @@ -1030,7 +1031,7 @@ def test_git_version_repo_attached_after_serialization( monkeypatch.setattr( spack.package_base.PackageBase, "git", "file://%s" % repo_path, raising=False ) - spec = spack.spec.Spec(f"git-test-commit@{commits[-2]}").concretized() + spec = spack.concretize.concretize_one(f"git-test-commit@{commits[-2]}") # Before serialization, the repo is attached assert spec.satisfies("@1.0") @@ -1050,7 +1051,7 @@ def test_resolved_git_version_is_shown_in_str( spack.package_base.PackageBase, "git", "file://%s" % repo_path, raising=False ) commit = commits[-3] - spec = spack.spec.Spec(f"git-test-commit@{commit}").concretized() + spec = spack.concretize.concretize_one(f"git-test-commit@{commit}") assert spec.version.satisfies(ver("1.0")) assert str(spec.version) == f"{commit}=1.0-git.1" diff --git a/lib/spack/spack/test/views.py b/lib/spack/spack/test/views.py index 38ca2ce6a3e..c94b36fea52 100644 --- a/lib/spack/spack/test/views.py +++ b/lib/spack/spack/test/views.py @@ -6,6 +6,7 @@ import pytest +import spack.concretize from spack.directory_layout import DirectoryLayout from spack.filesystem_view import SimpleFilesystemView, YamlFilesystemView from spack.installer import PackageInstaller @@ -16,7 +17,7 @@ def test_remove_extensions_ordered(install_mockery, mock_fetch, tmpdir): view_dir = str(tmpdir.join("view")) layout = DirectoryLayout(view_dir) view = YamlFilesystemView(view_dir, layout) - e2 = Spec("extension2").concretized() + e2 = spack.concretize.concretize_one("extension2") PackageInstaller([e2.package], explicit=True).install() view.add_specs(e2)