From 20a685fe7f133d668877e67757c4a83862717977 Mon Sep 17 00:00:00 2001 From: Ryan Crabbe Date: Sat, 21 Feb 2026 13:10:49 -0800 Subject: [PATCH 1/4] fix: make cached OpenAI init params immutable and fix import ordering - Move `import inspect` to stdlib import group - Change _OPENAI_INIT_PARAMS and _AZURE_OPENAI_INIT_PARAMS from mutable lists to immutable tuples to prevent accidental mutation - Update return type and helper to use Tuple[str, ...] --- litellm/llms/openai/common_utils.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/litellm/llms/openai/common_utils.py b/litellm/llms/openai/common_utils.py index 868d02ee1e..df9c78cdcc 100644 --- a/litellm/llms/openai/common_utils.py +++ b/litellm/llms/openai/common_utils.py @@ -3,9 +3,10 @@ Common helpers / utils across al OpenAI endpoints """ import hashlib +import inspect import json import ssl -from typing import Any, Dict, List, Literal, Optional, TYPE_CHECKING, Union +from typing import Any, Dict, List, Literal, Optional, Tuple, TYPE_CHECKING, Union import httpx import openai @@ -14,8 +15,6 @@ from openai import AsyncAzureOpenAI, AsyncOpenAI, AzureOpenAI, OpenAI if TYPE_CHECKING: from aiohttp import ClientSession -import inspect - import litellm from litellm.llms.base_llm.chat.transformation import BaseLLMException from litellm.llms.custom_httpx.http_handler import ( @@ -24,13 +23,13 @@ from litellm.llms.custom_httpx.http_handler import ( get_ssl_configuration, ) -def _get_client_init_params(cls: type) -> List[str]: +def _get_client_init_params(cls: type) -> Tuple[str, ...]: """Extract __init__ parameter names (excluding 'self') from a class.""" - return [p for p in inspect.signature(cls.__init__).parameters if p != "self"] + return tuple(p for p in inspect.signature(cls.__init__).parameters if p != "self") -_OPENAI_INIT_PARAMS: List[str] = _get_client_init_params(OpenAI) -_AZURE_OPENAI_INIT_PARAMS: List[str] = _get_client_init_params(AzureOpenAI) +_OPENAI_INIT_PARAMS: Tuple[str, ...] = _get_client_init_params(OpenAI) +_AZURE_OPENAI_INIT_PARAMS: Tuple[str, ...] = _get_client_init_params(AzureOpenAI) class OpenAIError(BaseLLMException): @@ -191,8 +190,8 @@ class BaseOpenAILLM: @staticmethod def get_openai_client_initialization_param_fields( client_type: Literal["openai", "azure"] - ) -> List[str]: - """Returns a list of fields that are used to initialize the OpenAI client""" + ) -> Tuple[str, ...]: + """Returns a tuple of fields that are used to initialize the OpenAI client""" if client_type == "openai": return _OPENAI_INIT_PARAMS else: From bbbec23c8bdbd8aba139c405256ceabbe55bd72d Mon Sep 17 00:00:00 2001 From: Ryan Crabbe Date: Sat, 21 Feb 2026 13:18:03 -0800 Subject: [PATCH 2/4] fix: update tests to match tuple return type for cached init params --- .../llms/openai/test_openai_common_utils.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_litellm/llms/openai/test_openai_common_utils.py b/tests/test_litellm/llms/openai/test_openai_common_utils.py index f2740be642..d0dedd3ed9 100644 --- a/tests/test_litellm/llms/openai/test_openai_common_utils.py +++ b/tests/test_litellm/llms/openai/test_openai_common_utils.py @@ -146,12 +146,12 @@ def test_precomputed_init_params_match_inspect_signature(): _OPENAI_INIT_PARAMS, ) - expected_openai = [ + expected_openai = tuple( p for p in inspect.signature(OpenAI.__init__).parameters if p != "self" - ] - expected_azure = [ + ) + expected_azure = tuple( p for p in inspect.signature(AzureOpenAI.__init__).parameters if p != "self" - ] + ) assert _OPENAI_INIT_PARAMS == expected_openai assert _AZURE_OPENAI_INIT_PARAMS == expected_azure @@ -161,6 +161,6 @@ def test_precomputed_init_params_match_inspect_signature(): def test_get_openai_client_initialization_param_fields(client_type): """Verify the method returns the correct pre-computed params for each client type.""" result = BaseOpenAILLM.get_openai_client_initialization_param_fields(client_type) - assert isinstance(result, list) + assert isinstance(result, tuple) assert len(result) > 0 assert "self" not in result From 9e1d83e3de5d94addd25e03e12afda2bbeffd2b5 Mon Sep 17 00:00:00 2001 From: Ryan Crabbe Date: Sat, 21 Feb 2026 13:25:23 -0800 Subject: [PATCH 3/4] fix: make LITELLM_CLIENT_SPECIFIC_PARAMS a tuple to prevent TypeError tuple + list raises TypeError in get_openai_client_cache_key. Also add test coverage for get_openai_client_cache_key to catch type mismatches. --- litellm/llms/openai/common_utils.py | 4 ++-- .../llms/openai/test_openai_common_utils.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/litellm/llms/openai/common_utils.py b/litellm/llms/openai/common_utils.py index a89f7f9c2b..a05482c800 100644 --- a/litellm/llms/openai/common_utils.py +++ b/litellm/llms/openai/common_utils.py @@ -168,12 +168,12 @@ class BaseOpenAILLM: f"is_async={client_initialization_params.get('is_async')}", ] - LITELLM_CLIENT_SPECIFIC_PARAMS = [ + LITELLM_CLIENT_SPECIFIC_PARAMS = ( "timeout", "max_retries", "organization", "api_base", - ] + ) openai_client_fields = ( BaseOpenAILLM.get_openai_client_initialization_param_fields( client_type=client_type diff --git a/tests/test_litellm/llms/openai/test_openai_common_utils.py b/tests/test_litellm/llms/openai/test_openai_common_utils.py index d0dedd3ed9..8489040660 100644 --- a/tests/test_litellm/llms/openai/test_openai_common_utils.py +++ b/tests/test_litellm/llms/openai/test_openai_common_utils.py @@ -164,3 +164,14 @@ def test_get_openai_client_initialization_param_fields(client_type): assert isinstance(result, tuple) assert len(result) > 0 assert "self" not in result + + +@pytest.mark.parametrize("client_type", ["openai", "azure"]) +def test_get_openai_client_cache_key(client_type): + """Verify get_openai_client_cache_key doesn't raise on tuple + tuple concatenation.""" + key = BaseOpenAILLM.get_openai_client_cache_key( + client_initialization_params={"api_key": "sk-test"}, + client_type=client_type, + ) + assert isinstance(key, str) + assert "api_key=sk-test" in key From dcbac4a4af480268e6bb5b9cd38b6408c3e87a14 Mon Sep 17 00:00:00 2001 From: Ryan Crabbe Date: Sat, 21 Feb 2026 13:31:19 -0800 Subject: [PATCH 4/4] style: add missing PEP 8 blank line before top-level function --- litellm/llms/openai/common_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/litellm/llms/openai/common_utils.py b/litellm/llms/openai/common_utils.py index a05482c800..28de9f1303 100644 --- a/litellm/llms/openai/common_utils.py +++ b/litellm/llms/openai/common_utils.py @@ -23,6 +23,7 @@ from litellm.llms.custom_httpx.http_handler import ( get_ssl_configuration, ) + def _get_client_init_params(cls: type) -> Tuple[str, ...]: """Extract __init__ parameter names (excluding 'self') from a class.""" return tuple(p for p in inspect.signature(cls.__init__).parameters if p != "self") # type: ignore[misc]