There is a bit of convoluted signal blocking code between the GraphView and BaseGraph that is complicating my next PR:
# Maintain first. When the root is a rustworkx graph the view shares the
# root's attribute dicts, so the values are already current and writing
# again would be redundant. Otherwise (e.g. a SQLGraph root) the view
# holds its own copy and has to be written through.
if not self._is_root_rx_graph:
if self.sync:
local_attrs = {
key: [new_attrs_by_id[node_id][key] for node_id in in_view]
for key in changed_keys
if all(key in new_attrs_by_id[node_id] for node_id in in_view)
}
if local_attrs:
with self.node_updated.blocked():
RustWorkXGraph.update_node_attrs(
self,
node_ids=self._map_to_local(in_view),
attrs=local_attrs,
)
else:
self._out_of_sync = True
# Notify second, now that root and view agree.
if is_signal_on(self.node_updated):
emit_node_updated_events(
self.node_updated,
((node_id, old_attrs_by_id[node_id], new_attrs_by_id[node_id]) for node_id in in_view),
changed_keys,
)
The key assertion seems to be that, no signals should be sent until both graphs are updated. Can we relax this? If you listen to the root signal, then the root should be updated. If you listen to the view signal, then the view should be updated. Why do we need both to be updated, instead of just the one being emitted?
Git history
There is a bit of convoluted signal blocking code between the GraphView and BaseGraph that is complicating my next PR:
The key assertion seems to be that, no signals should be sent until both graphs are updated. Can we relax this? If you listen to the root signal, then the root should be updated. If you listen to the view signal, then the view should be updated. Why do we need both to be updated, instead of just the one being emitted?
Git history
add_node.remove_nodeandupdate_node_attrsfor consistency withadd_node, and addedtest_graph_view_signals.pyasserting that listeners on either side see consistenthas_node/ attribute values at signal time.