Skip to content

Your Annotation is a Graph

Graph theory is a fundamental aspect of computer programming - nearly every problem can be modeled as a graph and in most cases, doing so can drastically reduce the complexity of the solution. We use graph theory to map your type annotations into a reliable resolution order for building out your marshalling and unmarshalling logic.

Handling Data Models

Below we map out some examples of the type graph for some common annotations:

---
title: "A Simple Mapping"
---
erDiagram
    "dict[str, int]" ||--|{ str : contains
    "dict[str, int]" ||--|{ int : contains

Given the above graph, the static order for resolving the type dict[str, int] would be: (0: str, 1: int, 2: dict[str, int]).

---
title: "A Data Class Definition"
---
erDiagram
    Customer ||--|| str : contains
    Customer ||--|| uuid : contains
    Customer ||--|| datetime : contains
    Customer {
        str name
        uuid id
        datetime created_at
    }

Given the above graph, the static order for resolving type Customer would be: (0: str, 1: uuid, 2: datetime, 3: Customer).

Implementers can iterate over the static order, building a localized context for the type definition as we traverse from outer edges to the root node.

Note

As an implementation detail, edge types will be resolved in the order they are declared within the containing type. However, we only guarantee that all edges will be provided before the containing type, the field-order of these edges is not guaranteed.

Handling Cyclic Data Models

Graphs may have cycles - if not addressed, this can result in infinite recursion. When we encounter a cyclic or direct recursive type, we wrap the cycle in a typing.ForwardRef and terminate that branch. This provides another guarantee to implementations which leverage our graph resolver - all forward references are cyclic types and should be delayed.

---
title: "A Recursive Type Definition"
---
erDiagram
    Node ||--o| Node : contains
    Node {
        parent Node
    }
---
title: "A Cyclic Type Definition"
---
erDiagram
    ClassA ||--|| ClassB : contains
    ClassB ||--o| ClassA : contains
    ClassA {
        ClassB attr
    }
    ClassB {
        ClassA attr
    }

Further Reading