Coverage for python/lsst/pipe/base/pipeline_graph/visualization/_options.py: 85%

28 statements  

« prev     ^ index     » next       coverage.py v7.14.3, created at 2026-06-25 08:10 +0000

1# This file is part of pipe_base. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This software is dual licensed under the GNU General Public License and also 

10# under a 3-clause BSD license. Recipients may choose which of these licenses 

11# to use; please see the files gpl-3.0.txt and/or bsd_license.txt, 

12# respectively. If you choose the GPL option then the following text applies 

13# (but note that there is still no warranty even if you opt for BSD instead): 

14# 

15# This program is free software: you can redistribute it and/or modify 

16# it under the terms of the GNU General Public License as published by 

17# the Free Software Foundation, either version 3 of the License, or 

18# (at your option) any later version. 

19# 

20# This program is distributed in the hope that it will be useful, 

21# but WITHOUT ANY WARRANTY; without even the implied warranty of 

22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

23# GNU General Public License for more details. 

24# 

25# You should have received a copy of the GNU General Public License 

26# along with this program. If not, see <http://www.gnu.org/licenses/>. 

27from __future__ import annotations 

28 

29__all__ = ("NodeAttributeOptions",) 

30 

31import dataclasses 

32from typing import Literal 

33 

34from .._nodes import NodeType 

35from ._status_annotator import NodeStatusOptions 

36 

37 

38@dataclasses.dataclass 

39class NodeAttributeOptions: 

40 """Struct holding options for how to display and possibly merge nodes.""" 

41 

42 dimensions: Literal["full"] | Literal["concise"] | Literal[False] | None 

43 """Options for displaying dimensions. 

44 

45 Possible values include: 

46 

47 - ``"full"``: report fully-expanded dimensions. 

48 - ``"concise"``: report only dimensions that are not required or implied 

49 dependencies of any reported dimension. 

50 - `False`: do not report dimensions at all. 

51 - `None`: context-dependent default behavior. 

52 """ 

53 

54 task_classes: Literal["full"] | Literal["concise"] | Literal[False] | None 

55 """Options for displaying task types. 

56 

57 Possible values include: 

58 

59 - ``"full"``: report the fully-qualified task class name. 

60 - ``"concise"``: report the task class name with no module or package. 

61 - `False`: do not report task classes at all. 

62 - `None`: context-dependent default behavior. 

63 """ 

64 

65 storage_classes: bool | None 

66 """Options for displaying dataset type storage classes. 

67 

68 Possible values include: 

69 

70 - `True`: report storage classes. 

71 - `False`: do not report storage classes. 

72 - `None`: context-dependent default behavior. 

73 """ 

74 

75 status: NodeStatusOptions | None 

76 """Options for displaying execution status.""" 

77 

78 def has_details(self, node_type: NodeType) -> bool: 

79 """Check whether there is any information beyond the node name for a 

80 node of the given type. 

81 

82 Parameters 

83 ---------- 

84 node_type : `NodeType` 

85 Type of node. 

86 

87 Returns 

88 ------- 

89 has_details : `bool` 

90 Whether a node of this type should display more than its name. 

91 """ 

92 if node_type is NodeType.DATASET_TYPE: 

93 return bool(self.dimensions or self.storage_classes) 

94 else: 

95 return bool(self.dimensions or self.task_classes) 

96 

97 def __bool__(self) -> bool: 

98 return bool(self.dimensions or self.storage_classes or self.task_classes or self.status) 

99 

100 def checked(self, is_resolved: bool, has_status: bool = False) -> NodeAttributeOptions: 

101 """Check these options against a pipeline graph's resolution status and 

102 fill in defaults. 

103 

104 Parameters 

105 ---------- 

106 is_resolved : `bool` 

107 Whether the pipeline graph to be displayed is resolved 

108 (`PipelineGraph.is_fully_resolved`). 

109 has_status : `bool` 

110 Whether the pipeline graph to be displayed has status information. 

111 Defaults to `False`. 

112 

113 Returns 

114 ------- 

115 options : `NodeAttributeOptions` 

116 Options with all `None` values in ``self`` filled in. Concise 

117 reporting is used by default if the graph is resolved. 

118 

119 Raises 

120 ------ 

121 ValueError 

122 Raised if an attribute is explicitly requested but the graph is not 

123 fully resolved. 

124 """ 

125 if self.dimensions and not is_resolved: 125 ↛ 126line 125 didn't jump to line 126 because the condition on line 125 was never true

126 raise ValueError("Cannot show dimensions unless they have been resolved.") 

127 if self.storage_classes and not is_resolved: 127 ↛ 128line 127 didn't jump to line 128 because the condition on line 127 was never true

128 raise ValueError("Cannot show storage classes unless they have been resolved.") 

129 return NodeAttributeOptions( 

130 dimensions=( 

131 self.dimensions if self.dimensions is not None else ("concise" if is_resolved else False) 

132 ), 

133 task_classes=( 

134 self.task_classes if self.task_classes is not None else ("concise" if is_resolved else False) 

135 ), 

136 storage_classes=(self.storage_classes if self.storage_classes is not None else is_resolved), 

137 status=self.status if has_status else None, 

138 )