From 8f854a35e7967f0a97ad39e5e5c609d2c1a3e761 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 13 Mar 2026 00:08:57 +0000 Subject: [PATCH] fix(mypy): fix scattered 1-off type errors across 14 files - utils.py: Add explicit return None at end of get_provider_chat_config - main.py: Add type: ignore for tools arg in token_counter call - __init__.py: Add type: ignore[no-redef] for get_model_info stub - vertex batch_embed: Annotate mode as Literal type, request_data as Dict - vertex llama3: Add type: ignore for finish_reason = None - types/utils.py: Add type: ignore for StreamingChoices finish_reason = None - anthropic/files: Cast headers to httpx.Headers for AnthropicError - key_management: Add None guard before model_dump() on object_permission - mcp_server/db.py: Add type: ignore for TypedDict dynamic key access - realtime_endpoints: Raise HTTPException instead of returning Response - completion_transformation: Annotate new_tcs as list - google_genai/main.py: Add type: ignore[valid-type] for TYPE_CHECKING classes - brave/search: Add type: ignore[import-untyped] for dateutil Co-authored-by: yuneng-jiang --- litellm/__init__.py | 2 +- litellm/llms/anthropic/files/transformation.py | 4 ++-- litellm/llms/brave/search/transformation.py | 2 +- .../gemini_embeddings/batch_embed_content_handler.py | 2 ++ .../vertex_ai_partner_models/llama3/transformation.py | 2 +- litellm/main.py | 2 +- litellm/proxy/_experimental/mcp_server/db.py | 6 +++--- .../proxy/management_endpoints/key_management_endpoints.py | 2 +- litellm/proxy/realtime_endpoints/endpoints.py | 5 ++--- .../litellm_completion_transformation/transformation.py | 2 +- litellm/types/google_genai/main.py | 6 +++--- litellm/types/utils.py | 2 +- litellm/utils.py | 2 ++ 13 files changed, 21 insertions(+), 18 deletions(-) diff --git a/litellm/__init__.py b/litellm/__init__.py index 8b3723cb2b0..dcd4ce29096 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -1897,7 +1897,7 @@ if TYPE_CHECKING: supports_reasoning: Callable[..., bool] acreate: Callable[..., Any] get_max_tokens: Callable[..., int] - get_model_info: Callable[..., _ModelInfoType] + get_model_info: Callable[..., _ModelInfoType] # type: ignore[no-redef] register_prompt_template: Callable[..., None] validate_environment: Callable[..., dict] check_valid_key: Callable[..., bool] diff --git a/litellm/llms/anthropic/files/transformation.py b/litellm/llms/anthropic/files/transformation.py index 8e7d9f07b54..0691742bb08 100644 --- a/litellm/llms/anthropic/files/transformation.py +++ b/litellm/llms/anthropic/files/transformation.py @@ -14,7 +14,7 @@ Anthropic Files API endpoints: import calendar import time -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Union, cast import httpx from openai.types.file_deleted import FileDeleted @@ -79,7 +79,7 @@ class AnthropicFilesConfig(BaseFilesConfig): return AnthropicError( status_code=status_code, message=error_message, - headers=headers, + headers=cast(httpx.Headers, headers) if isinstance(headers, dict) else headers, ) def validate_environment( diff --git a/litellm/llms/brave/search/transformation.py b/litellm/llms/brave/search/transformation.py index a73029b0409..9dfcd6bc75a 100644 --- a/litellm/llms/brave/search/transformation.py +++ b/litellm/llms/brave/search/transformation.py @@ -5,7 +5,7 @@ Documentation: https://api-dashboard.search.brave.com/app/documentation/web-sear from __future__ import annotations from datetime import datetime, timezone -from dateutil import parser +from dateutil import parser # type: ignore[import-untyped] from typing import Dict, List, Literal, Optional, TypedDict, Union import httpx import re diff --git a/litellm/llms/vertex_ai/gemini_embeddings/batch_embed_content_handler.py b/litellm/llms/vertex_ai/gemini_embeddings/batch_embed_content_handler.py index 3ec0bdf22a5..f003ba3fed7 100644 --- a/litellm/llms/vertex_ai/gemini_embeddings/batch_embed_content_handler.py +++ b/litellm/llms/vertex_ai/gemini_embeddings/batch_embed_content_handler.py @@ -153,6 +153,7 @@ class GoogleBatchEmbeddings(VertexLLM): is_multimodal = _is_multimodal_input(input) use_embed_content = is_multimodal or (custom_llm_provider == "vertex_ai") + mode: Literal["embedding", "batch_embedding"] if use_embed_content: mode = "embedding" else: @@ -200,6 +201,7 @@ class GoogleBatchEmbeddings(VertexLLM): ) ### TRANSFORMATION (sync path) ### + request_data: Dict[str, Any] if use_embed_content: resolved_files = {} if api_key: diff --git a/litellm/llms/vertex_ai/vertex_ai_partner_models/llama3/transformation.py b/litellm/llms/vertex_ai/vertex_ai_partner_models/llama3/transformation.py index b38b4535065..3031f159d87 100644 --- a/litellm/llms/vertex_ai/vertex_ai_partner_models/llama3/transformation.py +++ b/litellm/llms/vertex_ai/vertex_ai_partner_models/llama3/transformation.py @@ -190,7 +190,7 @@ class VertexAILlama3StreamingHandler(OpenAIChatCompletionStreamingHandler): ], ) # Modify current chunk to be the first chunk with role but no finish_reason - result.choices[0].finish_reason = None + result.choices[0].finish_reason = None # type: ignore[assignment] delta.role = "assistant" # Ensure content is empty string for first chunk, not None if delta.content is None: diff --git a/litellm/main.py b/litellm/main.py index f2ce894ba38..569a9133d2f 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -7700,7 +7700,7 @@ async def acount_tokens( local_count = litellm.token_counter( model=model, messages=fallback_messages, - tools=tools, + tools=tools, # type: ignore[arg-type] ) return TokenCountResponse( diff --git a/litellm/proxy/_experimental/mcp_server/db.py b/litellm/proxy/_experimental/mcp_server/db.py index 45ec1bcebdf..fbef33c32ed 100644 --- a/litellm/proxy/_experimental/mcp_server/db.py +++ b/litellm/proxy/_experimental/mcp_server/db.py @@ -142,9 +142,9 @@ def decrypt_credentials( "aws_session_token", ] for field in secret_fields: - value = credentials.get(field) - if value is not None: - credentials[field] = decrypt_value_helper( + value = credentials.get(field) # type: ignore[literal-required] + if value is not None and isinstance(value, str): + credentials[field] = decrypt_value_helper( # type: ignore[literal-required] value=value, key=field, exception_type="debug", diff --git a/litellm/proxy/management_endpoints/key_management_endpoints.py b/litellm/proxy/management_endpoints/key_management_endpoints.py index eb4bb7f8848..8a7478bb5bc 100644 --- a/litellm/proxy/management_endpoints/key_management_endpoints.py +++ b/litellm/proxy/management_endpoints/key_management_endpoints.py @@ -1778,7 +1778,7 @@ async def _validate_mcp_servers_for_key_update( ) object_permission_dict = ( data.object_permission.model_dump() - if hasattr(data.object_permission, "model_dump") + if data.object_permission is not None and hasattr(data.object_permission, "model_dump") else data.object_permission ) await validate_key_mcp_servers_against_team( diff --git a/litellm/proxy/realtime_endpoints/endpoints.py b/litellm/proxy/realtime_endpoints/endpoints.py index 0a91112298a..876ff330cc5 100644 --- a/litellm/proxy/realtime_endpoints/endpoints.py +++ b/litellm/proxy/realtime_endpoints/endpoints.py @@ -181,10 +181,9 @@ async def create_realtime_client_secret( upstream_resp.status_code, upstream_resp.text, ) - return Response( - content=upstream_resp.content, + raise HTTPException( status_code=upstream_resp.status_code, - media_type="application/json", + detail=upstream_resp.text, ) upstream_json: dict = upstream_resp.json() diff --git a/litellm/responses/litellm_completion_transformation/transformation.py b/litellm/responses/litellm_completion_transformation/transformation.py index 0310d758956..df24d51bf57 100644 --- a/litellm/responses/litellm_completion_transformation/transformation.py +++ b/litellm/responses/litellm_completion_transformation/transformation.py @@ -410,7 +410,7 @@ class LiteLLMCompletionResponsesConfig: else getattr(new_msg, "role", None) ) if new_role == "assistant": - new_tcs = ( + new_tcs: list = ( new_msg.get("tool_calls") if isinstance(new_msg, dict) else getattr(new_msg, "tool_calls", None) diff --git a/litellm/types/google_genai/main.py b/litellm/types/google_genai/main.py index 89781860d25..b2e1fb3d46b 100644 --- a/litellm/types/google_genai/main.py +++ b/litellm/types/google_genai/main.py @@ -19,11 +19,11 @@ if TYPE_CHECKING: GenerateContentRequestParametersDict = _genai_types._GenerateContentParametersDict ToolConfigDict = _genai_types.ToolConfigDict - class GenerateContentRequestDict(GenerateContentRequestParametersDict): # type: ignore[misc] + class GenerateContentRequestDict(GenerateContentRequestParametersDict): # type: ignore[misc, valid-type] generationConfig: Optional[Any] - tools: Optional[ToolConfigDict] # type: ignore[assignment] + tools: Optional[ToolConfigDict] # type: ignore[assignment, valid-type] - class GenerateContentResponse(GoogleGenAIGenerateContentResponse, BaseLiteLLMOpenAIResponseObject): # type: ignore[misc] + class GenerateContentResponse(GoogleGenAIGenerateContentResponse, BaseLiteLLMOpenAIResponseObject): # type: ignore[misc, valid-type] _hidden_params: dict = {} pass diff --git a/litellm/types/utils.py b/litellm/types/utils.py index de8e7074234..f9a4f1429b6 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -1663,7 +1663,7 @@ class StreamingChoices(OpenAIObject): if finish_reason: self.finish_reason = map_finish_reason(finish_reason) else: - self.finish_reason = None + self.finish_reason = None # type: ignore[assignment] self.index = index if delta is not None: if isinstance(delta, Delta): diff --git a/litellm/utils.py b/litellm/utils.py index ca878721197..b4ed37f9a78 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -8141,6 +8141,8 @@ class ProviderConfigManager: raise ValueError(f"Provider {provider.value} not found") return create_config_class(provider_config)() + return None + @staticmethod def get_provider_embedding_config( model: str,