Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,10 @@ def set_new_value(self, value: str, ignore_out_of_range: bool = False) -> float:

# Multiple-choice parameters: accept either the choice label or the numeric key
if self.is_multiple_choice:
new_value = float(s)
try:
new_value = float(s)
except ValueError as exc:
raise ValueError(_("The value for {param_name} must be a number.").format(param_name=self._name)) from exc
# No change
if new_value == self._new_value:
raise ParameterUnchangedError(
Expand Down
33 changes: 33 additions & 0 deletions tests/test_data_model_ardupilot_parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -1155,3 +1155,36 @@ def test_set_fc_value_maintains_comparison_state() -> None:

# Assert: No longer different
assert param.is_different_from_fc is False


def test_set_new_value_multiple_choice_non_numeric_raises_friendly_error(param_fixture) -> None:
"""
Bug fix: non-numeric input for a multiple-choice parameter raises a friendly ValueError.

GIVEN: A multiple-choice parameter (has a values dict)
WHEN: set_new_value is called with a non-numeric string like a choice label
THEN: A ValueError is raised with a user-friendly translated message,
not a raw Python 'could not convert string to float' error

Previously the is_multiple_choice branch called float(s) with no try/except,
while both the bitmask and numeric branches had proper error handling.
"""
full_param = param_fixture["full_param"]

with pytest.raises(ValueError, match="must be a number"):
full_param.set_new_value("Zero")


def test_set_new_value_multiple_choice_valid_numeric_string_succeeds(param_fixture) -> None:
"""
A valid numeric string for a multiple-choice parameter is accepted correctly.

GIVEN: A multiple-choice parameter with choices {"0": "Zero", "10": "Ten", "20": "Twenty"}
WHEN: set_new_value is called with "0" (a valid numeric choice key)
THEN: The new value is set to 0.0 and returned
"""
full_param = param_fixture["full_param"]

result = full_param.set_new_value("0")

assert result == 0.0
Loading