graphs

class InheritanceGraph(package_paths: Sequence[str | type | module], lineage_paths: Sequence[str | type | module] | None = None)

Bases: object

A builder of Graphviz inheritance graphs.

Here we build the inheritance graph of all classes found in uqbar.containers:

>>> import uqbar.apis
>>> graph = uqbar.apis.InheritanceGraph(
...     package_paths=["uqbar.containers"],
... )
>>> print(graph)
digraph InheritanceGraph {
    graph [bgcolor=transparent,
        color=lightsteelblue2,
        fontname=Arial,
        fontsize=10,
        outputorder=edgesfirst,
        overlap=prism,
        penwidth=2,
        rankdir=LR,
        splines=spline,
        style="dashed, rounded",
        truecolor=true];
    node [colorscheme=pastel19,
        fontname=Arial,
        fontsize=10,
        height=0,
        penwidth=2,
        shape=box,
        style="filled, rounded",
        width=0];
    edge [color=lightslategrey,
        penwidth=1];
    subgraph cluster_builtins {
        graph [label=builtins];
        node [color=1];
        "builtins.object" [label=object];
    }
    subgraph "cluster_uqbar.containers.dependency_graph" {
        graph [label="uqbar.containers.dependency_graph"];
        node [color=2];
        "uqbar.containers.dependency_graph.DependencyGraph" [label="Dependency\nGraph"];
    }
    subgraph "cluster_uqbar.containers.unique_tree" {
        graph [label="uqbar.containers.unique_tree"];
        node [color=3];
        "uqbar.containers.unique_tree.UniqueTreeContainer" [label="Unique\nTree\nContainer"];
        "uqbar.containers.unique_tree.UniqueTreeDict" [label="Unique\nTree\nDict"];
        "uqbar.containers.unique_tree.UniqueTreeList" [label="Unique\nTree\nList"];
        "uqbar.containers.unique_tree.UniqueTreeNode" [label="Unique\nTree\nNode"];
        "uqbar.containers.unique_tree.UniqueTreeSet" [label="Unique\nTree\nSet"];
        "uqbar.containers.unique_tree.UniqueTreeTuple" [label="Unique\nTree\nTuple"];
        "uqbar.containers.unique_tree.UniqueTreeContainer" -> "uqbar.containers.unique_tree.UniqueTreeDict";
        "uqbar.containers.unique_tree.UniqueTreeContainer" -> "uqbar.containers.unique_tree.UniqueTreeList";
        "uqbar.containers.unique_tree.UniqueTreeContainer" -> "uqbar.containers.unique_tree.UniqueTreeSet";
        "uqbar.containers.unique_tree.UniqueTreeContainer" -> "uqbar.containers.unique_tree.UniqueTreeTuple";
        "uqbar.containers.unique_tree.UniqueTreeNode" -> "uqbar.containers.unique_tree.UniqueTreeContainer";
    }
    "builtins.object" -> "uqbar.containers.dependency_graph.DependencyGraph";
    "builtins.object" -> "uqbar.containers.unique_tree.UniqueTreeNode";
}

We can calculate the “aspect ratio” of the graph - the number of generations vs the maximum generation size. This can be a useful metric for applying additional post-processing like Graphviz’ unflatten utility:

>>> graph.aspect_ratio
(3, 4)

Lineage paths constrain the classes in the graph to only those whose antecedents or descendants pass through the classes identified by those lineage paths. Here we collect all classes defined in uqbar and then constrain to those passing through uqbar.containers:

