Spec.tree: add type hints (#39948)

This commit is contained in:
Massimiliano Culpo 2023-09-13 11:53:14 +02:00 committed by GitHub
parent 2c13361b09
commit c4e2d24ca9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 21 deletions

View File

@ -214,6 +214,7 @@ def setup(sphinx):
# Spack classes that intersphinx is unable to resolve # Spack classes that intersphinx is unable to resolve
("py:class", "spack.version.StandardVersion"), ("py:class", "spack.version.StandardVersion"),
("py:class", "spack.spec.DependencySpec"), ("py:class", "spack.spec.DependencySpec"),
("py:class", "spack.spec.InstallStatus"),
("py:class", "spack.spec.SpecfileReaderBase"), ("py:class", "spack.spec.SpecfileReaderBase"),
("py:class", "spack.install_test.Pb"), ("py:class", "spack.install_test.Pb"),
] ]

View File

@ -56,7 +56,7 @@
import os import os
import re import re
import warnings import warnings
from typing import List, Tuple, Union from typing import Callable, List, Optional, Tuple, Union
import llnl.util.filesystem as fs import llnl.util.filesystem as fs
import llnl.util.lang as lang import llnl.util.lang as lang
@ -174,9 +174,12 @@
SPECFILE_FORMAT_VERSION = 4 SPECFILE_FORMAT_VERSION = 4
# InstallStatus is used to map install statuses to symbols for display
# Options are artificially disjoint for dispay purposes
class InstallStatus(enum.Enum): class InstallStatus(enum.Enum):
"""Maps install statuses to symbols for display.
Options are artificially disjoint for display purposes
"""
installed = "@g{[+]} " installed = "@g{[+]} "
upstream = "@g{[^]} " upstream = "@g{[^]} "
external = "@g{[e]} " external = "@g{[e]} "
@ -4509,29 +4512,51 @@ def _installed_explicitly(self):
except KeyError: except KeyError:
return None return None
def tree(self, **kwargs): def tree(
self,
*,
color: Optional[bool] = None,
depth: bool = False,
hashes: bool = False,
hashlen: Optional[int] = None,
cover: str = "nodes",
indent: int = 0,
format: str = DEFAULT_FORMAT,
deptypes: Union[Tuple[str, ...], str] = "all",
show_types: bool = False,
depth_first: bool = False,
recurse_dependencies: bool = True,
status_fn: Optional[Callable[["Spec"], InstallStatus]] = None,
prefix: Optional[Callable[["Spec"], str]] = None,
) -> str:
"""Prints out this spec and its dependencies, tree-formatted """Prints out this spec and its dependencies, tree-formatted
with indentation. with indentation.
Status function may either output a boolean or an InstallStatus Status function may either output a boolean or an InstallStatus
"""
color = kwargs.pop("color", clr.get_color_when())
depth = kwargs.pop("depth", False)
hashes = kwargs.pop("hashes", False)
hlen = kwargs.pop("hashlen", None)
status_fn = kwargs.pop("status_fn", False)
cover = kwargs.pop("cover", "nodes")
indent = kwargs.pop("indent", 0)
fmt = kwargs.pop("format", DEFAULT_FORMAT)
prefix = kwargs.pop("prefix", None)
show_types = kwargs.pop("show_types", False)
deptypes = kwargs.pop("deptypes", "all")
recurse_dependencies = kwargs.pop("recurse_dependencies", True)
depth_first = kwargs.pop("depth_first", False)
lang.check_kwargs(kwargs, self.tree)
Args:
color: if True, always colorize the tree. If False, don't colorize the tree. If None,
use the default from llnl.tty.color
depth: print the depth from the root
hashes: if True, print the hash of each node
hashlen: length of the hash to be printed
cover: either "nodes" or "edges"
indent: extra indentation for the tree being printed
format: format to be used to print each node
deptypes: dependency types to be represented in the tree
show_types: if True, show the (merged) dependency type of a node
depth_first: if True, traverse the DAG depth first when representing it as a tree
recurse_dependencies: if True, recurse on dependencies
status_fn: optional callable that takes a node as an argument and return its
installation status
prefix: optional callable that takes a node as an argument and return its
installation prefix
"""
out = "" out = ""
if color is None:
color = clr.get_color_when()
for d, dep_spec in traverse.traverse_tree( for d, dep_spec in traverse.traverse_tree(
[self], cover=cover, deptype=deptypes, depth_first=depth_first [self], cover=cover, deptype=deptypes, depth_first=depth_first
): ):
@ -4554,7 +4579,7 @@ def tree(self, **kwargs):
out += clr.colorize("@r{[-]} ", color=color) out += clr.colorize("@r{[-]} ", color=color)
if hashes: if hashes:
out += clr.colorize("@K{%s} ", color=color) % node.dag_hash(hlen) out += clr.colorize("@K{%s} ", color=color) % node.dag_hash(hashlen)
if show_types: if show_types:
if cover == "nodes": if cover == "nodes":
@ -4572,7 +4597,7 @@ def tree(self, **kwargs):
out += " " * d out += " " * d
if d > 0: if d > 0:
out += "^" out += "^"
out += node.format(fmt, color=color) + "\n" out += node.format(format, color=color) + "\n"
# Check if we wanted just the first line # Check if we wanted just the first line
if not recurse_dependencies: if not recurse_dependencies: