fix(valkey): scope basedpyright ignores to the lib_name stub gap

The merge of main into this branch (b9e2b36f) made the basedpyright
budget gate's reportUnknownMemberType/reportUnknownVariableType
ceilings breach by 22: our 3 from_url(..., lib_name=VALKEY_LIB_NAME)
call sites don't match either types-redis 4.6 stub overload (neither
declares lib_name), so basedpyright can't resolve a sound return type
for the client, and every downstream member access and variable
inherits Unknown.

Add targeted # pyright: ignore[<rule>] comments on the exact affected
lines in litellm/caching/valkey_semantic_cache.py and
litellm/llms/valkey/vector_stores/transformation.py, matching the
existing stub-gap-ignore style already used for reportCallIssue and
reportUnknownArgumentType in these files (see 4e4ff11b). No behavior
change.
This commit is contained in:
Jonathan Neufeld 2026-10-08 09:33:42 -06:00
parent b9e2b36f07
commit 1feb1aa37d
No known key found for this signature in database
2 changed files with 17 additions and 17 deletions

View file

@ -175,26 +175,26 @@ class ValkeySemanticCache(RedisSemanticCache):
if self._index_dim == dim:
return
try:
self.sync_client.ft(self.index_name).create_index(
self.sync_client.ft(self.index_name).create_index( # pyright: ignore[reportUnknownMemberType] # the from_url(lib_name=...) overload mismatch leaves sync_client's type unknown; .ft/.create_index inherit that
self._index_schema(dim), definition=self._index_definition()
)
except Exception as exc:
if not self._is_index_exists_error(exc):
raise
self._assert_dim_matches(self.sync_client.ft(self.index_name).info(), dim)
self._assert_dim_matches(self.sync_client.ft(self.index_name).info(), dim) # pyright: ignore[reportUnknownMemberType] # the from_url(lib_name=...) overload mismatch leaves sync_client's type unknown; .ft/.info inherit that
self._index_dim = dim
async def _ensure_index_async(self, dim: int) -> None:
if self._index_dim == dim:
return
try:
await self.async_client.ft(self.index_name).create_index(
await self.async_client.ft(self.index_name).create_index( # pyright: ignore[reportUnknownMemberType] # the from_url(lib_name=...) overload mismatch leaves async_client's type unknown; .ft/.create_index inherit that
self._index_schema(dim), definition=self._index_definition()
)
except Exception as exc:
if not self._is_index_exists_error(exc):
raise
info: Final = await self.async_client.ft(self.index_name).info()
info: Final = await self.async_client.ft(self.index_name).info() # pyright: ignore[reportUnknownMemberType] # the from_url(lib_name=...) overload mismatch leaves async_client's type unknown; .ft/.info inherit that
self._assert_dim_matches(info, dim)
self._index_dim = dim
@ -221,7 +221,7 @@ class ValkeySemanticCache(RedisSemanticCache):
async def _async_search(self, key: str, embedding: Sequence[float]) -> object:
"""Run the KNN query on the async client, stopping the untyped search surface here."""
return await self.async_client.ft(self.index_name).search(
return await self.async_client.ft(self.index_name).search( # pyright: ignore[reportUnknownMemberType] # the from_url(lib_name=...) overload mismatch leaves async_client's type unknown; .ft/.search inherit that
self._knn_query(key),
query_params={"vec": self._embedding_to_bytes(embedding)}, # pyright: ignore[reportArgumentType] # redis stubs omit bytes; KNN vectors are raw bytes at runtime
)
@ -273,10 +273,10 @@ class ValkeySemanticCache(RedisSemanticCache):
self._ensure_index_sync(len(embedding))
doc_key: Final = self._doc_key(key)
self.sync_client.hset(doc_key, mapping=self._doc_mapping(key, prompt, str(value), embedding))
self.sync_client.hset(doc_key, mapping=self._doc_mapping(key, prompt, str(value), embedding)) # pyright: ignore[reportUnknownMemberType] # the from_url(lib_name=...) overload mismatch leaves sync_client's type unknown; .hset inherits that
ttl: Final = self._get_ttl(**kwargs)
if ttl is not None:
self.sync_client.expire(doc_key, ttl)
self.sync_client.expire(doc_key, ttl) # pyright: ignore[reportUnknownMemberType] # the from_url(lib_name=...) overload mismatch leaves sync_client's type unknown; .expire inherits that
except Exception as e:
print_verbose(f"Error in Valkey semantic-cache set_cache: {e}")
@ -291,7 +291,7 @@ class ValkeySemanticCache(RedisSemanticCache):
embedding: Final = self._get_embedding(prompt)
self._ensure_index_sync(len(embedding))
search_result: Final = self.sync_client.ft(self.index_name).search(
search_result: Final = self.sync_client.ft(self.index_name).search( # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType] # the from_url(lib_name=...) overload mismatch leaves sync_client's type unknown; .ft/.search and their result inherit that
self._knn_query(key),
query_params={"vec": self._embedding_to_bytes(embedding)}, # pyright: ignore[reportArgumentType] # redis stubs omit bytes; KNN vectors are raw bytes at runtime
)
@ -312,10 +312,10 @@ class ValkeySemanticCache(RedisSemanticCache):
await self._ensure_index_async(len(embedding))
doc_key: Final = self._doc_key(key)
await self.async_client.hset(doc_key, mapping=self._doc_mapping(key, prompt, str(value), embedding))
await self.async_client.hset(doc_key, mapping=self._doc_mapping(key, prompt, str(value), embedding)) # pyright: ignore[reportUnknownMemberType] # the from_url(lib_name=...) overload mismatch leaves async_client's type unknown; .hset inherits that
ttl: Final = self._get_ttl(**kwargs)
if ttl is not None:
await self.async_client.expire(doc_key, ttl)
await self.async_client.expire(doc_key, ttl) # pyright: ignore[reportUnknownMemberType] # the from_url(lib_name=...) overload mismatch leaves async_client's type unknown; .expire inherits that
except Exception as e:
print_verbose(f"Error in async Valkey semantic-cache set_cache: {e}")
@ -343,4 +343,4 @@ class ValkeySemanticCache(RedisSemanticCache):
print_verbose(f"Error in Valkey semantic-cache async_set_cache_pipeline: {e}")
async def _index_info(self) -> Mapping[str, object]:
return await self.async_client.ft(self.index_name).info()
return await self.async_client.ft(self.index_name).info() # pyright: ignore[reportUnknownMemberType] # the from_url(lib_name=...) overload mismatch leaves async_client's type unknown; .ft/.info inherit that

View file

@ -245,17 +245,17 @@ class ValkeyVectorStoreConfig(BaseDirectVectorStoreConfig):
return self._to_response(raw, query_text, params.text_field)
connect_timeout, op_timeout = self._socket_timeouts(timeout)
client: Final = _import_sync_redis().from_url( # pyright: ignore[reportCallIssue] # types-redis 4.6 stubs shadow redis 5.3.1 and omit from_url(lib_name=...); redis-py accepts it at runtime
client: Final = _import_sync_redis().from_url( # pyright: ignore[reportCallIssue, reportUnknownVariableType] # types-redis 4.6 stubs shadow redis 5.3.1 and omit from_url(lib_name=...); redis-py accepts it at runtime, but the overload mismatch leaves the return type unknown
params.connection_url(),
socket_connect_timeout=connect_timeout,
socket_timeout=op_timeout,
lib_name=VALKEY_LIB_NAME,
)
try:
raw_result: Final = client.ft(vector_store_id).search(knn, query_params=vec_params)
raw_result: Final = client.ft(vector_store_id).search(knn, query_params=vec_params) # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType] # client's type is unknown (see from_url above), so .ft/.search and their result inherit that
return self._to_response(raw_result, query_text, params.text_field) # pyright: ignore[reportUnknownArgumentType] # raw_result flows from the from_url client whose return type the types-redis 4.6 stubs leave unknown; the shape is validated inside _to_response
finally:
client.close()
client.close() # pyright: ignore[reportUnknownMemberType] # client's type is unknown (see from_url above)
async def aexecute_search_vector_store_request(
self,
@ -296,19 +296,19 @@ class ValkeyVectorStoreConfig(BaseDirectVectorStoreConfig):
return self._to_response(raw, query_text, params.text_field)
connect_timeout, op_timeout = self._socket_timeouts(timeout)
client: Final = _import_async_redis().from_url( # pyright: ignore[reportCallIssue] # types-redis 4.6 stubs shadow redis 5.3.1 and omit from_url(lib_name=...); redis-py accepts it at runtime
client: Final = _import_async_redis().from_url( # pyright: ignore[reportCallIssue, reportUnknownVariableType] # types-redis 4.6 stubs shadow redis 5.3.1 and omit from_url(lib_name=...); redis-py accepts it at runtime, but the overload mismatch leaves the return type unknown
params.connection_url(),
socket_connect_timeout=connect_timeout,
socket_timeout=op_timeout,
lib_name=VALKEY_LIB_NAME,
)
try:
raw_result: Final = await client.ft(vector_store_id).search( # pyright: ignore[reportGeneralTypeIssues] # types-redis 4.6 stubs shadow redis 5.3.1 and type the async client's ft() as the sync Search, so search() returns a non-awaitable Result; it is a coroutine at runtime
raw_result: Final = await client.ft(vector_store_id).search( # pyright: ignore[reportGeneralTypeIssues, reportUnknownMemberType, reportUnknownVariableType] # types-redis 4.6 stubs shadow redis 5.3.1 and type the async client's ft() as the sync Search, so search() returns a non-awaitable Result; it is a coroutine at runtime. client's type is unknown (see from_url above), so .ft/.search and their result inherit that
knn, query_params=vec_params
)
return self._to_response(raw_result, query_text, params.text_field) # pyright: ignore[reportUnknownArgumentType] # raw_result flows from the from_url client whose return type the types-redis 4.6 stubs leave unknown; the shape is validated inside _to_response
finally:
await client.aclose()
await client.aclose() # pyright: ignore[reportUnknownMemberType] # client's type is unknown (see from_url above)
def transform_create_vector_store_request(
self,