>>> graph = uqbar.apis.InheritanceGraph(
...     package_paths=["uqbar"],
...     lineage_paths=["uqbar.containers"],
... )
>>> print(graph)
digraph InheritanceGraph {
    graph [bgcolor=transparent,
        color=lightsteelblue2,
        fontname=Arial,
        fontsize=10,
        outputorder=edgesfirst,
        overlap=prism,
        penwidth=2,
        rankdir=LR,
        splines=spline,
        style="dashed, rounded",
        truecolor=true];
    node [colorscheme=pastel19,
        fontname=Arial,
        fontsize=10,
        height=0,
        penwidth=2,
        shape=box,
        style="filled, rounded",
        width=0];
    edge [color=lightslategrey,
        penwidth=1];
    subgraph cluster_builtins {
        graph [label=builtins];
        node [color=1];
        "builtins.object" [label=object];
    }
    subgraph "cluster_uqbar.apis.nodes" {
        graph [label="uqbar.apis.nodes"];
        node [color=2];
        "uqbar.apis.nodes.ModuleNode" [label="Module\nNode"];
        "uqbar.apis.nodes.PackageNode" [label="Package\nNode"];
    }
    subgraph "cluster_uqbar.containers.dependency_graph" {
        graph [label="uqbar.containers.dependency_graph"];
        node [color=3];
        "uqbar.containers.dependency_graph.DependencyGraph" [label="Dependency\nGraph"];
    }
    subgraph "cluster_uqbar.containers.unique_tree" {
        graph [label="uqbar.containers.unique_tree"];
        node [color=4];
        "uqbar.containers.unique_tree.UniqueTreeContainer" [label="Unique\nTree\nContainer"];
        "uqbar.containers.unique_tree.UniqueTreeDict" [label="Unique\nTree\nDict"];
        "uqbar.containers.unique_tree.UniqueTreeList" [label="Unique\nTree\nList"];
        "uqbar.containers.unique_tree.UniqueTreeNode" [label="Unique\nTree\nNode"];
        "uqbar.containers.unique_tree.UniqueTreeSet" [label="Unique\nTree\nSet"];
        "uqbar.containers.unique_tree.UniqueTreeTuple" [label="Unique\nTree\nTuple"];
        "uqbar.containers.unique_tree.UniqueTreeContainer" -> "uqbar.containers.unique_tree.UniqueTreeDict";
        "uqbar.containers.unique_tree.UniqueTreeContainer" -> "uqbar.containers.unique_tree.UniqueTreeList";
        "uqbar.containers.unique_tree.UniqueTreeContainer" -> "uqbar.containers.unique_tree.UniqueTreeSet";
        "uqbar.containers.unique_tree.UniqueTreeContainer" -> "uqbar.containers.unique_tree.UniqueTreeTuple";
        "uqbar.containers.unique_tree.UniqueTreeNode" -> "uqbar.containers.unique_tree.UniqueTreeContainer";
    }
    subgraph "cluster_uqbar.graphs.core" {
        graph [label="uqbar.graphs.core"];
        node [color=5];
        "uqbar.graphs.core.Attachable" [label=Attachable];
        "uqbar.graphs.core.Graph" [label="Graph"];
        "uqbar.graphs.core.Node" [label="Node"];
    }
    subgraph "cluster_uqbar.graphs.html" {
        graph [label="uqbar.graphs.html"];
        node [color=6];
        "uqbar.graphs.html.HRule" [label=HRule];
        "uqbar.graphs.html.LineBreak" [label="Line\nBreak"];
        "uqbar.graphs.html.Table" [label=Table];
        "uqbar.graphs.html.TableCell" [label="Table\nCell"];
        "uqbar.graphs.html.TableRow" [label="Table\nRow"];
        "uqbar.graphs.html.Text" [label=Text];
        "uqbar.graphs.html.VRule" [label=VRule];
    }
    subgraph "cluster_uqbar.graphs.records" {
        graph [label="uqbar.graphs.records"];
        node [color=7];
        "uqbar.graphs.records.RecordField" [label="Record\nField"];
        "uqbar.graphs.records.RecordGroup" [label="Record\nGroup"];
    }
    "builtins.object" -> "uqbar.containers.dependency_graph.DependencyGraph";
    "builtins.object" -> "uqbar.containers.unique_tree.UniqueTreeNode";
    "uqbar.containers.unique_tree.UniqueTreeList" -> "uqbar.apis.nodes.PackageNode";
    "uqbar.containers.unique_tree.UniqueTreeList" -> "uqbar.graphs.core.Graph";
    "uqbar.containers.unique_tree.UniqueTreeList" -> "uqbar.graphs.core.Node";
    "uqbar.containers.unique_tree.UniqueTreeList" -> "uqbar.graphs.html.Table";
    "uqbar.containers.unique_tree.UniqueTreeList" -> "uqbar.graphs.html.TableCell";
    "uqbar.containers.unique_tree.UniqueTreeList" -> "uqbar.graphs.html.TableRow";
    "uqbar.containers.unique_tree.UniqueTreeList" -> "uqbar.graphs.records.RecordGroup";
    "uqbar.containers.unique_tree.UniqueTreeNode" -> "uqbar.apis.nodes.ModuleNode";
    "uqbar.containers.unique_tree.UniqueTreeNode" -> "uqbar.graphs.core.Attachable";
    "uqbar.containers.unique_tree.UniqueTreeNode" -> "uqbar.graphs.html.HRule";
    "uqbar.containers.unique_tree.UniqueTreeNode" -> "uqbar.graphs.html.LineBreak";
    "uqbar.containers.unique_tree.UniqueTreeNode" -> "uqbar.graphs.html.Text";
    "uqbar.containers.unique_tree.UniqueTreeNode" -> "uqbar.graphs.html.VRule";
    "uqbar.containers.unique_tree.UniqueTreeNode" -> "uqbar.graphs.records.RecordField";
    "uqbar.graphs.core.Attachable" -> "uqbar.graphs.html.TableCell";
    "uqbar.graphs.core.Attachable" -> "uqbar.graphs.records.RecordField";
}
>>> graph.aspect_ratio
(4, 7)
Parameters:
package_paths: Sequence[str | type | module]

a sequence of package path strings, classes or modules to seed the inheritance graph with

lineage_paths: Sequence[str | type | module] | None = None

a sequence of package path strings, classes or modules to constrain the inheritance graph with

__len__() int
build_graph(urls=None) Graph
property all_class_paths
property aspect_ratio
property children_to_parents
property parents_to_children