[issue40406] MagicMock __aenter__ should be AsyncMock(return_value=MagicMock())

2020-12-07 Thread Blue


Change by Blue :


--
nosy: +simon.d.beal

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue40406] MagicMock __aenter__ should be AsyncMock(return_value=MagicMock())

2020-05-01 Thread Karthikeyan Singaravelan


Karthikeyan Singaravelan  added the comment:

MagicMock object on call returns another MagicMock. AsyncMock object in turn 
returns a coroutine which has to be awaited. 

In the report mock.MagicMock().__aenter__() returns an AsyncMock object. 
Accessing the query attribute will create an AsyncMock object. Calling query() 
will return a coroutine which will not have a __aexit__. Mock supports 
configure_mock through which nested calls can be mocked but the return_value 
has to be accessed to mock the nested attributes. So a workaround could be 
below. The connection object is mocked such that the __aenter__ returns a 
MagicMock. That magic mock can have the query attribute to be mocked whose 
return_value is an AsyncMock if the the query object has to awaited.

See also issue37052 regarding adding an example. See also 
https://github.com/python/cpython/pull/16859 regarding adding an example along 
similar database mocking that will help.

>>> from unittest.mock import MagicMock, AsyncMock

>>> AsyncMock()()



import asyncio
from unittest.mock import MagicMock, AsyncMock, patch


class Database:
pass


async def mock_database():
with patch(f"{__name__}.Database") as db:
db.configure_mock(
**{
"connection.return_value.__aenter__.return_value": MagicMock(
**{
"query.return_value.__aenter__.return_value": AsyncMock(
return_value=[1]
)
}
)
}
)

async with db.connection() as conn:
async with conn.query() as query:
result = await query("select * from people")
assert result == [1]
print(f"Result : {result}")


asyncio.run(mock_database())


Hope it helps.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue40406] MagicMock __aenter__ should be AsyncMock(return_value=MagicMock())

2020-05-01 Thread Brian Curtin


Brian Curtin  added the comment:

graingert: Do you have a workaround for this? I'm doing roughly the same thing 
with an asyncpg connection pool nested with a transaction and am getting 
nowhere.


async with pg_pool.acquire() as conn:
async with conn.transaction():
...

--
nosy: +brian.curtin

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue40406] MagicMock __aenter__ should be AsyncMock(return_value=MagicMock())

2020-04-27 Thread Karthikeyan Singaravelan


Change by Karthikeyan Singaravelan :


--
nosy: +lisroach, xtreak
type:  -> behavior

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue40406] MagicMock __aenter__ should be AsyncMock(return_value=MagicMock())

2020-04-27 Thread Thomas Grainger


New submission from Thomas Grainger :

aentering a MagicMock() results in an AsyncMock which behaves differently than 
I expected:

```
python3.9 -m asyncio
asyncio REPL 3.9.0a5 (default, Apr 18 2020, 00:00:31) 
[GCC 9.3.0] on linux
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> from unittest import mock
>>> with mock.MagicMock() as m:
... with m.foo() as u:
... u.hello()
... 

>>> async with mock.MagicMock() as m:
... async with m.foo() as u:
... u.hello()
... 
:2: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was 
never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Traceback (most recent call last):
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 439, in result
return self.__get_result()
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 388, in 
__get_result
raise self._exception
  File "", line 2, in 
AttributeError: __aenter__
```

This is annoying for mocking database interfaces like

```
async def update_users(db, user):
async with db.connection() as conn:
async with conn.transaction() as tx:
...
```

--
components: Tests, asyncio
messages: 367419
nosy: asvetlov, graingert, yselivanov
priority: normal
severity: normal
status: open
title: MagicMock __aenter__ should be AsyncMock(return_value=MagicMock())
versions: Python 3.8, Python 3.9

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue40406] MagicMock __aenter__ should be AsyncMock(return_value=MagicMock())

2020-04-27 Thread Thomas Grainger


Thomas Grainger  added the comment:

Perhaps there could be a MagicAsyncMock that supports .__await__ and 
.__aenter__ etc?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com