Blame SOURCES/0002-support-python3.patch

rdobuilder 3e5fd2
From 050e291cbf63fd190f1ec14d65d1154a23ce8756 Mon Sep 17 00:00:00 2001
rdobuilder 3e5fd2
From: Sandro Tosi <morph@debian.org>
rdobuilder 3e5fd2
Date: Sun, 10 Jan 2016 00:25:45 +0000
rdobuilder 3e5fd2
Subject: support python3
rdobuilder 3e5fd2
rdobuilder 3e5fd2
Origin: https://github.com/nlhepler/pydot/tree/adf18a858a63b321b7e4ffd964a24d73add1bf4f
rdobuilder 3e5fd2
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=739858
rdobuilder 3e5fd2
Reviewed-by: Sandro Tosi <morph@debian.org>
rdobuilder 3e5fd2
Last-Update: 2016-01-10
rdobuilder 3e5fd2
rdobuilder 3e5fd2
---
rdobuilder 3e5fd2
 dot_parser.py |  429 ++++++++--------
rdobuilder 3e5fd2
 pydot.py      | 1553 +++++++++++++++++++++++++++------------------------------
rdobuilder 3e5fd2
 setup.py      |    6 +-
rdobuilder 3e5fd2
 3 files changed, 954 insertions(+), 1034 deletions(-)
rdobuilder 3e5fd2
rdobuilder 3e5fd2
diff --git a/dot_parser.py b/dot_parser.py
rdobuilder 3e5fd2
index dedd61a..4cdd482 100644
rdobuilder 3e5fd2
--- a/dot_parser.py
rdobuilder 3e5fd2
+++ b/dot_parser.py
rdobuilder 3e5fd2
@@ -1,4 +1,3 @@
rdobuilder 3e5fd2
-# -*- coding: Latin-1 -*-
rdobuilder 3e5fd2
 """Graphviz's dot language parser.
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 The dotparser parses graphviz files in dot and dot files and transforms them
rdobuilder 3e5fd2
@@ -10,236 +9,215 @@ Author: Michael Krause <michael@krause-software.de>
rdobuilder 3e5fd2
 Fixes by: Ero Carrera <ero@dkbza.org>
rdobuilder 3e5fd2
 """
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+from __future__ import division, print_function
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
 __author__ = ['Michael Krause', 'Ero Carrera']
rdobuilder 3e5fd2
 __license__ = 'MIT'
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 import sys
rdobuilder 3e5fd2
-import glob
rdobuilder 3e5fd2
 import pydot
rdobuilder 3e5fd2
-import re
rdobuilder 3e5fd2
 import codecs
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 from pyparsing import __version__ as pyparsing_version
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-from pyparsing import ( nestedExpr, Literal, CaselessLiteral, Word, Upcase, OneOrMore, ZeroOrMore,
rdobuilder 3e5fd2
-    Forward, NotAny, delimitedList, oneOf, Group, Optional, Combine, alphas, nums,
rdobuilder 3e5fd2
-    restOfLine, cStyleComment, nums, alphanums, printables, empty, quotedString,
rdobuilder 3e5fd2
-    ParseException, ParseResults, CharsNotIn, _noncomma, dblQuotedString, QuotedString, ParserElement )
rdobuilder 3e5fd2
+from pyparsing import (
rdobuilder 3e5fd2
+    nestedExpr, Literal, CaselessLiteral, Word, OneOrMore,
rdobuilder 3e5fd2
+    Forward, Group, Optional, Combine, nums, restOfLine,
rdobuilder 3e5fd2
+    cStyleComment, alphanums, printables, ParseException,
rdobuilder 3e5fd2
+    ParseResults, CharsNotIn, QuotedString
rdobuilder 3e5fd2
+    )
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+PY3 = not sys.version_info < (3, 0, 0)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+if PY3:
rdobuilder 3e5fd2
+    basestring = str
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 class P_AttrList:
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def __init__(self, toks):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
         self.attrs = {}
rdobuilder 3e5fd2
         i = 0
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         while i < len(toks):
rdobuilder 3e5fd2
             attrname = toks[i]
rdobuilder 3e5fd2
-            if i+2 < len(toks) and toks[i+1] == '=':
rdobuilder 3e5fd2
-                attrvalue = toks[i+2]
rdobuilder 3e5fd2
+            if i + 2 < len(toks) and toks[i + 1] == '=':
rdobuilder 3e5fd2
+                attrvalue = toks[i + 2]
rdobuilder 3e5fd2
                 i += 3
rdobuilder 3e5fd2
             else:
rdobuilder 3e5fd2
                 attrvalue = None
rdobuilder 3e5fd2
                 i += 1
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             self.attrs[attrname] = attrvalue
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-    def __repr__(self):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+    def __repr__(self):
rdobuilder 3e5fd2
         return "%s(%r)" % (self.__class__.__name__, self.attrs)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 class DefaultStatement(P_AttrList):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def __init__(self, default_type, attrs):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
         self.default_type = default_type
rdobuilder 3e5fd2
         self.attrs = attrs
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def __repr__(self):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-        return "%s(%s, %r)" % (self.__class__.__name__,
rdobuilder 3e5fd2
-            self.default_type, self.attrs)
rdobuilder 3e5fd2
+        return "%s(%s, %r)" % (
rdobuilder 3e5fd2
+            self.__class__.__name__,
rdobuilder 3e5fd2
+            self.default_type, self.attrs
rdobuilder 3e5fd2
+            )
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 top_graphs = list()
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-def push_top_graph_stmt(str, loc, toks):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+def push_top_graph_stmt(str, loc, toks):
rdobuilder 3e5fd2
     attrs = {}
rdobuilder 3e5fd2
     g = None
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     for element in toks:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-        if( isinstance(element, (ParseResults, tuple, list)) and
rdobuilder 3e5fd2
-            len(element) == 1 and isinstance(element[0], basestring) ):
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+        if (isinstance(element, (ParseResults, tuple, list)) and
rdobuilder 3e5fd2
+                len(element) == 1 and isinstance(element[0], basestring)):
rdobuilder 3e5fd2
             element = element[0]
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if element == 'strict':
rdobuilder 3e5fd2
             attrs['strict'] = True
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        elif element in ['graph', 'digraph']:
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        elif element in ['graph', 'digraph']:
rdobuilder 3e5fd2
             attrs = {}
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             g = pydot.Dot(graph_type=element, **attrs)
rdobuilder 3e5fd2
             attrs['type'] = element
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-            top_graphs.append( g )
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        elif isinstance( element, basestring):
rdobuilder 3e5fd2
-            g.set_name( element )
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+            top_graphs.append(g)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        elif isinstance(element, basestring):
rdobuilder 3e5fd2
+            g.set_name(element)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         elif isinstance(element, pydot.Subgraph):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-            g.obj_dict['attributes'].update( element.obj_dict['attributes'] )
rdobuilder 3e5fd2
-            g.obj_dict['edges'].update( element.obj_dict['edges'] )
rdobuilder 3e5fd2
-            g.obj_dict['nodes'].update( element.obj_dict['nodes'] )
rdobuilder 3e5fd2
-            g.obj_dict['subgraphs'].update( element.obj_dict['subgraphs'] )
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+            g.obj_dict['attributes'].update(element.obj_dict['attributes'])
rdobuilder 3e5fd2
+            g.obj_dict['edges'].update(element.obj_dict['edges'])
rdobuilder 3e5fd2
+            g.obj_dict['nodes'].update(element.obj_dict['nodes'])
rdobuilder 3e5fd2
+            g.obj_dict['subgraphs'].update(element.obj_dict['subgraphs'])
rdobuilder 3e5fd2
             g.set_parent_graph(g)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         elif isinstance(element, P_AttrList):
rdobuilder 3e5fd2
             attrs.update(element.attrs)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         elif isinstance(element, (ParseResults, list)):
rdobuilder 3e5fd2
             add_elements(g, element)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-            raise ValueError, "Unknown element statement: %r " % element
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+            raise ValueError("Unknown element statement: %r " % element)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     for g in top_graphs:
rdobuilder 3e5fd2
         update_parent_graph_hierarchy(g)
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    if len( top_graphs ) == 1:
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+    if len(top_graphs) == 1:
rdobuilder 3e5fd2
         return top_graphs[0]
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     return top_graphs
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def update_parent_graph_hierarchy(g, parent_graph=None, level=0):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     if parent_graph is None:
rdobuilder 3e5fd2
         parent_graph = g
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-    for key_name in ('edges',):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+    for key_name in ('edges',):
rdobuilder 3e5fd2
         if isinstance(g, pydot.frozendict):
rdobuilder 3e5fd2
             item_dict = g
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
             item_dict = g.obj_dict
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        if not item_dict.has_key( key_name ):
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if key_name not in item_dict:
rdobuilder 3e5fd2
             continue
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         for key, objs in item_dict[key_name].items():
rdobuilder 3e5fd2
             for obj in objs:
rdobuilder 3e5fd2
-                if 'parent_graph' in obj and obj['parent_graph'].get_parent_graph()==g:
rdobuilder 3e5fd2
+                if 'parent_graph' in obj and obj['parent_graph'].get_parent_graph() == g:
rdobuilder 3e5fd2
                     if obj['parent_graph'] is g:
rdobuilder 3e5fd2
                         pass
rdobuilder 3e5fd2
                     else:
rdobuilder 3e5fd2
                         obj['parent_graph'].set_parent_graph(parent_graph)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
                 if key_name == 'edges' and len(key) == 2:
rdobuilder 3e5fd2
-                    for idx, vertex in enumerate( obj['points'] ):
rdobuilder 3e5fd2
-                        if isinstance( vertex, (pydot.Graph, pydot.Subgraph, pydot.Cluster)):
rdobuilder 3e5fd2
+                    for idx, vertex in enumerate(obj['points']):
rdobuilder 3e5fd2
+                        if isinstance(vertex, (pydot.Graph, pydot.Subgraph, pydot.Cluster)):
rdobuilder 3e5fd2
                             vertex.set_parent_graph(parent_graph)
rdobuilder 3e5fd2
-                        if isinstance( vertex, pydot.frozendict):
rdobuilder 3e5fd2
+                        if isinstance(vertex, pydot.frozendict):
rdobuilder 3e5fd2
                             if vertex['parent_graph'] is g:
rdobuilder 3e5fd2
                                 pass
rdobuilder 3e5fd2
                             else:
rdobuilder 3e5fd2
                                 vertex['parent_graph'].set_parent_graph(parent_graph)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 def add_defaults(element, defaults):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     d = element.__dict__
rdobuilder 3e5fd2
     for key, value in defaults.items():
rdobuilder 3e5fd2
         if not d.get(key):
rdobuilder 3e5fd2
             d[key] = value
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 def add_elements(g, toks, defaults_graph=None, defaults_node=None, defaults_edge=None):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
     if defaults_graph is None:
rdobuilder 3e5fd2
         defaults_graph = {}
rdobuilder 3e5fd2
     if defaults_node is None:
rdobuilder 3e5fd2
         defaults_node = {}
rdobuilder 3e5fd2
     if defaults_edge is None:
rdobuilder 3e5fd2
         defaults_edge = {}
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     for elm_idx, element in enumerate(toks):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
         if isinstance(element, (pydot.Subgraph, pydot.Cluster)):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
             add_defaults(element, defaults_graph)
rdobuilder 3e5fd2
             g.add_subgraph(element)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         elif isinstance(element, pydot.Node):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
             add_defaults(element, defaults_node)
rdobuilder 3e5fd2
             g.add_node(element)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         elif isinstance(element, pydot.Edge):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
             add_defaults(element, defaults_edge)
rdobuilder 3e5fd2
             g.add_edge(element)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         elif isinstance(element, ParseResults):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
             for e in element:
rdobuilder 3e5fd2
                 add_elements(g, [e], defaults_graph, defaults_node, defaults_edge)
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         elif isinstance(element, DefaultStatement):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
             if element.default_type == 'graph':
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
                 default_graph_attrs = pydot.Node('graph', **element.attrs)
rdobuilder 3e5fd2
                 g.add_node(default_graph_attrs)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
             elif element.default_type == 'node':
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
                 default_node_attrs = pydot.Node('node', **element.attrs)
rdobuilder 3e5fd2
                 g.add_node(default_node_attrs)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
             elif element.default_type == 'edge':
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
                 default_edge_attrs = pydot.Node('edge', **element.attrs)
rdobuilder 3e5fd2
                 g.add_node(default_edge_attrs)
rdobuilder 3e5fd2
                 defaults_edge.update(element.attrs)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
             else:
rdobuilder 3e5fd2
-                raise ValueError, "Unknown DefaultStatement: %s " % element.default_type
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+                raise ValueError("Unknown DefaultStatement: %s " % element.default_type)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         elif isinstance(element, P_AttrList):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
             g.obj_dict['attributes'].update(element.attrs)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-            raise ValueError, "Unknown element statement: %r" % element
rdobuilder 3e5fd2
+            raise ValueError("Unknown element statement: %r" % element)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-def push_graph_stmt(str, loc, toks):            
rdobuilder 3e5fd2
-                       
rdobuilder 3e5fd2
+def push_graph_stmt(str, loc, toks):
rdobuilder 3e5fd2
     g = pydot.Subgraph('')
rdobuilder 3e5fd2
     add_elements(g, toks)
rdobuilder 3e5fd2
     return g
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def push_subgraph_stmt(str, loc, toks):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     g = pydot.Subgraph('')
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     for e in toks:
rdobuilder 3e5fd2
-        if len(e)==3:
rdobuilder 3e5fd2
+        if len(e) == 3:
rdobuilder 3e5fd2
             e[2].set_name(e[1])
rdobuilder 3e5fd2
             if e[0] == 'subgraph':
rdobuilder 3e5fd2
                 e[2].obj_dict['show_keyword'] = True
rdobuilder 3e5fd2
@@ -253,11 +231,9 @@ def push_subgraph_stmt(str, loc, toks):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def push_default_stmt(str, loc, toks):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     # The pydot class instances should be marked as
rdobuilder 3e5fd2
     # default statements to be inherited by actual
rdobuilder 3e5fd2
     # graphs, nodes and edges.
rdobuilder 3e5fd2
-    #
rdobuilder 3e5fd2
     default_type = toks[0][0]
rdobuilder 3e5fd2
     if len(toks) > 1:
rdobuilder 3e5fd2
         attrs = toks[1].attrs
rdobuilder 3e5fd2
@@ -267,90 +243,80 @@ def push_default_stmt(str, loc, toks):
rdobuilder 3e5fd2
     if default_type in ['graph', 'node', 'edge']:
rdobuilder 3e5fd2
         return DefaultStatement(default_type, attrs)
rdobuilder 3e5fd2
     else:
rdobuilder 3e5fd2
-        raise ValueError, "Unknown default statement: %r " % toks
rdobuilder 3e5fd2
+        raise ValueError("Unknown default statement: %r " % toks)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def push_attr_list(str, loc, toks):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     p = P_AttrList(toks)
rdobuilder 3e5fd2
     return p
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def get_port(node):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-    if len(node)>1:
rdobuilder 3e5fd2
+    if len(node) > 1:
rdobuilder 3e5fd2
         if isinstance(node[1], ParseResults):
rdobuilder 3e5fd2
-            if len(node[1][0])==2:
rdobuilder 3e5fd2
-                if node[1][0][0]==':':
rdobuilder 3e5fd2
+            if len(node[1][0]) == 2:
rdobuilder 3e5fd2
+                if node[1][0][0] == ':':
rdobuilder 3e5fd2
                     return node[1][0][1]
rdobuilder 3e5fd2
-                    
rdobuilder 3e5fd2
     return None
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-def do_node_ports(node):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+def do_node_ports(node):
rdobuilder 3e5fd2
     node_port = ''
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     if len(node) > 1:
rdobuilder 3e5fd2
-        node_port = ''.join( [str(a)+str(b) for a,b in node[1] ] )
rdobuilder 3e5fd2
+        node_port = ''.join([str(a) + str(b) for a, b in node[1]])
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     return node_port
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
 def push_edge_stmt(str, loc, toks):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
     tok_attrs = [a for a in toks if isinstance(a, P_AttrList)]
rdobuilder 3e5fd2
     attrs = {}
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     for a in tok_attrs:
rdobuilder 3e5fd2
         attrs.update(a.attrs)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     e = []
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     if isinstance(toks[0][0], pydot.Graph):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         n_prev = pydot.frozendict(toks[0][0].obj_dict)
rdobuilder 3e5fd2
-    else:        
rdobuilder 3e5fd2
-        n_prev = toks[0][0] + do_node_ports( toks[0] )
rdobuilder 3e5fd2
+    else:
rdobuilder 3e5fd2
+        n_prev = toks[0][0] + do_node_ports(toks[0])
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     if isinstance(toks[2][0], ParseResults):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-        n_next_list = [[n.get_name(),] for n in toks[2][0] ]
rdobuilder 3e5fd2
+        n_next_list = [[n.get_name()] for n in toks[2][0]]
rdobuilder 3e5fd2
         for n_next in [n for n in n_next_list]:
rdobuilder 3e5fd2
             n_next_port = do_node_ports(n_next)
