chore(lint): graduate 12 rules from the strict-gate ratchet

Zeroes the remaining violations for 12 rules so they can hard-fail
in the main ruff config instead of being budget-ratcheted, and drops
their strict-gate budgets to 0:

- B021: drop useless f-prefix on the Javelin docstring
- C404 / C419: dict()/any() around unnecessary list comprehension
- PLR0124: replace the 'value == value' NaN idiom (and the separate
  +/-inf exclusion) with math.isfinite in _validate_response_time
- SIM201: 'not X == "function"' -> 'X != "function"'
- SIM211: 'False if x is False else True' -> 'x is not False'
- SIM222: drop literal 'None or' before "success"
- UP036: remove the dead sys.version_info < (3, 8) branch (and the
  now-unused sys import) in the weights_biases TYPE_CHECKING block
- B018 x2: keep the deliberate property side-effect access but assign
  it ('_ = self.prompt_manager') as the rule requires
- PLR0206: the unusable '@property def api_version(self, api_version)'
  (a property getter cannot take extra args) becomes a @staticmethod
  matching its siblings get_api_base/get_api_key; it had no callers
- PLR1704: rename the loop variable (and the nested helper parameter)
  that shadowed abatch_completion_fastest_response's 'model' argument
- B004 x2: scoped noqa with rationale — both sites retrieve __call__
  to unwrap functors for iscoroutinefunction, which is a value use,
  not the callability test B004 assumes; the callable() autofix would
  break them

N999 intentionally stays on the ratchet (limit 1): it flags the
'litellm/proxy/lambda.py' filename, which needs a module rename.

Verified: full-tree 'ruff check litellm' green with the graduated
rules enforced; ruff-strict counts for all 12 rules are 0; budget
JSON regenerated in the gate script's json.dumps style.
This commit is contained in:
HUAHAODIA 2026-09-14 14:04:08 +08:00
parent 30f33a949b
commit 29cdcf4880
16 changed files with 44 additions and 48 deletions

View file

