directives: types, avoid redundant parsing (#45208)
This commit is contained in:
parent
568e79a1e3
commit
517b7fb0c9
@ -90,7 +90,7 @@ class OpenMpi(Package):
|
|||||||
_patch_order_index = 0
|
_patch_order_index = 0
|
||||||
|
|
||||||
|
|
||||||
SpecType = Union["spack.spec.Spec", str]
|
SpecType = str
|
||||||
DepType = Union[Tuple[str, ...], str]
|
DepType = Union[Tuple[str, ...], str]
|
||||||
WhenType = Optional[Union["spack.spec.Spec", str, bool]]
|
WhenType = Optional[Union["spack.spec.Spec", str, bool]]
|
||||||
Patcher = Callable[[Union["spack.package_base.PackageBase", Dependency]], None]
|
Patcher = Callable[[Union["spack.package_base.PackageBase", Dependency]], None]
|
||||||
@ -475,7 +475,7 @@ def _execute_version(pkg, ver, **kwargs):
|
|||||||
|
|
||||||
def _depends_on(
|
def _depends_on(
|
||||||
pkg: "spack.package_base.PackageBase",
|
pkg: "spack.package_base.PackageBase",
|
||||||
spec: SpecType,
|
spec: "spack.spec.Spec",
|
||||||
*,
|
*,
|
||||||
when: WhenType = None,
|
when: WhenType = None,
|
||||||
type: DepType = dt.DEFAULT_TYPES,
|
type: DepType = dt.DEFAULT_TYPES,
|
||||||
@ -485,11 +485,10 @@ def _depends_on(
|
|||||||
if not when_spec:
|
if not when_spec:
|
||||||
return
|
return
|
||||||
|
|
||||||
dep_spec = spack.spec.Spec(spec)
|
if not spec.name:
|
||||||
if not dep_spec.name:
|
raise DependencyError(f"Invalid dependency specification in package '{pkg.name}':", spec)
|
||||||
raise DependencyError("Invalid dependency specification in package '%s':" % pkg.name, spec)
|
if pkg.name == spec.name:
|
||||||
if pkg.name == dep_spec.name:
|
raise CircularReferenceError(f"Package '{pkg.name}' cannot depend on itself.")
|
||||||
raise CircularReferenceError("Package '%s' cannot depend on itself." % pkg.name)
|
|
||||||
|
|
||||||
depflag = dt.canonicalize(type)
|
depflag = dt.canonicalize(type)
|
||||||
|
|
||||||
@ -505,7 +504,7 @@ def _depends_on(
|
|||||||
# ensure `Spec.virtual` is a valid thing to call in a directive.
|
# ensure `Spec.virtual` is a valid thing to call in a directive.
|
||||||
# For now, we comment out the following check to allow for virtual packages
|
# For now, we comment out the following check to allow for virtual packages
|
||||||
# with package files.
|
# with package files.
|
||||||
# if patches and dep_spec.virtual:
|
# if patches and spec.virtual:
|
||||||
# raise DependencyPatchError("Cannot patch a virtual dependency.")
|
# raise DependencyPatchError("Cannot patch a virtual dependency.")
|
||||||
|
|
||||||
# ensure patches is a list
|
# ensure patches is a list
|
||||||
@ -520,13 +519,13 @@ def _depends_on(
|
|||||||
|
|
||||||
# this is where we actually add the dependency to this package
|
# this is where we actually add the dependency to this package
|
||||||
deps_by_name = pkg.dependencies.setdefault(when_spec, {})
|
deps_by_name = pkg.dependencies.setdefault(when_spec, {})
|
||||||
dependency = deps_by_name.get(dep_spec.name)
|
dependency = deps_by_name.get(spec.name)
|
||||||
|
|
||||||
if not dependency:
|
if not dependency:
|
||||||
dependency = Dependency(pkg, dep_spec, depflag=depflag)
|
dependency = Dependency(pkg, spec, depflag=depflag)
|
||||||
deps_by_name[dep_spec.name] = dependency
|
deps_by_name[spec.name] = dependency
|
||||||
else:
|
else:
|
||||||
dependency.spec.constrain(dep_spec, deps=False)
|
dependency.spec.constrain(spec, deps=False)
|
||||||
dependency.depflag |= depflag
|
dependency.depflag |= depflag
|
||||||
|
|
||||||
# apply patches to the dependency
|
# apply patches to the dependency
|
||||||
@ -591,12 +590,13 @@ def depends_on(
|
|||||||
@see The section "Dependency specs" in the Spack Packaging Guide.
|
@see The section "Dependency specs" in the Spack Packaging Guide.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if spack.spec.Spec(spec).name in SUPPORTED_LANGUAGES:
|
dep_spec = spack.spec.Spec(spec)
|
||||||
|
if dep_spec.name in SUPPORTED_LANGUAGES:
|
||||||
assert type == "build", "languages must be of 'build' type"
|
assert type == "build", "languages must be of 'build' type"
|
||||||
return _language(lang_spec_str=spec, when=when)
|
return _language(lang_spec_str=spec, when=when)
|
||||||
|
|
||||||
def _execute_depends_on(pkg: "spack.package_base.PackageBase"):
|
def _execute_depends_on(pkg: "spack.package_base.PackageBase"):
|
||||||
_depends_on(pkg, spec, when=when, type=type, patches=patches)
|
_depends_on(pkg, dep_spec, when=when, type=type, patches=patches)
|
||||||
|
|
||||||
return _execute_depends_on
|
return _execute_depends_on
|
||||||
|
|
||||||
@ -666,25 +666,24 @@ def extends(spec, when=None, type=("build", "run"), patches=None):
|
|||||||
|
|
||||||
keyword arguments can be passed to extends() so that extension
|
keyword arguments can be passed to extends() so that extension
|
||||||
packages can pass parameters to the extendee's extension
|
packages can pass parameters to the extendee's extension
|
||||||
mechanism.
|
mechanism."""
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _execute_extends(pkg):
|
def _execute_extends(pkg):
|
||||||
when_spec = _make_when_spec(when)
|
when_spec = _make_when_spec(when)
|
||||||
if not when_spec:
|
if not when_spec:
|
||||||
return
|
return
|
||||||
|
|
||||||
_depends_on(pkg, spec, when=when, type=type, patches=patches)
|
dep_spec = spack.spec.Spec(spec)
|
||||||
spec_obj = spack.spec.Spec(spec)
|
|
||||||
|
_depends_on(pkg, dep_spec, when=when, type=type, patches=patches)
|
||||||
|
|
||||||
# When extending python, also add a dependency on python-venv. This is done so that
|
# When extending python, also add a dependency on python-venv. This is done so that
|
||||||
# Spack environment views are Python virtual environments.
|
# Spack environment views are Python virtual environments.
|
||||||
if spec_obj.name == "python" and not pkg.name == "python-venv":
|
if dep_spec.name == "python" and not pkg.name == "python-venv":
|
||||||
_depends_on(pkg, "python-venv", when=when, type=("build", "run"))
|
_depends_on(pkg, spack.spec.Spec("python-venv"), when=when, type=("build", "run"))
|
||||||
|
|
||||||
# TODO: the values of the extendees dictionary are not used. Remove in next refactor.
|
# TODO: the values of the extendees dictionary are not used. Remove in next refactor.
|
||||||
pkg.extendees[spec_obj.name] = (spec_obj, None)
|
pkg.extendees[dep_spec.name] = (dep_spec, None)
|
||||||
|
|
||||||
return _execute_extends
|
return _execute_extends
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
import spack.compilers
|
import spack.compilers
|
||||||
import spack.config
|
import spack.config
|
||||||
|
import spack.dependency
|
||||||
import spack.deptypes as dt
|
import spack.deptypes as dt
|
||||||
import spack.directives
|
import spack.directives
|
||||||
import spack.directory_layout
|
import spack.directory_layout
|
||||||
|
@ -71,7 +71,7 @@ def test_extends_spec(config, mock_packages):
|
|||||||
def test_error_on_anonymous_dependency(config, mock_packages):
|
def test_error_on_anonymous_dependency(config, mock_packages):
|
||||||
pkg = spack.repo.PATH.get_pkg_class("pkg-a")
|
pkg = spack.repo.PATH.get_pkg_class("pkg-a")
|
||||||
with pytest.raises(spack.directives.DependencyError):
|
with pytest.raises(spack.directives.DependencyError):
|
||||||
spack.directives._depends_on(pkg, "@4.5")
|
spack.directives._depends_on(pkg, spack.spec.Spec("@4.5"))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.regression("34879")
|
@pytest.mark.regression("34879")
|
||||||
|
Loading…
Reference in New Issue
Block a user