rdobuilder 3e5fd2
-            e.append(pydot.Edge(n_prev, n_next[0]+n_next_port, **attrs))
rdobuilder 3e5fd2
+            e.append(pydot.Edge(n_prev, n_next[0] + n_next_port, **attrs))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     elif isinstance(toks[2][0], pydot.Graph):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         e.append(pydot.Edge(n_prev, pydot.frozendict(toks[2][0].obj_dict), **attrs))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     elif isinstance(toks[2][0], pydot.Node):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         node = toks[2][0]
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if node.get_port() is not None:
rdobuilder 3e5fd2
             name_port = node.get_name() + ":" + node.get_port()
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
             name_port = node.get_name()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         e.append(pydot.Edge(n_prev, name_port, **attrs))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     elif isinstance(toks[2][0], type('')):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         for n_next in [n for n in tuple(toks)[2::2]]:
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
             if isinstance(n_next, P_AttrList) or not isinstance(n_next[0], type('')):
rdobuilder 3e5fd2
                 continue
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-            n_next_port = do_node_ports( n_next )
rdobuilder 3e5fd2
-            e.append(pydot.Edge(n_prev, n_next[0]+n_next_port, **attrs))
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
-            n_prev = n_next[0]+n_next_port
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+            n_next_port = do_node_ports(n_next)
rdobuilder 3e5fd2
+            e.append(pydot.Edge(n_prev, n_next[0] + n_next_port, **attrs))
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+            n_prev = n_next[0] + n_next_port
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     else:
rdobuilder 3e5fd2
         # UNEXPECTED EDGE TYPE
rdobuilder 3e5fd2
         pass
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-    return e
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+    return e
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def push_node_stmt(s, loc, toks):
rdobuilder 3e5fd2
@@ -359,30 +325,25 @@ def push_node_stmt(s, loc, toks):
rdobuilder 3e5fd2
         attrs = toks[1].attrs
rdobuilder 3e5fd2
     else:
rdobuilder 3e5fd2
         attrs = {}
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     node_name = toks[0]
rdobuilder 3e5fd2
     if isinstance(node_name, list) or isinstance(node_name, tuple):
rdobuilder 3e5fd2
-        if len(node_name)>0:
rdobuilder 3e5fd2
+        if len(node_name) > 0:
rdobuilder 3e5fd2
             node_name = node_name[0]
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     n = pydot.Node(str(node_name), **attrs)
rdobuilder 3e5fd2
     return n
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 graphparser = None
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-def graph_definition():
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+def graph_definition():
rdobuilder 3e5fd2
     global graphparser
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     if not graphparser:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         # punctuation
rdobuilder 3e5fd2
-        colon  = Literal(":")
rdobuilder 3e5fd2
+        colon = Literal(":")
rdobuilder 3e5fd2
         lbrace = Literal("{")
rdobuilder 3e5fd2
         rbrace = Literal("}")
rdobuilder 3e5fd2
         lbrack = Literal("[")
rdobuilder 3e5fd2
@@ -390,142 +351,170 @@ def graph_definition():
rdobuilder 3e5fd2
         lparen = Literal("(")
rdobuilder 3e5fd2
         rparen = Literal(")")
rdobuilder 3e5fd2
         equals = Literal("=")
rdobuilder 3e5fd2
-        comma  = Literal(",")
rdobuilder 3e5fd2
-        dot    = Literal(".")
rdobuilder 3e5fd2
-        slash  = Literal("/")
rdobuilder 3e5fd2
-        bslash = Literal("\\")
rdobuilder 3e5fd2
-        star   = Literal("*")
rdobuilder 3e5fd2
-        semi   = Literal(";")
rdobuilder 3e5fd2
-        at     = Literal("@")
rdobuilder 3e5fd2
-        minus  = Literal("-")
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+        comma = Literal(",")
rdobuilder 3e5fd2
+        # dot = Literal(".")
rdobuilder 3e5fd2
+        # slash = Literal("/")
rdobuilder 3e5fd2
+        # bslash = Literal("\\")
rdobuilder 3e5fd2
+        # star = Literal("*")
rdobuilder 3e5fd2
+        semi = Literal(";")
rdobuilder 3e5fd2
+        at = Literal("@")
rdobuilder 3e5fd2
+        minus = Literal("-")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         # keywords
rdobuilder 3e5fd2
-        strict_    = CaselessLiteral("strict")
rdobuilder 3e5fd2
-        graph_     = CaselessLiteral("graph")
rdobuilder 3e5fd2
-        digraph_   = CaselessLiteral("digraph")
rdobuilder 3e5fd2
-        subgraph_  = CaselessLiteral("subgraph")
rdobuilder 3e5fd2
-        node_      = CaselessLiteral("node")
rdobuilder 3e5fd2
-        edge_      = CaselessLiteral("edge")
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+        strict_ = CaselessLiteral("strict")
rdobuilder 3e5fd2
+        graph_ = CaselessLiteral("graph")
rdobuilder 3e5fd2
+        digraph_ = CaselessLiteral("digraph")
rdobuilder 3e5fd2
+        subgraph_ = CaselessLiteral("subgraph")
rdobuilder 3e5fd2
+        node_ = CaselessLiteral("node")
rdobuilder 3e5fd2
+        edge_ = CaselessLiteral("edge")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         # token definitions
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        identifier = Word(alphanums + "_." ).setName("identifier")
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        double_quoted_string = QuotedString('"', multiline=True, unquoteResults=False) # dblQuotedString
rdobuilder 3e5fd2
+        identifier = Word(alphanums + "_.").setName("identifier")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        # dblQuotedString
rdobuilder 3e5fd2
+        double_quoted_string = QuotedString('"', multiline=True, unquoteResults=False)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        alphastring_ = OneOrMore(CharsNotIn(_noncomma + ' '))
rdobuilder 3e5fd2
+        noncomma_ = "".join([c for c in printables if c != ","])
rdobuilder 3e5fd2
+        alphastring_ = OneOrMore(CharsNotIn(noncomma_ + ' '))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         def parse_html(s, loc, toks):
rdobuilder 3e5fd2
             return '<%s>' % ''.join(toks[0])
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         opener = '<'
rdobuilder 3e5fd2
         closer = '>'
rdobuilder 3e5fd2
-        html_text = nestedExpr( opener, closer, 
rdobuilder 3e5fd2
-            ( CharsNotIn( opener + closer )  ) 
rdobuilder 3e5fd2
-                ).setParseAction(parse_html).leaveWhitespace()
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-        ID = ( identifier | html_text | 
rdobuilder 3e5fd2
-            double_quoted_string | #.setParseAction(strip_quotes) |
rdobuilder 3e5fd2
-            alphastring_ ).setName("ID")
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        float_number = Combine(Optional(minus) +	
rdobuilder 3e5fd2
-            OneOrMore(Word(nums + "."))).setName("float_number")
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        righthand_id =  (float_number | ID ).setName("righthand_id")
rdobuilder 3e5fd2
+        html_text = nestedExpr(
rdobuilder 3e5fd2
+            opener, closer,
rdobuilder 3e5fd2
+            (CharsNotIn(opener + closer))
rdobuilder 3e5fd2
+            ).setParseAction(parse_html).leaveWhitespace()
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        ID = (
rdobuilder 3e5fd2
+            identifier | html_text |
rdobuilder 3e5fd2
+            double_quoted_string |  # .setParseAction(strip_quotes) |
rdobuilder 3e5fd2
+            alphastring_
rdobuilder 3e5fd2
+            ).setName("ID")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        float_number = Combine(
rdobuilder 3e5fd2
+            Optional(minus) +
rdobuilder 3e5fd2
+            OneOrMore(Word(nums + "."))
rdobuilder 3e5fd2
+            ).setName("float_number")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        righthand_id = (float_number | ID).setName("righthand_id")
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         port_angle = (at + ID).setName("port_angle")
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        port_location = (OneOrMore(Group(colon + ID)) |	
rdobuilder 3e5fd2
-            Group(colon + lparen + ID + comma + ID + rparen)).setName("port_location")
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        port = (Group(port_location + Optional(port_angle)) |	
rdobuilder 3e5fd2
-            Group(port_angle + Optional(port_location))).setName("port")
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        port_location = (
rdobuilder 3e5fd2
+            OneOrMore(Group(colon + ID)) |
rdobuilder 3e5fd2
+            Group(colon + lparen + ID + comma + ID + rparen)
rdobuilder 3e5fd2
+            ).setName("port_location")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        port = (
rdobuilder 3e5fd2
+            Group(port_location + Optional(port_angle)) |
rdobuilder 3e5fd2
+            Group(port_angle + Optional(port_location))
rdobuilder 3e5fd2
+            ).setName("port")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         node_id = (ID + Optional(port))
rdobuilder 3e5fd2
-        a_list = OneOrMore(ID + Optional(equals + righthand_id) +
rdobuilder 3e5fd2
-            Optional(comma.suppress())).setName("a_list")
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        attr_list = OneOrMore(lbrack.suppress() + Optional(a_list) +	
rdobuilder 3e5fd2
-            rbrack.suppress()).setName("attr_list")
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+        a_list = OneOrMore(
rdobuilder 3e5fd2
+            ID + Optional(equals + righthand_id) + Optional(comma.suppress())
rdobuilder 3e5fd2
+            ).setName("a_list")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        attr_list = OneOrMore(
rdobuilder 3e5fd2
+            lbrack.suppress() + Optional(a_list) + rbrack.suppress()
rdobuilder 3e5fd2
+            ).setName("attr_list")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         attr_stmt = (Group(graph_ | node_ | edge_) + attr_list).setName("attr_stmt")
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         edgeop = (Literal("--") | Literal("->")).setName("edgeop")
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         stmt_list = Forward()
rdobuilder 3e5fd2
-        graph_stmt = Group(lbrace.suppress() + Optional(stmt_list) +	
rdobuilder 3e5fd2
-            rbrace.suppress() + Optional(semi.suppress()) ).setName("graph_stmt")
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+        graph_stmt = Group(
rdobuilder 3e5fd2
+            lbrace.suppress() + Optional(stmt_list) +
rdobuilder 3e5fd2
+            rbrace.suppress() + Optional(semi.suppress())
rdobuilder 3e5fd2
+            ).setName("graph_stmt")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         edge_point = Forward()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         edgeRHS = OneOrMore(edgeop + edge_point)
rdobuilder 3e5fd2
         edge_stmt = edge_point + edgeRHS + Optional(attr_list)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         subgraph = Group(subgraph_ + Optional(ID) + graph_stmt).setName("subgraph")
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        edge_point << Group( subgraph | graph_stmt | node_id ).setName('edge_point')
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        node_stmt = (node_id + Optional(attr_list) + Optional(semi.suppress())).setName("node_stmt")
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        edge_point << Group(subgraph | graph_stmt | node_id).setName('edge_point')
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        node_stmt = (
rdobuilder 3e5fd2
+            node_id + Optional(attr_list) + Optional(semi.suppress())
rdobuilder 3e5fd2
+            ).setName("node_stmt")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         assignment = (ID + equals + righthand_id).setName("assignment")
rdobuilder 3e5fd2
-        stmt =  (assignment | edge_stmt | attr_stmt | subgraph | graph_stmt | node_stmt).setName("stmt")
rdobuilder 3e5fd2
+        stmt = (
rdobuilder 3e5fd2
+            assignment | edge_stmt | attr_stmt |
rdobuilder 3e5fd2
+            subgraph | graph_stmt | node_stmt
rdobuilder 3e5fd2
+            ).setName("stmt")
rdobuilder 3e5fd2
         stmt_list << OneOrMore(stmt + Optional(semi.suppress()))
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        graphparser = OneOrMore( (Optional(strict_) + Group((graph_ | digraph_)) +
rdobuilder 3e5fd2
-            Optional(ID) + graph_stmt).setResultsName("graph") )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        graphparser = OneOrMore((
rdobuilder 3e5fd2
+            Optional(strict_) + Group((graph_ | digraph_)) +
rdobuilder 3e5fd2
+            Optional(ID) + graph_stmt
rdobuilder 3e5fd2
+            ).setResultsName("graph"))
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         singleLineComment = Group("//" + restOfLine) | Group("#" + restOfLine)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         # actions
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
         graphparser.ignore(singleLineComment)
rdobuilder 3e5fd2
         graphparser.ignore(cStyleComment)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         assignment.setParseAction(push_attr_list)
rdobuilder 3e5fd2
         a_list.setParseAction(push_attr_list)
rdobuilder 3e5fd2
         edge_stmt.setParseAction(push_edge_stmt)
rdobuilder 3e5fd2
         node_stmt.setParseAction(push_node_stmt)
rdobuilder 3e5fd2
         attr_stmt.setParseAction(push_default_stmt)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         subgraph.setParseAction(push_subgraph_stmt)
rdobuilder 3e5fd2
         graph_stmt.setParseAction(push_graph_stmt)
rdobuilder 3e5fd2
         graphparser.setParseAction(push_top_graph_stmt)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     return graphparser
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def parse_dot_data(data):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     global top_graphs
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     top_graphs = list()
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    if data.startswith(codecs.BOM_UTF8):
rdobuilder 3e5fd2
-        data = data.decode( 'utf-8' )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+    if PY3:
rdobuilder 3e5fd2
+        if isinstance(data, bytes):
rdobuilder 3e5fd2
+            # this is extremely hackish
rdobuilder 3e5fd2
+            try:
rdobuilder 3e5fd2
+                idx = data.index(b'charset') + 7
rdobuilder 3e5fd2
+                while data[idx] in b' \t\n\r=':
rdobuilder 3e5fd2
+                    idx += 1
rdobuilder 3e5fd2
+                fst = idx
rdobuilder 3e5fd2
+                while data[idx] not in b' \t\n\r];,':
rdobuilder 3e5fd2
+                    idx += 1
rdobuilder 3e5fd2
+                charset = data[fst:idx].strip(b'"\'').decode('ascii')
rdobuilder 3e5fd2
+                data = data.decode(charset)
rdobuilder 3e5fd2
+            except:
rdobuilder 3e5fd2
+                data = data.decode('utf-8')
rdobuilder 3e5fd2
+    else:
rdobuilder 3e5fd2
+        if data.startswith(codecs.BOM_UTF8):
rdobuilder 3e5fd2
+            data = data.decode('utf-8')
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     try:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         graphparser = graph_definition()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if pyparsing_version >= '1.2':
rdobuilder 3e5fd2
             graphparser.parseWithTabs()
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         tokens = graphparser.parseString(data)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         if len(tokens) == 1:
rdobuilder 3e5fd2
             return tokens[0]
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
             return [g for g in tokens]
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-    except ParseException, err:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-        print err.line
rdobuilder 3e5fd2
-        print " "*(err.column-1) + "^"
rdobuilder 3e5fd2
-        print err
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+    except ParseException:
rdobuilder 3e5fd2
+        err = sys.exc_info()[1]
rdobuilder 3e5fd2
+        print(err.line)
rdobuilder 3e5fd2
+        print(" " * (err.column - 1) + "^")
rdobuilder 3e5fd2
+        print(err)
rdobuilder 3e5fd2
         return None
rdobuilder 3e5fd2
diff --git a/pydot.py b/pydot.py
rdobuilder 3e5fd2
index e9bd2a1..c20db18 100644
rdobuilder 3e5fd2
--- a/pydot.py
rdobuilder 3e5fd2
+++ b/pydot.py
rdobuilder 3e5fd2
@@ -17,24 +17,40 @@ Copyright (c) 2005-2011 Ero Carrera <ero.carrera@gmail.com>
rdobuilder 3e5fd2
 Distributed under MIT license [http://opensource.org/licenses/mit-license.html].
rdobuilder 3e5fd2
 """
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-__revision__ = "$LastChangedRevision: 28 $"
rdobuilder 3e5fd2
+from __future__ import division, print_function
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
 __author__ = 'Ero Carrera'
rdobuilder 3e5fd2
-__version__ = '1.0.%d' % int( __revision__[21:-2] )
rdobuilder 3e5fd2
+__version__ = '1.0.29'
rdobuilder 3e5fd2
 __license__ = 'MIT'
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 import os
rdobuilder 3e5fd2
 import re
rdobuilder 3e5fd2
 import subprocess
rdobuilder 3e5fd2
+import sys
rdobuilder 3e5fd2
 import tempfile
rdobuilder 3e5fd2
 import copy
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+from operator import itemgetter
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
 try:
rdobuilder 3e5fd2
     import dot_parser
rdobuilder 3e5fd2
-except Exception, e:
rdobuilder 3e5fd2
-    print "Couldn't import dot_parser, loading of dot files will not be possible."
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+except Exception:
rdobuilder 3e5fd2
+    print("Couldn't import dot_parser, loading of dot files will not be possible.")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+PY3 = not sys.version_info < (3, 0, 0)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-GRAPH_ATTRIBUTES = set( ['Damping', 'K', 'URL', 'aspect', 'bb', 'bgcolor',
rdobuilder 3e5fd2
+if PY3:
rdobuilder 3e5fd2
+    NULL_SEP = b''
rdobuilder 3e5fd2
+    basestring = str
rdobuilder 3e5fd2
+    long = int
rdobuilder 3e5fd2
+    unicode = str
rdobuilder 3e5fd2
+else:
rdobuilder 3e5fd2
+    NULL_SEP = ''
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+GRAPH_ATTRIBUTES = set([
rdobuilder 3e5fd2
+    'Damping', 'K', 'URL', 'aspect', 'bb', 'bgcolor',
rdobuilder 3e5fd2
     'center', 'charset', 'clusterrank', 'colorscheme', 'comment', 'compound',
rdobuilder 3e5fd2
     'concentrate', 'defaultdist', 'dim', 'dimen', 'diredgeconstraints',
rdobuilder 3e5fd2
     'dpi', 'epsilon', 'esep', 'fontcolor', 'fontname', 'fontnames',
rdobuilder 3e5fd2
@@ -46,13 +62,15 @@ GRAPH_ATTRIBUTES = set( ['Damping', 'K', 'URL', 'aspect', 'bb', 'bgcolor',
rdobuilder 3e5fd2
     'overlap_scaling', 'pack', 'packmode', 'pad', 'page', 'pagedir',
rdobuilder 3e5fd2
     'quadtree', 'quantum', 'rankdir', 'ranksep', 'ratio', 'remincross',
rdobuilder 3e5fd2
     'repulsiveforce', 'resolution', 'root', 'rotate', 'searchsize', 'sep',
rdobuilder 3e5fd2
-    'showboxes', 'size', 'smoothing', 'sortv', 'splines', 'start', 
rdobuilder 3e5fd2
+    'showboxes', 'size', 'smoothing', 'sortv', 'splines', 'start',
rdobuilder 3e5fd2
     'stylesheet', 'target', 'truecolor', 'viewport', 'voro_margin',
rdobuilder 3e5fd2
-    # for subgraphs 
rdobuilder 3e5fd2
-    'rank' ] )
rdobuilder 3e5fd2
+    # for subgraphs
rdobuilder 3e5fd2
+    'rank'
rdobuilder 3e5fd2
+   ])
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-EDGE_ATTRIBUTES = set( ['URL', 'arrowhead', 'arrowsize', 'arrowtail',
rdobuilder 3e5fd2
+EDGE_ATTRIBUTES = set([
rdobuilder 3e5fd2
+    'URL', 'arrowhead', 'arrowsize', 'arrowtail',
rdobuilder 3e5fd2
     'color', 'colorscheme', 'comment', 'constraint', 'decorate', 'dir',
rdobuilder 3e5fd2
     'edgeURL', 'edgehref', 'edgetarget', 'edgetooltip', 'fontcolor',
rdobuilder 3e5fd2
     'fontname', 'fontsize', 'headURL', 'headclip', 'headhref', 'headlabel',
rdobuilder 3e5fd2
@@ -63,10 +81,12 @@ EDGE_ATTRIBUTES = set( ['URL', 'arrowhead', 'arrowsize', 'arrowtail',
rdobuilder 3e5fd2
     'nojustify', 'penwidth', 'pos', 'samehead', 'sametail', 'showboxes',
rdobuilder 3e5fd2
     'style', 'tailURL', 'tailclip', 'tailhref', 'taillabel', 'tailport',
rdobuilder 3e5fd2
     'tailtarget', 'tailtooltip', 'target', 'tooltip', 'weight',
rdobuilder 3e5fd2
-    'rank' ] )
rdobuilder 3e5fd2
+    'rank'
rdobuilder 3e5fd2
+   ])
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-NODE_ATTRIBUTES = set( ['URL', 'color', 'colorscheme', 'comment',
rdobuilder 3e5fd2
+NODE_ATTRIBUTES = set([
rdobuilder 3e5fd2
+    'URL', 'color', 'colorscheme', 'comment',
rdobuilder 3e5fd2
     'distortion', 'fillcolor', 'fixedsize', 'fontcolor', 'fontname',
rdobuilder 3e5fd2
     'fontsize', 'group', 'height', 'id', 'image', 'imagescale', 'label',
rdobuilder 3e5fd2
     'labelloc', 'layer', 'margin', 'nojustify', 'orientation', 'penwidth',
rdobuilder 3e5fd2
@@ -74,14 +94,62 @@ NODE_ATTRIBUTES = set( ['URL', 'color', 'colorscheme', 'comment',
rdobuilder 3e5fd2
     'shape', 'shapefile', 'showboxes', 'sides', 'skew', 'sortv', 'style',
rdobuilder 3e5fd2
     'target', 'tooltip', 'vertices', 'width', 'z',
rdobuilder 3e5fd2
     # The following are attributes dot2tex
rdobuilder 3e5fd2
-    'texlbl',  'texmode' ] )
rdobuilder 3e5fd2
+    'texlbl', 'texmode'
rdobuilder 3e5fd2
+   ])
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-CLUSTER_ATTRIBUTES = set( ['K', 'URL', 'bgcolor', 'color', 'colorscheme',
rdobuilder 3e5fd2
+CLUSTER_ATTRIBUTES = set([
rdobuilder 3e5fd2
+    'K', 'URL', 'bgcolor', 'color', 'colorscheme',
rdobuilder 3e5fd2
     'fillcolor', 'fontcolor', 'fontname', 'fontsize', 'label', 'labeljust',
rdobuilder 3e5fd2
     'labelloc', 'lheight', 'lp', 'lwidth', 'nojustify', 'pencolor',
rdobuilder 3e5fd2
-    'penwidth', 'peripheries', 'sortv', 'style', 'target', 'tooltip'] )
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+    'penwidth', 'peripheries', 'sortv', 'style', 'target', 'tooltip'
rdobuilder 3e5fd2
+   ])
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+def is_string_like(obj): # from John Hunter, types-free version
rdobuilder 3e5fd2
+    """Check if obj is string."""
rdobuilder 3e5fd2
+    try:
rdobuilder 3e5fd2
+        obj + ''
rdobuilder 3e5fd2
+    except (TypeError, ValueError):
rdobuilder 3e5fd2
+        return False
rdobuilder 3e5fd2
+    return True
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+def get_fobj(fname, mode='w+'):
rdobuilder 3e5fd2
+    """Obtain a proper file object.
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+    Parameters
rdobuilder 3e5fd2
+    ----------
rdobuilder 3e5fd2
+    fname : string, file object, file descriptor
rdobuilder 3e5fd2
+        If a string or file descriptor, then we create a file object. If *fname*
rdobuilder 3e5fd2
+        is a file object, then we do nothing and ignore the specified *mode*
rdobuilder 3e5fd2
+        parameter.
rdobuilder 3e5fd2
+    mode : str
rdobuilder 3e5fd2
+        The mode of the file to be opened.
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+    Returns
rdobuilder 3e5fd2
+    -------
rdobuilder 3e5fd2
+    fobj : file object
rdobuilder 3e5fd2
+        The file object.
rdobuilder 3e5fd2
+    close : bool
rdobuilder 3e5fd2
+        If *fname* was a string, then *close* will be *True* to signify that
rdobuilder 3e5fd2
+        the file object should be closed after writing to it. Otherwise, *close*
rdobuilder 3e5fd2
+        will be *False* signifying that the user, in essence, created the file
rdobuilder 3e5fd2
+        object already and that subsequent operations should not close it.
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+    """
rdobuilder 3e5fd2
+    if is_string_like(fname):
rdobuilder 3e5fd2
+        fobj = open(fname, mode)
rdobuilder 3e5fd2
+        close = True
rdobuilder 3e5fd2
+    elif hasattr(fname, 'write'):
rdobuilder 3e5fd2
+        # fname is a file-like object, perhaps a StringIO (for example)
rdobuilder 3e5fd2
+        fobj = fname
rdobuilder 3e5fd2
+        close = False
rdobuilder 3e5fd2
+    else:
rdobuilder 3e5fd2
+        # assume it is a file descriptor
rdobuilder 3e5fd2
+        fobj = os.fdopen(fname, mode)
rdobuilder 3e5fd2
+        close = False
rdobuilder 3e5fd2
+    return fobj, close
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 #
rdobuilder 3e5fd2
 # Extented version of ASPN's Python Cookbook Recipe:
rdobuilder 3e5fd2
@@ -92,7 +160,7 @@ CLUSTER_ATTRIBUTES = set( ['K', 'URL', 'bgcolor', 'color', 'colorscheme',
rdobuilder 3e5fd2
 #
rdobuilder 3e5fd2
 class frozendict(dict):
rdobuilder 3e5fd2
     def _blocked_attribute(obj):
rdobuilder 3e5fd2
-        raise AttributeError, "A frozendict cannot be modified."
rdobuilder 3e5fd2
+        raise AttributeError("A frozendict cannot be modified.")
rdobuilder 3e5fd2
     _blocked_attribute = property(_blocked_attribute)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     __delitem__ = __setitem__ = clear = _blocked_attribute
rdobuilder 3e5fd2
@@ -105,7 +173,7 @@ class frozendict(dict):
rdobuilder 3e5fd2
         for arg in args:
rdobuilder 3e5fd2
             if isinstance(arg, dict):
rdobuilder 3e5fd2
                 arg = copy.copy(arg)
rdobuilder 3e5fd2
-                for k, v in arg.iteritems():
rdobuilder 3e5fd2
+                for k, v in arg.items():
rdobuilder 3e5fd2
                     if isinstance(v, frozendict):
rdobuilder 3e5fd2
                         arg[k] = v
rdobuilder 3e5fd2
                     elif isinstance(v, dict):
rdobuilder 3e5fd2
@@ -114,13 +182,13 @@ class frozendict(dict):
rdobuilder 3e5fd2
                         v_ = list()
rdobuilder 3e5fd2
                         for elm in v:
rdobuilder 3e5fd2
                             if isinstance(elm, dict):
rdobuilder 3e5fd2
-                                v_.append( frozendict(elm) )
rdobuilder 3e5fd2
+                                v_.append(frozendict(elm))
rdobuilder 3e5fd2
                             else:
rdobuilder 3e5fd2
-                                v_.append( elm )
rdobuilder 3e5fd2
+                                v_.append(elm)
rdobuilder 3e5fd2
                         arg[k] = tuple(v_)
rdobuilder 3e5fd2
-                args_.append( arg )
rdobuilder 3e5fd2
+                args_.append(arg)
rdobuilder 3e5fd2
             else:
rdobuilder 3e5fd2
-                args_.append( arg )
rdobuilder 3e5fd2
+                args_.append(arg)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         dict.__init__(new, *args_, **kw)
rdobuilder 3e5fd2
         return new
rdobuilder 3e5fd2
@@ -132,7 +200,7 @@ class frozendict(dict):
rdobuilder 3e5fd2
         try:
rdobuilder 3e5fd2
             return self._cached_hash
rdobuilder 3e5fd2
         except AttributeError:
rdobuilder 3e5fd2
-            h = self._cached_hash = hash(tuple(sorted(self.iteritems())))
rdobuilder 3e5fd2
+            h = self._cached_hash = hash(tuple(sorted(self.items())))
rdobuilder 3e5fd2
             return h
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def __repr__(self):
rdobuilder 3e5fd2
@@ -142,23 +210,25 @@ class frozendict(dict):
rdobuilder 3e5fd2
 dot_keywords = ['graph', 'subgraph', 'digraph', 'node', 'edge', 'strict']
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 id_re_alpha_nums = re.compile('^[_a-zA-Z][a-zA-Z0-9_,]*$', re.UNICODE)
rdobuilder 3e5fd2
-id_re_alpha_nums_with_ports = re.compile('^[_a-zA-Z][a-zA-Z0-9_,:\"]*[a-zA-Z0-9_,\"]+$', re.UNICODE)
rdobuilder 3e5fd2
+id_re_alpha_nums_with_ports = re.compile(
rdobuilder 3e5fd2
+    '^[_a-zA-Z][a-zA-Z0-9_,:\"]*[a-zA-Z0-9_,\"]+$', re.UNICODE
rdobuilder 3e5fd2
+    )
rdobuilder 3e5fd2
 id_re_num = re.compile('^[0-9,]+$', re.UNICODE)
rdobuilder 3e5fd2
 id_re_with_port = re.compile('^([^:]*):([^:]*)$', re.UNICODE)
rdobuilder 3e5fd2
-id_re_dbl_quoted = re.compile('^\".*\"$', re.S|re.UNICODE)
rdobuilder 3e5fd2
-id_re_html = re.compile('^<.*>$', re.S|re.UNICODE)
rdobuilder 3e5fd2
+id_re_dbl_quoted = re.compile('^\".*\"$', re.S | re.UNICODE)
rdobuilder 3e5fd2
+id_re_html = re.compile('^<.*>$', re.S | re.UNICODE)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-def needs_quotes( s ):
rdobuilder 3e5fd2
+def needs_quotes(s):
rdobuilder 3e5fd2
     """Checks whether a string is a dot language ID.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     It will check whether the string is solely composed
rdobuilder 3e5fd2
     by the characters allowed in an ID or not.
rdobuilder 3e5fd2
     If the string is one of the reserved keywords it will
rdobuilder 3e5fd2
     need quotes too but the user will need to add them
rdobuilder 3e5fd2
     manually.
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     # If the name is a reserved keyword it will need quotes but pydot
rdobuilder 3e5fd2
     # can't tell when it's being used as a keyword or when it's simply
rdobuilder 3e5fd2
     # a name. Hence the user needs to supply the quotes when an element
rdobuilder 3e5fd2
@@ -168,11 +238,14 @@ def needs_quotes( s ):
rdobuilder 3e5fd2
     if s in dot_keywords:
rdobuilder 3e5fd2
         return False
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    chars = [ord(c) for c in s if ord(c)>0x7f or ord(c)==0]
rdobuilder 3e5fd2
+    chars = [ord(c) for c in s if ord(c) > 0x7f or ord(c) == 0]
rdobuilder 3e5fd2
     if chars and not id_re_dbl_quoted.match(s) and not id_re_html.match(s):
rdobuilder 3e5fd2
         return True
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-    for test_re in [id_re_alpha_nums, id_re_num, id_re_dbl_quoted, id_re_html, id_re_alpha_nums_with_ports]:
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+    for test_re in [
rdobuilder 3e5fd2
+            id_re_alpha_nums, id_re_num, id_re_dbl_quoted,
rdobuilder 3e5fd2
+            id_re_html, id_re_alpha_nums_with_ports
rdobuilder 3e5fd2
+           ]:
rdobuilder 3e5fd2
         if test_re.match(s):
rdobuilder 3e5fd2
             return False
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
@@ -184,109 +257,109 @@ def needs_quotes( s ):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def quote_if_necessary(s):
rdobuilder 3e5fd2
+    # Older versions of graphviz throws a syntax error for empty values without
rdobuilder 3e5fd2
+    # quotes, e.g. [label=]
rdobuilder 3e5fd2
+    if s == '':
rdobuilder 3e5fd2
+        return '""'
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     if isinstance(s, bool):
rdobuilder 3e5fd2
         if s is True:
rdobuilder 3e5fd2
             return 'True'
rdobuilder 3e5fd2
         return 'False'
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    if not isinstance( s, basestring ):
rdobuilder 3e5fd2
+    if not isinstance(s, basestring):
rdobuilder 3e5fd2
         return s
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     if not s:
rdobuilder 3e5fd2
         return s
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     if needs_quotes(s):
rdobuilder 3e5fd2
-        replace = {'"'  : r'\"',
rdobuilder 3e5fd2
-                   "\n" : r'\n',
rdobuilder 3e5fd2
-                   "\r" : r'\r'}
rdobuilder 3e5fd2
-        for (a,b) in replace.items():
rdobuilder 3e5fd2
+        replace = {'"': r'\"', "\n": r'\n', "\r": r'\r'}
rdobuilder 3e5fd2
+        for (a, b) in replace.items():
rdobuilder 3e5fd2
             s = s.replace(a, b)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         return '"' + s + '"'
rdobuilder 3e5fd2
-     
rdobuilder 3e5fd2
-    return s   
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+    return s
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def graph_from_dot_data(data):
rdobuilder 3e5fd2
     """Load graph as defined by data in DOT format.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     The data is assumed to be in DOT format. It will
rdobuilder 3e5fd2
-    be parsed and a Dot class will be returned, 
rdobuilder 3e5fd2
+    be parsed and a Dot class will be returned,
rdobuilder 3e5fd2
     representing the graph.
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     return dot_parser.parse_dot_data(data)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def graph_from_dot_file(path):
rdobuilder 3e5fd2
     """Load graph as defined by a DOT file.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     The file is assumed to be in DOT format. It will
rdobuilder 3e5fd2
-    be loaded, parsed and a Dot class will be returned, 
rdobuilder 3e5fd2
+    be loaded, parsed and a Dot class will be returned,
rdobuilder 3e5fd2
     representing the graph.
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    fd = file(path, 'rb')
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+    fd = open(path, 'rb')
rdobuilder 3e5fd2
     data = fd.read()
rdobuilder 3e5fd2
     fd.close()
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    return graph_from_dot_data(data)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+    return graph_from_dot_data(data)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def graph_from_edges(edge_list, node_prefix='', directed=False):
rdobuilder 3e5fd2
     """Creates a basic graph out of an edge list.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     The edge list has to be a list of tuples representing
rdobuilder 3e5fd2
     the nodes connected by the edge.
rdobuilder 3e5fd2
     The values can be anything: bool, int, float, str.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     If the graph is undirected by default, it is only
rdobuilder 3e5fd2
     calculated from one of the symmetric halves of the matrix.
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     if directed:
rdobuilder 3e5fd2
         graph = Dot(graph_type='digraph')
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     else:
rdobuilder 3e5fd2
         graph = Dot(graph_type='graph')
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     for edge in edge_list:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if isinstance(edge[0], str):
rdobuilder 3e5fd2
             src = node_prefix + edge[0]
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
             src = node_prefix + str(edge[0])
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if isinstance(edge[1], str):
rdobuilder 3e5fd2
             dst = node_prefix + edge[1]
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
             dst = node_prefix + str(edge[1])
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        e = Edge( src, dst )
rdobuilder 3e5fd2
+        e = Edge(src, dst)
rdobuilder 3e5fd2
         graph.add_edge(e)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     return graph
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-def graph_from_adjacency_matrix(matrix, node_prefix= u'', directed=False):
rdobuilder 3e5fd2
+def graph_from_adjacency_matrix(matrix, node_prefix='', directed=False):
rdobuilder 3e5fd2
     """Creates a basic graph out of an adjacency matrix.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     The matrix has to be a list of rows of values
rdobuilder 3e5fd2
     representing an adjacency matrix.
rdobuilder 3e5fd2
     The values can be anything: bool, int, float, as long
rdobuilder 3e5fd2
     as they can evaluate to True or False.
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     node_orig = 1
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     if directed:
rdobuilder 3e5fd2
         graph = Dot(graph_type='digraph')
rdobuilder 3e5fd2
     else:
rdobuilder 3e5fd2
         graph = Dot(graph_type='graph')
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     for row in matrix:
rdobuilder 3e5fd2
         if not directed:
rdobuilder 3e5fd2
             skip = matrix.index(row)
rdobuilder 3e5fd2
@@ -294,320 +367,297 @@ def graph_from_adjacency_matrix(matrix, node_prefix= u'', directed=False):
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
             skip = 0
rdobuilder 3e5fd2
             r = row
rdobuilder 3e5fd2
-        node_dest = skip+1
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+        node_dest = skip + 1
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         for e in r:
rdobuilder 3e5fd2
             if e:
rdobuilder 3e5fd2
                 graph.add_edge(
rdobuilder 3e5fd2
-                    Edge( node_prefix + node_orig, 
rdobuilder 3e5fd2
-                        node_prefix + node_dest) )
rdobuilder 3e5fd2
+                    Edge(
rdobuilder 3e5fd2
+                        node_prefix + node_orig,
rdobuilder 3e5fd2
+                        node_prefix + node_dest
rdobuilder 3e5fd2
+                        )
rdobuilder 3e5fd2
+                    )
rdobuilder 3e5fd2
             node_dest += 1
