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",
     [

Reply via email to