fix(serializer): handle single-string __slots__ and detect cycles in slotted objects
維護者通常 1 天內回覆
評估
這個 Issue 還沒有評估資料。
描述
Describe the bug
In langfuse._utils.serializer.EventSerializer, slotted objects are handled by iterating over obj.__slots__:
if hasattr(obj, "__slots__"):
return {
slot: self.default(getattr(obj, slot, None))
for slot in obj.__slots__
}
Two distinct defects exist in this logic:
-
Single string
__slots__attribute loss:
According to the Python Language Reference (Data Model §3.3.2.4:__slots__),__slots__can be defined as a single string naming a single attribute (e.g.__slots__ = "query"). When__slots__is a string, iterating directly over it yields individual characters (q,u,e,r,y).getattr(obj, "q", None)returnsNone, resulting in{"q": null, "u": null, ...}while the actual attributequeryis lost. -
Missing circular reference detection:
Unlike the__dict__branch which tracksobj_id in self.seento immediately break reference cycles, the__slots__branch lacksself.seenprotection. When slotted objects contain reference cycles, each branch expands down to_MAX_DEPTH = 20, causing redundant recursion and bloated payloads.
To Reproduce
import json
from langfuse._utils.serializer import EventSerializer
# Case 1: Single string slot
class SingleSlot:
__slots__ = "query"
def __init__(self):
self.query = "SELECT 1"
res = json.loads(EventSerializer().encode(SingleSlot()))
print(res)
# Current output: {"q": null, "u": null, "e": null, "r": null, "y": null}
# Expected: {"query": "SELECT 1"}
# Case 2: Self-referential slotted node
class SlotNode:
__slots__ = ("next",)
node = SlotNode()
node.next = node
res = json.loads(EventSerializer().encode(node))
# Current output: recurses 20 layers deep
# Expected: {"next": "SlotNode"}
Proposed Fix
- Normalize string
__slots__to a 1-tuple(obj.__slots__,)ifisinstance(obj.__slots__, str). - Add
self.seentracking withtry...finallyto__slots__(matching__dict__).
- 主要語言
- Python
- 星號
- 500
- 分支
- 367
- 平均合併
- 16 小時 18 分鐘
- 30 天內合併 PR
- 51
環境準備
- 沒有 Dockerfile 或 Docker Compose 檔案
- 有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
langfuse/langfuse-python 的其他 Issue
-
tests/unit/test_prompt.py fails on a fresh clone without LANGFUSE_* env vars可能已有人在做 @Mathoholic 於 9 天前認領。 未關閉bug feat-prompt-management sdk-python
難度 2/5 1-3 小時 新手友好度 80/100
langfuse/langfuse-python#1976 · 3 則留言 ·
維護者通常 1 天內回覆
-
bug(langchain): failed streaming LLM runs retain IDs in callback memo可能已有人在做 @hassiebp 於 9 天前認領。 未關閉bug integration-langchain sdk-python
langfuse/langfuse-python#1977 · 已指派 1 人 ·
維護者通常 1 天內回覆
-
bug: ChatPromptClient.compile appends str(whole list) once per non-dict placeholder item可能已有人在做 @hassiebp 於 11 天前認領。 未關閉bug feat-prompt-management sdk-python
langfuse/langfuse-python#1971 · 已指派 1 人 ·
維護者通常 1 天內回覆
-
bug: GCS upload detection in MediaManager uses substring match on the full URL可能已有人在做 @hassiebp 於 19 天前認領。 未關閉bug feat-multimodal-media sdk-python
langfuse/langfuse-python#1913 · 1 則留言 · 已指派 1 人 ·
維護者通常 1 天內回覆
-
mask is not applied to create_dataset_item or create_score(comment=)可能已有人在做 @hassiebp 於 27 天前認領。 未關閉bug compliance feat-data-masking sdk-python security
langfuse/langfuse-python#1896 · 1 則留言 · 已指派 1 人 ·
維護者通常 1 天內回覆
查看 langfuse/langfuse-python 的全部 Issue
相似的 Issue
-
Edit tool converts CRLF files to LF可能已有人在做 @RaphaelFakhri 今天認領。 未關閉
難度 2/5 1-3 小時 新手友好度 68/100
huggingface/tau#774 ·
維護者通常 1 天內回覆
-
show ignores the row limit when a column or table name contains "limit"可能已有人在做 @RaphaelFakhri 今天認領。 未關閉
難度 2/5 1-3 小時 新手友好度 88/100
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 84/100
維護者通常 2 天內回覆
-
documentation good first issue
難度 2/5 1-3 小時 新手友好度 82/100
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 74/100
eclipse-score/inc_someip_gateway#356 ·
維護者通常 2 天內回覆