_.isGenerator
A correctly-checked type test you'll rarely need
- obj
- *
_.isGenerator checks whether an object is a Python generator - the lazy iterator you get from a function containing yield. It's part of the sfinktah/comfy-ovum pack's ovum/underscore family, the auto-generated wrappers around underscore3 (a Python port of Underscore.js). Unlike a few of its siblings, this one's check is correct: type(self.obj) is GeneratorType is exactly the right way to ask the question. The only thing working against it is how rarely a generator shows up in a ComfyUI graph.
The family's README caveat applies - work in progress, "not recommended for use in workflows." For this node, the caution is mostly about relevance, not correctness.
What it does
Generators are the objects you get from calling a function that uses yield - they're lazy, meaning they produce values one at a time as you iterate them, and they're exhausted once consumed. The check type(self.obj) is GeneratorType catches exactly those. It won't match:
- Regular lists or tuples (eager, not generators).
- Iterator objects that aren't generators (a
mapobject or a file's line iterator is an iterator but not aGeneratorType). - Generator expressions - actually those are generator objects, so they'd read as
True.
Where would one actually appear in a graph? Custom nodes that yield values for lazy processing could hand you one. If some upstream node returns a generator and a downstream node expects a list, that's a classic mismatch - the fix is to materialize it with list(). _.isGenerator is the diagnostic that tells you that's what happened.
One practical warning about generators: they're single-use and they get consumed. Whatever node handed you one probably doesn't want you to copy it, and the underscore family's habit of deep-copying inputs is a real concern - you can't deep-copy a generator (it isn't copyable). Feeding one into a chain node may fail. This is squarely in "debug with care" territory.
Inputs and outputs
obj- the only input, type*, optional.- Output - a single
*socket holding a Python bool (the family's generic-typed output quirk).
Where it fits
Diagnostics. If a workflow that's supposed to fan out a list is doing something weird and you suspect an upstream node is emitting a lazy generator instead of a materialized list, _.isGenerator confirms it - then you list() it (or feed it into the pack's list converters) before it bites you. For anyone not feeding generator-producing nodes, this is a shelf-sitter.
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; underscore3 is vendored in the repo.
Gotchas
- It only matches true generator objects - plain iterators (like
mapresults) read asFalse. - Generators can't be deep-copied, and this family deep-copies its input. Passing a generator into a chain can fail outright.
- Generators are single-use; testing one doesn't consume it, but consuming one downstream does.
- Output wire is
*, notBOOLEAN.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| objopt | * | Primary input object. Also accepts _.CHAIN to continue chaining. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| * | * | — |