rdobuilder 3e5fd2
         node_orig += 1
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-    return graph
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+    return graph
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def graph_from_incidence_matrix(matrix, node_prefix='', directed=False):
rdobuilder 3e5fd2
     """Creates a basic graph out of an incidence matrix.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     The matrix has to be a list of rows of values
rdobuilder 3e5fd2
     representing an incidence matrix.
rdobuilder 3e5fd2
     The values can be anything: bool, int, float, as long
rdobuilder 3e5fd2
     as they can evaluate to True or False.
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    node_orig = 1
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     if directed:
rdobuilder 3e5fd2
         graph = Dot(graph_type='digraph')
rdobuilder 3e5fd2
     else:
rdobuilder 3e5fd2
         graph = Dot(graph_type='graph')
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     for row in matrix:
rdobuilder 3e5fd2
         nodes = []
rdobuilder 3e5fd2
         c = 1
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         for node in row:
rdobuilder 3e5fd2
             if node:
rdobuilder 3e5fd2
-                nodes.append(c*node)
rdobuilder 3e5fd2
+                nodes.append(c * node)
rdobuilder 3e5fd2
             c += 1
rdobuilder 3e5fd2
-            nodes.sort()
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        nodes.sort()
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if len(nodes) == 2:
rdobuilder 3e5fd2
-            graph.add_edge(	
rdobuilder 3e5fd2
-                Edge( node_prefix + abs(nodes[0]),	
rdobuilder 3e5fd2
-                    node_prefix + nodes[1] ))
rdobuilder 3e5fd2
+            graph.add_edge(
rdobuilder 3e5fd2
+                Edge(
rdobuilder 3e5fd2
+                    node_prefix + abs(nodes[0]),
rdobuilder 3e5fd2
+                    node_prefix + nodes[1]
rdobuilder 3e5fd2
+                    )
rdobuilder 3e5fd2
+                )
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     if not directed:
rdobuilder 3e5fd2
         graph.set_simplify(True)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     return graph
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 def __find_executables(path):
rdobuilder 3e5fd2
     """Used by find_graphviz
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     path - single directory as a string
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     If any of the executables are found, it will return a dictionary
rdobuilder 3e5fd2
     containing the program names as keys and their paths as values.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     Otherwise returns None
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     success = False
rdobuilder 3e5fd2
     progs = {'dot': '', 'twopi': '', 'neato': '', 'circo': '', 'fdp': '', 'sfdp': ''}
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     was_quoted = False
rdobuilder 3e5fd2
     path = path.strip()
rdobuilder 3e5fd2
     if path.startswith('"') and path.endswith('"'):
rdobuilder 3e5fd2
         path = path[1:-1]
rdobuilder 3e5fd2
-        was_quoted =  True
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    if os.path.isdir(path) : 
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-        for prg in progs.iterkeys():
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+        was_quoted = True
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+    if os.path.isdir(path):
rdobuilder 3e5fd2
+        for prg in progs.keys():
rdobuilder 3e5fd2
             if progs[prg]:
rdobuilder 3e5fd2
                 continue
rdobuilder 3e5fd2
-               
rdobuilder 3e5fd2
-            if os.path.exists( os.path.join(path, prg) ):
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+            if os.path.exists(os.path.join(path, prg)):
rdobuilder 3e5fd2
                 if was_quoted:
rdobuilder 3e5fd2
                     progs[prg] = '"' + os.path.join(path, prg) + '"'
rdobuilder 3e5fd2
                 else:
rdobuilder 3e5fd2
                     progs[prg] = os.path.join(path, prg)
rdobuilder 3e5fd2
-                    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
                 success = True
rdobuilder 3e5fd2
-               
rdobuilder 3e5fd2
-            elif os.path.exists( os.path.join(path, prg + '.exe') ):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+            elif os.path.exists(os.path.join(path, prg + '.exe')):
rdobuilder 3e5fd2
                 if was_quoted:
rdobuilder 3e5fd2
                     progs[prg] = '"' + os.path.join(path, prg + '.exe') + '"'
rdobuilder 3e5fd2
                 else:
rdobuilder 3e5fd2
                     progs[prg] = os.path.join(path, prg + '.exe')
rdobuilder 3e5fd2
-                    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
                 success = True
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     if success:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         return progs
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
     else:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         return None
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 # The multi-platform version of this 'find_graphviz' function was
rdobuilder 3e5fd2
 # contributed by Peter Cock
rdobuilder 3e5fd2
-#
rdobuilder 3e5fd2
 def find_graphviz():
rdobuilder 3e5fd2
     """Locate Graphviz's executables in the system.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     Tries three methods:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     First: Windows Registry (Windows only)
rdobuilder 3e5fd2
     This requires Mark Hammond's pywin32 is installed.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     Secondly: Search the path
rdobuilder 3e5fd2
     It will look for 'dot', 'twopi' and 'neato' in all the directories
rdobuilder 3e5fd2
     specified in the PATH environment variable.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     Thirdly: Default install location (Windows only)
rdobuilder 3e5fd2
     It will look for 'dot', 'twopi' and 'neato' in the default install
rdobuilder 3e5fd2
     location under the "Program Files" directory.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     It will return a dictionary containing the program names as keys
rdobuilder 3e5fd2
     and their paths as values.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     If this fails, it returns None.
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     # Method 1 (Windows only)
rdobuilder 3e5fd2
-    #
rdobuilder 3e5fd2
     if os.sys.platform == 'win32':
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        HKEY_LOCAL_MACHINE =    0x80000002
rdobuilder 3e5fd2
-        KEY_QUERY_VALUE =       0x0001
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        HKEY_LOCAL_MACHINE = 0x80000002
rdobuilder 3e5fd2
+        KEY_QUERY_VALUE = 0x0001
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         RegOpenKeyEx = None
rdobuilder 3e5fd2
         RegQueryValueEx = None
rdobuilder 3e5fd2
         RegCloseKey = None
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         try:
rdobuilder 3e5fd2
-            import win32api, win32con
rdobuilder 3e5fd2
+            import win32api
rdobuilder 3e5fd2
             RegOpenKeyEx = win32api.RegOpenKeyEx
rdobuilder 3e5fd2
             RegQueryValueEx = win32api.RegQueryValueEx
rdobuilder 3e5fd2
             RegCloseKey = win32api.RegCloseKey
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         except ImportError:
rdobuilder 3e5fd2
             # Print a messaged suggesting they install these?
rdobuilder 3e5fd2
-            #
rdobuilder 3e5fd2
             pass
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         try:
rdobuilder 3e5fd2
             import ctypes
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             def RegOpenKeyEx(key, subkey, opt, sam):
rdobuilder 3e5fd2
                 result = ctypes.c_uint(0)
rdobuilder 3e5fd2
                 ctypes.windll.advapi32.RegOpenKeyExA(key, subkey, opt, sam, ctypes.byref(result))
rdobuilder 3e5fd2
                 return result.value
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
-            def RegQueryValueEx( hkey, valuename ):
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+            def RegQueryValueEx(hkey, valuename):
rdobuilder 3e5fd2
                 data_type = ctypes.c_uint(0)
rdobuilder 3e5fd2
                 data_len = ctypes.c_uint(1024)
rdobuilder 3e5fd2
-                data = ctypes.create_string_buffer( 1024 )
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
-                res = ctypes.windll.advapi32.RegQueryValueExA(hkey, valuename, 0, 
rdobuilder 3e5fd2
-                    ctypes.byref(data_type), data, ctypes.byref(data_len))
rdobuilder 3e5fd2
-                    
rdobuilder 3e5fd2
+                data = ctypes.create_string_buffer(1024)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+                # this has a return value, which we should probably check
rdobuilder 3e5fd2
+                ctypes.windll.advapi32.RegQueryValueExA(
rdobuilder 3e5fd2
+                    hkey, valuename, 0, ctypes.byref(data_type),
rdobuilder 3e5fd2
+                    data, ctypes.byref(data_len)
rdobuilder 3e5fd2
+                    )
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
                 return data.value
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             RegCloseKey = ctypes.windll.advapi32.RegCloseKey
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         except ImportError:
rdobuilder 3e5fd2
             # Print a messaged suggesting they install these?
rdobuilder 3e5fd2
-            #
rdobuilder 3e5fd2
             pass
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         if RegOpenKeyEx is not None:
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
             # Get the GraphViz install path from the registry
rdobuilder 3e5fd2
-            #
rdobuilder 3e5fd2
             hkey = None
rdobuilder 3e5fd2
             potentialKeys = [
rdobuilder 3e5fd2
                 "SOFTWARE\\ATT\\Graphviz",
rdobuilder 3e5fd2
-                "SOFTWARE\\AT&T Research Labs\\Graphviz",
rdobuilder 3e5fd2
-            ]
rdobuilder 3e5fd2
+                "SOFTWARE\\AT&T Research Labs\\Graphviz"
rdobuilder 3e5fd2
+                ]
rdobuilder 3e5fd2
             for potentialKey in potentialKeys:
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
                 try:
rdobuilder 3e5fd2
-                    hkey = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
rdobuilder 3e5fd2
-                        potentialKey, 0, KEY_QUERY_VALUE )
rdobuilder 3e5fd2
-                    
rdobuilder 3e5fd2
+                    hkey = RegOpenKeyEx(
rdobuilder 3e5fd2
+                        HKEY_LOCAL_MACHINE,
rdobuilder 3e5fd2
+                        potentialKey, 0, KEY_QUERY_VALUE
rdobuilder 3e5fd2
+                        )
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
                     if hkey is not None:
rdobuilder 3e5fd2
-                        path = RegQueryValueEx( hkey, "InstallPath" )
rdobuilder 3e5fd2
-                        RegCloseKey( hkey )
rdobuilder 3e5fd2
-                        
rdobuilder 3e5fd2
+                        path = RegQueryValueEx(hkey, "InstallPath")
rdobuilder 3e5fd2
+                        RegCloseKey(hkey)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
                         # The regitry variable might exist, left by old installations
rdobuilder 3e5fd2
                         # but with no value, in those cases we keep searching...
rdobuilder 3e5fd2
                         if not path:
rdobuilder 3e5fd2
                             continue
rdobuilder 3e5fd2
-                        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
                         # Now append the "bin" subdirectory:
rdobuilder 3e5fd2
-                        #
rdobuilder 3e5fd2
                         path = os.path.join(path, "bin")
rdobuilder 3e5fd2
                         progs = __find_executables(path)
rdobuilder 3e5fd2
-                        if progs is not None :
rdobuilder 3e5fd2
-                            #print "Used Windows registry"
rdobuilder 3e5fd2
+                        if progs is not None:
rdobuilder 3e5fd2
+                            #print("Used Windows registry")
rdobuilder 3e5fd2
                             return progs
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
-                except Exception, excp:
rdobuilder 3e5fd2
-                    #raise excp
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+                except Exception:
rdobuilder 3e5fd2
+                    #raise
rdobuilder 3e5fd2
                     pass
rdobuilder 3e5fd2
                 else:
rdobuilder 3e5fd2
                     break
rdobuilder 3e5fd2
-                    
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     # Method 2 (Linux, Windows etc)
rdobuilder 3e5fd2
-    #
rdobuilder 3e5fd2
-    if os.environ.has_key('PATH'):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+    if 'PATH' in os.environ:
rdobuilder 3e5fd2
         for path in os.environ['PATH'].split(os.pathsep):
rdobuilder 3e5fd2
             progs = __find_executables(path)
rdobuilder 3e5fd2
-            if progs is not None :
rdobuilder 3e5fd2
-                #print "Used path"
rdobuilder 3e5fd2
+            if progs is not None:
rdobuilder 3e5fd2
+                #print("Used path")
rdobuilder 3e5fd2
                 return progs
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     # Method 3 (Windows only)
rdobuilder 3e5fd2
-    #
rdobuilder 3e5fd2
     if os.sys.platform == 'win32':
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         # Try and work out the equivalent of "C:\Program Files" on this
rdobuilder 3e5fd2
         # machine (might be on drive D:, or in a different language)
rdobuilder 3e5fd2
-        #
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        if os.environ.has_key('PROGRAMFILES'):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+        if 'PROGRAMFILES' in os.environ:
rdobuilder 3e5fd2
             # Note, we could also use the win32api to get this
rdobuilder 3e5fd2
             # information, but win32api may not be installed.
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
             path = os.path.join(os.environ['PROGRAMFILES'], 'ATT', 'GraphViz', 'bin')
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
             #Just in case, try the default...
rdobuilder 3e5fd2
             path = r"C:\Program Files\att\Graphviz\bin"
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         progs = __find_executables(path)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        if progs is not None :
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-            #print "Used default install location"
rdobuilder 3e5fd2
-            return progs
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        if progs is not None:
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+            #print("Used default install location")
rdobuilder 3e5fd2
+            return progs
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     for path in (
rdobuilder 3e5fd2
-        '/usr/bin', '/usr/local/bin',
rdobuilder 3e5fd2
-        '/opt/local/bin',
rdobuilder 3e5fd2
-        '/opt/bin', '/sw/bin', '/usr/share',
rdobuilder 3e5fd2
-        '/Applications/Graphviz.app/Contents/MacOS/' ):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+            '/usr/bin', '/usr/local/bin',
rdobuilder 3e5fd2
+            '/opt/local/bin',
rdobuilder 3e5fd2
+            '/opt/bin', '/sw/bin', '/usr/share',
rdobuilder 3e5fd2
+            '/Applications/Graphviz.app/Contents/MacOS/'
rdobuilder 3e5fd2
+            ):
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         progs = __find_executables(path)
rdobuilder 3e5fd2
-        if progs is not None :
rdobuilder 3e5fd2
-            #print "Used path"
rdobuilder 3e5fd2
+        if progs is not None:
rdobuilder 3e5fd2
+            #print("Used path")
rdobuilder 3e5fd2
             return progs
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     # Failed to find GraphViz
rdobuilder 3e5fd2
-    #
rdobuilder 3e5fd2
     return None
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-class Common:
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+class Common(object):
rdobuilder 3e5fd2
     """Common information to several classes.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     Should not be directly used, several classes are derived from
rdobuilder 3e5fd2
     this one.
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def __getstate__(self):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         dict = copy.copy(self.obj_dict)
rdobuilder 3e5fd2
-   
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return dict
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
     def __setstate__(self, state):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-        self.obj_dict = state
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        self.obj_dict = state
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def __get_attribute__(self, attr):
rdobuilder 3e5fd2
         """Look for default attributes for this node"""
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         attr_val = self.obj_dict['attributes'].get(attr, None)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if attr_val is None:
rdobuilder 3e5fd2
             # get the defaults for nodes/edges
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             default_node_name = self.obj_dict['type']
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             # The defaults for graphs are set on a node named 'graph'
rdobuilder 3e5fd2
             if default_node_name in ('subgraph', 'digraph', 'cluster'):
rdobuilder 3e5fd2
                 default_node_name = 'graph'
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             g = self.get_parent_graph()
rdobuilder 3e5fd2
             if g is not None:
rdobuilder 3e5fd2
-                defaults = g.get_node( default_node_name )
rdobuilder 3e5fd2
+                defaults = g.get_node(default_node_name)
rdobuilder 3e5fd2
             else:
rdobuilder 3e5fd2
                 return None
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             # Multiple defaults could be set by having repeated 'graph [...]'
rdobuilder 3e5fd2
             # 'node [...]', 'edge [...]' statements. In such case, if the
