@@ -166,9 +166,7 @@ def _get_built_in_fn_by_key(fn_key: str):
166166# For instance, a user does not have access to the numpy module directly, so they cannot invoke
167167# `numpy.save`. However, a user can access a numpy.ndarray instance from a tensor and, from there,
168168# an attempt to call `tofile` or `dump` etc. would need to be blocked.
169- _BLOCKED_METHODS_OR_ATTRS = MappingProxyType ({
170- np .ndarray : ['tofile' , 'dump' ]
171- })
169+ _BLOCKED_METHODS_OR_ATTRS = MappingProxyType ({np .ndarray : ['tofile' , 'dump' ]})
172170
173171# Special functions by class type (called from the Attrs.)
174172_SPECIAL_FUNCTIONS = {
@@ -403,11 +401,11 @@ def __init__(self, *, code: str, ctx: dict[str, Any], workflow, prompt, dynpromp
403401 self ._code = code
404402 self ._workflow = workflow
405403 self ._prompt = prompt
404+ self ._unique_id = unique_id
406405 self ._dynprompt = dynprompt
407- self ._prompt_nodes = []
408- if self ._prompt :
409- self ._prompt_nodes = [{'id' : id } | {** node } for id , node in self ._prompt .items ()]
410- self ._prompt_node = [n for n in self ._prompt_nodes if n ['id' ] == unique_id ][0 ]
406+ # These are now expanded lazily when needed.
407+ self ._prompt_nodes = None
408+ self ._prompt_node = None
411409
412410 def execute (self , code = Optional [str ]) -> Any :
413411 """Evaluates a the code block."""
@@ -431,9 +429,26 @@ def execute(self, code=Optional[str]) -> Any:
431429 random .setstate (initial_random_state )
432430 return last_value
433431
432+ def _get_prompt_nodes (self ):
433+ """Expands the prompt nodes lazily from the dynamic prompt.
434+
435+ https://github.com/comfyanonymous/ComfyUI/blob/fc657f471a29d07696ca16b566000e8e555d67d1/comfy_execution/graph.py#L22
436+ """
437+ if self ._prompt_nodes is None :
438+ self ._prompt_nodes = []
439+ if self ._dynprompt :
440+ all_ids = self ._dynprompt .all_node_ids ()
441+ self ._prompt_nodes = [{'id' : k } | {** self ._dynprompt .get_node (k )} for k in all_ids ]
442+ return self ._prompt_nodes
443+
444+ def _get_prompt_node (self ):
445+ if self ._prompt_nodes is None :
446+ self ._prompt_node = [n for n in self ._get_prompt_nodes () if n ['id' ] == self ._unique_id ][0 ]
447+ return self ._prompt_node
448+
434449 def _get_nodes (self , node_id : Union [int , str , re .Pattern , None ] = None ) -> list [Any ]:
435450 """Get a list of the nodes that match the node_id, or all the nodes in the prompt."""
436- nodes = self ._prompt_nodes .copy ()
451+ nodes = self ._get_prompt_nodes () .copy ()
437452 if not node_id :
438453 return nodes
439454
@@ -451,18 +466,18 @@ def _get_nodes(self, node_id: Union[int, str, re.Pattern, None] = None) -> list[
451466 def _get_node (self , node_id : Union [int , str , re .Pattern , None ] = None ) -> Union [Any , None ]:
452467 """Returns a prompt-node from the hidden prompt."""
453468 if node_id is None :
454- return self ._prompt_node
469+ return self ._get_prompt_node ()
455470 nodes = self ._get_nodes (node_id )
456471 if nodes and len (nodes ) > 1 :
457472 log_node_warn (_NODE_NAME , f"More than one node found for '{ node_id } '. Returning first." )
458473 return nodes [0 ] if nodes else None
459474
460475 def _get_input_node (self , input_name , node = None ):
461476 """Gets the (non-muted) node of an input connection from a node (default to the power puter)."""
462- node = node if node else self ._prompt_node
477+ node = node if node else self ._get_prompt_node ()
463478 try :
464479 connected_node_id = node ['inputs' ][input_name ][0 ]
465- return [n for n in self ._prompt_nodes if n ['id' ] == connected_node_id ][0 ]
480+ return [n for n in self ._get_prompt_nodes () if n ['id' ] == connected_node_id ][0 ]
466481 except (TypeError , IndexError , KeyError ):
467482 log_node_warn (_NODE_NAME , f'No input node found for "{ input_name } ". ' )
468483 return None
0 commit comments