Coverage for python/lsst/pipe/base/pipeline_graph/_task_subsets.py: 60%
37 statements
« prev ^ index » next coverage.py v7.3.0, created at 2023-08-23 10:31 +0000
« prev ^ index » next coverage.py v7.3.0, created at 2023-08-23 10:31 +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 program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
21from __future__ import annotations
23__all__ = ("TaskSubset",)
25from collections.abc import Iterator, MutableSet
27import networkx
28import networkx.algorithms.boundary
30from ._exceptions import PipelineGraphError
31from ._nodes import NodeKey, NodeType
34class TaskSubset(MutableSet[str]):
35 """A specialized set that represents a labeles subset of the tasks in a
36 pipeline graph.
38 Instances of this class should never be constructed directly; they should
39 only be accessed via the `PipelineGraph.task_subsets` attribute and created
40 by the `PipelineGraph.add_task_subset` method.
42 Parameters
43 ----------
44 parent_xgraph : `networkx.DiGraph`
45 Parent networkx graph that this subgraph is part of.
46 label : `str`
47 Label associated with this subset of the pipeline.
48 members : `set` [ `str` ]
49 Labels of the tasks that are members of this subset.
50 description : `str`, optional
51 Description string associated with this labeled subset.
53 Notes
54 -----
55 Iteration order is arbitrary, even when the parent pipeline graph is
56 ordered (there is no guarantee that an ordering of the tasks in the graph
57 implies a consistent ordering of subsets).
58 """
60 def __init__(
61 self,
62 parent_xgraph: networkx.DiGraph,
63 label: str,
64 members: set[str],
65 description: str,
66 ):
67 self._parent_xgraph = parent_xgraph
68 self._label = label
69 self._members = members
70 self._description = description
72 @property
73 def label(self) -> str:
74 """Label associated with this subset of the pipeline."""
75 return self._label
77 @property
78 def description(self) -> str:
79 """Description string associated with this labeled subset."""
80 return self._description
82 @description.setter
83 def description(self, value: str) -> None:
84 # Docstring in getter.
85 self._description = value
87 def __repr__(self) -> str:
88 return f"{self.label}: {self.description!r}, tasks={{{', '.join(iter(self))}}}"
90 def __contains__(self, key: object) -> bool:
91 return key in self._members
93 def __len__(self) -> int:
94 return len(self._members)
96 def __iter__(self) -> Iterator[str]:
97 return iter(self._members)
99 def add(self, task_label: str) -> None:
100 """Add a new task to this subset.
102 Parameters
103 ----------
104 task_label : `str`
105 Label for the task. Must already be present in the parent pipeline
106 graph.
107 """
108 key = NodeKey(NodeType.TASK, task_label)
109 if key not in self._parent_xgraph:
110 raise PipelineGraphError(f"{task_label!r} is not a task in the parent pipeline.")
111 self._members.add(key.name)
113 def discard(self, task_label: str) -> None:
114 """Remove a task from the subset if it is present.
116 Parameters
117 ----------
118 task_label : `str`
119 Label for the task. Must already be present in the parent pipeline
120 graph.
121 """
122 self._members.discard(task_label)