fix: fix numeric type conversion issue in if-else condition comparison (#28155)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
耐小心 2025-11-21 12:58:08 +08:00 committed by GitHub
parent c5b6219006
commit 06466cb73a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 99 additions and 48 deletions

View File

@ -265,6 +265,45 @@ def _assert_not_empty(*, value: object) -> bool:
return False
def _normalize_numeric_values(value: int | float, expected: object) -> tuple[int | float, int | float]:
"""
Normalize value and expected to compatible numeric types for comparison.
Args:
value: The actual numeric value (int or float)
expected: The expected value (int, float, or str)
Returns:
A tuple of (normalized_value, normalized_expected) with compatible types
Raises:
ValueError: If expected cannot be converted to a number
"""
if not isinstance(expected, (int, float, str)):
raise ValueError(f"Cannot convert {type(expected)} to number")
# Convert expected to appropriate numeric type
if isinstance(expected, str):
# Try to convert to float first to handle decimal strings
try:
expected_float = float(expected)
except ValueError as e:
raise ValueError(f"Cannot convert '{expected}' to number") from e
# If value is int and expected is a whole number, keep as int comparison
if isinstance(value, int) and expected_float.is_integer():
return value, int(expected_float)
else:
# Otherwise convert value to float for comparison
return float(value) if isinstance(value, int) else value, expected_float
elif isinstance(expected, float):
# If expected is already float, convert int value to float
return float(value) if isinstance(value, int) else value, expected
else:
# expected is int
return value, expected
def _assert_equal(*, value: object, expected: object) -> bool:
if value is None:
return False
@ -324,18 +363,8 @@ def _assert_greater_than(*, value: object, expected: object) -> bool:
if not isinstance(value, (int, float)):
raise ValueError("Invalid actual value type: number")
if isinstance(value, int):
if not isinstance(expected, (int, float, str)):
raise ValueError(f"Cannot convert {type(expected)} to int")
expected = int(expected)
else:
if not isinstance(expected, (int, float, str)):
raise ValueError(f"Cannot convert {type(expected)} to float")
expected = float(expected)
if value <= expected:
return False
return True
value, expected = _normalize_numeric_values(value, expected)
return value > expected
def _assert_less_than(*, value: object, expected: object) -> bool:
@ -345,18 +374,8 @@ def _assert_less_than(*, value: object, expected: object) -> bool:
if not isinstance(value, (int, float)):
raise ValueError("Invalid actual value type: number")
if isinstance(value, int):
if not isinstance(expected, (int, float, str)):
raise ValueError(f"Cannot convert {type(expected)} to int")
expected = int(expected)
else:
if not isinstance(expected, (int, float, str)):
raise ValueError(f"Cannot convert {type(expected)} to float")
expected = float(expected)
if value >= expected:
return False
return True
value, expected = _normalize_numeric_values(value, expected)
return value < expected
def _assert_greater_than_or_equal(*, value: object, expected: object) -> bool:
@ -366,18 +385,8 @@ def _assert_greater_than_or_equal(*, value: object, expected: object) -> bool:
if not isinstance(value, (int, float)):
raise ValueError("Invalid actual value type: number")
if isinstance(value, int):
if not isinstance(expected, (int, float, str)):
raise ValueError(f"Cannot convert {type(expected)} to int")
expected = int(expected)
else:
if not isinstance(expected, (int, float, str)):
raise ValueError(f"Cannot convert {type(expected)} to float")
expected = float(expected)
if value < expected:
return False
return True
value, expected = _normalize_numeric_values(value, expected)
return value >= expected
def _assert_less_than_or_equal(*, value: object, expected: object) -> bool:
@ -387,18 +396,8 @@ def _assert_less_than_or_equal(*, value: object, expected: object) -> bool:
if not isinstance(value, (int, float)):
raise ValueError("Invalid actual value type: number")
if isinstance(value, int):
if not isinstance(expected, (int, float, str)):
raise ValueError(f"Cannot convert {type(expected)} to int")
expected = int(expected)
else:
if not isinstance(expected, (int, float, str)):
raise ValueError(f"Cannot convert {type(expected)} to float")
expected = float(expected)
if value > expected:
return False
return True
value, expected = _normalize_numeric_values(value, expected)
return value <= expected
def _assert_null(*, value: object) -> bool:

View File

@ -0,0 +1,52 @@
from core.workflow.runtime import VariablePool
from core.workflow.utils.condition.entities import Condition
from core.workflow.utils.condition.processor import ConditionProcessor
def test_number_formatting():
condition_processor = ConditionProcessor()
variable_pool = VariablePool()
variable_pool.add(["test_node_id", "zone"], 0)
variable_pool.add(["test_node_id", "one"], 1)
variable_pool.add(["test_node_id", "one_one"], 1.1)
# 0 <= 0.95
assert (
condition_processor.process_conditions(
variable_pool=variable_pool,
conditions=[Condition(variable_selector=["test_node_id", "zone"], comparison_operator="", value="0.95")],
operator="or",
).final_result
== True
)
# 1 >= 0.95
assert (
condition_processor.process_conditions(
variable_pool=variable_pool,
conditions=[Condition(variable_selector=["test_node_id", "one"], comparison_operator="", value="0.95")],
operator="or",
).final_result
== True
)
# 1.1 >= 0.95
assert (
condition_processor.process_conditions(
variable_pool=variable_pool,
conditions=[
Condition(variable_selector=["test_node_id", "one_one"], comparison_operator="", value="0.95")
],
operator="or",
).final_result
== True
)
# 1.1 > 0
assert (
condition_processor.process_conditions(
variable_pool=variable_pool,
conditions=[Condition(variable_selector=["test_node_id", "one_one"], comparison_operator=">", value="0")],
operator="or",
).final_result
== True
)