def to_dot(self):
        """Render the dot for the recorded execution."""
        try:
            import pygraphviz as pgv
        except __HOLE__:
            warnings.warn('Extra requirements for "trace" are not available.')
            return
        graph = pgv.AGraph(directed=True, strict=False)

        hanging = set()
        for node_id, node_name in self.nodes.items():
            shape = 'box'
            if node_id in self.activities:
                shape = 'ellipse'
            finish_id = 'finish-%s' % node_id
            color, fontcolor = 'black', 'black'
            if node_id in self.errors:
                color, fontcolor = 'red', 'red'
            graph.add_node(node_id, label=node_name, shape=shape, width=0.8,
                           color=color, fontcolor=fontcolor)
            if node_id in self.results or node_id in self.errors:
                if node_id in self.errors:
                    rlabel = str(self.errors[node_id])
                else:
                    rlabel = short_repr.repr(self.results[node_id])
                    rlabel = ' ' + '\l '.join(rlabel.split('\n'))  # Left align
                graph.add_node(finish_id, label='', shape='point', width=0.1, color=color)
                graph.add_edge(node_id, finish_id, arrowhead='none', penwidth=3, fontsize=8,
                               color=color, fontcolor=fontcolor, label='  ' + rlabel)
            else:
                hanging.add(node_id)

        levels = ['l%s' % i for i in range(len(self.levels))]
        for l in levels:
            graph.add_node(l, shape='point', label='', width=0.1, style='invis')
        if levels:
            start = levels[0]
            for l in levels[1:]:
                graph.add_edge(start, l, style='invis')
                start = l

        for l_id, l in zip(levels, self.levels):
            if isinstance(l, list):
                graph.add_subgraph([l_id] + l, rank='same')
            else:
                graph.add_subgraph([l_id, 'finish-%s' % l], rank='same')

        for from_node, to_nodes in self.deps.items():
            if from_node in hanging:
                hanging.remove(from_node)
            color = 'black'
            style = ''
            if from_node in self.errors:
                color = 'red'
                from_node = 'finish-%s' % from_node
            elif from_node in self.results:
                from_node = 'finish-%s' % from_node
            else:
                style = 'dotted'
            for to_node in to_nodes:
                graph.add_edge(from_node, to_node, color=color, style=style)

        if hanging:
            for node_id in hanging:
                finish_id = 'finish-%s' % node_id
                graph.add_node(finish_id, label='', shape='point', width=0.1, style='invis')
                graph.add_edge(node_id, finish_id, style='dotted', arrowhead='none')
            # l_id is the last level here
            graph.add_subgraph([l_id] + ['finish-%s' % h for h in hanging], rank='same')

        for node_id in self.nodes:
            retries = self.timeouts[node_id]
            if retries:
                graph.add_edge(node_id, node_id, label=' %s' % retries, color='orange',
                               fontcolor='orange', fontsize=8)

        return graph
dataset/ETHPy150Open severb/flowy/flowy/tracer.py/ExecutionTracer.to_dot