rdobuilder 3e5fd2
             # same attribute is set in different statements, only the first
rdobuilder 3e5fd2
@@ -618,84 +668,78 @@ class Common:
rdobuilder 3e5fd2
             #
rdobuilder 3e5fd2
             if not isinstance(defaults, (list, tuple)):
rdobuilder 3e5fd2
                 defaults = [defaults]
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             for default in defaults:
rdobuilder 3e5fd2
                 attr_val = default.obj_dict['attributes'].get(attr, None)
rdobuilder 3e5fd2
                 if attr_val:
rdobuilder 3e5fd2
                     return attr_val
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
             return attr_val
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return None
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def set_parent_graph(self, parent_graph):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         self.obj_dict['parent_graph'] = parent_graph
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_parent_graph(self):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-        return self.obj_dict.get('parent_graph', None)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        return self.obj_dict.get('parent_graph', None)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def set(self, name, value):
rdobuilder 3e5fd2
         """Set an attribute value by name.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         Given an attribute 'name' it will set its value to 'value'.
rdobuilder 3e5fd2
         There's always the possibility of using the methods:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             set_'name'(value)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         which are defined for all the existing attributes.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         self.obj_dict['attributes'][name] = value
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     def get(self, name):
rdobuilder 3e5fd2
         """Get an attribute value by name.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         Given an attribute 'name' it will get its value.
rdobuilder 3e5fd2
         There's always the possibility of using the methods:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             get_'name'()
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         which are defined for all the existing attributes.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         return self.obj_dict['attributes'].get(name, None)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_attributes(self):
rdobuilder 3e5fd2
         """"""
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return self.obj_dict['attributes']
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
     def set_sequence(self, seq):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-        self.obj_dict['sequence'] = seq
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        self.obj_dict['sequence'] = seq
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_sequence(self):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return self.obj_dict['sequence']
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def create_attribute_methods(self, obj_attributes):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         #for attr in self.obj_dict['attributes']:
rdobuilder 3e5fd2
         for attr in obj_attributes:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             # Generate all the Setter methods.
rdobuilder 3e5fd2
             #
rdobuilder 3e5fd2
-            self.__setattr__( 'set_'+attr, lambda x, a=attr : self.obj_dict['attributes'].__setitem__(a, x) )
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+            self.__setattr__(
rdobuilder 3e5fd2
+                'set_' + attr,
rdobuilder 3e5fd2
+                lambda x, a=attr: self.obj_dict['attributes'].__setitem__(a, x)
rdobuilder 3e5fd2
+                )
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             # Generate all the Getter methods.
rdobuilder 3e5fd2
             #
rdobuilder 3e5fd2
-            self.__setattr__('get_'+attr, lambda a=attr : self.__get_attribute__(a))
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
+            self.__setattr__('get_' + attr, lambda a=attr: self.__get_attribute__(a))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 class Error(Exception):
rdobuilder 3e5fd2
@@ -703,6 +747,7 @@ class Error(Exception):
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
     def __init__(self, value):
rdobuilder 3e5fd2
         self.value = value
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def __str__(self):
rdobuilder 3e5fd2
         return self.value
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
@@ -712,119 +757,108 @@ class InvocationException(Exception):
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
     def __init__(self, value):
rdobuilder 3e5fd2
         self.value = value
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def __str__(self):
rdobuilder 3e5fd2
         return self.value
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-class Node(object, Common):
rdobuilder 3e5fd2
+class Node(Common):
rdobuilder 3e5fd2
     """A graph node.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     This class represents a graph's node with all its attributes.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     node(name, attribute=value, ...)
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     name: node's name
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     All the attributes defined in the Graphviz dot language should
rdobuilder 3e5fd2
     be supported.
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    def __init__(self, name = '', obj_dict = None, **attrs):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+    def __init__(self, name='', obj_dict=None, **attrs):
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         #
rdobuilder 3e5fd2
         # Nodes will take attributes of all other types because the defaults
rdobuilder 3e5fd2
         # for any GraphViz object are dealt with as if they were Node definitions
rdobuilder 3e5fd2
         #
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if obj_dict is not None:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
             self.obj_dict = obj_dict
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
             self.obj_dict = dict()
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             # Copy the attributes
rdobuilder 3e5fd2
             #
rdobuilder 3e5fd2
-            self.obj_dict[ 'attributes' ] = dict( attrs )
rdobuilder 3e5fd2
-            self.obj_dict[ 'type' ] = 'node'
rdobuilder 3e5fd2
-            self.obj_dict[ 'parent_graph' ] = None
rdobuilder 3e5fd2
-            self.obj_dict[ 'parent_node_list' ] = None
rdobuilder 3e5fd2
-            self.obj_dict[ 'sequence' ] = None
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+            self.obj_dict['attributes'] = dict(attrs)
rdobuilder 3e5fd2
+            self.obj_dict['type'] = 'node'
rdobuilder 3e5fd2
+            self.obj_dict['parent_graph'] = None
rdobuilder 3e5fd2
+            self.obj_dict['parent_node_list'] = None
rdobuilder 3e5fd2
+            self.obj_dict['sequence'] = None
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             # Remove the compass point
rdobuilder 3e5fd2
             #
rdobuilder 3e5fd2
             port = None
rdobuilder 3e5fd2
             if isinstance(name, basestring) and not name.startswith('"'):
rdobuilder 3e5fd2
                 idx = name.find(':')
rdobuilder 3e5fd2
-                if idx > 0 and idx+1 < len(name):
rdobuilder 3e5fd2
+                if idx > 0 and idx + 1 < len(name):
rdobuilder 3e5fd2
                     name, port = name[:idx], name[idx:]
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
             if isinstance(name, (long, int)):
rdobuilder 3e5fd2
                 name = str(name)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-            self.obj_dict['name'] = quote_if_necessary( name )
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+            self.obj_dict['name'] = quote_if_necessary(name)
rdobuilder 3e5fd2
             self.obj_dict['port'] = port
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         self.create_attribute_methods(NODE_ATTRIBUTES)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def set_name(self, node_name):
rdobuilder 3e5fd2
         """Set the node's name."""
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         self.obj_dict['name'] = node_name
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def get_name(self):
rdobuilder 3e5fd2
         """Get the node's name."""
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return self.obj_dict['name']
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
     def get_port(self):
rdobuilder 3e5fd2
         """Get the node's port."""
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        return self.obj_dict['port']
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        return self.obj_dict['port']
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def add_style(self, style):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         styles = self.obj_dict['attributes'].get('style', None)
rdobuilder 3e5fd2
         if not styles and style:
rdobuilder 3e5fd2
-            styles = [ style ]
rdobuilder 3e5fd2
+            styles = [style]
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
             styles = styles.split(',')
rdobuilder 3e5fd2
-            styles.append( style )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        self.obj_dict['attributes']['style'] = ','.join( styles )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+            styles.append(style)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        self.obj_dict['attributes']['style'] = ','.join(styles)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def to_string(self):
rdobuilder 3e5fd2
         """Returns a string representation of the node in dot language.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         # RMF: special case defaults for node, edge and graph properties.
rdobuilder 3e5fd2
         #
rdobuilder 3e5fd2
         node = quote_if_necessary(self.obj_dict['name'])
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         node_attr = list()
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        for attr, value in self.obj_dict['attributes'].iteritems():
rdobuilder 3e5fd2
+        for attr, value in sorted(self.obj_dict['attributes'].items(), key=itemgetter(0)):
rdobuilder 3e5fd2
             if value is not None:
rdobuilder 3e5fd2
-                node_attr.append( '%s=%s' % (attr, quote_if_necessary(value) ) )
rdobuilder 3e5fd2
+                node_attr.append('%s=%s' % (attr, quote_if_necessary(value)))
rdobuilder 3e5fd2
             else:
rdobuilder 3e5fd2
-                node_attr.append( attr )
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+                node_attr.append(attr)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         # No point in having nodes setting any defaults if the don't set
rdobuilder 3e5fd2
         # any attributes...
rdobuilder 3e5fd2
         #
rdobuilder 3e5fd2
         if node in ('graph', 'node', 'edge') and len(node_attr) == 0:
rdobuilder 3e5fd2
             return ''
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         node_attr = ', '.join(node_attr)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         if node_attr:
rdobuilder 3e5fd2
@@ -833,207 +867,191 @@ class Node(object, Common):
rdobuilder 3e5fd2
         return node + ';'
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-class Edge(object,  Common ):
rdobuilder 3e5fd2
+class Edge(Common):
rdobuilder 3e5fd2
     """A graph edge.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     This class represents a graph's edge with all its attributes.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     edge(src, dst, attribute=value, ...)
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     src: source node's name
rdobuilder 3e5fd2
     dst: destination node's name
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     All the attributes defined in the Graphviz dot language should
rdobuilder 3e5fd2
     be supported.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
- 	Attributes can be set through the dynamically generated methods:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+    Attributes can be set through the dynamically generated methods:
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
      set_[attribute name], i.e. set_label, set_fontname
rdobuilder 3e5fd2
-     
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     or directly by using the instance's special dictionary:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-     Edge.obj_dict['attributes'][attribute name], i.e. 
rdobuilder 3e5fd2
-     
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+     Edge.obj_dict['attributes'][attribute name], i.e.
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         edge_instance.obj_dict['attributes']['label']
rdobuilder 3e5fd2
         edge_instance.obj_dict['attributes']['fontname']
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-    """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+    """
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def __init__(self, src='', dst='', obj_dict=None, **attrs):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if isinstance(src, (list, tuple)) and dst == '':
rdobuilder 3e5fd2
             src, dst = src
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if obj_dict is not None:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             self.obj_dict = obj_dict
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             self.obj_dict = dict()
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             # Copy the attributes
rdobuilder 3e5fd2
             #
rdobuilder 3e5fd2
-            self.obj_dict[ 'attributes' ] = dict( attrs )
rdobuilder 3e5fd2
-            self.obj_dict[ 'type' ] = 'edge'
rdobuilder 3e5fd2
-            self.obj_dict[ 'parent_graph' ] = None
rdobuilder 3e5fd2
-            self.obj_dict[ 'parent_edge_list' ] = None
rdobuilder 3e5fd2
-            self.obj_dict[ 'sequence' ] = None
rdobuilder 3e5fd2
+            self.obj_dict['attributes'] = dict(attrs)
rdobuilder 3e5fd2
+            self.obj_dict['type'] = 'edge'
rdobuilder 3e5fd2
+            self.obj_dict['parent_graph'] = None
rdobuilder 3e5fd2
+            self.obj_dict['parent_edge_list'] = None
rdobuilder 3e5fd2
+            self.obj_dict['sequence'] = None
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
             if isinstance(src, Node):
rdobuilder 3e5fd2
                 src = src.get_name()
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             if isinstance(dst, Node):
rdobuilder 3e5fd2
                 dst = dst.get_name()
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-            points = ( quote_if_necessary( src) , quote_if_necessary( dst) )
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+            points = (quote_if_necessary(src), quote_if_necessary(dst))
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             self.obj_dict['points'] = points
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        self.create_attribute_methods(EDGE_ATTRIBUTES)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        self.create_attribute_methods(EDGE_ATTRIBUTES)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_source(self):
rdobuilder 3e5fd2
         """Get the edges source node name."""
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return self.obj_dict['points'][0]
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def get_destination(self):
rdobuilder 3e5fd2
         """Get the edge's destination node name."""
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return self.obj_dict['points'][1]
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def __hash__(self):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-         return hash( hash(self.get_source()) + hash(self.get_destination()) )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+        return hash(hash(self.get_source()) + hash(self.get_destination()))
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def __eq__(self, edge):
rdobuilder 3e5fd2
         """Compare two edges.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         If the parent graph is directed, arcs linking
rdobuilder 3e5fd2
         node A to B are considered equal and A->B != B->A
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         If the parent graph is undirected, any edge
rdobuilder 3e5fd2
         connecting two nodes is equal to any other
rdobuilder 3e5fd2
         edge connecting the same nodes, A->B == B->A
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if not isinstance(edge, Edge):
rdobuilder 3e5fd2
-            raise Error, "Can't compare and edge to a non-edge object."
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+            raise Error("Can't compare and edge to a non-edge object.")
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if self.get_parent_graph().get_top_graph_type() == 'graph':
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             # If the graph is undirected, the edge has neither
rdobuilder 3e5fd2
             # source nor destination.
rdobuilder 3e5fd2
             #
rdobuilder 3e5fd2
-            if	( ( self.get_source() == edge.get_source() and self.get_destination() == edge.get_destination() ) or
rdobuilder 3e5fd2
-                ( edge.get_source() == self.get_destination() and edge.get_destination() == self.get_source() ) ):
rdobuilder 3e5fd2
+            if ((self.get_source() == edge.get_source() and
rdobuilder 3e5fd2
+                    self.get_destination() == edge.get_destination()) or
rdobuilder 3e5fd2
+                (edge.get_source() == self.get_destination() and
rdobuilder 3e5fd2
+                    edge.get_destination() == self.get_source())):
rdobuilder 3e5fd2
                 return True
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-            if self.get_source()==edge.get_source() and self.get_destination()==edge.get_destination() :
rdobuilder 3e5fd2
+            if (self.get_source() == edge.get_source() and
rdobuilder 3e5fd2
+                    self.get_destination() == edge.get_destination()):
rdobuilder 3e5fd2
                 return True
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return False
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
     def parse_node_ref(self, node_str):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if not isinstance(node_str, str):
rdobuilder 3e5fd2
             return node_str
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if node_str.startswith('"') and node_str.endswith('"'):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
             return node_str
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         node_port_idx = node_str.rfind(':')
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        if node_port_idx>0 and node_str[0]=='"' and node_str[node_port_idx-1]=='"':
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if (node_port_idx > 0 and node_str[0] == '"' and
rdobuilder 3e5fd2
+                node_str[node_port_idx - 1] == '"'):
rdobuilder 3e5fd2
             return node_str
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
-        if node_port_idx>0:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if node_port_idx > 0:
rdobuilder 3e5fd2
             a = node_str[:node_port_idx]
rdobuilder 3e5fd2
-            b = node_str[node_port_idx+1:]
rdobuilder 3e5fd2
+            b = node_str[node_port_idx + 1:]
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
             node = quote_if_necessary(a)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-            node += ':'+quote_if_necessary(b)
rdobuilder 3e5fd2
+            node += ':' + quote_if_necessary(b)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
             return node
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return node_str
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def to_string(self):
rdobuilder 3e5fd2
         """Returns a string representation of the edge in dot language.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        src = self.parse_node_ref( self.get_source() )
rdobuilder 3e5fd2
-        dst = self.parse_node_ref( self.get_destination() )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+        src = self.parse_node_ref(self.get_source())
rdobuilder 3e5fd2
+        dst = self.parse_node_ref(self.get_destination())
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if isinstance(src, frozendict):
rdobuilder 3e5fd2
-            edge = [ Subgraph(obj_dict=src).to_string() ]
rdobuilder 3e5fd2
+            edge = [Subgraph(obj_dict=src).to_string()]
rdobuilder 3e5fd2
         elif isinstance(src, (int, long)):
rdobuilder 3e5fd2
-            edge = [ str(src) ]
rdobuilder 3e5fd2
+            edge = [str(src)]
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-            edge = [ src ]
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        if	(self.get_parent_graph() and
rdobuilder 3e5fd2
-            self.get_parent_graph().get_top_graph_type() and
rdobuilder 3e5fd2
-            self.get_parent_graph().get_top_graph_type() == 'digraph' ):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-            edge.append( '->' )
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+            edge = [src]
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if (self.get_parent_graph() and
rdobuilder 3e5fd2
+                self.get_parent_graph().get_top_graph_type() and
rdobuilder 3e5fd2
+                self.get_parent_graph().get_top_graph_type() == 'digraph'):
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+            edge.append('->')
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-            edge.append( '--' )
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+            edge.append('--')
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if isinstance(dst, frozendict):
rdobuilder 3e5fd2
-            edge.append( Subgraph(obj_dict=dst).to_string() )
rdobuilder 3e5fd2
+            edge.append(Subgraph(obj_dict=dst).to_string())
rdobuilder 3e5fd2
         elif isinstance(dst, (int, long)):
rdobuilder 3e5fd2
-            edge.append( str(dst) )
rdobuilder 3e5fd2
+            edge.append(str(dst))
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-            edge.append( dst )
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
+            edge.append(dst)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         edge_attr = list()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        for attr, value in self.obj_dict['attributes'].iteritems():
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        for attr, value in sorted(self.obj_dict['attributes'].items(), key=itemgetter(0)):
rdobuilder 3e5fd2
             if value is not None:
rdobuilder 3e5fd2
-                edge_attr.append( '%s=%s' % (attr, quote_if_necessary(value) ) )
rdobuilder 3e5fd2
+                edge_attr.append('%s=%s' % (attr, quote_if_necessary(value)))
rdobuilder 3e5fd2
             else:
