spack.dependency: add type hints (#34807)

This commit is contained in:
Massimiliano Culpo 2023-01-05 17:48:29 +01:00 committed by GitHub
parent 441c0a4fee
commit eace2ebb08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 18 deletions

View File

@ -3,6 +3,8 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""Data structures that represent Spack's dependency relationships.""" """Data structures that represent Spack's dependency relationships."""
from typing import Dict, List, Optional, Set, Tuple, Union
import spack.spec import spack.spec
#: The types of dependency relationships that Spack understands. #: The types of dependency relationships that Spack understands.
@ -11,8 +13,11 @@
#: Default dependency type if none is specified #: Default dependency type if none is specified
default_deptype = ("build", "link") default_deptype = ("build", "link")
#: Type hint for the arguments accepting a dependency type
DependencyArgument = Union[str, List[str], Tuple[str, ...]]
def deptype_chars(*type_tuples):
def deptype_chars(*type_tuples: str) -> str:
"""Create a string representing deptypes for many dependencies. """Create a string representing deptypes for many dependencies.
The string will be some subset of 'blrt', like 'bl ', 'b t', or The string will be some subset of 'blrt', like 'bl ', 'b t', or
@ -24,7 +29,7 @@ def deptype_chars(*type_tuples):
whether ANY dpeendency in the list has the deptypes (so the deptypes whether ANY dpeendency in the list has the deptypes (so the deptypes
are merged). are merged).
""" """
types = set() types: Set[str] = set()
for t in type_tuples: for t in type_tuples:
if t: if t:
types.update(t) types.update(t)
@ -32,13 +37,12 @@ def deptype_chars(*type_tuples):
return "".join(t[0] if t in types else " " for t in all_deptypes) return "".join(t[0] if t in types else " " for t in all_deptypes)
def canonical_deptype(deptype): def canonical_deptype(deptype: DependencyArgument) -> Tuple[str, ...]:
"""Convert deptype to a canonical sorted tuple, or raise ValueError. """Convert deptype to a canonical sorted tuple, or raise ValueError.
Args: Args:
deptype (str or list or tuple): string representing dependency deptype: string representing dependency type, or a list/tuple of such strings.
type, or a list/tuple of such strings. Can also be the Can also be the builtin function ``all`` or the string 'all', which result in
builtin function ``all`` or the string 'all', which result in
a tuple of all dependency types known to Spack. a tuple of all dependency types known to Spack.
""" """
if deptype in ("all", all): if deptype in ("all", all):
@ -58,7 +62,7 @@ def canonical_deptype(deptype):
raise ValueError("Invalid dependency type: %s" % repr(deptype)) raise ValueError("Invalid dependency type: %s" % repr(deptype))
class Dependency(object): class Dependency:
"""Class representing metadata for a dependency on a package. """Class representing metadata for a dependency on a package.
This class differs from ``spack.spec.DependencySpec`` because it This class differs from ``spack.spec.DependencySpec`` because it
@ -85,13 +89,18 @@ class Dependency(object):
""" """
def __init__(self, pkg, spec, type=default_deptype): def __init__(
self,
pkg: "spack.package_base.PackageBase",
spec: "spack.spec.Spec",
type: Optional[Tuple[str, ...]] = default_deptype,
):
"""Create a new Dependency. """Create a new Dependency.
Args: Args:
pkg (type): Package that has this dependency pkg: Package that has this dependency
spec (Spec): Spec indicating dependency requirements spec: Spec indicating dependency requirements
type (sequence): strings describing dependency relationship type: strings describing dependency relationship
""" """
assert isinstance(spec, spack.spec.Spec) assert isinstance(spec, spack.spec.Spec)
@ -100,7 +109,7 @@ def __init__(self, pkg, spec, type=default_deptype):
# This dict maps condition specs to lists of Patch objects, just # This dict maps condition specs to lists of Patch objects, just
# as the patches dict on packages does. # as the patches dict on packages does.
self.patches = {} self.patches: Dict[spack.spec.Spec, "List[spack.patch.Patch]"] = {}
if type is None: if type is None:
self.type = set(default_deptype) self.type = set(default_deptype)
@ -108,11 +117,11 @@ def __init__(self, pkg, spec, type=default_deptype):
self.type = set(type) self.type = set(type)
@property @property
def name(self): def name(self) -> str:
"""Get the name of the dependency package.""" """Get the name of the dependency package."""
return self.spec.name return self.spec.name
def merge(self, other): def merge(self, other: "Dependency"):
"""Merge constraints, deptypes, and patches of other into self.""" """Merge constraints, deptypes, and patches of other into self."""
self.spec.constrain(other.spec) self.spec.constrain(other.spec)
self.type |= other.type self.type |= other.type
@ -125,6 +134,6 @@ def merge(self, other):
else: else:
self.patches[cond] = other.patches[cond] self.patches[cond] = other.patches[cond]
def __repr__(self): def __repr__(self) -> str:
types = deptype_chars(self.type) types = deptype_chars(*self.type)
return "<Dependency: %s -> %s [%s]>" % (self.pkg.name, self.spec, types) return f"<Dependency: {self.pkg.name} -> {self.spec} [{types}]>"

View File

@ -569,7 +569,7 @@ def static_graph_dot(
def graph_dot( def graph_dot(
specs: List[spack.spec.Spec], specs: List[spack.spec.Spec],
builder: Optional[DotGraphBuilder] = None, builder: Optional[DotGraphBuilder] = None,
deptype: Optional[Union[str, Tuple[str, ...]]] = "all", deptype: spack.dependency.DependencyArgument = "all",
out: Optional[TextIO] = None, out: Optional[TextIO] = None,
): ):
"""DOT graph of the concrete specs passed as input. """DOT graph of the concrete specs passed as input.