Skip to content

Commit 6e0a270

Browse files
fix: replace shared mutable connection_kwargs defaults with None sentinels (#700)
## Summary All five extension constructors declare `connection_kwargs: dict[str, Any] = {}` (ruff B006). Python evaluates defaults once at import, so a single dict object is shared by every cache/history instance created without explicit kwargs — a latent cross-instance state-leak hazard for anything that mutates or stores it: - `extensions/cache/base.py` (`BaseCache`) - `extensions/cache/embeddings/embeddings.py` - `extensions/cache/llm/semantic.py` - `extensions/message_history/message_history.py` - `extensions/message_history/semantic_history.py` Each becomes `dict[str, Any] | None = None` with `connection_kwargs = connection_kwargs or {}` as the first statement after the docstring, so every existing caller — including ones passing `None` or `{}` explicitly — behaves identically. Also included: `type(top_k) != int` → `type(top_k) is not int` in `message_history.py` (E721; identity is the intended semantics, and this preserves the exact-type check that rejects `bool`). ## Testing `python -m py_compile` passes on all five files; `ruff check --select B006,E721` on the touched files goes clean. Scoped deliberately to the extension constructors — other B006 instances elsewhere in the repo are left for a follow-up if maintainers want them. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Constructor default and type-check cleanup only; behavior for existing callers is unchanged. No auth, data-path, or Redis protocol changes. > > **Overview** > Stops cache and message-history constructors from sharing one default `connection_kwargs` dict (B006). `BaseCache`, `EmbeddingsCache`, `SemanticCache`, `MessageHistory`, and `SemanticMessageHistory` now take `None` and assign `connection_kwargs = connection_kwargs or {}` so each instance gets its own dict. > > Also switches `MessageHistory.get_recent` from `type(top_k) != int` to `type(top_k) is not int` (E721), keeping the exact-type check that rejects `bool`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit b6039d8. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Signed-off-by: Harshad Khetpal <harshadkhetpal@users.noreply.github.com> Co-authored-by: Harshad Khetpal <harshadkhetpal@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent cb9acf9 commit 6e0a270

5 files changed

Lines changed: 11 additions & 6 deletions

File tree

redisvl/extensions/cache/base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def __init__(
3131
redis_client: SyncRedisClient | None = None,
3232
async_redis_client: AsyncRedisClient | None = None,
3333
redis_url: str = "redis://localhost:6379",
34-
connection_kwargs: dict[str, Any] = {},
34+
connection_kwargs: dict[str, Any] | None = None,
3535
):
3636
"""Initialize a base cache.
3737
@@ -45,6 +45,7 @@ def __init__(
4545
connection_kwargs (Dict[str, Any]): The connection arguments
4646
for the redis client. Defaults to empty {}.
4747
"""
48+
connection_kwargs = connection_kwargs or {}
4849
self.name = name
4950
self._ttl: int | None = None
5051
self.set_ttl(ttl)

redisvl/extensions/cache/embeddings/embeddings.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def __init__(
2323
redis_client: SyncRedisClient | None = None,
2424
async_redis_client: AsyncRedisClient | None = None,
2525
redis_url: str = "redis://localhost:6379",
26-
connection_kwargs: dict[str, Any] = {},
26+
connection_kwargs: dict[str, Any] | None = None,
2727
):
2828
"""Initialize an embeddings cache.
2929
@@ -45,6 +45,7 @@ def __init__(
4545
redis_url="redis://localhost:6379"
4646
)
4747
"""
48+
connection_kwargs = connection_kwargs or {}
4849
super().__init__(
4950
name=name,
5051
ttl=ttl,

redisvl/extensions/cache/llm/semantic.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def __init__(
6767
filterable_fields: list[dict[str, Any]] | None = None,
6868
redis_client: Redis | None = None,
6969
redis_url: str = "redis://localhost:6379",
70-
connection_kwargs: dict[str, Any] = {},
70+
connection_kwargs: dict[str, Any] | None = None,
7171
overwrite: bool = False,
7272
create_index: bool = True,
7373
**kwargs,
@@ -127,6 +127,7 @@ def __init__(
127127
create_index=False,
128128
)
129129
"""
130+
connection_kwargs = connection_kwargs or {}
130131
if not create_index and overwrite:
131132
raise ValueError(CREATE_INDEX_OVERWRITE_CONFLICT)
132133

redisvl/extensions/message_history/message_history.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(
3232
prefix: str | None = None,
3333
redis_client: Redis | None = None,
3434
redis_url: str = "redis://localhost:6379",
35-
connection_kwargs: dict[str, Any] = {},
35+
connection_kwargs: dict[str, Any] | None = None,
3636
create_index: bool = True,
3737
**kwargs,
3838
):
@@ -66,6 +66,7 @@ def __init__(
6666
Defaults to True.
6767
6868
"""
69+
connection_kwargs = connection_kwargs or {}
6970
super().__init__(name, session_tag)
7071

7172
prefix = prefix or name
@@ -182,7 +183,7 @@ def get_recent(
182183
ValueError: if top_k is not an integer greater than or equal to 0,
183184
or if role contains invalid values.
184185
"""
185-
if type(top_k) != int or top_k < 0:
186+
if type(top_k) is not int or top_k < 0:
186187
raise ValueError("top_k must be an integer greater than or equal to 0")
187188

188189
# Validate and normalize role parameter

redisvl/extensions/message_history/semantic_history.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def __init__(
4141
distance_threshold: float = 0.3,
4242
redis_client: Redis | None = None,
4343
redis_url: str = "redis://localhost:6379",
44-
connection_kwargs: dict[str, Any] = {},
44+
connection_kwargs: dict[str, Any] | None = None,
4545
overwrite: bool = False,
4646
create_index: bool = True,
4747
**kwargs,
@@ -84,6 +84,7 @@ def __init__(
8484
The proposed schema will support a single vector embedding constructed
8585
from either the prompt or response in a single string.
8686
"""
87+
connection_kwargs = connection_kwargs or {}
8788
if not create_index and overwrite:
8889
raise ValueError(CREATE_INDEX_OVERWRITE_CONFLICT)
8990

0 commit comments

Comments
 (0)