From c2b953e5f6bb0da05389e6c42c214d6bd8c504f2 Mon Sep 17 00:00:00 2001 From: derhornspieler <15236687+derhornspieler@users.noreply.github.com> Date: Tue, 25 Aug 2026 23:23:04 -0400 Subject: [PATCH] fix(tests): pass anthropic federation params as keywords, not dict splats Two test call sites splatted a plain dict of strings into a strongly typed callable. Because every parameter then looks like it might receive a str, basedpyright raised one error per parameter: 118 for the GenericLiteLLMParams construction and 30 for the completion call, 148 in a file that otherwise has 14. Passing the values as keywords types them properly and drops the file to those 14 pre-existing ones. The leak assertion that walked the old kwargs dict now walks a tuple of the same field names, so it still proves none of them reach the request body. HTTPHandler.get takes Mapping[str, Any] for headers rather than the Mapping[str, str] of the previous commit. The parameter was a bare dict, which accepts any value type, so narrowing it to str rejected existing callers that pass looser mappings and added six errors of its own. --- litellm/llms/custom_httpx/http_handler.py | 2 +- .../anthropic/test_anthropic_common_utils.py | 31 ++++++++++++------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/litellm/llms/custom_httpx/http_handler.py b/litellm/llms/custom_httpx/http_handler.py index 81b4b17fa1a..6e10bb539d2 100644 --- a/litellm/llms/custom_httpx/http_handler.py +++ b/litellm/llms/custom_httpx/http_handler.py @@ -1257,7 +1257,7 @@ class HTTPHandler: self, url: str, params: dict | None = None, - headers: Mapping[str, str] | None = None, + headers: Mapping[str, Any] | None = None, follow_redirects: bool | None = None, timeout: float | httpx.Timeout | None = None, ): diff --git a/tests/test_litellm/llms/anthropic/test_anthropic_common_utils.py b/tests/test_litellm/llms/anthropic/test_anthropic_common_utils.py index 6694eff4110..f1c1c46e1be 100644 --- a/tests/test_litellm/llms/anthropic/test_anthropic_common_utils.py +++ b/tests/test_litellm/llms/anthropic/test_anthropic_common_utils.py @@ -2664,7 +2664,11 @@ class TestWifLitellmParamsPlumbing: poster, _ = wif_engine headers = AnthropicSkillsConfig().validate_environment( headers={}, - litellm_params=GenericLiteLLMParams(**WIF_PARAMS_ONLY), + litellm_params=GenericLiteLLMParams( + anthropic_federation_rule_id=WIF_PARAMS_ONLY["anthropic_federation_rule_id"], + anthropic_organization_id=WIF_PARAMS_ONLY["anthropic_organization_id"], + anthropic_identity_token=WIF_PARAMS_ONLY["anthropic_identity_token"], + ), ) assert headers["authorization"] == f"Bearer {FAKE_MINTED_TOKEN}" @@ -2872,14 +2876,14 @@ class TestWifRespxEndToEnd: lambda litellm_params, api_base, model: get_anthropic_wif_token(litellm_params, api_base, model, engine), ) - wif_kwargs = { - "anthropic_federation_rule_id": "fdrl_e2e", - "anthropic_organization_id": "org-e2e", - "anthropic_service_account_id": "svcacct_e2e", - "anthropic_workspace_id": "wrkspc_e2e", - "anthropic_identity_token_file": str(token_file), - "anthropic_identity_token": "oidc/env/UNUSED_FALLBACK", - } + wif_kwarg_names: Final = ( + "anthropic_federation_rule_id", + "anthropic_organization_id", + "anthropic_service_account_id", + "anthropic_workspace_id", + "anthropic_identity_token_file", + "anthropic_identity_token", + ) anthropic_response = { "id": "msg_01", "type": "message", @@ -2903,7 +2907,12 @@ class TestWifRespxEndToEnd: response = litellm.completion( model="anthropic/claude-sonnet-4-5", messages=[{"role": "user", "content": "hi"}], - **wif_kwargs, + anthropic_federation_rule_id="fdrl_e2e", + anthropic_organization_id="org-e2e", + anthropic_service_account_id="svcacct_e2e", + anthropic_workspace_id="wrkspc_e2e", + anthropic_identity_token_file=str(token_file), + anthropic_identity_token="oidc/env/UNUSED_FALLBACK", ) assert response.choices[0].message.content == "Hello from WIF" @@ -2918,7 +2927,7 @@ class TestWifRespxEndToEnd: assert "x-api-key" not in data_request.headers assert "anthropic-dangerous-direct-browser-access" not in data_request.headers data_body = json.loads(data_request.content) - for key in wif_kwargs: + for key in wif_kwarg_names: assert key not in data_body def test_completion_with_trailing_slash_api_base_mints_at_clean_token_url(