diff --git a/lib/spack/spack/audit.py b/lib/spack/spack/audit.py index 40bd04e9bc..fedb6c1138 100644 --- a/lib/spack/spack/audit.py +++ b/lib/spack/spack/audit.py @@ -967,10 +967,10 @@ def _extracts_errors(triggers, summary): summary = f"{pkg_name}: wrong 'when=' condition for the '{provided}' virtual" errors.extend(_extracts_errors(triggers, summary)) - for _, triggers in pkg_cls.requirements.items(): - triggers = [when_spec for when_spec, _, _ in triggers] - summary = f"{pkg_name}: wrong 'when=' condition in 'requires' directive" - errors.extend(_extracts_errors(triggers, summary)) + for when, requirements, details in _error_items(pkg_cls.requirements): + errors.append( + error_cls(f"{pkg_name}: wrong 'when=' condition in 'requires' directive", details) + ) for when, _, details in _error_items(pkg_cls.patches): errors.append( diff --git a/lib/spack/spack/directives.py b/lib/spack/spack/directives.py index 75cda9f90b..e7fc6d9990 100644 --- a/lib/spack/spack/directives.py +++ b/lib/spack/spack/directives.py @@ -965,7 +965,7 @@ def license( @directive("requirements") -def requires(*requirement_specs, policy="one_of", when=None, msg=None): +def requires(*requirement_specs: str, policy="one_of", when=None, msg=None): """Allows a package to request a configuration to be present in all valid solutions. For instance, a package that is known to compile only with GCC can declare: @@ -984,7 +984,7 @@ def requires(*requirement_specs, policy="one_of", when=None, msg=None): msg: optional user defined message """ - def _execute_requires(pkg): + def _execute_requires(pkg: "spack.package_base.PackageBase"): if policy not in ("one_of", "any_of"): err_msg = ( f"the 'policy' argument of the 'requires' directive in {pkg.name} is set " @@ -997,9 +997,10 @@ def _execute_requires(pkg): return # Save in a list the requirements and the associated custom messages - when_spec_list = pkg.requirements.setdefault(tuple(requirement_specs), []) + requirement_list = pkg.requirements.setdefault(when_spec, []) msg_with_name = f"{pkg.name}: {msg}" if msg is not None else msg - when_spec_list.append((when_spec, policy, msg_with_name)) + requirements = tuple(spack.spec.Spec(s) for s in requirement_specs) + requirement_list.append((requirements, policy, msg_with_name)) return _execute_requires diff --git a/lib/spack/spack/package_base.py b/lib/spack/spack/package_base.py index 9b1b1c17c8..bb9fb6408c 100644 --- a/lib/spack/spack/package_base.py +++ b/lib/spack/spack/package_base.py @@ -562,6 +562,9 @@ class PackageBase(WindowsRPath, PackageViewMixin, metaclass=PackageMeta): versions: dict dependencies: Dict["spack.spec.Spec", Dict[str, "spack.dependency.Dependency"]] conflicts: Dict["spack.spec.Spec", List[Tuple["spack.spec.Spec", Optional[str]]]] + requirements: Dict[ + "spack.spec.Spec", List[Tuple[Tuple["spack.spec.Spec", ...], str, Optional[str]]] + ] patches: Dict["spack.spec.Spec", List["spack.patch.Patch"]] #: By default, packages are not virtual diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 3a0267a50c..617a11b452 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -1303,8 +1303,8 @@ def package_requirement_rules(self, pkg): def requirement_rules_from_package_py(self, pkg): rules = [] - for requirements, conditions in pkg.requirements.items(): - for when_spec, policy, message in conditions: + for when_spec, requirement_list in pkg.requirements.items(): + for requirements, policy, message in requirement_list: rules.append( RequirementRule( pkg_name=pkg.name,