Skip to content

Commit

Permalink
🔥 🐛 make sure for-loops re-set their value links like macros (#373)
Browse files Browse the repository at this point in the history
Honestly, I basically just forgot that for-loops are not actually macros. Ideally, this behaviour would come from a shared parent class, like `StaticComposite` analogous to `StaticNode`. Unfortunately, that gives circular imports because the creator object is on `Composite`. Once `Workflow` and `Macro` do not share access to the creator, such an abstraction will be possible. In the meantime, I just tolerate the once-duplicated code.
  • Loading branch information
liamhuber authored Jun 25, 2024
1 parent 3a3b3ee commit abdbe99
Showing 1 changed file with 52 additions and 0 deletions.
52 changes: 52 additions & 0 deletions pyiron_workflow/nodes/for_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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, ...]
Expand Down

0 comments on commit abdbe99

Please sign in to comment.