The current systax for waiting on something else is
```python
wg.tasks["label"].wait = [wg.tasks["other_label"]]
```
(see also example in [this Discourse post by Xing](https://aiida.discourse.group/t/workflow-optimization-starting-a-process-without-waiting-for-the-previous/430/9))
I think this syntax is, to me, not the one I would have intuitively expected.
I would probably expect a method to add nodes, e.g.
```python
wg.tasks["label"].wait_for([wg.tasks["other_label"]])
```
This would also have the option to just accept one task, without using list:
```python
wg.tasks["label"].wait_for(wg.tasks["other_label"])
```
Furthermore, it would (for me) make it possible/intuitive to have this function be called multiple times, and just keep appending to an internal list the other tasks you want to wait for.
So e.g.
```python
wg.tasks["label"].wait_for(wg.tasks["label1"])
wg.tasks["label"].wait_for(wg.tasks["label2"])
```
would be equivalent to
```python
wg.tasks["label"].wait_for([wg.tasks["label1"], wg.tasks["label2"]])
```
while with the current syntax, I imagine that one would need to do something like
```python
wg.tasks["label"].wait = [wg.tasks["label1"]
wg.tasks["label"].wait = wg.tasks["label"].wait + [wg.tasks["label2"]]
```
#### Text for the issue
At the moment, setting tasks to wait for is done with an attribute syntax:
```python
taks3.wait = [task1, taks2]
```
This *replaces* the current waiting list.
One can append to the list with:
```python
task3.wait.append(task4)
```
**NOTE**: This does not allow any validation on the appended items.
Suggestion: change to a function call.
```python
# wait_for will append the tasks internally.
task3.wait_for(task1) # syntactic sugar, equivalent to `task3.wait_for([task1])`
task3.wait_for([task1, task2])
```
Suggestion: make it mean "append to an internal waiting_list"
Then, we need to have a way to get the current full list, and then to reset it (in the rare cases people are working on this interactively).
Possible syntax:
```
waiting_list = task3.waiting_list # important: return a copy of the `_waiting_on` list, so user can not modify, e.g. in a subsequent `waiting_list.append(xxx)`
task3.clear_waiting_list()
```
Alternatives:
- use `waiting_on` instead of `waiting_list`?
- if we use `waiting_on`, what would the `clear()` method look like?
- Note that in the current suggestion, `waiting_on` is a class attribute with only the `get` method, so you cannot implement `waiting_on.clear()`, as waiting_on returns simply a list.
The alternative would be to return a special class, and use this syntax. It's more verbose.
```python=
tasks.waiting_on
>> WaitingList([task1, taks2])
task3.waiting_list.add([task1, task2])
task3.waiting_list.remove([task1, task2])
task3.waiting_list.clear()
```
Suggestion by EB: Maybe we can implement both, but we recommend only `task3.wait_on([task1, task2])` that is easier to read/type.
Note by GP: internally we probably use a set, and then add/remove/clear are set names. Decide if to keep the name `waiting_list` as maybe it's easier to undertsand than `waiting_set`.
Other option (final agreement with EB, GP, XW):
```python=
tasks.waiting_on
>> set([task1, taks2])
task3.waiting_on.add([task1, task2]) # append
task3.waiting_on.set([task1, task2]) # replace
task3.waiting_on.remove([task1, task2])
task3.waiting_on.clear()
```
but the *last two are advanced usages*, and the recommended one (shortcut) is
```python
# add check
task3.wait_on {task1, task2} # equivalent internally to `task3.waiting_on.add([task1, task2])`
```
```
task3.waiting_on = {task1, task2} # equivalent internally to `task3.waiting_on.add([task1, task2])`
```
add check for possible lock.