diff options
Diffstat (limited to 'sources/pyside2/doc/inheritance_diagram.py')
-rw-r--r-- | sources/pyside2/doc/inheritance_diagram.py | 372 |
1 files changed, 0 insertions, 372 deletions
diff --git a/sources/pyside2/doc/inheritance_diagram.py b/sources/pyside2/doc/inheritance_diagram.py deleted file mode 100644 index 054cb7be9..000000000 --- a/sources/pyside2/doc/inheritance_diagram.py +++ /dev/null @@ -1,372 +0,0 @@ -# -*- coding: utf-8 -*- -r""" - sphinx.ext.inheritance_diagram - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Defines a docutils directive for inserting inheritance diagrams. - - Provide the directive with one or more classes or modules (separated - by whitespace). For modules, all of the classes in that module will - be used. - - Example:: - - Given the following classes: - - class A: pass - class B(A): pass - class C(A): pass - class D(B, C): pass - class E(B): pass - - .. inheritance-diagram: D E - - Produces a graph like the following: - - A - / \ - B C - / \ / - E D - - The graph is inserted as a PNG+image map into HTML and a PDF in - LaTeX. - - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - :copyright: Copyright 2010-2011 by the PySide team. - :license: BSD, see LICENSE for details. -""" - -import os -import re -import sys -import inspect -try: - from hashlib import md5 -except ImportError: - from md5 import md5 - -from docutils import nodes -from docutils.parsers.rst import directives, Directive - -from sphinx.ext.graphviz import render_dot_html, render_dot_latex - -class InheritanceException(Exception): - pass - -# When passed something like: -# PySide2.QtCore.QStateMachine.SignalEvent -# try to import the underlying module and return a -# handle to the object. In a loop, import -# PySide2.QtCore.QStateMachine.SignalEvent -# PySide2.QtCore.QStateMachine -# PySide2.QtCore -# until the import succeeds and walk up the attributes -# to obtain the object - -def importClassOrModule(name): - components = name.split('.') - for i in range(len(components), 0, -1): - importPath = '.'.join(components[: i]) - try: - __import__(importPath) - except ImportError: - continue - if i == len(components): - return sys.modules[importPath] - remaining = components[i :] - cls = sys.modules[importPath] - for component in remaining: - try: - cls = getattr(cls, component) - except Exception: # No such attribute - return None - return cls - return None - -class InheritanceGraph(object): - """ - Given a list of classes, determines the set of classes that they inherit - from all the way to the root "object", and then is able to generate a - graphviz dot graph from them. - """ - def __init__(self, class_names, currmodule, show_builtins=False, parts=0): - """ - *class_names* is a list of child classes to show bases from. - - If *show_builtins* is True, then Python builtins will be shown - in the graph. - """ - self.class_names = class_names - classes = self._import_classes(class_names, currmodule) - self.class_info = self._class_info(classes, show_builtins, parts) - if not self.class_info: - raise InheritanceException('No classes found for ' - 'inheritance diagram') - - def _import_class_or_module(self, name, currmodule): - """ - Import a class using its fully-qualified *name*. - """ - todoc = importClassOrModule(name) - if not todoc and currmodule is not None: - todoc = importClassOrModule(currmodule + '.' + name) - if not todoc: - moduleStr = '(module {})'.format(currmodule) if currmodule else '' - raise InheritanceException('Could not import class {} specified for ' - 'inheritance diagram {}.'.format(name, moduleStr)) - if inspect.isclass(todoc): - return [todoc] - elif inspect.ismodule(todoc): - classes = [] - for cls in todoc.__dict__.values(): - if inspect.isclass(cls) and cls.__module__ == todoc.__name__: - classes.append(cls) - return classes - raise InheritanceException('%r specified for inheritance diagram is ' - 'not a class or module' % name) - - def _import_classes(self, class_names, currmodule): - """Import a list of classes.""" - classes = [] - for name in class_names: - classes.extend(self._import_class_or_module(name, currmodule)) - return classes - - def _class_info(self, classes, show_builtins, parts): - """Return name and bases for all classes that are ancestors of - *classes*. - - *parts* gives the number of dotted name parts that is removed from the - displayed node names. - """ - all_classes = {} - builtins = __builtins__.values() - - def recurse(cls): - if not show_builtins and cls in builtins: - return - - nodename = self.class_name(cls, parts) - fullname = self.class_name(cls, 0) - - baselist = [] - all_classes[cls] = (nodename, fullname, baselist) - for base in cls.__bases__: - if not show_builtins and base in builtins: - continue - if base.__name__ == "Object" and base.__module__ == "Shiboken": - continue - baselist.append(self.class_name(base, parts)) - if base not in all_classes: - recurse(base) - - for cls in classes: - recurse(cls) - - return list(all_classes.values()) - - def class_name(self, cls, parts=0): - """Given a class object, return a fully-qualified name. - - This works for things I've tested in matplotlib so far, but may not be - completely general. - """ - module = cls.__module__ - if module == '__builtin__': - fullname = cls.__name__ - else: - fullname = '%s.%s' % (module, cls.__name__) - if parts == 0: - return fullname - name_parts = fullname.split('.') - return '.'.join(name_parts[-parts:]) - - def get_all_class_names(self): - """ - Get all of the class names involved in the graph. - """ - return [fullname for (_, fullname, _) in self.class_info] - - # These are the default attrs for graphviz - default_graph_attrs = { - 'rankdir': 'LR', - 'size': '"8.0, 12.0"', - } - default_node_attrs = { - 'shape': 'box', - 'fontsize': 10, - 'height': 0.25, - 'fontname': '"Vera Sans, DejaVu Sans, Liberation Sans, ' - 'Arial, Helvetica, sans"', - 'style': '"setlinewidth(0.5)"', - } - default_edge_attrs = { - 'arrowsize': 0.5, - 'style': '"setlinewidth(0.5)"', - } - - def _format_node_attrs(self, attrs): - return ','.join(['%s=%s' % x for x in attrs.items()]) - - def _format_graph_attrs(self, attrs): - return ''.join(['%s=%s;\n' % x for x in attrs.items()]) - - def generate_dot(self, name, urls={}, env=None, - graph_attrs={}, node_attrs={}, edge_attrs={}): - """ - Generate a graphviz dot graph from the classes that - were passed in to __init__. - - *name* is the name of the graph. - - *urls* is a dictionary mapping class names to HTTP URLs. - - *graph_attrs*, *node_attrs*, *edge_attrs* are dictionaries containing - key/value pairs to pass on as graphviz properties. - """ - g_attrs = self.default_graph_attrs.copy() - n_attrs = self.default_node_attrs.copy() - e_attrs = self.default_edge_attrs.copy() - g_attrs.update(graph_attrs) - n_attrs.update(node_attrs) - e_attrs.update(edge_attrs) - if env: - g_attrs.update(env.config.inheritance_graph_attrs) - n_attrs.update(env.config.inheritance_node_attrs) - e_attrs.update(env.config.inheritance_edge_attrs) - - res = [] - res.append('digraph %s {\n' % name) - res.append(self._format_graph_attrs(g_attrs)) - - for name, fullname, bases in self.class_info: - # Write the node - this_node_attrs = n_attrs.copy() - url = urls.get(fullname) - if url is not None: - this_node_attrs['URL'] = '"%s"' % url - res.append(' "%s" [%s];\n' % - (name, self._format_node_attrs(this_node_attrs))) - - # Write the edges - for base_name in bases: - res.append(' "%s" -> "%s" [%s];\n' % - (base_name, name, - self._format_node_attrs(e_attrs))) - res.append('}\n') - return ''.join(res) - - -class inheritance_diagram(nodes.General, nodes.Element): - """ - A docutils node to use as a placeholder for the inheritance diagram. - """ - pass - - -class InheritanceDiagram(Directive): - """ - Run when the inheritance_diagram directive is first encountered. - """ - has_content = False - required_arguments = 1 - optional_arguments = 0 - final_argument_whitespace = True - option_spec = { - 'parts': directives.nonnegative_int, - } - - def run(self): - node = inheritance_diagram() - node.document = self.state.document - env = self.state.document.settings.env - class_names = self.arguments[0].split() - class_role = env.get_domain('py').role('class') - # Store the original content for use as a hash - node['parts'] = self.options.get('parts', 0) - node['content'] = ', '.join(class_names) - - # Create a graph starting with the list of classes - try: - graph = InheritanceGraph( - class_names, env.temp_data.get('py:module'), - parts=node['parts']) - except InheritanceException as err: - return [node.document.reporter.warning(err.args[0], - line=self.lineno)] - - # Create xref nodes for each target of the graph's image map and - # add them to the doc tree so that Sphinx can resolve the - # references to real URLs later. These nodes will eventually be - # removed from the doctree after we're done with them. - for name in graph.get_all_class_names(): - refnodes, x = class_role( - 'class', ':class:`%s`' % name, name, 0, self.state) - node.extend(refnodes) - # Store the graph object so we can use it to generate the - # dot file later - node['graph'] = graph - return [node] - - -def get_graph_hash(node): - hashString = node['content'] + str(node['parts']) - return md5(hashString.encode('utf-8')).hexdigest()[-10:] - - -def html_visit_inheritance_diagram(self, node): - """ - Output the graph for HTML. This will insert a PNG with clickable - image map. - """ - graph = node['graph'] - - graph_hash = get_graph_hash(node) - name = 'inheritance%s' % graph_hash - - # Create a mapping from fully-qualified class names to URLs. - urls = {} - for child in node: - if child.get('refuri') is not None: - urls[child['reftitle']] = child.get('refuri') - elif child.get('refid') is not None: - urls[child['reftitle']] = '#' + child.get('refid') - - dotcode = graph.generate_dot(name, urls, env=self.builder.env) - render_dot_html(self, node, dotcode, {}, 'inheritance', 'inheritance', - alt='Inheritance diagram of ' + node['content']) - raise nodes.SkipNode - - -def latex_visit_inheritance_diagram(self, node): - """ - Output the graph for LaTeX. This will insert a PDF. - """ - graph = node['graph'] - - graph_hash = get_graph_hash(node) - name = 'inheritance%s' % graph_hash - - dotcode = graph.generate_dot(name, env=self.builder.env, - graph_attrs={'size': '"6.0,6.0"'}) - render_dot_latex(self, node, dotcode, {}, 'inheritance') - raise nodes.SkipNode - - -def skip(self, node): - raise nodes.SkipNode - - -def setup(app): - app.setup_extension('sphinx.ext.graphviz') - app.add_node( - inheritance_diagram, - latex=(latex_visit_inheritance_diagram, None), - html=(html_visit_inheritance_diagram, None), - text=(skip, None), - man=(skip, None)) - app.add_directive('inheritance-diagram', InheritanceDiagram) - app.add_config_value('inheritance_graph_attrs', {}, False), - app.add_config_value('inheritance_node_attrs', {}, False), - app.add_config_value('inheritance_edge_attrs', {}, False), |