def test_klass_hierarchy(self):

        from traits.util.toposort import topological_sort

        from pgv.red.api import PythonNamespace

        namespace = PythonNamespace()
        package = namespace.lookup("quickblocks")

        def harvest_klasses(node):
            """ Recursively harvest all klasses from the given node. """

            klasses = []
            for child in node.children:
                if isinstance(child, Klass):
                    klasses.append(child)

                klasses.extend(harvest_klasses(child))

            return klasses

        klasses = harvest_klasses(package)

        # Build a dependency graph.
        graph = {}
        for klass in klasses:
            arcs = graph.setdefault(klass, [])
            # print 'Klass', klass.name, klass.module.filename
            arcs.extend(klass.bases)

        x = topological_sort(graph)
        print x

        return
示例#2
0
def get_distributions_in_egg_order(working_set, distributions=None):
    """ Return all distributions in Egg dependency order. """

    # If no specific list of distributions is specified then use all
    # distributions in the working set.
    if distributions is None:
        distributions = working_set

    # Build a dependency graph.
    graph = {}
    for distribution in distributions:
        arcs = graph.setdefault(distribution, [])
        arcs.extend(get_requires(working_set, distribution))

    distributions = topological_sort(graph)
    distributions.reverse()

    return distributions
示例#3
0
def get_distributions_in_egg_order(working_set, distributions=None):
    """ Return all distributions in Egg dependency order. """

    # If no specific list of distributions is specified then use all
    # distributions in the working set.
    if distributions is None:
        distributions = working_set

    # Build a dependency graph.
    graph = {}
    for distribution in distributions:
        arcs = graph.setdefault(distribution, [])
        arcs.extend(get_requires(working_set, distribution))

    distributions = topological_sort(graph)
    distributions.reverse()

    return distributions
示例#4
0
def closure(graph, sorted=True):
    """
    Returns the transitive closure of the graph.
    If sorted is True then the successor nodes will
    be sorted into topological order.
    """
    order = topological_sort(graph)
    # Map nodes to their index in the topologically sorted list for later use.
    idxorder = {}
    for i, obj in enumerate(order):
        idxorder[obj] = i
    reachable = {}
    for i in range(len(order) - 1, -1, -1):
        node = order[i]
        # We are going through in reverse topological order so we
        # are guaranteed that all of the children of the node
        # are already in reachable
        # We are using dicts to emulate sets for speed in Python 2.3.
        node_reachable = {}
        for child in graph.get(node, []):
            node_reachable[child] = 1
            node_reachable.update(reachable[child])
        reachable[node] = node_reachable
    # Now, build the return graph by doing a topological sort of
    # each reachable set, if required
    retval = {}
    for node, node_reachable in reachable.items():
        if not sorted:
            retval[node] = node_reachable.keys()
        else:
            # Create a tuple list so the faster built-in sort
            # comparator can be used.
            tmp = []
            reachable_list = node_reachable.keys()
            for n in reachable_list:
                tmp.append((idxorder[n], n))
            tmp.sort()
            reachable_list = [x[1] for x in tmp]
            retval[node] = reachable_list
    return retval
示例#5
0
def closure(graph, sorted=True):
    """
    Returns the transitive closure of the graph.
    If sorted is True then the successor nodes will
    be sorted into topological order.
    """
    order = topological_sort(graph)
    # Map nodes to their index in the topologically sorted list for later use.
    idxorder = {}
    for i, obj in enumerate(order):
        idxorder[obj] = i
    reachable = {}
    for i in range(len(order)-1, -1, -1):
        node = order[i]
        # We are going through in reverse topological order so we
        # are guaranteed that all of the children of the node
        # are already in reachable
        # We are using dicts to emulate sets for speed in Python 2.3.
        node_reachable = {}
        for child in graph.get(node, []):
            node_reachable[child] = 1
            node_reachable.update(reachable[child])
        reachable[node] = node_reachable
    # Now, build the return graph by doing a topological sort of
    # each reachable set, if required
    retval = {}
    for node, node_reachable in reachable.items():
        if not sorted:
            retval[node] = list(node_reachable.keys())
        else:
            # Create a tuple list so the faster built-in sort
            # comparator can be used.
            tmp = []
            reachable_list = list(node_reachable.keys())
            for n in reachable_list:
                tmp.append((idxorder[n], n))
            tmp.sort()
            reachable_list = [x[1] for x in tmp]
            retval[node] = reachable_list
    return retval
