clj-python / clj-python/libpython-clj
py/with macro doesn't bind the return value of __enter__ method
還沒有人認領這個 Issue。
- 主要語言
- Clojure
- 星號
- 1.2k
- 分支
- 74
- PR 合併指標
- 30 天內沒有已合併 PR
描述
The py/with macro implementation doesn't correctly follow Python's with statement semantics. According to the Python documentation, the value bound in a with statement should be the return value of calling __enter__() on the context manager:
manager = (EXPRESSION)
enter = type(manager).__enter__
exit = type(manager).__exit__
value = enter(manager) # This value should be bound to TARGET
hit_except = False
try:
TARGET = value # TARGET gets the return value of enter(manager)
SUITE
...
Current Implementation
The current macro (with.clj#L45-L63) calls __enter__ but discards its return value:
(py-fn/call-attr ~varname "__enter__" nil) ; Return value is ignored
(try
(let [retval# (do ~@body)]
...
Expected Behavior
The bound variable should receive the return value of __enter__(), not the context manager itself:
(let [enter-result# (py-fn/call-attr ~varname "__enter__" nil)]
(try
(let [~varname enter-result# ; Rebind to __enter__'s return value
retval# (do ~@body)]
...
Why Current Tests Pass
The existing test in python_test.clj#L167 uses a WithObjClass where __enter__() returns None (implicitly), and the test methods are called on the original object. This masks the bug.
Real-World Example
A common Python pattern that fails with the current implementation:
with open('file.txt', 'r') as f:
content = f.read() # f should be the file object returned by __enter__
With the current macro, f would be bound to the unopened file path/manager rather than the file object returned by __enter__().
Next Steps
- Add test cases that verify this behavior (e.g., update
WithObjClass.__enter__to return a different object, or test with Python's built-in file context manager) - Update the macro to correctly bind the return value of
__enter__()
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
研究方向
從 src/libpython_clj2/python/with.clj#L45-L63 和 test/libpython_clj2/python_test.clj#L167 中現有的測試開始。使用 enter 回傳不同物件的內容管理器來新增覆蓋,然後驗證繫結的值就是該回傳值,並且現有的 with 行為仍然通過。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- clojure, python
- 領域
- tooling
- Issue 類型
- 缺陷
- 難度
- 2/5
- 預估耗時
- 1-3 小時
- 活躍度
- 停滯
- 描述清晰度
- 描述清楚
- 新手友好度
- 58/100