mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-03-27 20:13:32 +08:00
* Add Number Convert node for unified numeric type conversion Consolidates fragmented IntToFloat/FloatToInt nodes (previously only available via third-party packs like ComfyMath, FillNodes, etc.) into a single core node. - Single input accepting INT, FLOAT, STRING, and BOOL types - Two outputs: FLOAT and INT - Conversion: bool→0/1, string→parsed number, float↔int standard cast - Follows Math Expression node patterns (comfy_api, io.Schema, etc.) Refs: COM-16925 * Register nodes_number_convert.py in extras_files list Without this entry in nodes.py, the Number Convert node file would not be discovered and loaded at startup. * Add isfinite guard, exception chaining, and unit tests for Number Convert node - Add math.isfinite() check to prevent int() crash on inf/nan string inputs - Use 'from None' for cleaner exception chaining on string parse failure - Add 21 unit tests covering all input types and error paths
80 lines
2.4 KiB
Python
80 lines
2.4 KiB
Python
"""Number Convert node for unified numeric type conversion.
|
|
|
|
Provides a single node that converts INT, FLOAT, STRING, and BOOL
|
|
inputs into FLOAT and INT outputs.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import math
|
|
|
|
from typing_extensions import override
|
|
|
|
from comfy_api.latest import ComfyExtension, io
|
|
|
|
|
|
class NumberConvertNode(io.ComfyNode):
|
|
"""Converts various types to numeric FLOAT and INT outputs."""
|
|
|
|
@classmethod
|
|
def define_schema(cls) -> io.Schema:
|
|
return io.Schema(
|
|
node_id="ComfyNumberConvert",
|
|
display_name="Number Convert",
|
|
category="math",
|
|
search_aliases=[
|
|
"int to float", "float to int", "number convert",
|
|
"int2float", "float2int", "cast", "parse number",
|
|
"string to number", "bool to int",
|
|
],
|
|
inputs=[
|
|
io.MultiType.Input(
|
|
"value",
|
|
[io.Int, io.Float, io.String, io.Boolean],
|
|
display_name="value",
|
|
),
|
|
],
|
|
outputs=[
|
|
io.Float.Output(display_name="FLOAT"),
|
|
io.Int.Output(display_name="INT"),
|
|
],
|
|
)
|
|
|
|
@classmethod
|
|
def execute(cls, value) -> io.NodeOutput:
|
|
if isinstance(value, bool):
|
|
float_val = 1.0 if value else 0.0
|
|
elif isinstance(value, (int, float)):
|
|
float_val = float(value)
|
|
elif isinstance(value, str):
|
|
text = value.strip()
|
|
if not text:
|
|
raise ValueError("Cannot convert empty string to number.")
|
|
try:
|
|
float_val = float(text)
|
|
except ValueError:
|
|
raise ValueError(
|
|
f"Cannot convert string to number: {value!r}"
|
|
) from None
|
|
else:
|
|
raise TypeError(
|
|
f"Unsupported input type: {type(value).__name__}"
|
|
)
|
|
|
|
if not math.isfinite(float_val):
|
|
raise ValueError(
|
|
f"Cannot convert non-finite value to number: {float_val}"
|
|
)
|
|
|
|
return io.NodeOutput(float_val, int(float_val))
|
|
|
|
|
|
class NumberConvertExtension(ComfyExtension):
|
|
@override
|
|
async def get_node_list(self) -> list[type[io.ComfyNode]]:
|
|
return [NumberConvertNode]
|
|
|
|
|
|
async def comfy_entrypoint() -> NumberConvertExtension:
|
|
return NumberConvertExtension()
|