@@ -44,6 +44,27 @@ def __getitem__(self, key: str) -> object:
4444 raise KeyError (key )
4545
4646
47+ class _BrokenNameMeta (type ):
48+ def __getattribute__ (cls , name : str ):
49+ if name == "__name__" :
50+ raise RuntimeError ("cannot read model name" )
51+ return super ().__getattribute__ (name )
52+
53+
54+ class _BrokenNameModel (metaclass = _BrokenNameMeta ):
55+ def __init__ (self , ** kwargs ):
56+ self .name = kwargs ["name" ]
57+ self .retries = kwargs .get ("retries" , 0 )
58+
59+
60+ class _BlankNameCallableModel :
61+ __name__ = " "
62+
63+ def __call__ (self , ** kwargs ):
64+ _ = kwargs
65+ raise RuntimeError ("call failed" )
66+
67+
4768def test_api_response_from_json_parses_model_data () -> None :
4869 response = APIResponse .from_json (
4970 {"name" : "job-1" , "retries" : 2 }, _SampleResponseModel
@@ -93,6 +114,14 @@ def test_api_response_from_json_wraps_non_hyperbrowser_errors() -> None:
93114 assert exc_info .value .original_error is not None
94115
95116
117+ def test_api_response_from_json_parses_model_when_name_lookup_fails () -> None :
118+ response = APIResponse .from_json ({"name" : "job-1" }, _BrokenNameModel )
119+
120+ assert isinstance (response .data , _BrokenNameModel )
121+ assert response .data .name == "job-1"
122+ assert response .status_code == 200
123+
124+
96125def test_api_response_from_json_wraps_unreadable_mapping_keys () -> None :
97126 with pytest .raises (
98127 HyperbrowserError ,
@@ -119,6 +148,17 @@ def test_api_response_from_json_wraps_unreadable_mapping_values() -> None:
119148 assert exc_info .value .original_error is not None
120149
121150
151+ def test_api_response_from_json_uses_default_name_for_blank_model_name () -> None :
152+ with pytest .raises (
153+ HyperbrowserError ,
154+ match = "Failed to parse response data for response model" ,
155+ ):
156+ APIResponse .from_json (
157+ {"name" : "job-1" },
158+ cast ("type[_SampleResponseModel]" , _BlankNameCallableModel ()),
159+ )
160+
161+
122162def test_api_response_from_json_preserves_hyperbrowser_errors () -> None :
123163 with pytest .raises (HyperbrowserError , match = "model validation failed" ) as exc_info :
124164 APIResponse .from_json ({}, _RaisesHyperbrowserModel )
0 commit comments