Restructuring: Store connections on the networkx graph only
Closed this issue · 1 comments
Currently we store connections in the networkx graph and inside the NodeConnector.
This could cause issues if only one of them is changed. It is rather unlikely because they are frozen but still possible.
My suggestion: use the networkx MultiDiGraph to store the connections there, and only there. Do not use a NodeConnector but a NodeConnection which reads from the graph to display how it is connected.
In this case the Node itself doesn't have to know anything about the graph it belongs to and the graph fulfills it's purpose of managing the connections instead of Connector.result()
First tests show that one could use:
class NodeBaseMixin:
def __getattribute__(self, item):
value = super().__getattribute__(item)
if NodeBaseMixin._graph_ is not None:
if item not in ["_graph_"] and not item.startswith("__"):
connector = Connection(instance=self, attribute=item)
return connector
return value
def __setattr__(self, item, value) -> None:
if isinstance(value, Connection):
assert id(self) in self._graph_
assert id(value.instance) in self._graph_
self._graph_.add_edge(
id(value.instance), id(self), i_attr=value.attribute, j_attr=item
)
super().__setattr__(item, value)
with
@dataclasses.dataclass(frozen=True)
class Connection:
"""A Connector for Nodes.
instance: either a Node or FucntionFuture
attribute:
Node.attribute
or FunctionFuture.result
or None if the class is passed and not an attribute
"""
instance: any
attribute: any
it is REALLY important to mention, that within the DiGraph
something like the following does not work within the context manager. This affects also all calls inside the __init__
or generally everything that is not specifically excluded inside __getattribute__
.
@dataclasses.dataclass()
class Node(NodeBaseMixin):
input: int
output: int = None
def __post_init__(self):
self.output = self.input * 2 # this can not work, because self.input is Connection and not int