async callable not awaited in side_effect for AsyncMock
オープン
まだ誰も着手していません。
stdlib
type-bug
- 主要言語
- Python
- スター
- 77.2k
- フォーク
- 35.9k
- 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 にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
Lib/unittest/mock.py の AsyncMockMixin._execute_mock_call から始め、リンクされた PR gh-156465 を確認してください。非同期の call メソッドを AsyncMock.side_effect として使用するオブジェクトの動作を確認し、その callable が正しく await されるように回帰テストのカバレッジを追加または更新してください。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- testing-qa
- issue の種類
- バグ
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 活発さ
- 停滞
- 明瞭さ
- 明確に書かれている
- 初心者へのやさしさ
- 35/100