起きる事象
comfyUIで使っているDynamicPromptsというカスタムノードが、下のようなアウトプットをほぼすべてのwildcardsで出す問題が長らく発生していた。いつからかはよくわかってない。
Unsupported list item: <MyValue1>
Unsupported list item: <MyValue2>
Unsupported list item: ...
Unsupported list item: ...
...
なお、これは、wildcards機能を使って、yamlファイルからプロンプトを生成している場合に起こっていた。
原因の発見
comfyUIのディレクトリをVSCodeで開いて、Ctrl+Shift+FからのUnsupported list itemで検索すると、ComfyUI\venv\Lib\site-packages\dynamicprompts\wildcards\collection\structured.pyというファイルがヒットする。
その中の、以下のコードが原因だった:
def _parse_structured_file_list(value: list[Any]) -> Iterable[str | WildcardItem]:
"""
Parse a single list in a structured file (JSON or YAML) and yield the wildcard items.
"""
for item in value:
if not item:
continue
if isinstance(item, str):
# See if the item _could_ have a prefix weight before attempting to parse.
if item[0].isdigit() and "::" in item:
weight_text, _, content = item.rpartition("::")
try:
yield WildcardItem(content=content, weight=float(weight_text))
continue
except ValueError:
# When failing to parse the weight,
# fall through to yielding the item as-is.
pass
yield item
elif isinstance(item, dict):
# Support {"text": "foo", "weight": 1.1} syntax
# and {"content": "foo", "weight": 1.1}
weight = float(item.get("weight", 1))
content = item.get("text") or item.get("content") or ""
if content:
if weight == 1:
yield content
else:
yield WildcardItem(content=content, weight=weight)
continue
log.warning("Unsupported list item: %s", item)
この最後の行の出力が大量に出ている模様。
問題を修正
ちょっと調べてみると、問題の出力はここのisinstance(item, str)を通って、yield itemでyieldしていた。そのあと、最後尾の文が実行されるので、出力が垂れ流しになってしまっていたようだ。
なので、yieldしたあと、continueするようにすればいい。修正はこのように:
def _parse_structured_file_list(value: list[Any]) -> Iterable[str | WildcardItem]:
"""
Parse a single list in a structured file (JSON or YAML) and yield the wildcard items.
"""
for item in value:
if not item:
continue
if isinstance(item, str):
# See if the item _could_ have a prefix weight before attempting to parse.
if item[0].isdigit() and "::" in item:
weight_text, _, content = item.rpartition("::")
try:
yield WildcardItem(content=content, weight=float(weight_text))
continue
except ValueError:
# When failing to parse the weight,
# fall through to yielding the item as-is.
pass
yield item
continue ### ここに追加する。最下部のログ出力を抑えるため。###
elif isinstance(item, dict):
# Support {"text": "foo", "weight": 1.1} syntax
# and {"content": "foo", "weight": 1.1}
weight = float(item.get("weight", 1))
content = item.get("text") or item.get("content") or ""
if content:
if weight == 1:
yield content
else:
yield WildcardItem(content=content, weight=weight)
continue
log.warning("Unsupported list item: %s", item)
これで直る。
そのほか
この部分のスクリプトは、カスタムノードから切り離されている、dynamicpromptsのコア部分に相当する。外部モジュールとしてこれを利用しているので、このスクリプトはカスタムノード部分のコードには存在しておらず、ふつうはvenvディレクトリの中に存在するはずである。
また、githubにあるこのスクリプトのコードを見ると、上の修正と同じようにcontinueがされていた。どうやら古いバージョンのdynamicpromptsコアモジュールが何かの原因でインストールされているため、このような出力大量を起こしていたようだ。
以上です。

