ComfyUI Node

_.clone

A copy you can mutate without breaking the original

By sfinktah·Created about a year ago·Updated 10 months ago· 7
_.clone
  • py_dict
  • *

_.clone copies an object - a dict, a list, whatever - so you get a separate instance you can mutate downstream without touching the original. In Comfy this matters more than it looks, because the graph caches node outputs and reuses them between runs. If two branches both need to reshape the same dict and one of them modifies it in place, the other branch can silently receive already-modified data. _.clone in front of each branch keeps them honest.

The author's description is precise about what you're getting: "Create a shallow-copied clone of the provided plain object. Any nested objects or arrays will be copied by reference, not duplicated."

How it works

Generated wrapper around underscore3, the bundled Python port of Underscore.js. The key word in that description is shallow. The top level of the object is copied - keys in a new dict, items in a new list - but anything nested (a dict inside your dict, a list inside your list) is shared by reference with the original. So:

  • Mutating clone["top_level_key"] = x is safe; the original is untouched.
  • Mutating clone["nested"]["deep_key"] = y does affect the original, because clone["nested"] is the same inner dict.

If you need a deep copy that breaks every level of nesting, this isn't it - that's what a JSON round-trip or _.extendDeep-style behavior is for. For the common "give each branch its own top-level dict to play with" case, shallow is exactly right and much cheaper.

Inputs and output

  • py_dict (any type) - the object to clone. Despite the name, the underscore3 port will clone lists and other plain values too; it's named for the object case because that's what the wrapper expects as its primary input. Accepts a _.CHAIN to continue a chain.
  • Output: * (any type) - the cloned object, same shape as the input.

No widgets, no options. Feed it an object, get a fresh copy back.

Installing it

Part of sfinktah/comfy-ovum ("comfy-ovum"):

  • ComfyUI Manager: search "comfy-ovum", install, restart.
  • Manual: cd ComfyUI/custom_nodes && git clone https://github.com/sfinktah/comfy-ovum, restart.

No model files, light dependencies, underscore3 bundled in the repo.

When you'd actually use it

The honest answer: less often than you'd think, because most Comfy nodes don't mutate their inputs. The case that earns its keep is shared mutable state - a dict wired into two branches that both write to it, or a pipeline where a loop node rewrites a structure and you need the pristine version later for comparison. And if you find yourself needing to protect nested data, remember the shallow caveat and pair it with a deep merge/copy step. Like the rest of this family it's flagged as work-in-progress by the author, but the mechanism is simple enough that the risk is low.

Categoryovum/underscore

Inputs (1)

NameTypeDefaultDescription
py_dictopt*Primary input object (expected object). You can still pass any JSON-serializable value. Also accepts _.CHAIN to continue chaining.

Outputs (1)

NameTypeDescription
**