예제 #1
0
 def test_topological_sort_2(self):
     """ Does another basic topological sort work?
     """
     pairs = [(1, 2), (1, 3), (2, 4), (3, 4), (5, 6), (4, 5)]
     result, has_cycles = topological_sort(pairs)
     self.assertTrue(not has_cycles)
     self.assertEqual(result, [1, 2, 3, 4, 5, 6])
예제 #2
0
 def test_topological_sort_2(self):
     """ Does another basic topological sort work?
     """
     pairs = [ (1,2), (1,3), (2,4), (3,4), (5,6), (4,5) ]
     result, has_cycles = topological_sort(pairs)
     self.assert_(not has_cycles)
     self.assertEquals(result, [1, 2, 3, 4, 5, 6])
 def test_topological_sort_1(self):
     """ Does a basic topological sort work?
     """
     pairs = [(1, 2), (3, 5), (4, 6), (1, 3), (1, 4), (1, 6), (2, 4)]
     result, has_cycles = topological_sort(pairs)
     self.assert_(not has_cycles)
     self.assertEquals(result, [1, 2, 3, 4, 5, 6])
예제 #4
0
파일: sortutil.py 프로젝트: pombreda/peppy2
def before_after_wildcard_sort(items):
    """ Sort a sequence of items with 'before', 'after', and 'id' attributes.
        
    The sort is topological. If an item does not specify a 'before' or 'after',
    it is placed after the preceding item.
    
    Simple wildcards are allowed in the 'before' or 'after' attributes.  The
    asterisk must be the last character in the string, so the form "text*"
    will match any id that starts with "text".

    If a cycle is found in the dependencies, a warning is logged and the order
    of the items is undefined.
    """
    # Handle a degenerate case for which the logic below will fail (because
    # prev_item will not be set).
    if len(items) < 2:
        return items

    # Build a set of pairs representing the graph.
    item_map = dict((item.id, item) for item in items if item.id)
    pairs = []
    prev_item = None
    for item in items:
        # Attempt to use 'before' and 'after' to make pairs.
        new_pairs = []
        if hasattr(item, 'before') and item.before:
            if item.before.endswith("*"):
                for child in find_wildcard_matches(item_map, item.before):
#                    print "%s should be before %s" % (item.id, child.id)
                    new_pairs.append((item, child))
            else:
                child = item_map.get(item.before)
                if child:
                    new_pairs.append((item, child))
        if hasattr(item, 'after') and item.after:
            if item.after.endswith("*"):
                for parent in find_wildcard_matches(item_map, item.after):
#                    print "%s should be after %s" % (item.id, parent.id)
                    new_pairs.append((parent, item))
            else:
                parent = item_map.get(item.after)
                if parent:
                    new_pairs.append((parent, item))

        # If we have any pairs, use them. Otherwise, use the previous unmatched
        # item as a parent, if possible.
        if new_pairs:
            pairs.extend(new_pairs)
        else:
            if prev_item:
                pairs.append((prev_item, item))
            prev_item = item

    # Now perform the actual sort.
    result, has_cycle = topological_sort(pairs)
    if has_cycle:
        logger.warning('Cycle in before/after sort for items %r', items)
    return result
예제 #5
0
 def test_topological_sort_3(self):
     """ Does cycle detection work?
     """
     pairs = [(1, 2), (2, 3), (3, 1)]
     result, has_cycles = topological_sort(pairs)
     self.assertTrue(has_cycles)
예제 #6
0
 def test_topological_sort_3(self):
     """ Does cycle detection work?
     """
     pairs = [ (1,2), (2,3), (3,1) ]
     result, has_cycles = topological_sort(pairs)
     self.assert_(has_cycles)