summaryrefslogtreecommitdiff
path: root/venv/Lib/site-packages/pylint/pyreverse/writer.py
diff options
context:
space:
mode:
Diffstat (limited to 'venv/Lib/site-packages/pylint/pyreverse/writer.py')
-rw-r--r--venv/Lib/site-packages/pylint/pyreverse/writer.py213
1 files changed, 213 insertions, 0 deletions
diff --git a/venv/Lib/site-packages/pylint/pyreverse/writer.py b/venv/Lib/site-packages/pylint/pyreverse/writer.py
new file mode 100644
index 0000000..609b1ef
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/pyreverse/writer.py
@@ -0,0 +1,213 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2008-2010, 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
+# Copyright (c) 2014 Arun Persaud <arun@nubati.net>
+# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com>
+# Copyright (c) 2015 Mike Frysinger <vapier@gentoo.org>
+# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org>
+# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro>
+# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com>
+# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu>
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+"""Utilities for creating VCG and Dot diagrams"""
+
+from pylint.graph import DotBackend
+from pylint.pyreverse.utils import is_exception
+from pylint.pyreverse.vcgutils import VCGPrinter
+
+
+class DiagramWriter:
+ """base class for writing project diagrams
+ """
+
+ def __init__(self, config, styles):
+ self.config = config
+ self.pkg_edges, self.inh_edges, self.imp_edges, self.association_edges = styles
+ self.printer = None # defined in set_printer
+
+ def write(self, diadefs):
+ """write files for <project> according to <diadefs>
+ """
+ for diagram in diadefs:
+ basename = diagram.title.strip().replace(" ", "_")
+ file_name = "%s.%s" % (basename, self.config.output_format)
+ self.set_printer(file_name, basename)
+ if diagram.TYPE == "class":
+ self.write_classes(diagram)
+ else:
+ self.write_packages(diagram)
+ self.close_graph()
+
+ def write_packages(self, diagram):
+ """write a package diagram"""
+ # sorted to get predictable (hence testable) results
+ for i, obj in enumerate(sorted(diagram.modules(), key=lambda x: x.title)):
+ self.printer.emit_node(i, label=self.get_title(obj), shape="box")
+ obj.fig_id = i
+ # package dependencies
+ for rel in diagram.get_relationships("depends"):
+ self.printer.emit_edge(
+ rel.from_object.fig_id, rel.to_object.fig_id, **self.pkg_edges
+ )
+
+ def write_classes(self, diagram):
+ """write a class diagram"""
+ # sorted to get predictable (hence testable) results
+ for i, obj in enumerate(sorted(diagram.objects, key=lambda x: x.title)):
+ self.printer.emit_node(i, **self.get_values(obj))
+ obj.fig_id = i
+ # inheritance links
+ for rel in diagram.get_relationships("specialization"):
+ self.printer.emit_edge(
+ rel.from_object.fig_id, rel.to_object.fig_id, **self.inh_edges
+ )
+ # implementation links
+ for rel in diagram.get_relationships("implements"):
+ self.printer.emit_edge(
+ rel.from_object.fig_id, rel.to_object.fig_id, **self.imp_edges
+ )
+ # generate associations
+ for rel in diagram.get_relationships("association"):
+ self.printer.emit_edge(
+ rel.from_object.fig_id,
+ rel.to_object.fig_id,
+ label=rel.name,
+ **self.association_edges
+ )
+
+ def set_printer(self, file_name, basename):
+ """set printer"""
+ raise NotImplementedError
+
+ def get_title(self, obj):
+ """get project title"""
+ raise NotImplementedError
+
+ def get_values(self, obj):
+ """get label and shape for classes."""
+ raise NotImplementedError
+
+ def close_graph(self):
+ """finalize the graph"""
+ raise NotImplementedError
+
+
+class DotWriter(DiagramWriter):
+ """write dot graphs from a diagram definition and a project
+ """
+
+ def __init__(self, config):
+ styles = [
+ dict(arrowtail="none", arrowhead="open"),
+ dict(arrowtail="none", arrowhead="empty"),
+ dict(arrowtail="node", arrowhead="empty", style="dashed"),
+ dict(
+ fontcolor="green", arrowtail="none", arrowhead="diamond", style="solid"
+ ),
+ ]
+ DiagramWriter.__init__(self, config, styles)
+
+ def set_printer(self, file_name, basename):
+ """initialize DotWriter and add options for layout.
+ """
+ layout = dict(rankdir="BT")
+ self.printer = DotBackend(basename, additional_param=layout)
+ self.file_name = file_name
+
+ def get_title(self, obj):
+ """get project title"""
+ return obj.title
+
+ def get_values(self, obj):
+ """get label and shape for classes.
+
+ The label contains all attributes and methods
+ """
+ label = obj.title
+ if obj.shape == "interface":
+ label = "«interface»\\n%s" % label
+ if not self.config.only_classnames:
+ label = r"%s|%s\l|" % (label, r"\l".join(obj.attrs))
+ for func in obj.methods:
+ args = [arg.name for arg in func.args.args if arg.name != "self"]
+ label = r"%s%s(%s)\l" % (label, func.name, ", ".join(args))
+ label = "{%s}" % label
+ if is_exception(obj.node):
+ return dict(fontcolor="red", label=label, shape="record")
+ return dict(label=label, shape="record")
+
+ def close_graph(self):
+ """print the dot graph into <file_name>"""
+ self.printer.generate(self.file_name)
+
+
+class VCGWriter(DiagramWriter):
+ """write vcg graphs from a diagram definition and a project
+ """
+
+ def __init__(self, config):
+ styles = [
+ dict(arrowstyle="solid", backarrowstyle="none", backarrowsize=0),
+ dict(arrowstyle="solid", backarrowstyle="none", backarrowsize=10),
+ dict(
+ arrowstyle="solid",
+ backarrowstyle="none",
+ linestyle="dotted",
+ backarrowsize=10,
+ ),
+ dict(arrowstyle="solid", backarrowstyle="none", textcolor="green"),
+ ]
+ DiagramWriter.__init__(self, config, styles)
+
+ def set_printer(self, file_name, basename):
+ """initialize VCGWriter for a UML graph"""
+ self.graph_file = open(file_name, "w+")
+ self.printer = VCGPrinter(self.graph_file)
+ self.printer.open_graph(
+ title=basename,
+ layoutalgorithm="dfs",
+ late_edge_labels="yes",
+ port_sharing="no",
+ manhattan_edges="yes",
+ )
+ self.printer.emit_node = self.printer.node
+ self.printer.emit_edge = self.printer.edge
+
+ def get_title(self, obj):
+ """get project title in vcg format"""
+ return r"\fb%s\fn" % obj.title
+
+ def get_values(self, obj):
+ """get label and shape for classes.
+
+ The label contains all attributes and methods
+ """
+ if is_exception(obj.node):
+ label = r"\fb\f09%s\fn" % obj.title
+ else:
+ label = r"\fb%s\fn" % obj.title
+ if obj.shape == "interface":
+ shape = "ellipse"
+ else:
+ shape = "box"
+ if not self.config.only_classnames:
+ attrs = obj.attrs
+ methods = [func.name for func in obj.methods]
+ # box width for UML like diagram
+ maxlen = max(len(name) for name in [obj.title] + methods + attrs)
+ line = "_" * (maxlen + 2)
+ label = r"%s\n\f%s" % (label, line)
+ for attr in attrs:
+ label = r"%s\n\f08%s" % (label, attr)
+ if attrs:
+ label = r"%s\n\f%s" % (label, line)
+ for func in methods:
+ label = r"%s\n\f10%s()" % (label, func)
+ return dict(label=label, shape=shape)
+
+ def close_graph(self):
+ """close graph and file"""
+ self.printer.close_graph()
+ self.graph_file.close()