diff --git a/pyiron_workflow/nodes/for_loop.py b/pyiron_workflow/nodes/for_loop.py index c38d68af..b6ece86d 100644 --- a/pyiron_workflow/nodes/for_loop.py +++ b/pyiron_workflow/nodes/for_loop.py @@ -347,9 +347,46 @@ def _build_inputs_preview(cls) -> dict[str, tuple[Any, Any]]: def _build_outputs_preview(cls) -> dict[str, Any]: return {"df": DataFrame} + @property + def _input_value_links(self): + """ + Value connections between child output and macro in string representation based + on labels. + + The string representation helps storage, and having it as a property ensures + the name is protected. + """ + # Duplicated value linking behaviour from Macro class + return [ + (c.label, (c.value_receiver.owner.label, c.value_receiver.label)) + for c in self.inputs + ] + + @property + def _output_value_links(self): + """ + Value connections between macro and child input in string representation based + on labels. + + The string representation helps storage, and having it as a property ensures + the name is protected. + """ + # Duplicated value linking behaviour from Macro class + return [ + ((c.owner.label, c.label), c.value_receiver.label) + for child in self + for c in child.outputs + if c.value_receiver is not None + ] + def __getstate__(self): state = super().__getstate__() state["body_node_executor"] = None + + # Duplicated value linking behaviour from Macro class + state["_input_value_links"] = self._input_value_links + state["_output_value_links"] = self._output_value_links + return state def _get_state_from_remote_other(self, other_self): @@ -358,6 +395,21 @@ def _get_state_from_remote_other(self, other_self): # so keep local return state + def __setstate__(self, state): + # Duplicated value linking behaviour from Macro class + # Purge value links from the state + input_links = state.pop("_input_value_links") + output_links = state.pop("_output_value_links") + + super().__setstate__(state) + + # Re-forge value links + for inp, (child, child_inp) in input_links: + self.inputs[inp].value_receiver = self.children[child].inputs[child_inp] + + for (child, child_out), out in output_links: + self.children[child].outputs[child_out].value_receiver = self.outputs[out] + def _for_node_class_name( body_node_class: type[StaticNode], iter_on: tuple[str, ...], zip_on: tuple[str, ...]