This is an automated email from the ASF dual-hosted git repository.
skrawcz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/burr.git
The following commit(s) were added to refs/heads/main by this push:
new 1a92593f fix(pydantic): improve error message for untyped state
parameter
1a92593f is described below
commit 1a92593f938abeb82bd7b004230bc49e3c99d71c
Author: majiayu000 <[email protected]>
AuthorDate: Tue Dec 30 14:30:06 2025 +0800
fix(pydantic): improve error message for untyped state parameter
When a pydantic_action function has a 'state' parameter without type
annotation, raise a clear ValueError explaining that the parameter must
be annotated with a pydantic.BaseModel subclass, instead of a cryptic
KeyError.
Closes #385
Signed-off-by: majiayu000 <[email protected]>
---
burr/integrations/pydantic.py | 11 +++++++----
tests/integrations/test_burr_pydantic.py | 12 ++++++++++++
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/burr/integrations/pydantic.py b/burr/integrations/pydantic.py
index 5354537a..dd1f95a5 100644
--- a/burr/integrations/pydantic.py
+++ b/burr/integrations/pydantic.py
@@ -129,14 +129,17 @@ def _validate_and_extract_signature_types(
"action must be the state object. Got signature: {sig}."
)
type_hints = typing.get_type_hints(fn)
+ state_model = type_hints.get("state")
- if (state_model := type_hints["state"]) is inspect.Parameter.empty or not
issubclass(
- state_model, pydantic.BaseModel
+ if (
+ state_model is None
+ or state_model is inspect.Parameter.empty
+ or not issubclass(state_model, pydantic.BaseModel)
):
raise ValueError(
f"Function fn: {fn.__qualname__} is not a valid pydantic action. "
- "a type annotation of a type extending: pydantic.BaseModel. Got
parameter "
- "state: {state_model.__qualname__}."
+ "The 'state' parameter must be annotated with a type extending
pydantic.BaseModel. "
+ f"Got: {state_model}."
)
if (ret_hint := type_hints.get("return")) is None or not issubclass(
ret_hint, pydantic.BaseModel
diff --git a/tests/integrations/test_burr_pydantic.py
b/tests/integrations/test_burr_pydantic.py
index 6c25520f..8fbb94c0 100644
--- a/tests/integrations/test_burr_pydantic.py
+++ b/tests/integrations/test_burr_pydantic.py
@@ -185,6 +185,10 @@ def _fn_with_no_return_type(state: OriginalModel):
...
+def _fn_with_untyped_state_arg(state) -> OriginalModel:
+ ...
+
+
def _fn_correct_same_itype_otype(state: OriginalModel, input_1: int) ->
OriginalModel:
...
@@ -200,6 +204,7 @@ def _fn_correct_diff_itype_otype(state: OriginalModel,
input_1: int) -> NestedMo
(_fn_with_incorrect_state_arg, ValueError),
(_fn_with_incorrect_return_type, ValueError),
(_fn_with_no_return_type, ValueError),
+ (_fn_with_untyped_state_arg, ValueError),
],
)
def test__validate_and_extract_signature_types_error(fn, expected_exception):
@@ -207,6 +212,13 @@ def test__validate_and_extract_signature_types_error(fn,
expected_exception):
_validate_and_extract_signature_types(fn)
+def test__validate_and_extract_signature_types_untyped_state_error_message():
+ """Test that the error message is informative when state is not
type-annotated."""
+ with pytest.raises(ValueError) as excinfo:
+ _validate_and_extract_signature_types(_fn_with_untyped_state_arg)
+ assert "'state' parameter must be annotated" in str(excinfo.value)
+
+
@pytest.mark.parametrize(
"fn,expected",
[