示例#6
0
# FIXME Implement graphs with sets of values instead of lists of values
def eq(g1, g2):
    return map_values(set, g1) == map_values(set, g2)


def reachable_graph(graph, nodes):
    ''' Return the subgraph of the given graph reachable from the given nodes.

        >>> reachable_graph({'a':'bc', 'b':'c' }, 'a')
        {'a': 'bc', 'b': 'c'}
        >>> reachable_graph({'a':'bc', 'b':'c' }, 'b')
        {'b': 'c'}
        >>> reachable_graph({'a':'bc', 'b':'c' }, 'c')
        {}
    '''
    ret = {}
    closed = closure(graph)
    for n in chain(nodes, flatten([closed[n] for n in nodes])):
        if n in graph.keys():
            ret[n] = graph[n]
    return ret


if __name__ == "__main__":
    g = {1: [2, 3], 2: [3, 4], 6: [3], 4: [6]}
    print topological_sort(g)
    print closure(g)

#### EOF ######################################################################
示例#7
0
# FIXME Implement graphs with sets of values instead of lists of values
def eq(g1, g2):
    return map_values(set, g1) == map_values(set, g2)


def reachable_graph(graph, nodes):
    ''' Return the subgraph of the given graph reachable from the given nodes.

        >>> sorted(reachable_graph({'a':'bc', 'b':'c' }, 'a').items())
        [('a', 'bc'), ('b', 'c')]
        >>> reachable_graph({'a':'bc', 'b':'c' }, 'b')
        {'b': 'c'}
        >>> reachable_graph({'a':'bc', 'b':'c' }, 'c')
        {}
    '''
    ret = {}
    closed = closure(graph)
    for n in chain(nodes, flatten([closed[n] for n in nodes])):
        if n in list(graph.keys()):
            ret[n] = graph[n]
    return ret


if __name__ == "__main__":
    g = {1: [2, 3], 2: [3, 4], 6: [3], 4: [6]}
    print((topological_sort(g)))
    print((closure(g)))

#### EOF ######################################################################
示例#8
0
# FIXME Implement graphs with sets of values instead of lists of values
def eq(g1, g2):
    return map_values(set, g1) == map_values(set, g2)

def reachable_graph(graph, nodes):
    ''' Return the subgraph of the given graph reachable from the given nodes.

        >>> sorted(reachable_graph({'a':'bc', 'b':'c' }, 'a').items())
        [('a', 'bc'), ('b', 'c')]
        >>> reachable_graph({'a':'bc', 'b':'c' }, 'b')
        {'b': 'c'}
        >>> reachable_graph({'a':'bc', 'b':'c' }, 'c')
        {}
    '''
    ret = {}
    closed = closure(graph)
    for n in chain(nodes, flatten([ closed[n] for n in nodes ])):
        if n in list(graph.keys()):
            ret[n] = graph[n]
    return ret

if __name__ == "__main__":
    g = {1:[2,3],
         2:[3,4],
         6:[3],
         4:[6]}
    print((topological_sort(g)))
    print((closure(g)))

#### EOF ######################################################################
示例#9
0
文件: graph.py 项目: B-Rich/codetools
# FIXME Implement graphs with sets of values instead of lists of values
def eq(g1, g2):
    return map_values(set, g1) == map_values(set, g2)

def reachable_graph(graph, nodes):
    ''' Return the subgraph of the given graph reachable from the given nodes.

        >>> reachable_graph({'a':'bc', 'b':'c' }, 'a')
        {'a': 'bc', 'b': 'c'}
        >>> reachable_graph({'a':'bc', 'b':'c' }, 'b')
        {'b': 'c'}
        >>> reachable_graph({'a':'bc', 'b':'c' }, 'c')
        {}
    '''
    ret = {}
    closed = closure(graph)
    for n in chain(nodes, flatten([ closed[n] for n in nodes ])):
        if n in graph.keys():
            ret[n] = graph[n]
    return ret

if __name__ == "__main__":
    g = {1:[2,3],
         2:[3,4],
         6:[3],
         4:[6]}
    print topological_sort(g)
    print closure(g)

#### EOF ######################################################################