Skip to content

Commit 906f75f

Browse files
cursoragentszokeasaurusrex
authored andcommitted
fix(langchain): Make span_map an instance variable
1 parent 0e21fa2 commit 906f75f

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

sentry_sdk/integrations/langchain.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,9 @@ def __init__(self, span):
8787
class SentryLangchainCallback(BaseCallbackHandler): # type: ignore[misc]
8888
"""Base callback handler that can be used to handle callbacks from langchain."""
8989

90-
span_map = OrderedDict() # type: OrderedDict[UUID, WatchedSpan]
91-
92-
max_span_map_size = 0
93-
9490
def __init__(self, max_span_map_size, include_prompts, tiktoken_encoding_name=None):
9591
# type: (int, bool, Optional[str]) -> None
92+
self.span_map = OrderedDict() # type: OrderedDict[UUID, WatchedSpan]
9693
self.max_span_map_size = max_span_map_size
9794
self.include_prompts = include_prompts
9895

tests/integrations/langchain/test_langchain.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
from langchain_core.outputs import ChatGenerationChunk
1818

1919
from sentry_sdk import start_transaction
20-
from sentry_sdk.integrations.langchain import LangchainIntegration
20+
from sentry_sdk.integrations.langchain import (
21+
LangchainIntegration,
22+
SentryLangchainCallback,
23+
)
2124
from langchain.agents import tool, AgentExecutor, create_openai_tools_agent
2225
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
2326

@@ -342,3 +345,22 @@ def test_span_origin(sentry_init, capture_events):
342345
assert event["contexts"]["trace"]["origin"] == "manual"
343346
for span in event["spans"]:
344347
assert span["origin"] == "auto.ai.langchain"
348+
349+
350+
def test_span_map_is_instance_variable():
351+
"""Test that each SentryLangchainCallback instance has its own span_map."""
352+
# Create two separate callback instances
353+
callback1 = SentryLangchainCallback(max_span_map_size=100, include_prompts=True)
354+
callback2 = SentryLangchainCallback(max_span_map_size=100, include_prompts=True)
355+
356+
# Verify they have different span_map instances
357+
assert (
358+
callback1.span_map is not callback2.span_map
359+
), "span_map should be an instance variable, not shared between instances"
360+
361+
362+
def test_span_map_not_class_attribute():
363+
"""Test that span_map is not accessible as a class attribute."""
364+
# This should raise AttributeError if span_map is properly an instance variable
365+
with pytest.raises(AttributeError):
366+
SentryLangchainCallback.span_map

0 commit comments

Comments
 (0)