@ -379,7 +379,7 @@ class ArizePhoenixPromptManager(CustomPromptManagement):
"""Reload prompts from Arize Phoenix."""
if self.prompt_id:
self._prompt_manager = None # Reset to force reload
self.prompt_manager # This will trigger reload
_ = self.prompt_manager # access triggers lazy reload
def should_run_prompt_management(
self,

View file

@ -406,7 +406,7 @@ class BitBucketPromptManager(CustomPromptManagement):
"""Reload prompts from BitBucket."""
if self.prompt_id:
self._prompt_manager = None # Reset to force reload
self.prompt_manager # This will trigger reload
_ = self.prompt_manager # access triggers lazy reload
def should_run_prompt_management(
self,

View file

@ -4,18 +4,10 @@ imported_openAIResponse = True
try:
import io
import logging
import sys
from typing import Any, TypeVar
from typing import Any, Literal, Protocol, TypeVar
from wandb.sdk.data_types import trace_tree
if sys.version_info >= (3, 8):
from typing import Literal, Protocol
else:
from typing import Literal
from typing_extensions import Protocol
logger: Final = logging.getLogger(__name__)
K = TypeVar("K", bound=str)

View file

@ -36,7 +36,9 @@ class CoroutineChecker:
target = callback
if not inspect.isfunction(target) and not inspect.ismethod(target):
try:
call_attr: Final = getattr(target, "__call__", None)
# Value unwrap so iscoroutinefunction can see through functors;
# B004's callable() advice does not apply here.
call_attr: Final = getattr(target, "__call__", None) # noqa: B004
if call_attr is not None:
target = call_attr
except Exception:

View file

@ -1757,7 +1757,7 @@ def convert_to_anthropic_tool_invoke(
anthropic_tool_invoke: Final[list[AnthropicMessagesToolUseParam | dict[str, object]]] = []
for tool in tool_calls:
if not get_attribute_or_key(tool, "type") == "function":
if get_attribute_or_key(tool, "type") != "function":
continue
tool_id = cast(str, get_attribute_or_key(tool, "id"))

View file

@ -454,7 +454,7 @@ def token_counter(
params: Final = _MessageCountParams(model, custom_tokenizer)
num_tokens = _count_messages(params, new_messages, use_default_image_token_count, default_token_count)
if count_response_tokens is False:
includes_system_message: Final = any([message.get("role", None) == "system" for message in new_messages])
includes_system_message: Final = any(message.get("role", None) == "system" for message in new_messages)
num_tokens += _count_extra(params.count_function, tools, tool_choice, includes_system_message)
else:

View file

@ -144,10 +144,9 @@ class AzureFoundryModelInfo(BaseLLMModelInfo):
def get_api_key(api_key: str | None = None) -> str | None:
return api_key or litellm.api_key or get_secret_str("AZURE_AI_API_KEY")
@property
def api_version(self, api_version: str | None = None) -> str | None:
api_version = api_version or litellm.api_version or get_secret_str("AZURE_API_VERSION")
return api_version
@staticmethod
def get_api_version(api_version: str | None = None) -> str | None:
return api_version or litellm.api_version or get_secret_str("AZURE_API_VERSION")
def get_token_counter(self) -> BaseTokenCounter | None:
"""

View file

@ -44,7 +44,7 @@ class JavelinGuardrail(CustomGuardrail):
application: str | None = None,
**kwargs,
):
f"""
"""
Initialize the JavelinGuardrail class.
This calls: {api_base}/{api_version}/guardrail/{guardrail_name}/apply

View file

@ -15,7 +15,7 @@ def initialize_guardrail(litellm_params: "LitellmParams", guardrail: "Guardrail"
# We check the raw guardrail dict because LitellmParams normalizes None → False,
# making it impossible to distinguish "not set" from "explicitly false" via litellm_params.
_raw_default_on: Final = cast(dict[str, Any], guardrail).get("litellm_params", {}).get("default_on")
_default_on: Final = False if _raw_default_on is False else True
_default_on: Final = _raw_default_on is not False
_callback: Final = MCPEndUserPermissionGuardrail(
guardrail_name=guardrail.get("guardrail_name", ""),

View file

@ -115,9 +115,10 @@ async def run_team_metadata_validation(
"error": f"custom_team_metadata_validate is an Enterprise feature. {CommonProxyErrors.not_premium_user.value}"
},
)
if not (
inspect.iscoroutinefunction(validator) or inspect.iscoroutinefunction(getattr(validator, "__call__", None))
):
# Value unwrap so iscoroutinefunction can see through functors;
# B004's callable() advice does not apply here.
validator_call = getattr(validator, "__call__", None) # noqa: B004
if not (inspect.iscoroutinefunction(validator) or inspect.iscoroutinefunction(validator_call)):
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail={ # mutable-ok: HTTPException.detail has no immutable form

View file

@ -159,7 +159,7 @@ def _get_spend_logs_metadata(
requester_ip_address=None,
additional_usage_values=None,
applied_guardrails=None,
status=None or "success",
status="success",
error_information=None,
proxy_server_request=None,
batch_models=None,

View file

@ -4,6 +4,7 @@ import copy
import hashlib
import inspect
import json
import math
import os
import smtplib
import ssl
@ -6404,7 +6405,7 @@ class PrismaClient:
return None
try:
value: Final = float(response_time_ms)
return value if value == value and value not in (float("inf"), float("-inf")) else None
return value if math.isfinite(value) else None
except (ValueError, TypeError):
verbose_proxy_logger.warning("Invalid response_time_ms value: %s", response_time_ms)
return None

View file

@ -4108,16 +4108,16 @@ class Router:
models: Final = [m.strip() for m in model.split(",")]
async def _async_completion_no_exceptions(
model: str, messages: list[dict[str, str]], stream: bool, **kwargs: Any
model_name: str, messages: list[dict[str, str]], stream: bool, **kwargs: Any
) -> ModelResponse | CustomStreamWrapper | Exception:
"""
Wrapper around self.acompletion that catches exceptions and returns them as a result
"""
try:
result = await self.acompletion(model=model, messages=messages, stream=stream, **kwargs)
result = await self.acompletion(model=model_name, messages=messages, stream=stream, **kwargs)
return result
except asyncio.CancelledError:
verbose_router_logger.debug("Received 'task.cancel'. Cancelling call w/ model=%s.", model)
verbose_router_logger.debug("Received 'task.cancel'. Cancelling call w/ model=%s.", model_name)
raise
except Exception as e:
return e
@ -4144,9 +4144,9 @@ class Router:
except KeyError:
pass
for model in models:
for model_name in models:
task = asyncio.create_task(
_async_completion_no_exceptions(model=model, messages=messages, stream=stream, **kwargs)
_async_completion_no_exceptions(model_name=model_name, messages=messages, stream=stream, **kwargs)
)
pending_tasks.append(task)

View file

@ -6264,7 +6264,7 @@ def function_to_dict(input_function) -> dict:
"enum": param_enum,
}
parameters[param_name] = dict([(k, v) for k, v in param_dict.items() if isinstance(v, str)])
parameters[param_name] = {k: v for k, v in param_dict.items() if isinstance(v, str)}
# Check if the parameter has no default value (i.e., it's required)
if param.default == param.empty:

View file

@ -30,7 +30,7 @@
"limit": 11
},
"B004": {
"limit": 2
"limit": 0
},
"B006": {
"limit": 176
@ -45,13 +45,13 @@
"limit": 187
},
"B018": {
"limit": 2
"limit": 0
},
"B019": {
"limit": 1
},
"B021": {
"limit": 1
"limit": 0
},
"B026": {
"limit": 3
@ -63,7 +63,7 @@
"limit": 8
},
"C404": {
"limit": 1
"limit": 0
},
"C405": {
"limit": 19
@ -75,7 +75,7 @@
"limit": 4
},
"C419": {
"limit": 1
"limit": 0
},
"C901": {
"limit": 306
@ -138,13 +138,13 @@
"limit": 46
},
"PLR0124": {
"limit": 1
"limit": 0
},
"PLR0206": {
"limit": 1
"limit": 0
},
"PLR1704": {
"limit": 1
"limit": 0
},
"PLR1714": {
"limit": 253
@ -213,16 +213,16 @@
"limit": 6
},
"SIM201": {
"limit": 1
"limit": 0
},
"SIM210": {
"limit": 8
},
"SIM211": {
"limit": 1
"limit": 0
},
"SIM222": {
"limit": 1
"limit": 0
},
"SIM401": {
"limit": 11
@ -255,6 +255,6 @@
"limit": 2
},
"UP036": {
"limit": 1
"limit": 0
}
}

View file

@ -4,11 +4,12 @@ lint.ignore = ["F405", "E402", "F403"]
# That gives editors and `ruff check --fix` the diagnostic, which the gate script cannot.
lint.extend-select = [
"T20", "PGH004", "RUF008", "RUF009", "RUF100",
"B033", "FURB136", "FURB168", "FURB188", "I001", "PERF402", "PIE790", "PIE800", "PLC0208",
"PLR0402", "PLR1711", "PLR1730", "PLR2044", "PLW0133", "PYI030", "PYI041", "PYI064", "RET501",
"RUF010", "RUF022", "RUF023", "RUF051", "S113", "SIM114", "SIM118", "TC005", "UP006", "UP007",
"UP008",
"UP012", "UP018", "UP024", "UP032", "UP034", "UP035", "UP037", "UP045",
"B004", "B018", "B021", "B033", "FURB136", "FURB168", "FURB188", "I001", "PERF402", "PIE790",
"PIE800", "PLC0208", "PLR0124", "PLR0402", "PLR0206", "PLR1704", "PLR1711", "PLR1730", "PLR2044",
"PLW0133", "PYI030", "PYI041", "PYI064", "RET501", "RUF010", "RUF022", "RUF023", "RUF051", "S113",
"SIM114", "SIM118", "SIM201", "SIM211", "SIM222", "TC005", "UP006", "UP007", "UP008",
"UP012", "UP018", "UP024", "UP032", "UP034", "UP035", "UP036", "UP037", "UP045",
"C404", "C419",
]
# RUF100 (unused-noqa) only knows the rules enabled in THIS config, so it would strip
# `# noqa` directives that protect rules enforced elsewhere. List those codes as external