mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-01 07:03:02 +00:00
* chore(caching)!: remove the disk cache backend Drop the disk cache type and its diskcache dependency, along with the caching install extra that existed only to pull it in. diskcache has not had a release since August 2023 Cache now raises a ValueError listing the supported types when it gets a type it does not know. Before, an unknown type built a Cache with no backend, which only failed on first use BREAKING CHANGE: cache_params type "disk" and the litellm[caching] extra are gone. A proxy configured with type disk now refuses to start. Use local or redis instead * test(proxy): expect the unsupported cache type error from _init_cache The test pinned the old fallthrough, where an unknown type left the cache without a backend and the proxy hit an AttributeError reading it * chore(deps): drop the diskcache scan ignore main extended diskcache is no longer in the lock, so the ignore matches nothing * fix(caching): ignore a leftover disk_cache_dir instead of crashing redis and s3 Dropping the disk_cache_dir parameter sent the key into **kwargs, which the redis and s3 branches hand to their clients, so a config that moved from the disk cache to redis or s3 and kept the key failed with a TypeError. Accept the key again, ignore it, and log a warning The unsupported type test now checks the whole supported list, and two proxy docstrings no longer name disk as a cache backend * fix(caching): warn about a leftover disk_cache_dir only once the cache is built The warning ran before the type check, so a config with type disk logged that the key was ignored and then failed on the type anyway. It now logs only after a supported backend is built. The test also checks that a cache without the key logs nothing
464 lines
17 KiB
TOML
464 lines
17 KiB
TOML
[project]
|
|
name = "litellm"
|
|
version = "1.109.0"
|
|
description = "Library to easily interface with LLM API providers"
|
|
readme = "README.md"
|
|
requires-python = ">=3.10, <3.16"
|
|
license = "MIT"
|
|
license-files = ["LICENSE"]
|
|
authors = [
|
|
{ name = "BerriAI" },
|
|
]
|
|
dependencies = [
|
|
# Ranges (not exact pins) so SDK consumers can coexist with their other
|
|
# deps. Reproducibility for our Docker/CI comes from `uv.lock`.
|
|
# When changing a floor, verify it installs + imports on every supported
|
|
# Python with: `uv pip install --resolution=lowest-direct .`
|
|
"fastuuid>=0.14.0,<1.0; python_version < '3.15'",
|
|
"filelock>=3.16.1,<4.0",
|
|
"httpx[http2]>=0.28.0,<1.0",
|
|
"openai>=2.20.0,<4.0.0",
|
|
"python-dotenv>=1.0.0,<2.0",
|
|
"pyyaml>=6.0.3,<7.0",
|
|
"packaging>=24.0",
|
|
"importlib-metadata>=8.0.0,<9.0",
|
|
"tiktoken>=0.8.0,<1.0; python_version < '3.14'",
|
|
"tiktoken>=0.12.0,<1.0; python_version == '3.14'",
|
|
"tiktoken>=0.14.0,<1.0; python_version >= '3.15'",
|
|
"tokenizers>=0.21.0,<1.0",
|
|
"huggingface-hub>=0.34.0,<2.0",
|
|
"click>=8.0.0,<9.0",
|
|
"jinja2>=3.1.6,<4.0",
|
|
"aiohttp>=3.14.2,<4.0",
|
|
"anyio>=4.14.0,<5.0",
|
|
"async-timeout>=4.0.3,<6.0; python_version < '3.11'",
|
|
"pydantic>=2.11.0,<3.0.0; python_version < '3.14'",
|
|
"pydantic>=2.12.0,<3.0.0; python_version == '3.14'",
|
|
"pydantic>=2.14.0,<3.0.0; python_version >= '3.15'",
|
|
"pydantic-settings>=2.14.1,<3.0",
|
|
"jsonschema>=4.0.0,<5.0",
|
|
"boto3>=1.43.117,<2.0",
|
|
"certifi>=2026.10.19",
|
|
"typing-extensions>=4.13.0,<5.0",
|
|
]
|
|
|
|
[project.urls]
|
|
Homepage = "https://litellm.ai"
|
|
Repository = "https://github.com/BerriAI/litellm"
|
|
Documentation = "https://docs.litellm.ai"
|
|
|
|
# Optional extras use compatible ranges (like the core SDK above) so downstream
|
|
# consumers can coexist with other packages and pick up security patches without
|
|
# forking. Reproducibility for our Docker/CI comes from `uv.lock` (images install
|
|
# via `uv sync --frozen`). A few deps stay exact-pinned: litellm's own
|
|
# sub-packages and the opentelemetry trio move in lockstep, and grpcio is
|
|
# supply-chain-pinned to a vetted, aged release.
|
|
[project.optional-dependencies]
|
|
proxy = [
|
|
"gunicorn>=23.0.0,<24.0",
|
|
"uvicorn>=0.33.0,<1.0",
|
|
"granian>=2.7.4,<3.0; python_version < '3.15'",
|
|
"granian>=2.8.0,<3.0; python_version >= '3.15'",
|
|
"uvloop>=0.22.1,<1.0; sys_platform != 'win32'",
|
|
"fastapi>=0.136.3,<1.0",
|
|
"starlette>=1.0.1,<2.0",
|
|
"backoff>=2.2.1,<3.0",
|
|
"pyyaml>=6.0.3,<7.0",
|
|
"rq>=2.7.0,<3.0",
|
|
"orjson>=3.11.6,<4.0; python_version < '3.15'",
|
|
"orjson>=3.12.0,<4.0; python_version >= '3.15'",
|
|
# redis-py's C response parser. It arrives with redis (via rq) either way; naming
|
|
# it here is what makes redis-py select _HiredisParser instead of the Python one.
|
|
"hiredis>=3.0.0,<4.0; python_version < '3.15'",
|
|
"hiredis>=3.5.0,<4.0; python_version >= '3.15'",
|
|
"apscheduler>=3.11.2,<4.0",
|
|
"fastapi-sso>=0.19.0,<1.0",
|
|
"PyJWT>=2.13.0,<3.0",
|
|
"python-multipart>=0.0.27,<1.0",
|
|
"cryptography>=49.0.0,<51.0",
|
|
"pynacl>=1.6.2,<2.0",
|
|
"websockets>=15.0.1,<16.0",
|
|
"boto3>=1.43.117,<2.0",
|
|
"azure-identity>=1.25.2,<2.0",
|
|
"azure-storage-blob>=12.28.0,<13.0",
|
|
"mcp>=2.3.0,<3",
|
|
"httpx2>=2.10.0,<3",
|
|
"pydantic>=2.12.0,<3",
|
|
"litellm-proxy-extras==0.4.112",
|
|
"litellm-enterprise==0.1.81",
|
|
"RestrictedPython>=8.5,<9.0",
|
|
"rich>=13.9.4,<14.0",
|
|
"InquirerPy>=0.3.4,<1.0",
|
|
"tomlkit>=0.13.3,<1.0",
|
|
"polars>=1.38.1,<2.0",
|
|
"soundfile>=0.12.1,<1.0",
|
|
"pyroscope-io>=0.8.16,<1.0; sys_platform != 'win32'",
|
|
"expression>=5.6.0,<6.0",
|
|
"backports-zstd>=1.0.0,<2.0; python_version < '3.14'",
|
|
]
|
|
# Thin client install for the `lite` CLI on developer laptops. The CLI's heavy
|
|
# imports are all guarded, so it runs on the base SDK plus these packages, and
|
|
# none of the server runtime in `proxy` is pulled in. On Linux,
|
|
# keyring reaches the Secret Service through secretstorage, which brings
|
|
# cryptography with it.
|
|
cli = [
|
|
"rich>=13.9.4,<14.0",
|
|
"pyyaml>=6.0.3,<7.0",
|
|
"requests>=2.32.0,<3.0",
|
|
"InquirerPy>=0.3.4,<1.0",
|
|
"keyring>=25.6.0,<26.0",
|
|
"tomlkit>=0.13.3,<1.0",
|
|
]
|
|
extra_proxy = [
|
|
"prisma>=0.11.0,<1.0",
|
|
# Used by ProxyExtrasDBManager.spend_logs_is_partitioned() to detect a
|
|
# partitioned LiteLLM_SpendLogs and keep schema reconciliation from
|
|
# fighting its composite primary key.
|
|
"psycopg>=3.2,<4.0",
|
|
"psycopg-binary>=3.2,<4.0",
|
|
"azure-identity>=1.25.2,<2.0",
|
|
"azure-keyvault-secrets>=4.10.0,<5.0",
|
|
# Not in PyPI proxy extra.
|
|
"google-cloud-kms>=2.24.2,<3.0",
|
|
"google-cloud-iam>=2.19.1,<3.0",
|
|
# Not in PyPI proxy extra.
|
|
"resend>=2.23.0,<3.0",
|
|
"redisvl>=0.4.1,<1.0",
|
|
"a2a-sdk>=1.1.0,<2.0",
|
|
]
|
|
utils = [
|
|
# Not in Docker or PyPI proxy extra.
|
|
"numpydoc>=1.8.0,<2.0",
|
|
]
|
|
mcp = ["mcp>=2.3.0,<3", "httpx2>=2.10.0,<3", "pydantic>=2.12.0,<3"]
|
|
# Driver for the MongoDB Atlas vector store; Atlas Vector Search has no HTTP query API.
|
|
# The floor is 4.9 because that is the release AsyncMongoClient landed in.
|
|
# SAML SSO for the admin UI. python3-saml pulls in xmlsec/lxml, whose wheels
|
|
# bundle the native libxmlsec1/libxml2 libraries, so no system packages are
|
|
# required. Kept out of the base `proxy` extra so it stays optional.
|
|
saml = ["python3-saml>=1.16.0,<2.0"]
|
|
semantic-router = [
|
|
"semantic-router>=0.1.15,<1.0; python_version < '3.14'",
|
|
"aurelio-sdk>=0.0.19,<1.0; python_version < '3.14'",
|
|
]
|
|
mlflow = ["mlflow>=3.17.2,<4.0"]
|
|
grpc = [
|
|
# First release whose bundled roots.pem drops the compromised eMudhra roots, ahead of the 30-day cutoff
|
|
"grpcio==1.84.1",
|
|
]
|
|
stt-vertex-chirp = [
|
|
# Google Cloud Speech-to-Text v2 streaming (gRPC) for Chirp models on
|
|
# /v1/realtime. Imported lazily inside the backend so litellm core stays
|
|
# usable without it.
|
|
"google-cloud-speech>=2.40.0,<3.0",
|
|
]
|
|
stt-nvidia-riva = [
|
|
# NVIDIA Riva STT provider (gRPC). These are imported lazily inside the
|
|
# provider handler so litellm core remains usable without them.
|
|
"nvidia-riva-client>=2.15.0",
|
|
"soundfile>=0.12.1",
|
|
"audioread>=3.0.1",
|
|
"numpy>=1.26.0",
|
|
]
|
|
google = ["google-cloud-aiplatform>=1.133.0,<2.0"]
|
|
bedrock-realtime = [
|
|
# Bedrock Nova Sonic realtime (speech-to-speech) uses the
|
|
# InvokeModelWithBidirectionalStream API, which boto3 cannot do. This
|
|
# experimental AWS SDK (with its smithy-* deps, pulled transitively)
|
|
# provides the bidirectional stream; imported lazily in the realtime
|
|
# handler so litellm core stays usable without it. The awscrt extra is
|
|
# required: the SDK's default aiohttp transport has no duplex streaming.
|
|
"aws-sdk-bedrock-runtime[awscrt]>=0.10.0,<0.12.0; python_version >= '3.12'",
|
|
]
|
|
proxy-runtime = [
|
|
# Historically bundled in the proxy Docker images via requirements.txt.
|
|
# Keep these in a dedicated extra so uv-based images preserve the same
|
|
# feature surface without forcing the base SDK install to grow.
|
|
"google-cloud-aiplatform>=1.133.0,<2.0",
|
|
"google-cloud-speech>=2.40.0,<3.0",
|
|
"google-genai>=1.37.0,<2.0",
|
|
"anthropic[vertex]>=0.84.0,<1.0",
|
|
"grpcio==1.84.1",
|
|
"prometheus-client>=0.20.0,<1.0",
|
|
"langfuse>=4.7,<5.0",
|
|
"opentelemetry-api==1.45.1",
|
|
"opentelemetry-sdk==1.45.1",
|
|
"opentelemetry-exporter-otlp==1.45.1",
|
|
"opentelemetry-instrumentation-fastapi==0.66b1",
|
|
"ddtrace>=4.8.2,<5.0",
|
|
"sentry-sdk>=2.21.0,<3.0",
|
|
"mangum>=0.17.0,<1.0",
|
|
"azure-ai-contentsafety>=1.0.0,<2.0",
|
|
"azure-storage-file-datalake>=12.20.0,<13.0",
|
|
"pypdf>=6.21.2,<7.0",
|
|
"llm-sandbox>=0.3.39,<1.0",
|
|
"detect-secrets>=1.5.0,<2.0",
|
|
]
|
|
|
|
[project.scripts]
|
|
litellm = "litellm_cli.main:proxy_server"
|
|
lite = "litellm_cli.main:cli"
|
|
litellm-proxy = "litellm_cli.main:litellm_proxy_cli"
|
|
|
|
[dependency-groups]
|
|
dev = [
|
|
"numpy>=1.26.0,<3.0",
|
|
"diff-cover==9.7.2",
|
|
"hypothesis==6.165.10",
|
|
"reportlab==5.0.1",
|
|
"basedpyright==1.39.7",
|
|
"mypy==1.20.1",
|
|
"keyring==25.7.0",
|
|
"pytest==9.0.3",
|
|
"pytest-socket==0.8.1",
|
|
"tomli==2.4.1; python_version < '3.11'",
|
|
"pytest-mock==3.15.1",
|
|
"pytest-asyncio==1.3.0",
|
|
"psycopg==3.3.6",
|
|
"psycopg-binary==3.3.6",
|
|
"pytest-xdist==3.8.0",
|
|
"requests-mock==1.12.1",
|
|
"responses==0.26.0",
|
|
"respx==0.22.0",
|
|
"ruff==0.15.3",
|
|
"types-requests==2.32.4.20260107",
|
|
"types-setuptools==75.8.0.20250225",
|
|
"types-redis==4.6.0.20241004",
|
|
"types-PyYAML==6.0.12.20250915",
|
|
"botocore-stubs==1.43.14",
|
|
"types-boto3[bedrock,bedrock-agent,bedrock-runtime,kms,s3,sagemaker-runtime,sts]==1.43.30",
|
|
"opentelemetry-api==1.45.1",
|
|
"opentelemetry-sdk==1.45.1",
|
|
"opentelemetry-exporter-otlp==1.45.1",
|
|
"opentelemetry-instrumentation-fastapi==0.66b1",
|
|
"langfuse>=4.7,<5.0",
|
|
"fastapi-offline==1.7.6",
|
|
"fakeredis==2.34.1",
|
|
"pytest-rerunfailures==15.1",
|
|
"pytest-cov==5.0.0",
|
|
"parameterized==0.9.0",
|
|
"openapi-core==0.22.0",
|
|
"pytest-timeout==2.4.0",
|
|
"vcrpy==8.2.1",
|
|
"pytest-recording==0.13.4",
|
|
]
|
|
e2e-dev = [
|
|
"playwright==1.61.0",
|
|
"websockets>=15.0.1,<16.0",
|
|
"locust==2.45.0",
|
|
"anthropic==0.84.0",
|
|
"psutil==7.2.2",
|
|
"mcp>=2.3.0,<3",
|
|
]
|
|
admin-mcp = [
|
|
"litellm-admin-mcp @ https://github.com/BerriAI/liteadmin-mcp/archive/d35ec9c19c117d4c50cc1eccf6ce1296aac25a1a.tar.gz#sha256=86b930f6706fb2da10d53d1798ee7fd14e44fb0afdef0da122cf0e6bb88fa2c3 ; python_version >= '3.12'",
|
|
]
|
|
proxy-dev = [
|
|
{ include-group = "admin-mcp" },
|
|
"prisma==0.11.0",
|
|
"hypercorn==0.17.3",
|
|
"prometheus-client==0.20.0",
|
|
"sentry-sdk==2.21.0",
|
|
"opentelemetry-api==1.45.1",
|
|
"opentelemetry-sdk==1.45.1",
|
|
"opentelemetry-exporter-otlp==1.45.1",
|
|
"opentelemetry-instrumentation-fastapi==0.66b1",
|
|
"azure-identity==1.25.2",
|
|
"a2a-sdk==1.1.0",
|
|
"backports-zstd==1.8.0; python_version < '3.14'",
|
|
]
|
|
ci = [
|
|
"psutil==7.2.2",
|
|
# These are lazily imported at call sites; keep them out of core deps to
|
|
# avoid bloating the base SDK install (google-generativeai pulls grpcio +
|
|
# protobuf, Pillow is a compiled C extension).
|
|
"tenacity==8.5.0",
|
|
"google-generativeai==0.8.6",
|
|
"Pillow==12.3.0; python_version == '3.10'",
|
|
"Pillow==13.0.0; python_version >= '3.11'",
|
|
# Azure batch E2E tests still import psycopg2 directly.
|
|
"psycopg2-binary==2.9.11",
|
|
"pytest-codspeed==4.3.0",
|
|
"pytest-retry==1.7.0",
|
|
"pyarrow==23.0.1",
|
|
"langchain==1.3.9",
|
|
"lunary==1.4.36; python_version == '3.10'",
|
|
"lunary==1.4.37; python_version >= '3.11'",
|
|
"logfire==5.2.0",
|
|
"traceloop-sdk==0.34.0",
|
|
"detect-secrets==1.5.0",
|
|
"PyGithub==2.8.1",
|
|
"aiodynamo==24.7",
|
|
"argon2-cffi==25.1.0",
|
|
"assemblyai==0.52.4",
|
|
"jsonlines==4.0.0",
|
|
"anthropic==0.84.0",
|
|
"blockbuster==1.5.26",
|
|
"beautifulsoup4==4.14.3",
|
|
"pylint==4.0.9",
|
|
"langchain-openai==1.1.14",
|
|
"langgraph>=1.2.4,<1.3.0",
|
|
"langgraph-prebuilt>=1.1.0,<1.3.0",
|
|
"claude-agent-sdk==0.2.165",
|
|
"google-cloud-speech==2.40.0",
|
|
]
|
|
healthcheck = [
|
|
"httpx==0.28.1",
|
|
"pyyaml==6.0.3",
|
|
]
|
|
benchmarks = [
|
|
"pytest==9.0.3",
|
|
"pytest-codspeed==4.3.0",
|
|
"mcp>=2.3.0,<3",
|
|
"a2a-sdk==1.1.0",
|
|
]
|
|
|
|
[build-system]
|
|
requires = ["maturin==1.15.0"]
|
|
build-backend = "maturin"
|
|
|
|
[tool.maturin]
|
|
manifest-path = "litellm-rust/crates/python-bridge/Cargo.toml"
|
|
module-name = "litellm.rust_bridge._native"
|
|
python-source = "."
|
|
python-packages = ["litellm_cli"]
|
|
bindings = "pyo3"
|
|
features = ["extension-module"]
|
|
profile = "release"
|
|
editable-profile = "dev"
|
|
include = [
|
|
"litellm/proxy/_experimental/out/**",
|
|
"litellm/router_strategy/complexity_router/artifacts/*.json",
|
|
"litellm/router_strategy/complexity_router/fuse_presets.json",
|
|
"litellm/proxy/model_insights_tasks.json",
|
|
"litellm/proxy/public_endpoints/whats_new.json",
|
|
"litellm/proxy/common_utils/codex_base_instructions.md",
|
|
"litellm/proxy/common_utils/codex_bundled_models_0.159.3.json",
|
|
{ path = "model_prices_and_context_window.json", format = "sdist" },
|
|
]
|
|
exclude = [
|
|
"litellm/proxy/enterprise",
|
|
"litellm/proxy/enterprise/**",
|
|
"litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/guardrail_benchmarks",
|
|
"litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/guardrail_benchmarks/**",
|
|
"**/__pycache__",
|
|
"**/__pycache__/**",
|
|
"**/.pytest_cache",
|
|
"**/.pytest_cache/**",
|
|
"**/.ruff_cache",
|
|
"**/.ruff_cache/**",
|
|
]
|
|
|
|
[tool.uv]
|
|
cache-keys = [
|
|
{ file = "pyproject.toml" },
|
|
{ file = "rust-toolchain.toml" },
|
|
{ file = ".cargo/config.toml" },
|
|
{ file = "litellm-rust/Cargo.lock" },
|
|
{ file = "litellm-rust/Cargo.toml" },
|
|
{ file = "litellm-rust/crates/**/*" },
|
|
{ file = "model_prices_and_context_window.json" },
|
|
]
|
|
constraint-dependencies = [
|
|
"tornado>=6.5.8",
|
|
"tornado>=6.6; python_version >= '3.11'",
|
|
"aiohttp>=3.14.2,<4.0",
|
|
"packaging>=24.0",
|
|
"soupsieve>=2.8.4",
|
|
"httplib2>=0.32.0",
|
|
"setuptools>=84.1.0",
|
|
"dnspython>=2.9.0; python_version >= '3.11'",
|
|
]
|
|
override-dependencies = [
|
|
# a2a-sdk 1.x requires packaging>=24.0; lunary 1.4.x still caps at <24.0.
|
|
"packaging>=24.0",
|
|
"cryptography>=50.0.0,<51.0",
|
|
"mcp>=2.3.0,<3",
|
|
]
|
|
default-groups = ["dev"]
|
|
required-version = ">=0.10.9"
|
|
exclude-newer = "3 days"
|
|
|
|
[tool.uv.exclude-newer-package]
|
|
# TODO: remove after 2026-10-25, once brotli 1.2.1 (CVE-2026-111497) clears the 3-day window
|
|
brotli = "2026-10-22T14:01:00Z"
|
|
|
|
[tool.uv.sources]
|
|
litellm-proxy-extras = { workspace = true }
|
|
litellm-enterprise = { workspace = true }
|
|
|
|
[tool.uv.workspace]
|
|
members = ["enterprise", "litellm-proxy-extras"]
|
|
|
|
[tool.commitizen]
|
|
version = "1.109.0"
|
|
version_files = [
|
|
"pyproject.toml:^version",
|
|
]
|
|
|
|
[tool.pytest.ini_options]
|
|
pythonpath = ["scripts"]
|
|
asyncio_mode = "auto"
|
|
asyncio_default_fixture_loop_scope = "session"
|
|
markers = [
|
|
"asyncio: mark test as an asyncio test",
|
|
"limit_leaks: mark test with memory limit for leak detection (e.g., '40 MB')",
|
|
"no_parallel: mark test to run sequentially (not in parallel) - typically for memory measurement tests",
|
|
"requires_rust_extension: public Python contract tests that run against the release-built wheel",
|
|
]
|
|
filterwarnings = [
|
|
# Suppress Pydantic serializer warnings from mock server responses (non-critical for memory tests)
|
|
# These occur because the mock server returns a simplified response format
|
|
"ignore:Pydantic serializer warnings:UserWarning",
|
|
"ignore::UserWarning:pydantic.main",
|
|
# Suppress pytest-asyncio event loop deprecation warning (handled automatically by pytest-asyncio)
|
|
"ignore::DeprecationWarning:pytest_asyncio.plugin",
|
|
]
|
|
|
|
[tool.mutmut]
|
|
# Mutation-testing scope. Driven by the manually-triggered workflow at
|
|
# .github/workflows/mutation-test.yml. mutmut is not part of the project's
|
|
# default install; it is pulled in via `uv run --with mutmut==<version>` in CI.
|
|
# `also_copy = ["litellm/"]` is required because mutmut runs in a `mutants/`
|
|
# sandbox and the test conftest imports from across the litellm package.
|
|
paths_to_mutate = [
|
|
"litellm/proxy/management_endpoints/",
|
|
]
|
|
# Only the unit tier that maps to paths_to_mutate. mutmut times and
|
|
# coverage-maps this whole set once before mutating, so a tier that needs a
|
|
# seeded database (tests/proxy_behavior/) kills the run before it starts, and
|
|
# a mutation score is only meaningful against the tests that claim to cover
|
|
# the mutated code anyway.
|
|
tests_dir = [
|
|
"tests/unit/proxy/management_endpoints/",
|
|
]
|
|
also_copy = [
|
|
"litellm/",
|
|
]
|
|
# Run the test suite once before mutation to gather line coverage, then skip
|
|
# mutating lines no test exercises. Those mutants would survive regardless
|
|
# (no test hits the line to kill them), so generating them wastes hours of CI.
|
|
# The score now reads as "mutation score over covered code" — pair with a
|
|
# line-coverage number when reporting.
|
|
mutate_only_covered_lines = true
|
|
# Disable rerun/parallel plugins for mutation runs:
|
|
# - pytest-retry triggers an `INTERNALERROR: no option named 'filtered_exceptions'`
|
|
# when invoked via mutmut's in-process `pytest.main()` call.
|
|
# - rerunning a "failed" test on a mutant would mask which mutants are killed
|
|
# vs. survive, so reruns are wrong for mutation testing regardless.
|
|
# - xdist is unnecessary inside mutmut (mutmut handles its own parallelism).
|
|
# test_saml_sso.py cannot run inside mutmut's mutants/ sandbox: the copied tree
|
|
# re-imports cryptography's hash classes under a second identity, so x509 .sign()
|
|
# rejects the SHA256 instance the fixture builds with "Algorithm must be a
|
|
# registered hash algorithm". Nothing to do with mutation coverage, and one
|
|
# erroring test is enough to end the stats phase before any mutant runs.
|
|
pytest_add_cli_args = [
|
|
"-p", "no:pytest-retry",
|
|
"-p", "no:rerunfailures",
|
|
"-p", "no:xdist",
|
|
"--ignore=tests/unit/proxy/management_endpoints/test_saml_sso.py",
|
|
]
|
|
|
|
[tool.coverage.run]
|
|
source = ["litellm"]
|
|
relative_files = true
|