async callable not awaited in side_effect for AsyncMock
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 36k
- PR merge metrics
- PR metrics pending
Description
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in Lib/unittest/mock.py at AsyncMockMixin._execute_mock_call and review the linked PR gh-156465. Confirm the behavior for an object whose async call method is used as AsyncMock.side_effect, then add or update regression coverage so that callable is awaited correctly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100