rdobuilder 3e5fd2
-                edge_attr.append( attr )
rdobuilder 3e5fd2
+                edge_attr.append(attr)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         edge_attr = ', '.join(edge_attr)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if edge_attr:
rdobuilder 3e5fd2
-            edge.append( ' [' + edge_attr + ']' )
rdobuilder 3e5fd2
+            edge.append(' [' + edge_attr + ']')
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         return ' '.join(edge) + ';'
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-class Graph(object, Common):
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+class Graph(Common):
rdobuilder 3e5fd2
     """Class representing a graph in Graphviz's dot language.
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     This class implements the methods to work on a representation
rdobuilder 3e5fd2
     of a graph in Graphviz's dot language.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    graph(  graph_name='G', graph_type='digraph',
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+    graph(graph_name='G', graph_type='digraph',
rdobuilder 3e5fd2
         strict=False, suppress_disconnected=False, attribute=value, ...)
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     graph_name:
rdobuilder 3e5fd2
         the graph's name
rdobuilder 3e5fd2
     graph_type:
rdobuilder 3e5fd2
@@ -1045,222 +1063,178 @@ class Graph(object, Common):
rdobuilder 3e5fd2
         if True it will avoid displaying equal edges, i.e.
rdobuilder 3e5fd2
         only one edge between two nodes. removing the
rdobuilder 3e5fd2
         duplicated ones.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     All the attributes defined in the Graphviz dot language should
rdobuilder 3e5fd2
     be supported.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     Attributes can be set through the dynamically generated methods:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
      set_[attribute name], i.e. set_size, set_fontname
rdobuilder 3e5fd2
-     
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     or using the instance's attributes:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-     Graph.obj_dict['attributes'][attribute name], i.e. 
rdobuilder 3e5fd2
-     
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+     Graph.obj_dict['attributes'][attribute name], i.e.
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         graph_instance.obj_dict['attributes']['label']
rdobuilder 3e5fd2
         graph_instance.obj_dict['attributes']['fontname']
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    def __init__(self, graph_name='G', obj_dict=None, graph_type='digraph', strict=False,
rdobuilder 3e5fd2
-        suppress_disconnected=False, simplify=False, **attrs):
rdobuilder 3e5fd2
+    def __init__(
rdobuilder 3e5fd2
+            self, graph_name='G', obj_dict=None, graph_type='digraph', strict=False,
rdobuilder 3e5fd2
+            suppress_disconnected=False, simplify=False, **attrs):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         if obj_dict is not None:
rdobuilder 3e5fd2
             self.obj_dict = obj_dict
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
             self.obj_dict = dict()
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             self.obj_dict['attributes'] = dict(attrs)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             if graph_type not in ['graph', 'digraph']:
rdobuilder 3e5fd2
-                raise Error, 'Invalid type "%s". Accepted graph types are: graph, digraph, subgraph' % graph_type
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+                raise Error((
rdobuilder 3e5fd2
+                    'Invalid type "%s". Accepted graph types are: '
rdobuilder 3e5fd2
+                    'graph, digraph, subgraph' % graph_type
rdobuilder 3e5fd2
+                    ))
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             self.obj_dict['name'] = quote_if_necessary(graph_name)
rdobuilder 3e5fd2
             self.obj_dict['type'] = graph_type
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             self.obj_dict['strict'] = strict
rdobuilder 3e5fd2
             self.obj_dict['suppress_disconnected'] = suppress_disconnected
rdobuilder 3e5fd2
             self.obj_dict['simplify'] = simplify
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             self.obj_dict['current_child_sequence'] = 1
rdobuilder 3e5fd2
             self.obj_dict['nodes'] = dict()
rdobuilder 3e5fd2
             self.obj_dict['edges'] = dict()
rdobuilder 3e5fd2
             self.obj_dict['subgraphs'] = dict()
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
             self.set_parent_graph(self)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         self.create_attribute_methods(GRAPH_ATTRIBUTES)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     def get_graph_type(self):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         return self.obj_dict['type']
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     def get_top_graph_type(self):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         parent = self
rdobuilder 3e5fd2
         while True:
rdobuilder 3e5fd2
             parent_ = parent.get_parent_graph()
rdobuilder 3e5fd2
             if parent_ == parent:
rdobuilder 3e5fd2
                 break
rdobuilder 3e5fd2
             parent = parent_
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return parent.obj_dict['type']
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def set_graph_defaults(self, **attrs):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-        self.add_node( Node('graph', **attrs) )
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
+        self.add_node(Node('graph', **attrs))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_graph_defaults(self, **attrs):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         graph_nodes = self.get_node('graph')
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        if isinstance( graph_nodes, (list, tuple)):
rdobuilder 3e5fd2
-            return [ node.get_attributes() for node in graph_nodes ]
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        return graph_nodes.get_attributes()            
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    def set_node_defaults(self, **attrs):
rdobuilder 3e5fd2
+        if isinstance(graph_nodes, (list, tuple)):
rdobuilder 3e5fd2
+            return [node.get_attributes() for node in graph_nodes]
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        self.add_node( Node('node', **attrs) )
rdobuilder 3e5fd2
+        return graph_nodes.get_attributes()
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+    def set_node_defaults(self, **attrs):
rdobuilder 3e5fd2
+        self.add_node(Node('node', **attrs))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_node_defaults(self, **attrs):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         graph_nodes = self.get_node('node')
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        if isinstance( graph_nodes, (list, tuple)):
rdobuilder 3e5fd2
-            return [ node.get_attributes() for node in graph_nodes ]
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        return graph_nodes.get_attributes()            
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-    def set_edge_defaults(self, **attrs):
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-        self.add_node( Node('edge', **attrs) )
rdobuilder 3e5fd2
+        if isinstance(graph_nodes, (list, tuple)):
rdobuilder 3e5fd2
+            return [node.get_attributes() for node in graph_nodes]
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        return graph_nodes.get_attributes()
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+    def set_edge_defaults(self, **attrs):
rdobuilder 3e5fd2
+        self.add_node(Node('edge', **attrs))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_edge_defaults(self, **attrs):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         graph_nodes = self.get_node('edge')
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        if isinstance( graph_nodes, (list, tuple)):
rdobuilder 3e5fd2
-            return [ node.get_attributes() for node in graph_nodes ]
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        return graph_nodes.get_attributes()            
rdobuilder 3e5fd2
+        if isinstance(graph_nodes, (list, tuple)):
rdobuilder 3e5fd2
+            return [node.get_attributes() for node in graph_nodes]
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+        return graph_nodes.get_attributes()
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def set_simplify(self, simplify):
rdobuilder 3e5fd2
         """Set whether to simplify or not.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         If True it will avoid displaying equal edges, i.e.
rdobuilder 3e5fd2
         only one edge between two nodes. removing the
rdobuilder 3e5fd2
         duplicated ones.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        self.obj_dict['simplify'] = simplify
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        self.obj_dict['simplify'] = simplify
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_simplify(self):
rdobuilder 3e5fd2
         """Get whether to simplify or not.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         Refer to set_simplify for more information.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return self.obj_dict['simplify']
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
     def set_type(self, graph_type):
rdobuilder 3e5fd2
         """Set the graph's type, 'graph' or 'digraph'."""
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         self.obj_dict['type'] = graph_type
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
     def get_type(self):
rdobuilder 3e5fd2
         """Get the graph's type, 'graph' or 'digraph'."""
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         return self.obj_dict['type']
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     def set_name(self, graph_name):
rdobuilder 3e5fd2
         """Set the graph's name."""
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        self.obj_dict['name'] = graph_name
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        self.obj_dict['name'] = graph_name
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_name(self):
rdobuilder 3e5fd2
         """Get the graph's name."""
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        return self.obj_dict['name']
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        return self.obj_dict['name']
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-                    
rdobuilder 3e5fd2
     def set_strict(self, val):
rdobuilder 3e5fd2
         """Set graph to 'strict' mode.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         This option is only valid for top level graphs.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        self.obj_dict['strict'] = val
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        self.obj_dict['strict'] = val
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_strict(self, val):
rdobuilder 3e5fd2
         """Get graph's 'strict' mode (True, False).
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         This option is only valid for top level graphs.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        return self.obj_dict['strict']
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        return self.obj_dict['strict']
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def set_suppress_disconnected(self, val):
rdobuilder 3e5fd2
         """Suppress disconnected nodes in the output graph.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         This option will skip nodes in the graph with no incoming or outgoing
rdobuilder 3e5fd2
         edges. This option works also for subgraphs and has effect only in the
rdobuilder 3e5fd2
         current graph/subgraph.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        self.obj_dict['suppress_disconnected'] = val
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        self.obj_dict['suppress_disconnected'] = val
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_suppress_disconnected(self, val):
rdobuilder 3e5fd2
         """Get if suppress disconnected is set.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         Refer to set_suppress_disconnected for more information.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return self.obj_dict['suppress_disconnected']
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_next_sequence_number(self):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         seq = self.obj_dict['current_child_sequence']
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
         self.obj_dict['current_child_sequence'] += 1
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
         return seq
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def add_node(self, graph_node):
rdobuilder 3e5fd2
         """Adds a node object to the graph.
rdobuilder 3e5fd2
@@ -1268,106 +1242,101 @@ class Graph(object, Common):
rdobuilder 3e5fd2
         It takes a node object as its only argument and returns
rdobuilder 3e5fd2
         None.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if not isinstance(graph_node, Node):
rdobuilder 3e5fd2
             raise TypeError('add_node() received a non node class object: ' + str(graph_node))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
         node = self.get_node(graph_node.get_name())
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if not node:
rdobuilder 3e5fd2
+            self.obj_dict['nodes'][graph_node.get_name()] = [graph_node.obj_dict]
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-            self.obj_dict['nodes'][graph_node.get_name()] = [ graph_node.obj_dict ]
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
             #self.node_dict[graph_node.get_name()] = graph_node.attributes
rdobuilder 3e5fd2
             graph_node.set_parent_graph(self.get_parent_graph())
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-            self.obj_dict['nodes'][graph_node.get_name()].append( graph_node.obj_dict )
rdobuilder 3e5fd2
+            self.obj_dict['nodes'][graph_node.get_name()].append(graph_node.obj_dict)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         graph_node.set_sequence(self.get_next_sequence_number())
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     def del_node(self, name, index=None):
rdobuilder 3e5fd2
         """Delete a node from the graph.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         Given a node's name all node(s) with that same name
rdobuilder 3e5fd2
         will be deleted if 'index' is not specified or set
rdobuilder 3e5fd2
         to None.
rdobuilder 3e5fd2
         If there are several nodes with that same name and
rdobuilder 3e5fd2
         'index' is given, only the node in that position
rdobuilder 3e5fd2
         will be deleted.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        'index' should be an integer specifying the position 
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        'index' should be an integer specifying the position
rdobuilder 3e5fd2
         of the node to delete. If index is larger than the
rdobuilder 3e5fd2
         number of nodes with that name, no action is taken.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         If nodes are deleted it returns True. If no action
rdobuilder 3e5fd2
         is taken it returns False.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if isinstance(name, Node):
rdobuilder 3e5fd2
             name = name.get_name()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        if self.obj_dict['nodes'].has_key(name):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if name in self.obj_dict['nodes']:
rdobuilder 3e5fd2
             if index is not None and index < len(self.obj_dict['nodes'][name]):
rdobuilder 3e5fd2
                 del self.obj_dict['nodes'][name][index]
rdobuilder 3e5fd2
                 return True
rdobuilder 3e5fd2
             else:
rdobuilder 3e5fd2
                 del self.obj_dict['nodes'][name]
rdobuilder 3e5fd2
                 return True
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return False
rdobuilder 3e5fd2
-                        
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_node(self, name):
rdobuilder 3e5fd2
         """Retrieve a node from the graph.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         Given a node's name the corresponding Node
rdobuilder 3e5fd2
         instance will be returned.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         If one or more nodes exist with that name a list of
rdobuilder 3e5fd2
         Node instances is returned.
rdobuilder 3e5fd2
         An empty list is returned otherwise.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         match = list()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        if self.obj_dict['nodes'].has_key(name):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-            match.extend( [ Node( obj_dict = obj_dict ) for obj_dict in self.obj_dict['nodes'][name] ])
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        return match
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        if name in self.obj_dict['nodes']:
rdobuilder 3e5fd2
+            match.extend([
rdobuilder 3e5fd2
+                Node(obj_dict=obj_dict)
rdobuilder 3e5fd2
+                for obj_dict
rdobuilder 3e5fd2
+                in self.obj_dict['nodes'][name]
rdobuilder 3e5fd2
+                ])
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        return match
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_nodes(self):
rdobuilder 3e5fd2
         """Get the list of Node instances."""
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return self.get_node_list()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def get_node_list(self):
rdobuilder 3e5fd2
         """Get the list of Node instances.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         This method returns the list of Node instances
rdobuilder 3e5fd2
         composing the graph.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         node_objs = list()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        for node, obj_dict_list in self.obj_dict['nodes'].iteritems():
rdobuilder 3e5fd2
-                node_objs.extend( [ Node( obj_dict = obj_d ) for obj_d in obj_dict_list ] )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        return node_objs
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        for node, obj_dict_list in self.obj_dict['nodes'].items():
rdobuilder 3e5fd2
+            node_objs.extend([
rdobuilder 3e5fd2
+                Node(obj_dict=obj_d)
rdobuilder 3e5fd2
+                for obj_d
rdobuilder 3e5fd2
+                in obj_dict_list
rdobuilder 3e5fd2
+                ])
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        return node_objs
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def add_edge(self, graph_edge):
rdobuilder 3e5fd2
         """Adds an edge object to the graph.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         It takes a edge object as its only argument and returns
rdobuilder 3e5fd2
         None.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
@@ -1375,78 +1344,70 @@ class Graph(object, Common):
rdobuilder 3e5fd2
         if not isinstance(graph_edge, Edge):
rdobuilder 3e5fd2
             raise TypeError('add_edge() received a non edge class object: ' + str(graph_edge))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        edge_points = ( graph_edge.get_source(), graph_edge.get_destination() )
rdobuilder 3e5fd2
+        edge_points = (graph_edge.get_source(), graph_edge.get_destination())
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        if self.obj_dict['edges'].has_key(edge_points):
rdobuilder 3e5fd2
+        if edge_points in self.obj_dict['edges']:
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
             edge_list = self.obj_dict['edges'][edge_points]
rdobuilder 3e5fd2
             edge_list.append(graph_edge.obj_dict)
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
+            self.obj_dict['edges'][edge_points] = [graph_edge.obj_dict]
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-            self.obj_dict['edges'][edge_points] = [ graph_edge.obj_dict ]
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-        graph_edge.set_sequence( self.get_next_sequence_number() )
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-        graph_edge.set_parent_graph( self.get_parent_graph() )
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
+        graph_edge.set_sequence(self.get_next_sequence_number())
rdobuilder 3e5fd2
+        graph_edge.set_parent_graph(self.get_parent_graph())
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def del_edge(self, src_or_list, dst=None, index=None):
rdobuilder 3e5fd2
         """Delete an edge from the graph.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         Given an edge's (source, destination) node names all
rdobuilder 3e5fd2
         matching edges(s) will be deleted if 'index' is not
rdobuilder 3e5fd2
         specified or set to None.
rdobuilder 3e5fd2
         If there are several matching edges and 'index' is
rdobuilder 3e5fd2
         given, only the edge in that position will be deleted.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        'index' should be an integer specifying the position 
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        'index' should be an integer specifying the position
rdobuilder 3e5fd2
         of the edge to delete. If index is larger than the
rdobuilder 3e5fd2
         number of matching edges, no action is taken.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         If edges are deleted it returns True. If no action
rdobuilder 3e5fd2
         is taken it returns False.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        if isinstance( src_or_list, (list, tuple)):
rdobuilder 3e5fd2
+        if isinstance(src_or_list, (list, tuple)):
rdobuilder 3e5fd2
             if dst is not None and isinstance(dst, (int, long)):
rdobuilder 3e5fd2
                 index = dst
rdobuilder 3e5fd2
             src, dst = src_or_list
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
             src, dst = src_or_list, dst
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if isinstance(src, Node):
rdobuilder 3e5fd2
             src = src.get_name()
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         if isinstance(dst, Node):
rdobuilder 3e5fd2
             dst = dst.get_name()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        if self.obj_dict['edges'].has_key( (src, dst) ):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if (src, dst) in self.obj_dict['edges']:
rdobuilder 3e5fd2
             if index is not None and index < len(self.obj_dict['edges'][(src, dst)]):
rdobuilder 3e5fd2
                 del self.obj_dict['edges'][(src, dst)][index]
rdobuilder 3e5fd2
                 return True
rdobuilder 3e5fd2
             else:
rdobuilder 3e5fd2
                 del self.obj_dict['edges'][(src, dst)]
