diff --git a/.style.yapf b/.style.yapf new file mode 100644 index 00000000..2ef2b908 --- /dev/null +++ b/.style.yapf @@ -0,0 +1,4 @@ +[style] +based_on_style=facebook +blank_line_before_nested_class_or_def=True +column_limit=79 diff --git a/dot_parser.py b/dot_parser.py index e9bc2538..14bfbd05 100644 --- a/dot_parser.py +++ b/dot_parser.py @@ -12,24 +12,9 @@ import sys from pyparsing import ( - nestedExpr, - Literal, - CaselessLiteral, - Word, - OneOrMore, - Forward, - Group, - Optional, - Combine, - restOfLine, - cStyleComment, - nums, - alphanums, - printables, - ParseException, - ParseResults, - CharsNotIn, - QuotedString, + nestedExpr, Literal, CaselessLiteral, Word, OneOrMore, Forward, Group, + Optional, Combine, restOfLine, cStyleComment, nums, alphanums, printables, + ParseException, ParseResults, CharsNotIn, QuotedString ) import pydot @@ -37,7 +22,6 @@ __author__ = ['Michael Krause', 'Ero Carrera'] __license__ = 'MIT' - PY3 = sys.version_info >= (3, 0, 0) if PY3: str_type = str @@ -46,6 +30,7 @@ class P_AttrList(object): + def __init__(self, toks): self.attrs = {} i = 0 @@ -66,15 +51,14 @@ def __repr__(self): class DefaultStatement(P_AttrList): + def __init__(self, default_type, attrs): self.default_type = default_type self.attrs = attrs def __repr__(self): return "%s(%s, %r)" % ( - self.__class__.__name__, - self.default_type, - self.attrs, + self.__class__.__name__, self.default_type, self.attrs ) @@ -88,9 +72,8 @@ def push_top_graph_stmt(str, loc, toks): for element in toks: if ( - isinstance(element, (ParseResults, tuple, list)) - and len(element) == 1 - and isinstance(element[0], str_type) + isinstance(element, (ParseResults, tuple, list)) and + len(element) == 1 and isinstance(element[0], str_type) ): element = element[0] @@ -143,7 +126,7 @@ def update_parent_graph_hierarchy(g, parent_graph=None, level=0): if parent_graph is None: parent_graph = g - for key_name in ('edges',): + for key_name in ('edges', ): if isinstance(g, pydot.frozendict): item_dict = g @@ -156,8 +139,8 @@ def update_parent_graph_hierarchy(g, parent_graph=None, level=0): for key, objs in item_dict[key_name].items(): for obj in objs: if ( - 'parent_graph' in obj - and obj['parent_graph'].get_parent_graph() == g + 'parent_graph' in obj and + obj['parent_graph'].get_parent_graph() == g ): if obj['parent_graph'] is g: pass @@ -168,7 +151,7 @@ def update_parent_graph_hierarchy(g, parent_graph=None, level=0): for idx, vertex in enumerate(obj['points']): if isinstance( vertex, - (pydot.Graph, pydot.Subgraph, pydot.Cluster), + (pydot.Graph, pydot.Subgraph, pydot.Cluster) ): vertex.set_parent_graph(parent_graph) if isinstance(vertex, pydot.frozendict): @@ -334,12 +317,9 @@ def push_edge_stmt(str, loc, toks): if isinstance(toks[2][0], ParseResults): - n_next_list = [ - [ - n.get_name(), - ] - for n in toks[2][0] - ] + n_next_list = [[ + n.get_name(), + ] for n in toks[2][0]] for n_next in [n for n in n_next_list]: n_next_port = do_node_ports(n_next) e.append(pydot.Edge(n_prev, n_next[0] + n_next_port, **attrs)) @@ -366,8 +346,9 @@ def push_edge_stmt(str, loc, toks): for n_next in [n for n in tuple(toks)[2::2]]: - if isinstance(n_next, P_AttrList) or not isinstance( - n_next[0], str_type + if ( + isinstance(n_next, P_AttrList) or + not isinstance(n_next[0], str_type) ): continue @@ -448,35 +429,32 @@ def parse_html(s, loc, toks): opener = '<' closer = '>' - html_text = ( - nestedExpr(opener, closer, (CharsNotIn(opener + closer))) - .setParseAction(parse_html) - .leaveWhitespace() - ) + html_text = nestedExpr(opener, closer, + (CharsNotIn(opener + closer) + )).setParseAction(parse_html).leaveWhitespace() - ID = ( - identifier | html_text | double_quoted_string | alphastring_ - ).setName("ID") + ID = (identifier | html_text | double_quoted_string | + alphastring_).setName("ID") - float_number = Combine( - Optional(minus) + OneOrMore(Word(nums + ".")) - ).setName("float_number") + float_number = Combine(Optional(minus) + + OneOrMore(Word(nums + + "."))).setName("float_number") righthand_id = (float_number | ID).setName("righthand_id") port_angle = (at + ID).setName("port_angle") port_location = ( - OneOrMore(Group(colon + ID)) - | Group(colon + lparen + ID + comma + ID + rparen) + OneOrMore(Group(colon + ID)) | + Group(colon + lparen + ID + comma + ID + rparen) ).setName("port_location") port = ( - Group(port_location + Optional(port_angle)) - | Group(port_angle + Optional(port_location)) + Group(port_location + Optional(port_angle)) | + Group(port_angle + Optional(port_location)) ).setName("port") - node_id = ID + Optional(port) + node_id = (ID + Optional(port)) a_list = OneOrMore( ID + Optional(equals + righthand_id) + Optional(comma.suppress()) ).setName("a_list") @@ -485,18 +463,15 @@ def parse_html(s, loc, toks): lbrack.suppress() + Optional(a_list) + rbrack.suppress() ).setName("attr_list") - attr_stmt = (Group(graph_ | node_ | edge_) + attr_list).setName( - "attr_stmt" - ) + attr_stmt = (Group(graph_ | node_ | edge_) + + attr_list).setName("attr_stmt") edgeop = (Literal("--") | Literal("->")).setName("edgeop") stmt_list = Forward() graph_stmt = Group( - lbrace.suppress() - + Optional(stmt_list) - + rbrace.suppress() - + Optional(semi.suppress()) + lbrace.suppress() + Optional(stmt_list) + rbrace.suppress() + + Optional(semi.suppress()) ).setName("graph_stmt") edge_point = Forward() @@ -504,13 +479,11 @@ def parse_html(s, loc, toks): edgeRHS = OneOrMore(edgeop + edge_point) edge_stmt = edge_point + edgeRHS + Optional(attr_list) - subgraph = Group(subgraph_ + Optional(ID) + graph_stmt).setName( - "subgraph" - ) + subgraph = Group(subgraph_ + Optional(ID) + + graph_stmt).setName("subgraph") - edge_point << Group(subgraph | graph_stmt | node_id).setName( - 'edge_point' - ) + edge_point << Group(subgraph | graph_stmt | + node_id).setName('edge_point') node_stmt = ( node_id + Optional(attr_list) + Optional(semi.suppress()) @@ -518,21 +491,15 @@ def parse_html(s, loc, toks): assignment = (ID + equals + righthand_id).setName("assignment") stmt = ( - assignment - | edge_stmt - | attr_stmt - | subgraph - | graph_stmt - | node_stmt + assignment | edge_stmt | attr_stmt | subgraph | graph_stmt | + node_stmt ).setName("stmt") stmt_list << OneOrMore(stmt + Optional(semi.suppress())) graphparser = OneOrMore( ( - Optional(strict_) - + Group((graph_ | digraph_)) - + Optional(ID) - + graph_stmt + Optional(strict_) + Group((graph_ | digraph_)) + Optional(ID) + + graph_stmt ).setResultsName("graph") ) diff --git a/pydot.py b/pydot.py index 89ff3de7..294d6a7e 100644 --- a/pydot.py +++ b/pydot.py @@ -20,248 +20,62 @@ "The error was: {e}".format(e=e) ) - __author__ = 'Ero Carrera' __version__ = '2.0.0.dev0' __license__ = 'MIT' - PY3 = sys.version_info >= (3, 0, 0) if PY3: str_type = str else: str_type = basestring - GRAPH_ATTRIBUTES = { - 'Damping', - 'K', - 'URL', - 'aspect', - 'bb', - 'bgcolor', - 'center', - 'charset', - 'clusterrank', - 'colorscheme', - 'comment', - 'compound', - 'concentrate', - 'defaultdist', - 'dim', - 'dimen', - 'diredgeconstraints', - 'dpi', - 'epsilon', - 'esep', - 'fontcolor', - 'fontname', - 'fontnames', - 'fontpath', - 'fontsize', - 'id', - 'label', - 'labeljust', - 'labelloc', - 'landscape', - 'layers', - 'layersep', - 'layout', - 'levels', - 'levelsgap', - 'lheight', - 'lp', - 'lwidth', - 'margin', - 'maxiter', - 'mclimit', - 'mindist', - 'mode', - 'model', - 'mosek', - 'nodesep', - 'nojustify', - 'normalize', - 'nslimit', - 'nslimit1', - 'ordering', - 'orientation', - 'outputorder', - 'overlap', - 'overlap_scaling', - 'pack', - 'packmode', - 'pad', - 'page', - 'pagedir', - 'quadtree', - 'quantum', - 'rankdir', - 'ranksep', - 'ratio', - 'remincross', - 'repulsiveforce', - 'resolution', - 'root', - 'rotate', - 'searchsize', - 'sep', - 'showboxes', - 'size', - 'smoothing', - 'sortv', - 'splines', - 'start', - 'stylesheet', - 'target', - 'truecolor', - 'viewport', - 'voro_margin', - # for subgraphs - 'rank', -} - + 'Damping', 'K', 'URL', 'aspect', 'bb', 'bgcolor', 'center', 'charset', + 'clusterrank', 'colorscheme', 'comment', 'compound', 'concentrate', + 'defaultdist', 'dim', 'dimen', 'diredgeconstraints', 'dpi', 'epsilon', + 'esep', 'fontcolor', 'fontname', 'fontnames', 'fontpath', 'fontsize', 'id', + 'label', 'labeljust', 'labelloc', 'landscape', 'layers', 'layersep', + 'layout', 'levels', 'levelsgap', 'lheight', 'lp', 'lwidth', 'margin', + 'maxiter', 'mclimit', 'mindist', 'mode', 'model', 'mosek', 'nodesep', + 'nojustify', 'normalize', 'nslimit', 'nslimit1', 'ordering', 'orientation', + 'outputorder', 'overlap', 'overlap_scaling', 'pack', 'packmode', 'pad', + 'page', 'pagedir', 'quadtree', 'quantum', 'rankdir', 'ranksep', 'ratio', + 'remincross', 'repulsiveforce', 'resolution', 'root', 'rotate', + 'searchsize', 'sep', 'showboxes', 'size', 'smoothing', 'sortv', 'splines', + 'start', 'stylesheet', 'target', 'truecolor', 'viewport', 'voro_margin' +} | {'rank'} # for subgraphs EDGE_ATTRIBUTES = { - 'URL', - 'arrowhead', - 'arrowsize', - 'arrowtail', - 'color', - 'colorscheme', - 'comment', - 'constraint', - 'decorate', - 'dir', - 'edgeURL', - 'edgehref', - 'edgetarget', - 'edgetooltip', - 'fontcolor', - 'fontname', - 'fontsize', - 'headURL', - 'headclip', - 'headhref', - 'headlabel', - 'headport', - 'headtarget', - 'headtooltip', - 'href', - 'id', - 'label', - 'labelURL', - 'labelangle', - 'labeldistance', - 'labelfloat', - 'labelfontcolor', - 'labelfontname', - 'labelfontsize', - 'labelhref', - 'labeltarget', - 'labeltooltip', - 'layer', - 'len', - 'lhead', - 'lp', - 'ltail', - 'minlen', - 'nojustify', - 'penwidth', - 'pos', - 'samehead', - 'sametail', - 'showboxes', - 'style', - 'tailURL', - 'tailclip', - 'tailhref', - 'taillabel', - 'tailport', - 'tailtarget', - 'tailtooltip', - 'target', - 'tooltip', - 'weight', - 'rank', + 'URL', 'arrowhead', 'arrowsize', 'arrowtail', 'color', 'colorscheme', + 'comment', 'constraint', 'decorate', 'dir', 'edgeURL', 'edgehref', + 'edgetarget', 'edgetooltip', 'fontcolor', 'fontname', 'fontsize', + 'headURL', 'headclip', 'headhref', 'headlabel', 'headport', 'headtarget', + 'headtooltip', 'href', 'id', 'label', 'labelURL', 'labelangle', + 'labeldistance', 'labelfloat', 'labelfontcolor', 'labelfontname', + 'labelfontsize', 'labelhref', 'labeltarget', 'labeltooltip', 'layer', + 'len', 'lhead', 'lp', 'ltail', 'minlen', 'nojustify', 'penwidth', 'pos', + 'samehead', 'sametail', 'showboxes', 'style', 'tailURL', 'tailclip', + 'tailhref', 'taillabel', 'tailport', 'tailtarget', 'tailtooltip', 'target', + 'tooltip', 'weight', 'rank' } - NODE_ATTRIBUTES = { - 'URL', - 'color', - 'colorscheme', - 'comment', - 'distortion', - 'fillcolor', - 'fixedsize', - 'fontcolor', - 'fontname', - 'fontsize', - 'group', - 'height', - 'id', - 'image', - 'imagescale', - 'label', - 'labelloc', - 'layer', - 'margin', - 'nojustify', - 'orientation', - 'penwidth', - 'peripheries', - 'pin', - 'pos', - 'rects', - 'regular', - 'root', - 'samplepoints', - 'shape', - 'shapefile', - 'showboxes', - 'sides', - 'skew', - 'sortv', - 'style', - 'target', - 'tooltip', - 'vertices', - 'width', - 'z', - # The following are attributes dot2tex - 'texlbl', - 'texmode', -} - + 'URL', 'color', 'colorscheme', 'comment', 'distortion', 'fillcolor', + 'fixedsize', 'fontcolor', 'fontname', 'fontsize', 'group', 'height', 'id', + 'image', 'imagescale', 'label', 'labelloc', 'layer', 'margin', 'nojustify', + 'orientation', 'penwidth', 'peripheries', 'pin', 'pos', 'rects', 'regular', + 'root', 'samplepoints', 'shape', 'shapefile', 'showboxes', 'sides', 'skew', + 'sortv', 'style', 'target', 'tooltip', 'vertices', 'width', 'z' +} | {'texlbl', 'texmode'} # The last set contains attributes dot2tex CLUSTER_ATTRIBUTES = { - 'K', - 'URL', - 'bgcolor', - 'color', - 'colorscheme', - 'fillcolor', - 'fontcolor', - 'fontname', - 'fontsize', - 'label', - 'labeljust', - 'labelloc', - 'lheight', - 'lp', - 'lwidth', - 'nojustify', - 'pencolor', - 'penwidth', - 'peripheries', - 'sortv', - 'style', - 'target', - 'tooltip', + 'K', 'URL', 'bgcolor', 'color', 'colorscheme', 'fillcolor', 'fontcolor', + 'fontname', 'fontsize', 'label', 'labeljust', 'labelloc', 'lheight', 'lp', + 'lwidth', 'nojustify', 'pencolor', 'penwidth', 'peripheries', 'sortv', + 'style', 'target', 'tooltip' } - DEFAULT_PROGRAMS = { 'dot', 'twopi', @@ -280,7 +94,6 @@ def is_windows(): def is_anaconda(): # type: () -> bool import glob - conda_pattern = os.path.join(sys.prefix, 'conda-meta\\graphviz*.json') return glob.glob(conda_pattern) != [] @@ -336,6 +149,7 @@ def call_graphviz(program, arguments, working_dir, **kwargs): # This version freezes dictionaries used as values within dictionaries. # class frozendict(dict): + def _blocked_attribute(obj): raise AttributeError('A frozendict cannot be modified.') @@ -417,16 +231,13 @@ def needs_quotes(s): if s in dot_keywords: return False - chars = [ord(c) for c in s if ord(c) > 0x7F or ord(c) == 0] + chars = [ord(c) for c in s if ord(c) > 0x7f or ord(c) == 0] if chars and not id_re_dbl_quoted.match(s) and not id_re_html.match(s): return True for test_re in [ - id_re_alpha_nums, - id_re_num, - id_re_dbl_quoted, - id_re_html, - id_re_alpha_nums_with_ports, + id_re_alpha_nums, id_re_num, id_re_dbl_quoted, id_re_html, + id_re_alpha_nums_with_ports ]: if test_re.match(s): return False @@ -560,7 +371,7 @@ def graph_from_adjacency_matrix(matrix, node_prefix=u'', directed=False): graph.add_edge( Edge( '%s%s' % (node_prefix, node_orig), - '%s%s' % (node_prefix, node_dest), + '%s%s' % (node_prefix, node_dest) ) ) node_dest += 1 @@ -597,7 +408,7 @@ def graph_from_incidence_matrix(matrix, node_prefix='', directed=False): graph.add_edge( Edge( '%s%s' % (node_prefix, abs(nodes[0])), - '%s%s' % (node_prefix, nodes[1]), + '%s%s' % (node_prefix, nodes[1]) ) ) @@ -708,9 +519,8 @@ def create_attribute_methods(self, obj_attributes): # self.__setattr__( 'set_' + attr, - lambda x, a=attr: self.obj_dict['attributes'].__setitem__( - a, x - ), + lambda x, a=attr: self.obj_dict['attributes']. + __setitem__(a, x) ) # Generate all the Getter methods. @@ -721,7 +531,8 @@ def create_attribute_methods(self, obj_attributes): class Error(Exception): - """General error handling class.""" + """General error handling class. + """ def __init__(self, value): self.value = value @@ -731,7 +542,8 @@ def __str__(self): class InvocationException(Exception): - """Indicate problem while running any GraphViz executable.""" + """Indicate problem while running any GraphViz executable. + """ def __init__(self, value): self.value = value @@ -930,18 +742,20 @@ def __eq__(self, edge): # source nor destination. # if ( - self.get_source() == edge.get_source() - and self.get_destination() == edge.get_destination() - ) or ( - edge.get_source() == self.get_destination() - and edge.get_destination() == self.get_source() + ( + self.get_source() == edge.get_source() and + self.get_destination() == edge.get_destination() + ) or ( + edge.get_source() == self.get_destination() and + edge.get_destination() == self.get_source() + ) ): return True else: if ( - self.get_source() == edge.get_source() - and self.get_destination() == edge.get_destination() + self.get_source() == edge.get_source() and + self.get_destination() == edge.get_destination() ): return True @@ -966,15 +780,14 @@ def parse_node_ref(self, node_str): node_port_idx = node_str.rfind(':') if ( - node_port_idx > 0 - and node_str[0] == '"' - and node_str[node_port_idx - 1] == '"' + node_port_idx > 0 and node_str[0] == '"' and + node_str[node_port_idx - 1] == '"' ): return node_str if node_port_idx > 0: a = node_str[:node_port_idx] - b = node_str[node_port_idx + 1 :] + b = node_str[node_port_idx + 1:] node = quote_if_necessary(a) node += ':' + quote_if_necessary(b) @@ -996,9 +809,9 @@ def to_string(self): edge = [src] if ( - self.get_parent_graph() - and self.get_parent_graph().get_top_graph_type() - and self.get_parent_graph().get_top_graph_type() == 'digraph' + self.get_parent_graph() and + self.get_parent_graph().get_top_graph_type() and + self.get_parent_graph().get_top_graph_type() == 'digraph' ): edge.append('->') @@ -1242,9 +1055,8 @@ def add_node(self, graph_node): """ if not isinstance(graph_node, Node): raise TypeError( - 'add_node() received ' - + 'a non node class object: ' - + str(graph_node) + 'add_node() received a non node class object: ' + + str(graph_node) ) node = self.get_node(graph_node.get_name()) @@ -1283,7 +1095,10 @@ def del_node(self, name, index=None): if name in self.obj_dict['nodes']: - if index is not None and index < len(self.obj_dict['nodes'][name]): + if ( + index is not None and + index < len(self.obj_dict['nodes'][name]) + ): del self.obj_dict['nodes'][name][index] return True else: @@ -1341,8 +1156,8 @@ def add_edge(self, graph_edge): """ if not isinstance(graph_edge, Edge): raise TypeError( - 'add_edge() received a non edge class object: ' - + str(graph_edge) + 'add_edge() received a non edge class object: ' + + str(graph_edge) ) edge_points = (graph_edge.get_source(), graph_edge.get_destination()) @@ -1386,8 +1201,9 @@ def del_edge(self, src_or_list, dst=None, index=None): dst = dst.get_name() if (src, dst) in self.obj_dict['edges']: - if index is not None and index < len( - self.obj_dict['edges'][(src, dst)] + if ( + index is not None and + index < len(self.obj_dict['edges'][(src, dst)]) ): del self.obj_dict['edges'][(src, dst)][index] return True @@ -1417,12 +1233,12 @@ def get_edge(self, src_or_list, dst=None): match = list() if edge_points in self.obj_dict['edges'] or ( - self.get_top_graph_type() == 'graph' - and edge_points_reverse in self.obj_dict['edges'] + self.get_top_graph_type() == 'graph' and + edge_points_reverse in self.obj_dict['edges'] ): edges_obj_dict = self.obj_dict['edges'].get( edge_points, - self.obj_dict['edges'].get(edge_points_reverse, None), + self.obj_dict['edges'].get(edge_points_reverse, None) ) for edge_obj_dict in edges_obj_dict: @@ -1457,12 +1273,13 @@ def add_subgraph(self, sgraph): It takes a subgraph object as its only argument and returns None. """ - if not isinstance(sgraph, Subgraph) and not isinstance( - sgraph, Cluster + if ( + not isinstance(sgraph, Subgraph) and + not isinstance(sgraph, Cluster) ): raise TypeError( - 'add_subgraph() received a non subgraph class object:' - + str(sgraph) + 'add_subgraph() received a non subgraph class object:' + + str(sgraph) ) if sgraph.get_name() in self.obj_dict['subgraphs']: @@ -1544,13 +1361,14 @@ def to_string(self): if self.obj_dict.get('strict', None) is not None: - if self == self.get_parent_graph() and self.obj_dict['strict']: + if (self == self.get_parent_graph() and self.obj_dict['strict']): graph.append('strict ') graph_type = self.obj_dict['type'] - if graph_type == 'subgraph' and not self.obj_dict.get( - 'show_keyword', True + if ( + graph_type == 'subgraph' and + not self.obj_dict.get('show_keyword', True) ): graph_type = '' s = '{type} {name} {{\n'.format( @@ -1608,8 +1426,8 @@ def to_string(self): if self.obj_dict.get('suppress_disconnected', False): if ( - node.get_name() not in edge_src_set - and node.get_name() not in edge_dst_set + node.get_name() not in edge_src_set and + node.get_name() not in edge_dst_set ): continue @@ -1618,7 +1436,9 @@ def to_string(self): elif obj['type'] == 'edge': edge = Edge(obj_dict=obj) - if self.obj_dict.get('simplify', False) and edge in edges_done: + if ( + self.obj_dict.get('simplify', False) and edge in edges_done + ): continue graph.append(edge.to_string() + '\n') @@ -1760,42 +1580,11 @@ def __init__(self, *argsl, **argsd): self.shape_files = list() self.formats = [ - 'canon', - 'cmap', - 'cmapx', - 'cmapx_np', - 'dia', - 'dot', - 'fig', - 'gd', - 'gd2', - 'gif', - 'hpgl', - 'imap', - 'imap_np', - 'ismap', - 'jpe', - 'jpeg', - 'jpg', - 'mif', - 'mp', - 'pcl', - 'pdf', - 'pic', - 'plain', - 'plain-ext', - 'png', - 'ps', - 'ps2', - 'svg', - 'svgz', - 'vml', - 'vmlz', - 'vrml', - 'vtx', - 'wbmp', - 'xdot', - 'xlib', + 'canon', 'cmap', 'cmapx', 'cmapx_np', 'dia', 'dot', 'fig', 'gd', + 'gd2', 'gif', 'hpgl', 'imap', 'imap_np', 'ismap', 'jpe', 'jpeg', + 'jpg', 'mif', 'mp', 'pcl', 'pdf', 'pic', 'plain', 'plain-ext', + 'png', 'ps', 'ps2', 'svg', 'svgz', 'vml', 'vmlz', 'vrml', 'vtx', + 'wbmp', 'xdot', 'xlib' ] self.prog = 'dot' @@ -1984,13 +1773,9 @@ def create(self, prog=None, format='ps', encoding=None): f.write(f_data) f.close() - arguments = ( - [ - '-T{}'.format(format), - ] - + args - + [tmp_name] - ) + arguments = [ + '-T{}'.format(format), + ] + args + [tmp_name] try: stdout_data, stderr_data, process = call_graphviz( @@ -2025,12 +1810,12 @@ def create(self, prog=None, format='ps', encoding=None): ) print(message) - assert ( - process.returncode == 0 - ), '"{prog}" with args {arguments} returned code: {code}'.format( - prog=prog, - arguments=arguments, - code=process.returncode, + assert process.returncode == 0, ( + '"{prog}" with args {arguments} returned code: {code}'.format( + prog=prog, + arguments=arguments, + code=process.returncode, + ) ) return stdout_data diff --git a/setup.py b/setup.py index ae3d3eeb..054deb3e 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,6 @@ import os import re - CURRENT_DIR = os.path.dirname(__file__) @@ -69,5 +68,5 @@ def get_version(): long_description_content_type="text/markdown", py_modules=['pydot', 'dot_parser'], install_requires=['pyparsing>=2.1.4'], - tests_require=['chardet'], + tests_require=['chardet'] ) diff --git a/test/pydot_unittest.py b/test/pydot_unittest.py index df3b3f1b..cd33e132 100644 --- a/test/pydot_unittest.py +++ b/test/pydot_unittest.py @@ -19,13 +19,13 @@ import pydot import unittest - TEST_PROGRAM = 'dot' TESTS_DIR_1 = 'my_tests' TESTS_DIR_2 = 'graphs' class TestGraphAPI(unittest.TestCase): + def setUp(self): self._reset_graphs() @@ -62,7 +62,7 @@ def test_create_simple_graph_with_node(self): def test_attribute_with_implicit_value(self): d = 'digraph {\na -> b[label="hi", decorate];\n}' graphs = pydot.graph_from_dot_data(d) - (g,) = graphs + (g, ) = graphs attrs = g.get_edges()[0].get_attributes() self.assertEqual('decorate' in attrs, True) @@ -105,7 +105,7 @@ def test_unicode_ids(self): self.assertEqual(g.get_edges()[0].get_source(), node1) self.assertEqual(g.get_edges()[0].get_destination(), node2) graphs = pydot.graph_from_dot_data(g.to_string()) - (g2,) = graphs + (g2, ) = graphs self.assertEqual(g2.get_node(node1)[0].get_name(), node1) self.assertEqual(g2.get_node(node2)[0].get_name(), node2) @@ -125,8 +125,7 @@ def test_graph_simplify(self): 'graph', False, 'graph G { a -- b; a -- b; b -- a; b -- a; }', - ), - ( + ), ( 'graph', True, 'graph G { a -- b; }', @@ -135,19 +134,16 @@ def test_graph_simplify(self): 'digraph', False, 'digraph G { a -> b; a -> b; b -> a; b -> a; }', - ), - ( + ), ( 'digraph', True, 'digraph G { a -> b; b -> a; }', - ), + ) ] expected_concat = observed_concat = '' for (graph_type, simplify, expected) in test_combinations: expected_concat += 'graph_type %s, simplify %s: %s\n' % ( - graph_type, - simplify, - expected, + graph_type, simplify, expected ) g.set_type(graph_type) g.set_simplify(simplify) @@ -156,9 +152,7 @@ def test_graph_simplify(self): except (NameError, TypeError) as e: observed = '%s: %s' % (type(e).__name__, e) observed_concat += 'graph_type %s, simplify %s: %s\n' % ( - graph_type, - simplify, - observed, + graph_type, simplify, observed ) self.maxDiff = None self.assertMultiLineEqual(expected_concat, observed_concat) @@ -176,8 +170,7 @@ def test_graph_with_shapefiles(self): pngs = [ os.path.join(shapefile_dir, fname) - for fname in os.listdir(shapefile_dir) - if fname.endswith('.png') + for fname in os.listdir(shapefile_dir) if fname.endswith('.png') ] f = open(dot_file, 'rt') @@ -185,7 +178,7 @@ def test_graph_with_shapefiles(self): f.close() graphs = pydot.graph_from_dot_data(graph_data) - (g,) = graphs + (g, ) = graphs g.set_shape_files(pngs) jpe_data = g.create(format='jpe') @@ -291,12 +284,13 @@ def test_keyword_node_id_to_string_with_attributes(self): def test_names_of_a_thousand_nodes(self): self._reset_graphs() - names = {'node_%05d' % i for i in range(10 ** 3)} + names = {'node_%05d' % i for i in range(10**3)} for name in names: self.graph_directed.add_node(pydot.Node(name, label=name)) self.assertEqual( - {n.get_name() for n in self.graph_directed.get_nodes()}, names + {n.get_name() + for n in self.graph_directed.get_nodes()}, names ) def test_executable_not_found_exception(self): @@ -371,7 +365,7 @@ def test_edge_point_object_cluster(self): ) self.assertEqual( self.graph_directed.get_edges()[0].to_string(), - 'cluster_a -> cluster_b;', + 'cluster_a -> cluster_b;' ) def test_graph_from_adjacency_matrix(self): @@ -403,9 +397,10 @@ def check_path(): not_check = parse_args() if not_check: return - assert not os.path.isfile( - 'setup.py' - ), 'running out of source does not test the installed `pydot`.' + assert not os.path.isfile('setup.py'), ( + 'running out of source does not ' + 'test the installed `pydot`.' + ) def parse_args(): @@ -417,7 +412,7 @@ def parse_args(): help=( 'do not require that no `setup.py` be present ' 'in the current working directory.' - ), + ) ) args, unknown = parser.parse_known_args() # avoid confusing `unittest`