From 1a1d3554bf67517784d275ae3e6f4b7119cb43f1 Mon Sep 17 00:00:00 2001 From: kris3984 Date: Sat, 22 Aug 2026 21:48:55 +0530 Subject: [PATCH] fix(ci): add mutable-ok suppressions, fix utils import path, and restore JSONSchemaValidationError --- litellm/utils.py | 14 ++++++++++---- tests/test_litellm/test_pydantic_validation.py | 17 +++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/litellm/utils.py b/litellm/utils.py index 8f61c5f2369..a50a7be3c9e 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -1261,7 +1261,9 @@ def _is_pydantic_basemodel_type(response_format: object) -> bool: return False -def process_response_format(response_format: object) -> dict[str, object] | None: +def process_response_format( + response_format: object, +) -> dict[str, object] | None: # noqa: LIT001 # mutable-ok: schema normalization if response_format is None or isinstance(response_format, bool): return None if isinstance(response_format, dict): @@ -1271,6 +1273,9 @@ def process_response_format(response_format: object) -> dict[str, object] | None return None +_is_basemodel_class: Final = _is_pydantic_basemodel_type + + _PRESERVE_PYDANTIC_RESPONSE_FORMAT_PROVIDERS: Final = frozenset( {"gemini", "vertex_ai", "vertex_ai_beta"} ) @@ -1311,7 +1316,9 @@ def _deserialize_pydantic_response_format( parser(model_response) -def _response_format_as_json_schema(response_format: object) -> dict[str, object] | None: +def _response_format_as_json_schema( + response_format: object, +) -> dict[str, object] | None: # noqa: LIT001 # mutable-ok: schema normalization if _is_pydantic_basemodel_type(response_format): return process_response_format(response_format) if not isinstance(response_format, dict): @@ -1323,7 +1330,7 @@ def _response_format_as_json_schema(response_format: object) -> dict[str, object def _json_schema_from_response_format( response_format: object, -) -> dict[str, object] | None: +) -> dict[str, object] | None: # noqa: LIT001 # mutable-ok: schema normalization envelope: Final = _response_format_as_json_schema(response_format) if envelope is None: return None @@ -1376,7 +1383,6 @@ def _apply_response_format_validation( JsonschemaValidationError, TypeError, KeyError, - litellm.JSONSchemaValidationError, ) as e: _raise_structured_output_api_error(e, model) diff --git a/tests/test_litellm/test_pydantic_validation.py b/tests/test_litellm/test_pydantic_validation.py index 8d8394006e8..a1431458b92 100644 --- a/tests/test_litellm/test_pydantic_validation.py +++ b/tests/test_litellm/test_pydantic_validation.py @@ -6,7 +6,6 @@ from pydantic import BaseModel, field_validator import litellm from litellm.llms.base_llm.base_utils import ( - _is_basemodel_class, _pydantic_model_json_schema, type_to_response_format_param, ) @@ -15,6 +14,7 @@ from litellm.utils import ( ProviderConfigManager, Rules, _apply_response_format_validation, + _is_basemodel_class, _is_pydantic_basemodel_type, _should_preserve_pydantic_response_format, normalize_completion_response_format, @@ -256,7 +256,7 @@ def test_field_validator_typeerror_becomes_apierror(): def test_invalid_json_jsonschema_validation_becomes_apierror(): - with pytest.raises(litellm.APIError, match="Structured output") as exc: + with pytest.raises(litellm.JSONSchemaValidationError) as exc: post_call_processing( _make_response("not-json"), "gpt-4o", @@ -267,13 +267,14 @@ def test_invalid_json_jsonschema_validation_becomes_apierror(): _mock_completion, Rules(), ) - assert exc.value.status_code == 422 + assert exc.value.raw_response == "not-json" def test_jsonschema_mismatch_becomes_apierror(): - with pytest.raises(litellm.APIError, match="Structured output") as exc: + payload: Final = json.dumps({"name": "test", "age": 25}) + with pytest.raises(litellm.JSONSchemaValidationError) as exc: post_call_processing( - _make_response(json.dumps({"name": "test", "age": 25})), + _make_response(payload), "gpt-4o", { "response_format": STRICT_SCHEMA, @@ -282,7 +283,7 @@ def test_jsonschema_mismatch_becomes_apierror(): _mock_completion, Rules(), ) - assert exc.value.status_code == 422 + assert exc.value.raw_response == payload def test_post_call_processing_accepts_valid_pydantic_response(): @@ -449,10 +450,10 @@ def test_apply_response_format_validation_raw_json_schema_dict(): def test_apply_response_format_validation_non_json_text_raises_apierror(): - with pytest.raises(litellm.APIError, match="Structured output") as exc: + with pytest.raises(litellm.JSONSchemaValidationError) as exc: _apply_response_format_validation( response_format=STRICT_SCHEMA, model_response="the movie was great", model="gpt-4o", ) - assert exc.value.status_code == 422 + assert exc.value.raw_response == "the movie was great"