TypeResolver: import internal _io so isinstance chain sees DynamicSlot

The public `comfy_api.latest.io` re-export does not include DynamicSlot,
so the isinstance chain in _effective_io_type raised AttributeError the
first time it ran against any V3 input that wasn't an Autogrow. End-to-end
test caught this with a MatchType chain feeding a probe node.

Amp-Thread-ID: https://ampcode.com/threads/T-019e8568-f382-743d-a97f-0de3ff29d501
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Jedrzej Kosinski 2026-06-01 17:08:50 -07:00
parent 004ac8820b
commit 0e4a15b7fb
2 changed files with 31 additions and 1 deletions

View File

@ -14,7 +14,7 @@ from __future__ import annotations
import logging
from typing import Any
from comfy_api.latest import io
from comfy_api.latest import _io as io
from comfy_api.internal import _ComfyNodeInternal

View File

@ -328,6 +328,36 @@ def test_effective_slot_type_peels_autogrow(fake_nodes_module, TypeResolver):
# compute_live_input_types
# ---------------------------------------------------------------------------
def test_effective_slot_type_on_v3_plain_input(fake_nodes_module, TypeResolver):
"""V3 input that is neither Autogrow/DynamicSlot/DynamicCombo must still resolve.
Regression test: importing ``io`` from the public re-export skipped
``DynamicSlot``, so an ``isinstance`` chain in ``_effective_io_type`` raised
``AttributeError`` the first time it ran against a plain V3 input.
"""
from comfy_api.latest import io
class BoolSink(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="BoolSink",
inputs=[io.Boolean.Input("flag")],
outputs=[io.Boolean.Output()],
)
@classmethod
def execute(cls, flag):
return io.NodeOutput(flag)
BoolSink.GET_SCHEMA()
fake_nodes_module["BoolSink"] = BoolSink
prompt = {"n": {"class_type": "BoolSink", "inputs": {"flag": True}}}
r = TypeResolver(prompt)
assert r.get_declared_slot_io_type("n", "flag") == "BOOLEAN"
assert r.compute_live_input_types("n") == {"flag": "BOOLEAN"}
def test_compute_live_input_types_mixes_links_and_literals(fake_nodes_module, TypeResolver):
fake_nodes_module["Src"] = _v1_node(("MODEL",))
fake_nodes_module["Sink"] = _v1_node(