async callable not awaited in side_effect for AsyncMock
未关闭
还没有人认领这个 Issue。
stdlib
type-bug
- 主要语言
- Python
- 星标
- 77.2k
- 派生
- 36k
- PR 合并指标
- PR 指标待抓取
描述
Bug report
Bug description:
In the AsyncMockMixin._execute_mock_call, the following test is done:
if effect is not None:
if _is_exception(effect):
raise effect
elif not _callable(effect):
try:
result = next(effect)
except StopIteration:
# It is impossible to propagate a StopIteration
# through coroutines because of PEP 479
raise StopAsyncIteration
if _is_exception(result):
raise result
elif iscoroutinefunction(effect):
result = await effect(*args, **kwargs)
else:
result = effect(*args, **kwargs)
However elif iscoroutinefunction(effect) will return False for an awaitable that was defined this way:
class AsyncCallable:
async def __call__(self, *args, **kwargs):
# await stuff
pass
Note that __call__ is awaitable here but not detected as such.
iscoroutinefunction(effect.__call__) would return True in such a case however, so the fix might be as simple as:
elif iscoroutinefunction(effect) or iscoroutinefunction(getattr(effect, '__call__', None)):
In the meantime, the workaround is to add markcoroutinefunction(self) to the class.
class AsyncCallable:
def __init__(self, *args, **kwargs):
# init code
markcoroutinefunction(self) # workaround for iscoroutinefunction check in side_effect to return True
...
CPython versions tested on:
3.14
Operating systems tested on:
Linux
Linked PRs
- gh-156465
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 Lib/unittest/mock.py 中的 AsyncMockMixin._execute_mock_call 开始,检查关联的 PR gh-156465。确认将某个对象的异步 call 方法用作 AsyncMock.side_effect 时的行为,然后添加或更新回归测试覆盖,确保该可调用对象被正确 await。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- testing-qa
- Issue 类型
- 缺陷
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 活跃度
- 停滞
- 描述清晰度
- 描述清楚
- 新手友好度
- 35/100