Marks a set of nodes returned by "get_ready" as processed. This method unblocks any successor of each node in *nodes* for being returned in the future by a call to "get_ready". Raises ValueError if any node in *nodes* has already been marked as processed by a previo
(self, *nodes)
| 153 | return self.is_active() |
| 154 | |
| 155 | def done(self, *nodes): |
| 156 | """Marks a set of nodes returned by "get_ready" as processed. |
| 157 | |
| 158 | This method unblocks any successor of each node in *nodes* for being returned |
| 159 | in the future by a call to "get_ready". |
| 160 | |
| 161 | Raises ValueError if any node in *nodes* has already been marked as |
| 162 | processed by a previous call to this method, if a node was not added to the |
| 163 | graph by using "add" or if called without calling "prepare" previously or if |
| 164 | node has not yet been returned by "get_ready". |
| 165 | """ |
| 166 | |
| 167 | if self._ready_nodes is None: |
| 168 | raise ValueError("prepare() must be called first") |
| 169 | |
| 170 | n2i = self._node2info |
| 171 | |
| 172 | for node in nodes: |
| 173 | |
| 174 | # Check if we know about this node (it was added previously using add() |
| 175 | if (nodeinfo := n2i.get(node)) is None: |
| 176 | raise ValueError(f"node {node!r} was not added using add()") |
| 177 | |
| 178 | # If the node has not being returned (marked as ready) previously, inform the user. |
| 179 | stat = nodeinfo.npredecessors |
| 180 | if stat != _NODE_OUT: |
| 181 | if stat >= 0: |
| 182 | raise ValueError( |
| 183 | f"node {node!r} was not passed out (still not ready)" |
| 184 | ) |
| 185 | elif stat == _NODE_DONE: |
| 186 | raise ValueError(f"node {node!r} was already marked done") |
| 187 | else: |
| 188 | assert False, f"node {node!r}: unknown status {stat}" |
| 189 | |
| 190 | # Mark the node as processed |
| 191 | nodeinfo.npredecessors = _NODE_DONE |
| 192 | |
| 193 | # Go to all the successors and reduce the number of predecessors, collecting all the ones |
| 194 | # that are ready to be returned in the next get_ready() call. |
| 195 | for successor in nodeinfo.successors: |
| 196 | successor_info = n2i[successor] |
| 197 | successor_info.npredecessors -= 1 |
| 198 | if successor_info.npredecessors == 0: |
| 199 | self._ready_nodes.append(successor) |
| 200 | self._nfinished += 1 |
| 201 | |
| 202 | # See note "On Finding Cycles" at the bottom. |
| 203 | def _find_cycle(self): |