Repository: capsulecorplab/mindgraph

Issue:
add precedence for "blockers" in todo() method
Current `todo()` method implementation, only accounts for `Task.subtasks` and `Task.priority`. Needs to also account for `Task.blockers`, such that `Task` objects in "blockers" yield prior to `Task` objects in "subtasks".

Comments:

Patch:
diff --git a/mindgraph/graph.py b/mindgraph/graph.py
index be55272..c1dc475 100644
--- a/mindgraph/graph.py
+++ b/mindgraph/graph.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
-from typing import (Any, Callable, Generator, Iterator, List, Optional, Set,
-                    Tuple)
+from typing import Any, Callable, Iterator, List, Set, Tuple
+
 from yaml import dump, load
 
 
@@ -67,34 +67,36 @@ class Task(object):
                    depth: int = 0,
                    visited: Set["Task"] = None,
                    taskkey: Callable[["Task"], Any]=None,
-                   ) -> Generator[Tuple[int, "Task"], None, Set["Task"]]:
+                   ) -> Iterator[Tuple[int, "Task"]]:
         """Post-order traversal of Project rooted at Task"""
+        from itertools import chain
+
         if visited is None:
             visited = set()
 
-        children = self._subtasks
-        if taskkey is not None:
-            children = sorted(self._subtasks, key=taskkey)
+        if taskkey is None:
+            blockers = self.blockers
+            subtasks = self.subtasks
+        else:
+            blockers = sorted(self.blockers, key=taskkey)
+            subtasks = sorted(self.subtasks, key=taskkey)
 
-        for child in children:
-            if child not in visited:
-                visited = yield from child._postorder(depth+1,
-                                                      visited,
-                                                      taskkey)
+        for node in chain(blockers, subtasks):
+            if node in visited:
+                continue
+            yield from node._postorder(depth+1, visited, taskkey)
 
         yield (depth, self)
         visited.add(self)
 
-        return visited
-
     def todo(self) -> Iterator["Task"]:
         """Generate Tasks in todo order
 
         Tasks are scheduled by priority and to resolve blocking tasks
         """
         # sorts by priority (2 before 1), then alphabetical
-        def taskkey(Task):
-            return (-Task.priority, Task.name)
+        def taskkey(task):
+            return (-task.priority, task.name)
         return (x[1] for x in self._postorder(taskkey=taskkey))
 
     def __str__(self) -> str:


Test patch:
diff --git a/test/test_mindgraph.py b/test/test_mindgraph.py
index 3a375fa..368b7a3 100644
--- a/test/test_mindgraph.py
+++ b/test/test_mindgraph.py
@@ -1,10 +1,10 @@
 import os
-from random import choice
 import string
 from argparse import Namespace
+from random import choice
+from unittest.mock import mock_open, patch
 
 import pytest
-from unittest.mock import mock_open, patch
 import yaml
 
 from mindgraph import *
@@ -39,8 +39,8 @@ def task_project():
     t31 = t3.append('task 3.1')
     t32 = t3.append('task 3.2')
 
-    t32.subtasks.append(t22)
-    t12.subtasks.append(t22)
+    t32.blockedby(t22)
+    t12.blockedby(t22)
     return g