diff --git a/packages/gds-framework/gds/parameters.py b/packages/gds-framework/gds/parameters.py index 8899fba..ca4ba34 100644 --- a/packages/gds-framework/gds/parameters.py +++ b/packages/gds-framework/gds/parameters.py @@ -37,8 +37,11 @@ def check_value(self, value: Any) -> bool: if not self.typedef.check_value(value): return False if self.bounds is not None: - low, high = self.bounds - if not (low <= value <= high): + try: + low, high = self.bounds + if not (low <= value <= high): + return False + except Exception: return False return True diff --git a/packages/gds-framework/gds/types/typedef.py b/packages/gds-framework/gds/types/typedef.py index 78e56a1..dae0336 100644 --- a/packages/gds-framework/gds/types/typedef.py +++ b/packages/gds-framework/gds/types/typedef.py @@ -32,7 +32,12 @@ def check_value(self, value: Any) -> bool: """Check if a value satisfies this type definition.""" if not isinstance(value, self.python_type): return False - return self.constraint is None or self.constraint(value) + if self.constraint is None: + return True + try: + return bool(self.constraint(value)) + except Exception: + return False # ── Built-in types ────────────────────────────────────────── diff --git a/packages/gds-framework/tests/test_types.py b/packages/gds-framework/tests/test_types.py index 8e914a2..d54cf61 100644 --- a/packages/gds-framework/tests/test_types.py +++ b/packages/gds-framework/tests/test_types.py @@ -180,6 +180,34 @@ def test_frozen(self): with pytest.raises(ValidationError): t.name = "Other" # type: ignore[misc] + def test_constraint_exception_returns_false(self): + """Constraint that raises should return False, not propagate.""" + t = TypeDef( + name="Bad", + python_type=float, + constraint=lambda x: 1 / 0, # ZeroDivisionError + ) + assert t.check_value(1.0) is False + + def test_constraint_type_error_returns_false(self): + """Constraint that raises TypeError should return False.""" + t = TypeDef( + name="Bad", + python_type=float, + constraint=lambda x: x > "not a number", # TypeError + ) + assert t.check_value(1.0) is False + + def test_constraint_returns_truthy_non_bool(self): + """Constraint returning truthy non-bool value should work.""" + t = TypeDef( + name="Truthy", + python_type=str, + constraint=lambda x: x, # non-empty string is truthy + ) + assert t.check_value("hello") is True + assert t.check_value("") is False + # ── Built-in types ───────────────────────────────────────────