mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
fix(vector_stores): stop sharing one list across default-constructed registries
VectorStoreIndexRegistry and VectorStoreRegistry took a mutable list as their default argument. Python evaluates that once at class definition, so every registry built without arguments shared one list. The proxy builds one that way during startup, so an upsert into it leaked into every registry created after, and into the class default itself. Default to None and build a fresh list per instance. A caller-supplied list is still used as given, including an empty one, so nothing that passes its own list changes behaviour. Fixes #38874
This commit is contained in:
parent
98d46ee59d
commit
2851271f34
2 changed files with 45 additions and 5 deletions
|
|
@ -32,8 +32,10 @@ else:
|
|||
|
||||
|
||||
class VectorStoreIndexRegistry:
|
||||
def __init__(self, vector_store_indexes: list[LiteLLM_ManagedVectorStoreIndex] = []):
|
||||
self.vector_store_indexes: list[LiteLLM_ManagedVectorStoreIndex] = vector_store_indexes
|
||||
def __init__(self, vector_store_indexes: list[LiteLLM_ManagedVectorStoreIndex] | None = None):
|
||||
self.vector_store_indexes: list[LiteLLM_ManagedVectorStoreIndex] = (
|
||||
vector_store_indexes if vector_store_indexes is not None else []
|
||||
)
|
||||
|
||||
def get_vector_store_indexes(self) -> list[LiteLLM_ManagedVectorStoreIndex]:
|
||||
"""
|
||||
|
|
@ -101,8 +103,8 @@ class VectorStoreIndexRegistry:
|
|||
|
||||
|
||||
class VectorStoreRegistry:
|
||||
def __init__(self, vector_stores: list[LiteLLM_ManagedVectorStore] = []):
|
||||
self.vector_stores: list[LiteLLM_ManagedVectorStore] = vector_stores
|
||||
def __init__(self, vector_stores: list[LiteLLM_ManagedVectorStore] | None = None):
|
||||
self.vector_stores: list[LiteLLM_ManagedVectorStore] = vector_stores if vector_stores is not None else []
|
||||
self.vector_store_ids_to_vector_store_map: dict[str, LiteLLM_ManagedVectorStore] = {}
|
||||
|
||||
def _extract_tool_params(self, tool: dict) -> VectorStoreToolParams:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@ from unittest.mock import MagicMock
|
|||
import litellm
|
||||
from litellm.types.vector_stores import LiteLLM_ManagedVectorStore
|
||||
from litellm.vector_stores.main import search
|
||||
from litellm.vector_stores.vector_store_registry import VectorStoreRegistry
|
||||
from litellm.vector_stores.vector_store_registry import (
|
||||
VectorStoreIndexRegistry,
|
||||
VectorStoreRegistry,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
|
@ -182,3 +185,38 @@ def test_search_uses_registry_credentials():
|
|||
assert getattr(called_params, "aws_region_name") == "us-east-1"
|
||||
finally:
|
||||
litellm.vector_store_registry = original_registry
|
||||
|
||||
|
||||
class TestRegistriesDoNotShareDefaultState:
|
||||
"""#38874: a mutable default argument made every default-constructed registry share
|
||||
one list, so upserting into one polluted every other instance and the class default."""
|
||||
|
||||
def test_vector_store_registries_do_not_share_a_list(self):
|
||||
first = VectorStoreRegistry()
|
||||
second = VectorStoreRegistry()
|
||||
assert first.vector_stores is not second.vector_stores
|
||||
|
||||
def test_index_registries_do_not_share_a_list(self):
|
||||
first = VectorStoreIndexRegistry()
|
||||
second = VectorStoreIndexRegistry()
|
||||
assert first.vector_store_indexes is not second.vector_store_indexes
|
||||
|
||||
def test_mutating_one_registry_leaves_the_next_one_empty(self):
|
||||
first = VectorStoreRegistry()
|
||||
first.vector_stores.append(
|
||||
LiteLLM_ManagedVectorStore(vector_store_id="vs-leak", custom_llm_provider="bedrock")
|
||||
)
|
||||
assert VectorStoreRegistry().vector_stores == []
|
||||
|
||||
def test_mutating_one_index_registry_leaves_the_next_one_empty(self):
|
||||
first = VectorStoreIndexRegistry()
|
||||
first.vector_store_indexes.append({"index_name": "leak"})
|
||||
assert VectorStoreIndexRegistry().get_vector_store_indexes() == []
|
||||
|
||||
def test_a_supplied_list_is_still_used_as_given(self):
|
||||
supplied = [LiteLLM_ManagedVectorStore(vector_store_id="vs-1", custom_llm_provider="bedrock")]
|
||||
assert VectorStoreRegistry(vector_stores=supplied).vector_stores is supplied
|
||||
|
||||
def test_a_supplied_empty_list_is_still_used_as_given(self):
|
||||
supplied: list = []
|
||||
assert VectorStoreRegistry(vector_stores=supplied).vector_stores is supplied
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue