_.isList
An exact-type check so you know whether to fan out or not
- obj
- *
The classic ComfyUI ambiguity: a dynamic node hands you a value, and you don't know if it's a single item or a whole list. Get it wrong and your downstream list node either iterates one useless item or crashes trying to index a scalar. _.isList from the sfinktah/comfy-ovum pack answers the question - but with a catch: it's an exact Python type check, so "list" means list and nothing else.
This is part of the ovum/underscore family, auto-generated wrappers around underscore3, a Python port of Underscore.js. The README's own verdict on the family is "work in progress" and "not recommended for use in workflows" - blunt, and aimed at the auto-generated zoo as a whole. _.isList is one of the plain ones: the mechanism is short enough to read and trust.
What it does
The check is type(self.obj) is list. Exactly that. No isinstance, no duck typing, no tolerance. So:
- A Python
list→True. - A tuple →
False. - A
set→False. - A NumPy array →
False. - A string →
False.
That strictness is both the feature and the trap. If a node upstream gives you a tuple or a numpy array, _.isList says "not a list" even though you can iterate it fine. If you want "behaves like a list" rather than "is literally a list," the pack's _.isListlike is the looser sibling that checks for list-ish methods instead of exact type.
Like the rest of the family, it takes a plain value and returns the boolean, or it takes a _.CHAIN from _.chain and passes the chain onward.
Inputs and outputs
obj- the only input, type*, optional. Wire your ambiguous value here.- Output - a single
*socket. The value is a real Python bool, but the socket is typed generic rather thanBOOLEAN(a quirk of the auto-generator - only a few methods get proper boolean sockets). It'll connect to anything, but a node demanding a strictBOOLEANinput may want a cast first.
Where it fits
The shape-test pattern. Some pack's list builder might give you [item] in one path and a bare item in another. Feed the value into _.isList, then branch: if it's a list, wire it straight into your fan-out; if not, wrap it or handle it as a singleton. This is the honest way to write "I don't know what shape this is" logic instead of hoping.
It's also useful for sanity-checking dict methods - _.isList on the result of _.keys tells you whether you actually got the list shape you expect before indexing into it.
Installing it
Install the whole pack via ComfyUI Manager - search comfy-ovum - or:
cd ComfyUI/custom_nodes
git clone https://github.com/sfinktah/comfy-ovum
Restart ComfyUI. underscore3 is vendored in the repo, so no extra pip install for this node; Manager resolves the pack's requirements.txt (aiohttp, pillow, numpy, requests, and a few more) automatically.
Gotchas
- Exact type only: tuples, sets, numpy arrays, and strings all read as
False. BOOLEAN-typed downstream inputs may reject the*wire even though the value is a bool.- If your value came from a node that returns
LIST-typed outputs, ComfyUI may have already wrapped it - theis_listflag on the socket isn't the same as the Python type, so trust the node, not the wire color.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| objopt | * | Primary input object. Also accepts _.CHAIN to continue chaining. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| * | * | — |