rdobuilder 3e5fd2
                 return True
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         return False
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_edge(self, src_or_list, dst=None):
rdobuilder 3e5fd2
         """Retrieved an edge from the graph.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         Given an edge's source and destination the corresponding
rdobuilder 3e5fd2
         Edge instance(s) will be returned.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         If one or more edges exist with that source and destination
rdobuilder 3e5fd2
         a list of Edge instances is returned.
rdobuilder 3e5fd2
         An empty list is returned otherwise.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        if isinstance( src_or_list, (list, tuple)) and dst is None:
rdobuilder 3e5fd2
+        if isinstance(src_or_list, (list, tuple)) and dst is None:
rdobuilder 3e5fd2
             edge_points = tuple(src_or_list)
rdobuilder 3e5fd2
             edge_points_reverse = (edge_points[1], edge_points[0])
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
@@ -1454,224 +1415,205 @@ class Graph(object, Common):
rdobuilder 3e5fd2
             edge_points_reverse = (dst, src_or_list)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         match = list()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        if self.obj_dict['edges'].has_key( edge_points ) or (
rdobuilder 3e5fd2
-            self.get_top_graph_type() == 'graph' and self.obj_dict['edges'].has_key( edge_points_reverse )):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if edge_points in self.obj_dict['edges'] or (
rdobuilder 3e5fd2
+                self.get_top_graph_type() == 'graph' and
rdobuilder 3e5fd2
+                edge_points_reverse in self.obj_dict['edges']
rdobuilder 3e5fd2
+                ):
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             edges_obj_dict = self.obj_dict['edges'].get(
rdobuilder 3e5fd2
                 edge_points,
rdobuilder 3e5fd2
-                self.obj_dict['edges'].get( edge_points_reverse, None ))
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+                self.obj_dict['edges'].get(edge_points_reverse, None))
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             for edge_obj_dict in edges_obj_dict:
rdobuilder 3e5fd2
-                match.append( Edge( edge_points[0], edge_points[1], obj_dict = edge_obj_dict ) )
rdobuilder 3e5fd2
+                match.append(
rdobuilder 3e5fd2
+                    Edge(edge_points[0], edge_points[1], obj_dict=edge_obj_dict)
rdobuilder 3e5fd2
+                    )
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         return match
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     def get_edges(self):
rdobuilder 3e5fd2
         return self.get_edge_list()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def get_edge_list(self):
rdobuilder 3e5fd2
         """Get the list of Edge instances.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         This method returns the list of Edge instances
rdobuilder 3e5fd2
         composing the graph.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         edge_objs = list()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        for edge, obj_dict_list in self.obj_dict['edges'].iteritems():
rdobuilder 3e5fd2
-                edge_objs.extend( [ Edge( obj_dict = obj_d ) for obj_d in obj_dict_list ] )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        return edge_objs
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        for edge, obj_dict_list in self.obj_dict['edges'].items():
rdobuilder 3e5fd2
+            edge_objs.extend([
rdobuilder 3e5fd2
+                Edge(obj_dict=obj_d)
rdobuilder 3e5fd2
+                for obj_d
rdobuilder 3e5fd2
+                in obj_dict_list
rdobuilder 3e5fd2
+                ])
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        return edge_objs
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
     def add_subgraph(self, sgraph):
rdobuilder 3e5fd2
         """Adds an subgraph object to the graph.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         It takes a subgraph object as its only argument and returns
rdobuilder 3e5fd2
         None.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         if not isinstance(sgraph, Subgraph) and not isinstance(sgraph, Cluster):
rdobuilder 3e5fd2
             raise TypeError('add_subgraph() received a non subgraph class object:' + str(sgraph))
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        if self.obj_dict['subgraphs'].has_key(sgraph.get_name()):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-            sgraph_list = self.obj_dict['subgraphs'][ sgraph.get_name() ]
rdobuilder 3e5fd2
-            sgraph_list.append( sgraph.obj_dict )
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if sgraph.get_name() in self.obj_dict['subgraphs']:
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+            sgraph_list = self.obj_dict['subgraphs'][sgraph.get_name()]
rdobuilder 3e5fd2
+            sgraph_list.append(sgraph.obj_dict)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-            self.obj_dict['subgraphs'][ sgraph.get_name() ] = [ sgraph.obj_dict ]
rdobuilder 3e5fd2
-         
rdobuilder 3e5fd2
-        sgraph.set_sequence( self.get_next_sequence_number() )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        sgraph.set_parent_graph( self.get_parent_graph() )
rdobuilder 3e5fd2
+            self.obj_dict['subgraphs'][sgraph.get_name()] = [sgraph.obj_dict]
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        sgraph.set_sequence(self.get_next_sequence_number())
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        sgraph.set_parent_graph(self.get_parent_graph())
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
     def get_subgraph(self, name):
rdobuilder 3e5fd2
         """Retrieved a subgraph from the graph.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         Given a subgraph's name the corresponding
rdobuilder 3e5fd2
         Subgraph instance will be returned.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         If one or more subgraphs exist with the same name, a list of
rdobuilder 3e5fd2
         Subgraph instances is returned.
rdobuilder 3e5fd2
         An empty list is returned otherwise.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         match = list()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        if self.obj_dict['subgraphs'].has_key( name ):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-            sgraphs_obj_dict = self.obj_dict['subgraphs'].get( name )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if name in self.obj_dict['subgraphs']:
rdobuilder 3e5fd2
+            sgraphs_obj_dict = self.obj_dict['subgraphs'].get(name)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             for obj_dict_list in sgraphs_obj_dict:
rdobuilder 3e5fd2
-                #match.extend( Subgraph( obj_dict = obj_d ) for obj_d in obj_dict_list )
rdobuilder 3e5fd2
-                match.append( Subgraph( obj_dict = obj_dict_list ) )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        return match
rdobuilder 3e5fd2
+                #match.extend(Subgraph(obj_dict = obj_d) for obj_d in obj_dict_list)
rdobuilder 3e5fd2
+                match.append(Subgraph(obj_dict=obj_dict_list))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        return match
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def get_subgraphs(self):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
         return self.get_subgraph_list()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def get_subgraph_list(self):
rdobuilder 3e5fd2
         """Get the list of Subgraph instances.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         This method returns the list of Subgraph instances
rdobuilder 3e5fd2
         in the graph.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         sgraph_objs = list()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        for sgraph, obj_dict_list in self.obj_dict['subgraphs'].iteritems():
rdobuilder 3e5fd2
-                sgraph_objs.extend( [ Subgraph( obj_dict = obj_d ) for obj_d in obj_dict_list ] )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        return sgraph_objs
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        for sgraph, obj_dict_list in self.obj_dict['subgraphs'].items():
rdobuilder 3e5fd2
+            sgraph_objs.extend([
rdobuilder 3e5fd2
+                Subgraph(obj_dict=obj_d)
rdobuilder 3e5fd2
+                for obj_d
rdobuilder 3e5fd2
+                in obj_dict_list
rdobuilder 3e5fd2
+                ])
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        return sgraph_objs
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def set_parent_graph(self, parent_graph):
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         self.obj_dict['parent_graph'] = parent_graph
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        for obj_list in self.obj_dict['nodes'].itervalues():
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        for obj_list in self.obj_dict['nodes'].values():
rdobuilder 3e5fd2
             for obj in obj_list:
rdobuilder 3e5fd2
                 obj['parent_graph'] = parent_graph
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        for obj_list in self.obj_dict['edges'].itervalues():
rdobuilder 3e5fd2
+        for obj_list in self.obj_dict['edges'].values():
rdobuilder 3e5fd2
             for obj in obj_list:
rdobuilder 3e5fd2
                 obj['parent_graph'] = parent_graph
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        for obj_list in self.obj_dict['subgraphs'].itervalues():
rdobuilder 3e5fd2
+        for obj_list in self.obj_dict['subgraphs'].values():
rdobuilder 3e5fd2
             for obj in obj_list:
rdobuilder 3e5fd2
                 Graph(obj_dict=obj).set_parent_graph(parent_graph)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
     def to_string(self):
rdobuilder 3e5fd2
         """Returns a string representation of the graph in dot language.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         It will return the graph and all its subelements in string from.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         graph = list()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if self.obj_dict.get('strict', None) is not None:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-            if self==self.get_parent_graph() and self.obj_dict['strict']:
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+            if self == self.get_parent_graph() and self.obj_dict['strict']:
rdobuilder 3e5fd2
                 graph.append('strict ')
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         if self.obj_dict['name'] == '':
rdobuilder 3e5fd2
             if 'show_keyword' in self.obj_dict and self.obj_dict['show_keyword']:
rdobuilder 3e5fd2
-                graph.append( 'subgraph {\n' )
rdobuilder 3e5fd2
+                graph.append('subgraph {\n')
rdobuilder 3e5fd2
             else:
rdobuilder 3e5fd2
-                graph.append( '{\n' )
rdobuilder 3e5fd2
+                graph.append('{\n')
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
-            graph.append( '%s %s {\n' % (self.obj_dict['type'], self.obj_dict['name']) )
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
+            graph.append('%s %s {\n' % (self.obj_dict['type'], self.obj_dict['name']))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        for attr in self.obj_dict['attributes'].iterkeys():
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-            if self.obj_dict['attributes'].get(attr, None) is not None:
rdobuilder 3e5fd2
-       
rdobuilder 3e5fd2
-                val = self.obj_dict['attributes'].get(attr)
rdobuilder 3e5fd2
-                if val is not None:
rdobuilder 3e5fd2
-                    graph.append( '%s=%s' % (attr, quote_if_necessary(val)) )
rdobuilder 3e5fd2
-                else:
rdobuilder 3e5fd2
-                    graph.append( attr )
rdobuilder 3e5fd2
-                    
rdobuilder 3e5fd2
-                graph.append( ';\n' )
rdobuilder 3e5fd2
+        for attr, value in sorted(self.obj_dict['attributes'].items(), key=itemgetter(0)):
rdobuilder 3e5fd2
+            if value is not None:
rdobuilder 3e5fd2
+                graph.append('%s=%s' % (attr, quote_if_necessary(value)))
rdobuilder 3e5fd2
+            else:
rdobuilder 3e5fd2
+                graph.append(attr)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+            graph.append(';\n')
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         edges_done = set()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         edge_obj_dicts = list()
rdobuilder 3e5fd2
-        for e in self.obj_dict['edges'].itervalues():
rdobuilder 3e5fd2
+        for e in self.obj_dict['edges'].values():
rdobuilder 3e5fd2
             edge_obj_dicts.extend(e)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if edge_obj_dicts:
rdobuilder 3e5fd2
-            edge_src_set, edge_dst_set = zip( *[obj['points'] for obj in edge_obj_dicts] )
rdobuilder 3e5fd2
+            edge_src_set, edge_dst_set = list(zip(*[obj['points'] for obj in edge_obj_dicts]))
rdobuilder 3e5fd2
             edge_src_set, edge_dst_set = set(edge_src_set), set(edge_dst_set)
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
             edge_src_set, edge_dst_set = set(), set()
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         node_obj_dicts = list()
rdobuilder 3e5fd2
-        for e in self.obj_dict['nodes'].itervalues():
rdobuilder 3e5fd2
+        for e in self.obj_dict['nodes'].values():
rdobuilder 3e5fd2
             node_obj_dicts.extend(e)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         sgraph_obj_dicts = list()
rdobuilder 3e5fd2
-        for sg in self.obj_dict['subgraphs'].itervalues():
rdobuilder 3e5fd2
+        for sg in self.obj_dict['subgraphs'].values():
rdobuilder 3e5fd2
             sgraph_obj_dicts.extend(sg)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        obj_list = [ (obj['sequence'], obj) for obj in (edge_obj_dicts + node_obj_dicts + sgraph_obj_dicts) ]
rdobuilder 3e5fd2
-        obj_list.sort()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+        obj_list = sorted([
rdobuilder 3e5fd2
+            (obj['sequence'], obj)
rdobuilder 3e5fd2
+            for obj
rdobuilder 3e5fd2
+            in (edge_obj_dicts + node_obj_dicts + sgraph_obj_dicts)
rdobuilder 3e5fd2
+            ])
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         for idx, obj in obj_list:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
             if obj['type'] == 'node':
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
                 node = Node(obj_dict=obj)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
                 if self.obj_dict.get('suppress_disconnected', False):
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
                     if (node.get_name() not in edge_src_set and
rdobuilder 3e5fd2
-                        node.get_name() not in edge_dst_set):
rdobuilder 3e5fd2
-                        
rdobuilder 3e5fd2
+                            node.get_name() not in edge_dst_set):
rdobuilder 3e5fd2
                         continue
rdobuilder 3e5fd2
-                        
rdobuilder 3e5fd2
-                graph.append( node.to_string()+'\n' )
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-            elif obj['type'] == 'edge':
rdobuilder 3e5fd2
+                graph.append(node.to_string() + '\n')
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+            elif obj['type'] == 'edge':
rdobuilder 3e5fd2
                 edge = Edge(obj_dict=obj)
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
                 if self.obj_dict.get('simplify', False) and edge in edges_done:
rdobuilder 3e5fd2
                     continue
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
-                graph.append( edge.to_string() + '\n' )
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+                graph.append(edge.to_string() + '\n')
rdobuilder 3e5fd2
                 edges_done.add(edge)
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
             else:
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
                 sgraph = Subgraph(obj_dict=obj)
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
-                graph.append( sgraph.to_string()+'\n' )
rdobuilder 3e5fd2
+                graph.append(sgraph.to_string() + '\n')
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        graph.append( '}\n' )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        return ''.join(graph)
rdobuilder 3e5fd2
+        graph.append('}\n')
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        return ''.join(graph)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 class Subgraph(Graph):
rdobuilder 3e5fd2
@@ -1680,9 +1622,9 @@ class Subgraph(Graph):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     This class implements the methods to work on a representation
rdobuilder 3e5fd2
     of a subgraph in Graphviz's dot language.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     subgraph(graph_name='subG', suppress_disconnected=False, attribute=value, ...)
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     graph_name:
rdobuilder 3e5fd2
         the subgraph's name
rdobuilder 3e5fd2
     suppress_disconnected:
rdobuilder 3e5fd2
@@ -1690,46 +1632,43 @@ class Subgraph(Graph):
rdobuilder 3e5fd2
         subgraph any disconnected nodes.
rdobuilder 3e5fd2
     All the attributes defined in the Graphviz dot language should
rdobuilder 3e5fd2
     be supported.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     Attributes can be set through the dynamically generated methods:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
      set_[attribute name], i.e. set_size, set_fontname
rdobuilder 3e5fd2
-     
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     or using the instance's attributes:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-     Subgraph.obj_dict['attributes'][attribute name], i.e. 
rdobuilder 3e5fd2
-     
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+     Subgraph.obj_dict['attributes'][attribute name], i.e.
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         subgraph_instance.obj_dict['attributes']['label']
rdobuilder 3e5fd2
         subgraph_instance.obj_dict['attributes']['fontname']
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     # RMF: subgraph should have all the attributes of graph so it can be passed
rdobuilder 3e5fd2
     # as a graph to all methods
rdobuilder 3e5fd2
     #
