Nodes/comfy-ovum/_.isListlike
ComfyUI Node

_.isListlike

The pragmatic 'can I iterate this' test, without exact-type pedantry

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

_.isListlike is the sibling of _.isList that stops being pedantic about types. Where _.isList demands the exact Python list type, this one asks a more practical question: does this object act like a list? It's from the sfinktah/comfy-ovum pack's ovum/underscore family - auto-generated wrappers around underscore3, a Python port of Underscore.js - and it's one of the few family members with a duck-typing soul.

The family's README warning is worth repeating once: work in progress, "not recommended for use in workflows." Mostly that's aimed at the exotic method nodes. This one's fine - it's a couple of attribute checks, easy to reason about.

What it does

The underlying implementation is a small static helper, _isListlike, that checks whether the object has three callable attributes: append, remove, and __len__. If all three exist and are callable, it's "listlike."

Work through what that means for real data:

  • A listTrue (has append, remove, __len__).
  • A setFalse (no remove that matches... actually sets have remove and __len__ but no append - so False).
  • A tupleFalse (no append or remove; it's immutable).
  • A strFalse (no append or remove).
  • A dictFalse (no append or remove, though it has __len__).

So it's a "can I treat this as a mutable, indexable, sized sequence" test. Note it's not a full sequence check - __getitem__ isn't part of the test, and neither is __iter__. It's tuned to the specific operations the pack's own list-manipulation nodes use, which makes it a natural gate before you feed something into a list-op node.

Like everything in the family, feed it a plain value and get the boolean back, or feed it a _.CHAIN and it runs on the wrapped object, passing the chain onward.

Inputs and outputs

  • obj - the only input, type *, optional.
  • Output - a single * socket holding a Python bool. Same family quirk as most of these: the value is a real boolean, the socket type is generic, so a strict BOOLEAN consumer might want a cast.

Where it fits

Use it where "exactly a list" is the wrong question. If an upstream node could hand you a list or a tuple - which happens constantly with Python-ported node packs - _.isList says False for the tuple and _.isListlike says True. That's the one you actually want when the next step is "iterate it" or "feed it to a list operation." The tuple isn't a problem for the downstream op; the downstream op just needs to know the shape is iterable-and-sized, not exactly list.

Installing it

Install the pack via ComfyUI Manager (search comfy-ovum) or:

cd ComfyUI/custom_nodes
git clone https://github.com/sfinktah/comfy-ovum

Restart ComfyUI. No extra dependencies for this node - underscore3 is bundled in the repo - and Manager handles the pack's requirements.txt for everything else.

Gotchas

  • Sets, tuples, strings, and dicts all come back False. If "iterable" is your only concern, this is more conservative than isinstance(x, collections.abc.Iterable) would be.
  • It checks for methods, not for __getitem__ or __iter__, so a custom class that's indexable but lacks append reads as not-listlike. That's by design, but it can surprise you with exotic object types.
  • Output wire is *, not BOOLEAN - value is right, type label is loose.
Categoryovum/underscore

Inputs (1)

NameTypeDefaultDescription
objopt*Primary input object. Also accepts _.CHAIN to continue chaining.

Outputs (1)

NameTypeDescription
**