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