Python Exec
Arbitrary code, behind a locked door
- param_0
- *
Python Exec lets you run arbitrary Python inside a ComfyUI graph. That's a genuinely powerful capability - and the entire story of this node is that it ships disabled. If you drop one into a workflow and hit "Queue," it errors out on purpose until you flip a specific environment variable. The pack's authors know exactly what they're giving you, and they're making you confirm you want it.
The inputs
code- a multiline string of Python to execute.param_0,param_1, … - dynamic inputs passed to your code.- output -
*, the value of a variable your code must set.
The contract is minimal: your code runs with a params list containing your param_N inputs in order, and whatever you store in a variable named result comes out the output. Nothing else is handed to you - no pre-imported torch, no ComfyUI objects. local_vars = {"params": params}; exec(code, {}, local_vars) is the whole mechanism, and result is what's returned.
The locked door
Out of the box, this node raises a RuntimeError: "Execution of arbitrary code is disabled by default for security reasons." To unlock it, set the environment variable COMFYUI_FUNCTIONAL_DANGER_MODE to 1 before starting ComfyUI:
# Linux/macOS - in the shell you launch ComfyUI from
export COMFYUI_FUNCTIONAL_DANGER_MODE=1
# or Windows: set COMFYUI_FUNCTIONAL_DANGER_MODE=1
The "DANGER_MODE" name isn't editorializing. ComfyUI custom nodes run with your full OS user permissions - no sandbox - and exec() executes code verbatim. The KB's history here is not theoretical: the ComfyUI_LLMVISION malware incident of 2024 distributed a malicious custom node that ran code on import, and it led to a federal prosecution because a machine got compromised through exactly this kind of execution surface. So: only enable this for workflows you wrote and read yourself. If you load a shared workflow that "needs Python Exec," treat the code as hostile until you've read every line.
How to use it safely-ish
Keep the code tiny and self-contained. Want a list of squared numbers?
result = [i * i for i in params[0]]
Want a sum or a string join? Same shape. The whole value proposition is the small, boring math you don't want to wire node-by-node - not "import subprocess and own your machine." Every import you pull in is code you're trusting.
Where people get burned
- Forgetting the env var - the node errors with "disabled by default" and that's correct behavior, not a bug.
- No
resultvariable - if your code never setsresult, you getNoneout. Set it explicitly. - Expecting imports -
torchand friends aren't auto-imported. Putimport torchin your code if you need it. - Side effects - Python Exec is not in the pack's side-effect list, so caching isn't auto-busted. If it must always rerun, be aware the result may be cached.
Installing it
Part of Duanyll/comfyui_functional. ComfyUI Manager: search "Duanyll/comfyui_functional", or:
cd ComfyUI/custom_nodes
git clone https://github.com/Duanyll/comfyui_functional
# restart ComfyUI
No models, no pip deps. It's the pack's sharpest tool - respect the lock, and it's a genuinely handy escape hatch for quick math that shouldn't be a wall of nodes.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| code | STRING | — | |
| param_0opt | * | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| * | * | — |