Raise ValueError for invalid boolean query params in resource templates (#3424) (#3434)

This commit is contained in:
Jeremiah Lowin 2026-03-07 11:40:29 -05:00 committed by GitHub
commit 9ccaef2b6a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 77 additions and 2 deletions

View file

@ -409,9 +409,17 @@ class FunctionResourceTemplate(ResourceTemplate):
elif annotation is float:
kwargs[param_name] = float(param_value)
elif annotation is bool:
kwargs[param_name] = param_value.lower() in ("true", "1", "yes")
lower = param_value.lower()
if lower in ("true", "1", "yes"):
kwargs[param_name] = True
elif lower in ("false", "0", "no"):
kwargs[param_name] = False
else:
raise ValueError(
f"Invalid boolean value for {param_name}: {param_value!r}"
)
except (ValueError, AttributeError):
pass
raise
# self.fn is wrapped by without_injected_parameters which handles
# dependency resolution internally, so we call it directly

View file

@ -263,6 +263,73 @@ class TestQueryParameterWithWildcards:
assert result["lines"] == 50 # provided
class TestBooleanQueryParameterValidation:
"""Test that invalid boolean query parameter values raise errors."""
async def _make_template(self):
def get_config(name: str, enabled: bool = False) -> dict:
return {"name": name, "enabled": enabled}
return ResourceTemplate.from_function(
fn=get_config,
uri_template="config://{name}{?enabled}",
name="test",
)
async def test_invalid_boolean_value_raises_error(self):
"""Test that nonsense boolean values like 'banana' raise ValueError."""
template = await self._make_template()
with pytest.raises(ValueError, match="Invalid boolean value for enabled"):
resource = await template.create_resource(
"config://feature?enabled=banana",
{"name": "feature", "enabled": "banana"},
)
await resource.read()
@pytest.mark.parametrize(
"value", ["true", "True", "TRUE", "1", "yes", "Yes", "YES"]
)
async def test_valid_true_values(self, value: str):
"""Test that all accepted truthy string values coerce to True."""
template = await self._make_template()
resource = await template.create_resource(
f"config://feature?enabled={value}",
{"name": "feature", "enabled": value},
)
result = await resource.read()
assert isinstance(result, dict)
assert result["enabled"] is True
@pytest.mark.parametrize(
"value", ["false", "False", "FALSE", "0", "no", "No", "NO"]
)
async def test_valid_false_values(self, value: str):
"""Test that all accepted falsy string values coerce to False."""
template = await self._make_template()
resource = await template.create_resource(
f"config://feature?enabled={value}",
{"name": "feature", "enabled": value},
)
result = await resource.read()
assert isinstance(result, dict)
assert result["enabled"] is False
@pytest.mark.parametrize("value", ["banana", "nope", "2", "truee", ""])
async def test_various_invalid_boolean_values(self, value: str):
"""Test that various invalid boolean strings raise ValueError."""
template = await self._make_template()
with pytest.raises(ValueError, match="Invalid boolean value for enabled"):
resource = await template.create_resource(
f"config://feature?enabled={value}",
{"name": "feature", "enabled": value},
)
await resource.read()
class TestResourceTemplateFieldDefaults:
"""Test resource templates with Field() defaults."""