Skip to content

Commit eb389f6

Browse files
committed
fix(validation): handle functools.partial objects in type name access
Replace direct __name__ attribute access with getattr() fallback pattern to safely handle functools.partial objects and other callable types that may not have a __name__ attribute. This prevents AttributeError when validating component data types that use partial functions. - Use getattr(type, "__name__", repr(type)) for safe attribute access - Apply fix in data_model_vehicle_components_validation.py (2 locations) - Apply fix in data_model_vehicle_components_base.py (2 locations) Fixes #1244
1 parent d55c8b0 commit eb389f6

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

ardupilot_methodic_configurator/data_model_vehicle_components_base.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,15 +157,17 @@ def _safe_cast_value( # noqa: PLR0911 pylint: disable=too-many-return-statement
157157

158158
# Special handling for list/dict types
159159
if datatype in (list, dict):
160-
logging_error(_("Invalid datatype '%s' for path %s"), value, datatype.__name__, path)
160+
type_name = getattr(datatype, "__name__", repr(datatype))
161+
logging_error(_("Invalid value '%s' for datatype %s at path %s"), value, type_name, path)
161162
return ""
162163

163164
# Standard type conversion
164165
return datatype(value)
165166

166167
except (ValueError, TypeError, AttributeError) as e:
167168
# Log the error and fall back to the original processing method
168-
logging_warning(_("Failed to cast value '%s' to %s for path %s: %s"), value, datatype.__name__, path, e)
169+
type_name = getattr(datatype, "__name__", repr(datatype))
170+
logging_warning(_("Failed to cast value '%s' to %s for path %s: %s"), value, type_name, path, e)
169171
return self._process_value(path, str(value) if value is not None else None)
170172

171173
def _process_value(self, path: ComponentPath, value: Union[str, None]) -> ComponentValue:

ardupilot_methodic_configurator/data_model_vehicle_components_validation.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -451,12 +451,14 @@ def validate_entry_limits(self, value: str, path: ComponentPath) -> tuple[str, O
451451
try:
452452
typed_value = data_type(value)
453453
if typed_value < limits[0] or typed_value > limits[1]:
454-
error_msg = _("{name} must be a {data_type.__name__} between {limits[0]} and {limits[1]}")
454+
error_msg = _("{name} must be a {data_type_name} between {min} and {max}")
455455
limited_value = limits[0] if typed_value < limits[0] else limits[1]
456-
return error_msg.format(name=name, data_type=data_type, limits=limits), limited_value
456+
type_name = getattr(data_type, "__name__", repr(data_type))
457+
return error_msg.format(name=name, data_type_name=type_name, min=limits[0], max=limits[1]), limited_value
457458
except ValueError:
458-
error_msg = _("Invalid {data_type.__name__} value for {name}")
459-
return error_msg.format(data_type=data_type, name=name), None
459+
error_msg = _("Invalid {data_type_name} value for {name}")
460+
type_name = getattr(data_type, "__name__", repr(data_type))
461+
return error_msg.format(data_type_name=type_name, name=name), None
460462

461463
# Validate takeoff weight limits
462464
if path[0] == "Frame" and path[1] == "Specifications" and "TOW" in path[2]:

0 commit comments

Comments
 (0)