rdobuilder 3e5fd2
-    def __init__(self, graph_name='', obj_dict=None, suppress_disconnected=False,
rdobuilder 3e5fd2
-        simplify=False, **attrs):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+    def __init__(
rdobuilder 3e5fd2
+            self, graph_name='', obj_dict=None, suppress_disconnected=False,
rdobuilder 3e5fd2
+            simplify=False, **attrs):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        Graph.__init__(self, graph_name=graph_name, obj_dict=obj_dict,
rdobuilder 3e5fd2
+        Graph.__init__(
rdobuilder 3e5fd2
+            self, graph_name=graph_name, obj_dict=obj_dict,
rdobuilder 3e5fd2
             suppress_disconnected=suppress_disconnected, simplify=simplify, **attrs)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         if obj_dict is None:
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
             self.obj_dict['type'] = 'subgraph'
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 class Cluster(Graph):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     """Class representing a cluster in Graphviz's dot language.
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     This class implements the methods to work on a representation
rdobuilder 3e5fd2
     of a cluster in Graphviz's dot language.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     cluster(graph_name='subG', suppress_disconnected=False, attribute=value, ...)
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     graph_name:
rdobuilder 3e5fd2
         the cluster's name (the string 'cluster' will be always prepended)
rdobuilder 3e5fd2
     suppress_disconnected:
rdobuilder 3e5fd2
@@ -1737,38 +1676,35 @@ class Cluster(Graph):
rdobuilder 3e5fd2
         cluster any disconnected nodes.
rdobuilder 3e5fd2
     All the attributes defined in the Graphviz dot language should
rdobuilder 3e5fd2
     be supported.
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     Attributes can be set through the dynamically generated methods:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
      set_[attribute name], i.e. set_color, set_fontname
rdobuilder 3e5fd2
-     
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     or using the instance's attributes:
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-     Cluster.obj_dict['attributes'][attribute name], i.e. 
rdobuilder 3e5fd2
-     
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+     Cluster.obj_dict['attributes'][attribute name], i.e.
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         cluster_instance.obj_dict['attributes']['label']
rdobuilder 3e5fd2
         cluster_instance.obj_dict['attributes']['fontname']
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-    def __init__(self, graph_name='subG', obj_dict=None, suppress_disconnected=False,
rdobuilder 3e5fd2
-        simplify=False, **attrs):
rdobuilder 3e5fd2
+    def __init__(
rdobuilder 3e5fd2
+            self, graph_name='subG', obj_dict=None, suppress_disconnected=False,
rdobuilder 3e5fd2
+            simplify=False, **attrs):
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        Graph.__init__(self, graph_name=graph_name, obj_dict=obj_dict,
rdobuilder 3e5fd2
-            suppress_disconnected=suppress_disconnected, simplify=simplify, **attrs)
rdobuilder 3e5fd2
+        Graph.__init__(
rdobuilder 3e5fd2
+            self, graph_name=graph_name, obj_dict=obj_dict,
rdobuilder 3e5fd2
+            suppress_disconnected=suppress_disconnected, simplify=simplify, **attrs
rdobuilder 3e5fd2
+            )
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         if obj_dict is None:
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
             self.obj_dict['type'] = 'subgraph'
rdobuilder 3e5fd2
-            self.obj_dict['name'] = 'cluster_'+graph_name
rdobuilder 3e5fd2
+            self.obj_dict['name'] = 'cluster_' + graph_name
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         self.create_attribute_methods(CLUSTER_ATTRIBUTES)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-   
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
 class Dot(Graph):
rdobuilder 3e5fd2
     """A container for handling a dot language file.
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
@@ -1776,144 +1712,148 @@ class Dot(Graph):
rdobuilder 3e5fd2
     a dot language file. It is a derived class of
rdobuilder 3e5fd2
     the base class 'Graph'.
rdobuilder 3e5fd2
     """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-     
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def __init__(self, *argsl, **argsd):
rdobuilder 3e5fd2
         Graph.__init__(self, *argsl, **argsd)
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         self.shape_files = list()
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
         self.progs = None
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        self.formats = ['canon', 'cmap', 'cmapx', 'cmapx_np', 'dia', 'dot',
rdobuilder 3e5fd2
+        self.formats = [
rdobuilder 3e5fd2
+            'canon', 'cmap', 'cmapx', 'cmapx_np', 'dia', 'dot',
rdobuilder 3e5fd2
             'fig', 'gd', 'gd2', 'gif', 'hpgl', 'imap', 'imap_np', 'ismap',
rdobuilder 3e5fd2
             'jpe', 'jpeg', 'jpg', 'mif', 'mp', 'pcl', 'pdf', 'pic', 'plain',
rdobuilder 3e5fd2
             'plain-ext', 'png', 'ps', 'ps2', 'svg', 'svgz', 'vml', 'vmlz',
rdobuilder 3e5fd2
-            'vrml', 'vtx', 'wbmp', 'xdot', 'xlib' ]
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
+            'vrml', 'vtx', 'wbmp', 'xdot', 'xlib'
rdobuilder 3e5fd2
+            ]
rdobuilder 3e5fd2
         self.prog = 'dot'
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         # Automatically creates all the methods enabling the creation
rdobuilder 3e5fd2
         # of output in any of the supported formats.
rdobuilder 3e5fd2
         for frmt in self.formats:
rdobuilder 3e5fd2
             self.__setattr__(
rdobuilder 3e5fd2
-                'create_'+frmt,
rdobuilder 3e5fd2
-                lambda f=frmt, prog=self.prog : self.create(format=f, prog=prog))
rdobuilder 3e5fd2
-            f = self.__dict__['create_'+frmt]
rdobuilder 3e5fd2
-            f.__doc__ = '''Refer to the docstring accompanying the 'create' method for more information.'''
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        for frmt in self.formats+['raw']:
rdobuilder 3e5fd2
+                'create_' + frmt,
rdobuilder 3e5fd2
+                lambda f=frmt, prog=self.prog: self.create(format=f, prog=prog)
rdobuilder 3e5fd2
+                )
rdobuilder 3e5fd2
+            f = self.__dict__['create_' + frmt]
rdobuilder 3e5fd2
+            f.__doc__ = (
rdobuilder 3e5fd2
+                '''Refer to the docstring accompanying the'''
rdobuilder 3e5fd2
+                ''''create' method for more information.'''
rdobuilder 3e5fd2
+                )
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        for frmt in self.formats + ['raw']:
rdobuilder 3e5fd2
             self.__setattr__(
rdobuilder 3e5fd2
-                'write_'+frmt,
rdobuilder 3e5fd2
-                lambda path, f=frmt, prog=self.prog : self.write(path, format=f, prog=prog))
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
-            f = self.__dict__['write_'+frmt]
rdobuilder 3e5fd2
-            f.__doc__ = '''Refer to the docstring accompanying the 'write' method for more information.'''
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+                'write_' + frmt,
rdobuilder 3e5fd2
+                lambda path, f=frmt, prog=self.prog: self.write(path, format=f, prog=prog)
rdobuilder 3e5fd2
+                )
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+            f = self.__dict__['write_' + frmt]
rdobuilder 3e5fd2
+            f.__doc__ = (
rdobuilder 3e5fd2
+                '''Refer to the docstring accompanying the'''
rdobuilder 3e5fd2
+                ''''write' method for more information.'''
rdobuilder 3e5fd2
+                )
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def __getstate__(self):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        dict = copy.copy(self.obj_dict)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        return dict
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+        return copy.copy(self.obj_dict)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def __setstate__(self, state):
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
         self.obj_dict = state
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def set_shape_files(self, file_paths):
rdobuilder 3e5fd2
         """Add the paths of the required image files.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         If the graph needs graphic objects to be used as shapes or otherwise
rdobuilder 3e5fd2
         those need to be in the same folder as the graph is going to be rendered
rdobuilder 3e5fd2
         from. Alternatively the absolute path to the files can be specified when
rdobuilder 3e5fd2
         including the graphics in the graph.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         The files in the location pointed to by the path(s) specified as arguments
rdobuilder 3e5fd2
         to this method will be copied to the same temporary location where the
rdobuilder 3e5fd2
         graph is going to be rendered.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        if isinstance( file_paths, basestring ):
rdobuilder 3e5fd2
-            self.shape_files.append( file_paths )
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        if isinstance( file_paths, (list, tuple) ):
rdobuilder 3e5fd2
-            self.shape_files.extend( file_paths )
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if isinstance(file_paths, basestring):
rdobuilder 3e5fd2
+            self.shape_files.append(file_paths)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if isinstance(file_paths, (list, tuple)):
rdobuilder 3e5fd2
+            self.shape_files.extend(file_paths)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
     def set_prog(self, prog):
rdobuilder 3e5fd2
         """Sets the default program.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         Sets the default program in charge of processing
rdobuilder 3e5fd2
         the dot file into a graph.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
         self.prog = prog
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def set_graphviz_executables(self, paths):
rdobuilder 3e5fd2
         """This method allows to manually specify the location of the GraphViz executables.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         The argument to this method should be a dictionary where the keys are as follows:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             {'dot': '', 'twopi': '', 'neato': '', 'circo': '', 'fdp': ''}
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         and the values are the paths to the corresponding executable, including the name
rdobuilder 3e5fd2
         of the executable itself.
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
-        self.progs = paths
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        self.progs = paths
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def write(self, path, prog=None, format='raw'):
rdobuilder 3e5fd2
-        """Writes a graph to a file.
rdobuilder 3e5fd2
-
rdobuilder 3e5fd2
+        """
rdobuilder 3e5fd2
         Given a filename 'path' it will open/create and truncate
rdobuilder 3e5fd2
         such file and write on it a representation of the graph
rdobuilder 3e5fd2
         defined by the dot object and in the format specified by
rdobuilder 3e5fd2
-        'format'.
rdobuilder 3e5fd2
+        'format'. 'path' can also be an open file-like object, such as
rdobuilder 3e5fd2
+        a StringIO instance.
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         The format 'raw' is used to dump the string representation
rdobuilder 3e5fd2
         of the Dot object, without further processing.
rdobuilder 3e5fd2
         The output can be processed by any of graphviz tools, defined
rdobuilder 3e5fd2
         in 'prog', which defaults to 'dot'
rdobuilder 3e5fd2
         Returns True or False according to the success of the write
rdobuilder 3e5fd2
         operation.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         There's also the preferred possibility of using:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             write_'format'(path, prog='program')
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         which are automatically defined for all the supported formats.
rdobuilder 3e5fd2
         [write_ps(), write_gif(), write_dia(), ...]
rdobuilder 3e5fd2
-        """
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        """
rdobuilder 3e5fd2
         if prog is None:
rdobuilder 3e5fd2
             prog = self.prog
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        dot_fd = file(path, "w+b")
rdobuilder 3e5fd2
-        if format == 'raw':
rdobuilder 3e5fd2
-            data = self.to_string()
rdobuilder 3e5fd2
-            if isinstance(data, basestring):
rdobuilder 3e5fd2
-                if not isinstance(data, unicode):
rdobuilder 3e5fd2
-                    try:
rdobuilder 3e5fd2
-                        data = unicode(data, 'utf-8')
rdobuilder 3e5fd2
-                    except:
rdobuilder 3e5fd2
-                        pass
rdobuilder 3e5fd2
-                        
rdobuilder 3e5fd2
-            try:
rdobuilder 3e5fd2
-                data = data.encode('utf-8')
rdobuilder 3e5fd2
-            except:
rdobuilder 3e5fd2
-                pass
rdobuilder 3e5fd2
-            dot_fd.write(data)
rdobuilder 3e5fd2
-        else:
rdobuilder 3e5fd2
-            dot_fd.write(self.create(prog, format))
rdobuilder 3e5fd2
-        dot_fd.close()
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-        return True
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+        fobj, close = get_fobj(path, 'w+b')
rdobuilder 3e5fd2
+        try:
rdobuilder 3e5fd2
+            if format == 'raw':
rdobuilder 3e5fd2
+                data = self.to_string()
rdobuilder 3e5fd2
+                if isinstance(data, basestring):
rdobuilder 3e5fd2
+                    if not isinstance(data, unicode):
rdobuilder 3e5fd2
+                        try:
rdobuilder 3e5fd2
+                            data = unicode(data, 'utf-8')
rdobuilder 3e5fd2
+                        except:
rdobuilder 3e5fd2
+                            pass
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+                try:
rdobuilder 3e5fd2
+                    charset = self.get_charset()
rdobuilder 3e5fd2
+                    if not PY3 or not charset:
rdobuilder 3e5fd2
+                        charset = 'utf-8'
rdobuilder 3e5fd2
+                    data = data.encode(charset)
rdobuilder 3e5fd2
+                except:
rdobuilder 3e5fd2
+                    if PY3:
rdobuilder 3e5fd2
+                        data = data.encode('utf-8')
rdobuilder 3e5fd2
+                    pass
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+                fobj.write(data)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+            else:
rdobuilder 3e5fd2
+                fobj.write(self.create(prog, format))
rdobuilder 3e5fd2
+        finally:
rdobuilder 3e5fd2
+            if close:
rdobuilder 3e5fd2
+                fobj.close()
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        return True
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
     def create(self, prog=None, format='ps'):
rdobuilder 3e5fd2
         """Creates and returns a Postscript representation of the graph.
rdobuilder 3e5fd2
@@ -1923,75 +1863,71 @@ class Dot(Graph):
rdobuilder 3e5fd2
         reading the Postscript output and returning it as a string is the
rdobuilder 3e5fd2
         operation is successful.
rdobuilder 3e5fd2
         On failure None is returned.
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         There's also the preferred possibility of using:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             create_'format'(prog='program')
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         which are automatically defined for all the supported formats.
rdobuilder 3e5fd2
         [create_ps(), create_gif(), create_dia(), ...]
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         If 'prog' is a list instead of a string the fist item is expected
rdobuilder 3e5fd2
         to be the program name, followed by any optional command-line
rdobuilder 3e5fd2
         arguments for it:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-            [ 'twopi', '-Tdot', '-s10' ]
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+            ['twopi', '-Tdot', '-s10']
rdobuilder 3e5fd2
         """
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if prog is None:
rdobuilder 3e5fd2
             prog = self.prog
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if isinstance(prog, (list, tuple)):
rdobuilder 3e5fd2
             prog, args = prog[0], prog[1:]
rdobuilder 3e5fd2
         else:
rdobuilder 3e5fd2
             args = []
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if self.progs is None:
rdobuilder 3e5fd2
             self.progs = find_graphviz()
rdobuilder 3e5fd2
             if self.progs is None:
rdobuilder 3e5fd2
                 raise InvocationException(
rdobuilder 3e5fd2
-                    'GraphViz\'s executables not found' )
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
-        if not self.progs.has_key(prog):
rdobuilder 3e5fd2
+                    'GraphViz\'s executables not found')
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if prog not in self.progs:
rdobuilder 3e5fd2
             raise InvocationException(
rdobuilder 3e5fd2
-                'GraphViz\'s executable "%s" not found' % prog )
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        if not os.path.exists( self.progs[prog] ) or not os.path.isfile( self.progs[prog] ):
rdobuilder 3e5fd2
+                'GraphViz\'s executable "%s" not found' % prog)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if not os.path.exists(self.progs[prog]) or not os.path.isfile(self.progs[prog]):
rdobuilder 3e5fd2
             raise InvocationException(
rdobuilder 3e5fd2
-                'GraphViz\'s executable "%s" is not a file or doesn\'t exist' % self.progs[prog] )
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+                'GraphViz\'s executable "%s" is not a file or doesn\'t exist' % self.progs[prog])
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         tmp_fd, tmp_name = tempfile.mkstemp()
rdobuilder 3e5fd2
         os.close(tmp_fd)
rdobuilder 3e5fd2
         self.write(tmp_name)
rdobuilder 3e5fd2
-        tmp_dir = os.path.dirname(tmp_name )
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+        tmp_dir = os.path.dirname(tmp_name)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         # For each of the image files...
rdobuilder 3e5fd2
-        #
rdobuilder 3e5fd2
         for img in self.shape_files:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             # Get its data
rdobuilder 3e5fd2
-            #
rdobuilder 3e5fd2
-            f = file(img, 'rb')
rdobuilder 3e5fd2
+            f = open(img, 'rb')
rdobuilder 3e5fd2
             f_data = f.read()
rdobuilder 3e5fd2
             f.close()
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             # And copy it under a file with the same name in the temporary directory
rdobuilder 3e5fd2
-            #
rdobuilder 3e5fd2
-            f = file( os.path.join( tmp_dir, os.path.basename(img) ), 'wb' )
rdobuilder 3e5fd2
+            f = open(os.path.join(tmp_dir, os.path.basename(img)), 'wb')
rdobuilder 3e5fd2
             f.write(f_data)
rdobuilder 3e5fd2
             f.close()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        cmdline = [self.progs[prog], '-T'+format, tmp_name] + args
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        cmdline = [self.progs[prog], '-T' + format, tmp_name] + args
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         p = subprocess.Popen(
rdobuilder 3e5fd2
             cmdline,
rdobuilder 3e5fd2
             cwd=tmp_dir,
rdobuilder 3e5fd2
             stderr=subprocess.PIPE, stdout=subprocess.PIPE)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         stderr = p.stderr
rdobuilder 3e5fd2
         stdout = p.stdout
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         stdout_output = list()
rdobuilder 3e5fd2
         while True:
rdobuilder 3e5fd2
             data = stdout.read()
rdobuilder 3e5fd2
@@ -1999,9 +1935,9 @@ class Dot(Graph):
rdobuilder 3e5fd2
                 break
rdobuilder 3e5fd2
             stdout_output.append(data)
rdobuilder 3e5fd2
         stdout.close()
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
-        stdout_output = ''.join(stdout_output)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        stdout_output = NULL_SEP.join(stdout_output)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         if not stderr.closed:
rdobuilder 3e5fd2
             stderr_output = list()
rdobuilder 3e5fd2
             while True:
rdobuilder 3e5fd2
@@ -2010,29 +1946,28 @@ class Dot(Graph):
rdobuilder 3e5fd2
                     break
rdobuilder 3e5fd2
                 stderr_output.append(data)
rdobuilder 3e5fd2
             stderr.close()
rdobuilder 3e5fd2
-                
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             if stderr_output:
rdobuilder 3e5fd2
-                stderr_output = ''.join(stderr_output)
rdobuilder 3e5fd2
-            
rdobuilder 3e5fd2
+                stderr_output = NULL_SEP.join(stderr_output)
rdobuilder 3e5fd2
+                if PY3:
rdobuilder 3e5fd2
+                    stderr_output = stderr_output.decode(sys.stderr.encoding)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         #pid, status = os.waitpid(p.pid, 0)
rdobuilder 3e5fd2
         status = p.wait()
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        if status != 0 :
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
+        if status != 0:
rdobuilder 3e5fd2
             raise InvocationException(
rdobuilder 3e5fd2
                 'Program terminated with status: %d. stderr follows: %s' % (
rdobuilder 3e5fd2
-                    status, stderr_output) )
rdobuilder 3e5fd2
+                    status, stderr_output))
rdobuilder 3e5fd2
         elif stderr_output:
rdobuilder 3e5fd2
-            print stderr_output
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+            print(stderr_output)
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
         # For each of the image files...
rdobuilder 3e5fd2
-        #
rdobuilder 3e5fd2
         for img in self.shape_files:
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
+
rdobuilder 3e5fd2
             # remove it
rdobuilder 3e5fd2
-            #
rdobuilder 3e5fd2
-            os.unlink( os.path.join( tmp_dir, os.path.basename(img) ) )
rdobuilder 3e5fd2
+            os.unlink(os.path.join(tmp_dir, os.path.basename(img)))
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
         os.unlink(tmp_name)
rdobuilder 3e5fd2
-        
rdobuilder 3e5fd2
-        return stdout_output
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
+        return stdout_output
rdobuilder 3e5fd2
diff --git a/setup.py b/setup.py
rdobuilder 3e5fd2
index 27328d8..92890d7 100644
rdobuilder 3e5fd2
--- a/setup.py
rdobuilder 3e5fd2
+++ b/setup.py
rdobuilder 3e5fd2
@@ -1,10 +1,6 @@
rdobuilder 3e5fd2
 #!/usr/bin/env python
rdobuilder 3e5fd2
 
rdobuilder 3e5fd2
-try:
rdobuilder 3e5fd2
-    from distutils.core import setup
rdobuilder 3e5fd2
-except ImportError, excp:
rdobuilder 3e5fd2
-    from setuptools import setup
rdobuilder 3e5fd2
-    
rdobuilder 3e5fd2
+from setuptools import setup
rdobuilder 3e5fd2
 import pydot
rdobuilder 3e5fd2
 import os
rdobuilder 3e5fd2