PageRenderTime 40ms CodeModel.GetById 2ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 0ms

/circuits/tools/__init__.py

https://bitbucket.org/prologic/circuits/
Python | 167 lines | 160 code | 1 blank | 6 comment | 0 complexity | 96032ea6746b7586e72ce55f0390728f MD5 | raw file
  1# Module:   __init__
  2# Date:     8th November 2008
  3# Author:   James Mills, prologic at shortcircuit dot net dot au
  4
  5"""Circuits Tools
  6
  7circuits.tools contains a standard set of tools for circuits. These
  8tools are installed as executables with a prefix of "circuits."
  9"""
 10
 11from functools import wraps
 12from warnings import warn, warn_explicit
 13
 14from circuits.six import _func_code
 15
 16
 17def tryimport(modules, obj=None, message=None):
 18    modules = (modules,) if isinstance(modules, str) else modules
 19
 20    for module in modules:
 21        try:
 22            m = __import__(module, globals(), locals())
 23            return getattr(m, obj) if obj is not None else m
 24        except:
 25            pass
 26
 27    if message is not None:
 28        warn(message)
 29
 30
 31def walk(x, f, d=0, v=None):
 32    if not v:
 33        v = set()
 34    yield f(d, x)
 35    for c in x.components.copy():
 36        if c not in v:
 37            v.add(c)
 38            for r in walk(c, f, d + 1, v):
 39                yield r
 40
 41
 42def edges(x, e=None, v=None, d=0):
 43    if not e:
 44        e = set()
 45    if not v:
 46        v = []
 47    d += 1
 48    for c in x.components.copy():
 49        e.add((x, c, d))
 50        edges(c, e, v, d)
 51    return e
 52
 53
 54def findroot(x):
 55    if x.parent == x:
 56        return x
 57    else:
 58        return findroot(x.parent)
 59
 60
 61def kill(x):
 62    for c in x.components.copy():
 63        kill(c)
 64    if x.parent is not x:
 65        x.unregister()
 66
 67
 68def graph(x, name=None):
 69    """Display a directed graph of the Component structure of x
 70
 71    :param x: A Component or Manager to graph
 72    :type  x: Component or Manager
 73
 74    :param name: A name for the graph (defaults to x's name)
 75    :type  name: str
 76
 77    @return: A directed graph representing x's Component structure.
 78    @rtype:  str
 79    """
 80
 81    networkx = tryimport("networkx")
 82    pygraphviz = tryimport("pygraphviz")
 83    plt = tryimport("matplotlib.pyplot", "pyplot")
 84
 85    if networkx is not None and pygraphviz is not None and plt is not None:
 86        graph_edges = []
 87        for (u, v, d) in edges(x):
 88            graph_edges.append((u.name, v.name, float(d)))
 89
 90        g = networkx.DiGraph()
 91        g.add_weighted_edges_from(graph_edges)
 92
 93        elarge = [(u, v) for (u, v, d) in g.edges(data=True)
 94                  if d["weight"] > 3.0]
 95        esmall = [(u, v) for (u, v, d) in g.edges(data=True)
 96                  if d["weight"] <= 3.0]
 97
 98        pos = networkx.spring_layout(g)  # positions for all nodes
 99
100        # nodes
101        networkx.draw_networkx_nodes(g, pos, node_size=700)
102
103        # edges
104        networkx.draw_networkx_edges(g, pos, edgelist=elarge, width=1)
105        networkx.draw_networkx_edges(
106            g, pos, edgelist=esmall, width=1,
107            alpha=0.5, edge_color="b", style="dashed"
108        )
109
110        # labels
111        networkx.draw_networkx_labels(
112            g, pos, font_size=10, font_family="sans-serif"
113        )
114
115        plt.axis("off")
116
117        plt.savefig("{0:s}.png".format(name or x.name))
118        networkx.write_dot(g, "{0:s}.dot".format(name or x.name))
119
120        plt.clf()
121
122    def printer(d, x):
123        return "%s* %s" % (" " * d, x)
124
125    return "\n".join(walk(x, printer))
126
127
128def inspect(x):
129    """Display an inspection report of the Component or Manager x
130
131    :param x: A Component or Manager to graph
132    :type  x: Component or Manager
133
134    @return: A detailed inspection report of x
135    @rtype:  str
136    """
137
138    s = []
139    write = s.append
140
141    write(" Components: %d\n" % len(x.components))
142    for component in x.components:
143        write("  %s\n" % component)
144    write("\n")
145
146    from circuits import reprhandler
147
148    write(" Event Handlers: %d\n" % len(x._handlers.values()))
149    for event, handlers in x._handlers.items():
150        write("  %s; %d\n" % (event, len(x._handlers[event])))
151        for handler in x._handlers[event]:
152            write("   %s\n" % reprhandler(handler))
153
154    return "".join(s)
155
156
157def deprecated(f):
158    @wraps(f)
159    def wrapper(*args, **kwargs):
160        warn_explicit(
161            "Call to deprecated function {0:s}".format(f.__name__),
162            category=DeprecationWarning,
163            filename=getattr(f, _func_code).co_filename,
164            lineno=getattr(f, _func_code).co_firstlineno + 1
165        )
166        return f(*args, **kwargs)
167    return wrapper