aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2023-06-16 10:24:49 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-06-16 21:12:12 +0000
commit54a8785cab070bca044ca0ceeff3219e20514a37 (patch)
tree91bd72e1b2da84df4b1dd25df7ef28b4600f7868
parent69a353f625ac8d4ae0a3d53ca804ebd7bbf47647 (diff)
Split out a test driver from the Sphinx inheritance graph generation
Similar to 5b0918c6c6fa575a16b3ec1637281397e951f62b, 3a1e793c0a91deae4e986efb11724040349ce9ca. Add a note to the README.md and fix it to be viewable. Task-number: PYSIDE-2362 Task-number: PYSIDE-1106 Change-Id: I1c0bbc745fffc16d6981e806618c1fce04ac8d18 Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> (cherry picked from commit 7008aa6bd17d1f56b54c30e60110668aed79a3cb) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--sources/pyside6/doc/README.md15
-rw-r--r--sources/pyside6/doc/inheritance_diagram.py102
-rw-r--r--sources/pyside6/doc/inheritance_diagram.pyproject6
-rw-r--r--sources/pyside6/doc/inheritance_graph.py126
4 files changed, 148 insertions, 101 deletions
diff --git a/sources/pyside6/doc/README.md b/sources/pyside6/doc/README.md
index 88bf3a64d..746e44989 100644
--- a/sources/pyside6/doc/README.md
+++ b/sources/pyside6/doc/README.md
@@ -4,7 +4,7 @@ The source tree contains .rst files containing the module description in
doc/extras (named for example "QtCore.rst"). They are extracted/adapted from
the C++ module descriptions. If there is no module description file, shiboken
will extract the module description from the webxml files generated by qdoc.
-This ends up in the build directory under doc/rst/PySide6/<module>/index.rst.
+This ends up in the build directory under doc/rst/PySide6/&lt;module&gt;/index.rst.
It can be used as a starting point for a module description file. C++
specific information like build instructions should be removed.
@@ -20,6 +20,7 @@ adaption by shiboken/sphinx.
The list can be created by the below script and some hand-editing. It will find
almost all documents. Quite a number of them might be unreferenced, but there
is no good way of filtering for this.
+Pages of examples that exist in Python should be removed.
for F in *.webxml
do
@@ -32,3 +33,15 @@ is no good way of filtering for this.
fi
fi
done
+
+# Inheritance graphs
+
+`inheritance_diagram.pyproject` lists the script involved in inheritance graph
+generation, `inheritance_diagram.py` being the main one used by sphinx. The
+others have main-test drivers for checking.
+
+There are 2 scripts used for determining the inheritance:
+* json_inheritance.py (env var `INHERITANCE_FILE`) reads a
+ inheritance.json file containing the class hierarchy generated by
+ shiboken's doc generator.
+* import_inheritance.py actually tries to import the class (legacy)
diff --git a/sources/pyside6/doc/inheritance_diagram.py b/sources/pyside6/doc/inheritance_diagram.py
index 22d7d87ad..d1e095ce6 100644
--- a/sources/pyside6/doc/inheritance_diagram.py
+++ b/sources/pyside6/doc/inheritance_diagram.py
@@ -48,111 +48,13 @@ from docutils.parsers.rst import directives, Directive
from sphinx.ext.graphviz import render_dot_html, render_dot_latex
+from inheritance_graph import InheritanceGraph
from import_inheritance import (get_inheritance_entries_by_import,
InheritanceException)
from json_inheritance import (is_inheritance_from_json_enabled,
get_inheritance_entries_from_json)
-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
- if is_inheritance_from_json_enabled():
- self.class_info = get_inheritance_entries_from_json(class_names)
- else:
- self.class_info = get_inheritance_entries_by_import(class_names,
- currmodule,
- __builtins__,
- show_builtins,
- 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([f'{x[0]}={x[1]}' for x in attrs.items()])
-
- def _format_graph_attrs(self, attrs):
- return ''.join([f"{x[0]}={x[1]};\n" 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(f'digraph {name} {{\n')
- 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'] = f'"{url}"'
- this_node_attrs['target'] = '"_top"' # Browser target frame attribute (same page)
- attribute = self._format_node_attrs(this_node_attrs)
- res.append(f' "{name}" [{attribute}];\n')
-
- # Write the edges
- for base_name in bases:
- attribute = self._format_node_attrs(e_attrs)
- res.append(f' "{base_name}" -> "{name}" [{attribute}];\n')
- 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.
@@ -186,7 +88,7 @@ class InheritanceDiagram(Directive):
try:
graph = InheritanceGraph(
class_names, env.temp_data.get('py:module'),
- parts=node['parts'])
+ __builtins__, parts=node['parts'])
except InheritanceException as err:
return [node.document.reporter.warning(err.args[0],
line=self.lineno)]
diff --git a/sources/pyside6/doc/inheritance_diagram.pyproject b/sources/pyside6/doc/inheritance_diagram.pyproject
new file mode 100644
index 000000000..a44dc93b8
--- /dev/null
+++ b/sources/pyside6/doc/inheritance_diagram.pyproject
@@ -0,0 +1,6 @@
+{
+ "files": ["inheritance_diagram.py",
+ "import_inheritance.py",
+ "inheritance_graph.py",
+ "json_inheritance.py"]
+}
diff --git a/sources/pyside6/doc/inheritance_graph.py b/sources/pyside6/doc/inheritance_graph.py
new file mode 100644
index 000000000..2911b4582
--- /dev/null
+++ b/sources/pyside6/doc/inheritance_graph.py
@@ -0,0 +1,126 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import sys
+
+from import_inheritance import (get_inheritance_entries_by_import,
+ InheritanceException)
+from json_inheritance import (is_inheritance_from_json_enabled,
+ get_inheritance_entries_from_json)
+
+
+TEST_DRIVER_USAGE = """Usage: inheritance_graph.py [module] [class]
+
+Example:
+python inheritance_graph.py PySide6.QtWidgets PySide6.QtWidgets.QWizard
+"""
+
+
+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, builtins=None, 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
+ if is_inheritance_from_json_enabled():
+ self.class_info = get_inheritance_entries_from_json(class_names)
+ else:
+ self.class_info = get_inheritance_entries_by_import(class_names,
+ currmodule,
+ builtins,
+ show_builtins,
+ 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([f'{x[0]}={x[1]}' for x in attrs.items()])
+
+ def _format_graph_attrs(self, attrs):
+ return ''.join([f"{x[0]}={x[1]};\n" 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(f'digraph {name} {{\n')
+ 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'] = f'"{url}"'
+ this_node_attrs['target'] = '"_top"' # Browser target frame attribute (same page)
+ attribute = self._format_node_attrs(this_node_attrs)
+ res.append(f' "{name}" [{attribute}];\n')
+
+ # Write the edges
+ for base_name in bases:
+ attribute = self._format_node_attrs(e_attrs)
+ res.append(f' "{base_name}" -> "{name}" [{attribute}];\n')
+ res.append('}\n')
+ return ''.join(res)
+
+
+if __name__ == "__main__":
+ if len(sys.argv) < 2:
+ print(TEST_DRIVER_USAGE)
+ sys.exit(-1)
+ module = sys.argv[1]
+ class_names = sys.argv[2:]
+ graph = InheritanceGraph(class_names, module)
+ dot = graph.generate_dot("test")
+ print(dot)