mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-07 08:26:10 +00:00
test: gate the test suite on F601, B023, B025 and F632
Four more ruff rules for code the test suite runs but never checks. F601 is the one that paid: the duplicate key it flagged in a get_form_data fixture was the mock reproducing the production bug fixed in the previous commit. B025 removed two unreachable handlers, one of them a pytest.skip shadowed by an earlier `pass`, so an upstream Vertex flake reported green having asserted nothing. F632 turned an `is ""` identity check, which passes only on CPython interning, into the `== ""` it meant. B023 fixed three closures over loop variables, all latent today but one iteration-order change away from checking the last case N times.
This commit is contained in:
parent
b573679384
commit
b7f8016002
9 changed files with 28 additions and 35 deletions
|
|
@ -36,6 +36,17 @@
|
|||
# `re.search`, so a `.` copied out of an error message is a wildcard and the block
|
||||
# accepts messages the author never meant to accept. Mark a real regex raw, wrap a
|
||||
# literal message in `re.escape`, and the pattern says which one it is
|
||||
# F601 the same key literal twice in one dict. Python keeps the last value, so the
|
||||
# first is dropped before the test ever runs, and a fixture that looks like it
|
||||
# covers two cases covers one
|
||||
# B023 a closure over a loop variable. Every closure sees the last iteration's value,
|
||||
# so a per-case callback built in a loop checks the last case N times. Bind the
|
||||
# value as a parameter instead
|
||||
# B025 an `except` for a type an earlier `except` already catches. The second handler
|
||||
# is unreachable, so the recovery or skip written there never happens
|
||||
# F632 `is` against a literal. It compares identity, so it passes only where CPython
|
||||
# happens to intern the value and stops meaning what it says the moment the
|
||||
# value is built at runtime
|
||||
#
|
||||
# No target-version here on purpose: it resolves from requires-python (>=3.10), so
|
||||
# 3.11-only builtins like BaseExceptionGroup are correctly flagged in a tree that
|
||||
|
|
@ -58,4 +69,8 @@ lint.select = [
|
|||
"PLR0133",
|
||||
"PLW0127",
|
||||
"RUF043",
|
||||
"F601",
|
||||
"B023",
|
||||
"B025",
|
||||
"F632",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ def get_bedrock_pricing(url, providers):
|
|||
else:
|
||||
# General logic for other providers
|
||||
section = soup.find(
|
||||
"h2", text=lambda t: t and provider.lower() in t.lower()
|
||||
"h2", text=lambda t, needle=provider.lower(): t and needle in t.lower()
|
||||
)
|
||||
if not section:
|
||||
pricing_data[provider] = "Provider section not found"
|
||||
|
|
|
|||
|
|
@ -66,11 +66,6 @@ def test_langsmith_logging_async():
|
|||
except Exception as e:
|
||||
pytest.fail(f"An exception occurred - {e}")
|
||||
|
||||
except litellm.Timeout as e:
|
||||
pass
|
||||
except Exception as e:
|
||||
pytest.fail(f"An exception occurred - {e}")
|
||||
|
||||
|
||||
async def make_async_calls(metadata=None, **completion_kwargs):
|
||||
total_tasks = 300
|
||||
|
|
|
|||
|
|
@ -4207,13 +4207,7 @@ def test_gemini_google_maps_tool_simple():
|
|||
)
|
||||
print(f"Response: {response.model_dump_json(indent=4)}")
|
||||
assert response.choices[0].message.content is not None
|
||||
except (litellm.RateLimitError, litellm.InternalServerError):
|
||||
# Transient Vertex-side failures (rate limiting, 500 INTERNAL from the
|
||||
# Google Maps grounding backend) are not LiteLLM bugs — don't fail CI.
|
||||
pass
|
||||
except litellm.InternalServerError:
|
||||
pytest.skip(
|
||||
"Google Maps Platform returned a transient 500 (upstream flake); skipping."
|
||||
)
|
||||
except (litellm.RateLimitError, litellm.InternalServerError) as e:
|
||||
pytest.skip(f"Transient Vertex-side failure, not a LiteLLM bug: {e}")
|
||||
except Exception as e:
|
||||
pytest.fail(f"Error occurred: {e}")
|
||||
|
|
|
|||
|
|
@ -148,7 +148,6 @@ def test_spend_logs_payload(model_id: Optional[str]):
|
|||
"completion_start_time": datetime.datetime(2024, 6, 7, 12, 43, 30, 954146),
|
||||
"max_tokens": 10,
|
||||
"extra_body": {},
|
||||
"custom_llm_provider": "azure",
|
||||
"input": [
|
||||
{"role": "system", "content": "you are a helpful assistant.\n"},
|
||||
{"role": "user", "content": "bom dia"},
|
||||
|
|
|
|||
|
|
@ -3327,16 +3327,17 @@ async def test_team_access_groups(prisma_client):
|
|||
|
||||
request._url = URL(url="/chat/completions")
|
||||
|
||||
def body_reader(requested_model: str):
|
||||
async def return_body() -> bytes:
|
||||
return f'{{"model": "{requested_model}"}}'.encode()
|
||||
|
||||
return return_body
|
||||
|
||||
for model in ["gpt-4o", "gemini-pro-vision"]:
|
||||
# Expect these to pass
|
||||
async def return_body():
|
||||
return_string = f'{{"model": "{model}"}}'
|
||||
# return string as bytes
|
||||
return return_string.encode()
|
||||
|
||||
request = Request(scope={"type": "http"})
|
||||
request._url = URL(url="/chat/completions")
|
||||
request.body = return_body
|
||||
request.body = body_reader(model)
|
||||
|
||||
# use generated key to auth in
|
||||
print(
|
||||
|
|
@ -3346,14 +3347,9 @@ async def test_team_access_groups(prisma_client):
|
|||
|
||||
for model in ["gpt-4", "gpt-4o-mini", "gemini-experimental"]:
|
||||
# Expect these to fail
|
||||
async def return_body_2():
|
||||
return_string = f'{{"model": "{model}"}}'
|
||||
# return string as bytes
|
||||
return return_string.encode()
|
||||
|
||||
request = Request(scope={"type": "http"})
|
||||
request._url = URL(url="/chat/completions")
|
||||
request.body = return_body_2
|
||||
request.body = body_reader(model)
|
||||
|
||||
# use generated key to auth in
|
||||
print(
|
||||
|
|
|
|||
|
|
@ -480,7 +480,7 @@ class TestOllamaTextCompletionResponseIterator:
|
|||
assert isinstance(result, ModelResponseStream)
|
||||
assert result.choices and result.choices[0].delta is not None
|
||||
assert result.choices[0].delta.content == None
|
||||
assert getattr(result.choices[0].delta, "reasoning_content", None) is ""
|
||||
assert getattr(result.choices[0].delta, "reasoning_content", None) == ""
|
||||
|
||||
def test_chunk_parser_done_chunk(self):
|
||||
"""Test that done chunks work correctly."""
|
||||
|
|
|
|||
|
|
@ -129,11 +129,7 @@ class TestGenerateIAMToken:
|
|||
mock_client.reset_mock()
|
||||
mock_cache.reset_mock()
|
||||
|
||||
# Configure mock to return values based on env_keys
|
||||
def get_secret_side_effect(key):
|
||||
return env_keys.get(key)
|
||||
|
||||
mock_get_secret_str.side_effect = get_secret_side_effect
|
||||
mock_get_secret_str.side_effect = env_keys.get
|
||||
|
||||
mock_response = MagicMock()
|
||||
mock_response.json.return_value = {
|
||||
|
|
|
|||
|
|
@ -864,7 +864,6 @@ def test_aaamodel_prices_and_context_window_json_is_valid():
|
|||
"input_cost_per_character_above_128k_tokens": {"type": "number"},
|
||||
"input_cost_per_image": {"type": "number"},
|
||||
"input_cost_per_image_above_128k_tokens": {"type": "number"},
|
||||
"input_cost_per_image_token": {"type": "number"},
|
||||
"input_cost_per_video_token": {"type": "number"},
|
||||
"input_cost_per_token_above_200k_tokens": {"type": "number"},
|
||||
"input_cost_per_token_above_256k_tokens": {"type": "number"},
|
||||
|
|
@ -1008,7 +1007,6 @@ def test_aaamodel_prices_and_context_window_json_is_valid():
|
|||
},
|
||||
"bedrock_converse_supports_strict_tools": {"type": "boolean"},
|
||||
"tpm": {"type": "number"},
|
||||
"provider_specific_entry": {"type": "object"},
|
||||
"supported_endpoints": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue