python / cpython

The Python programming language
https://www.python.org
Other
62.7k stars 30.06k forks source link

AsyncMock force always creating an AsyncMock for child mocks #82303

Open lisroach opened 5 years ago

lisroach commented 5 years ago
BPO 38122
Nosy @cjw296, @ezio-melotti, @voidspace, @phmc, @matrixise, @lisroach, @tirkarthi
PRs
  • python/cpython#16099
  • python/cpython#16137
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields: ```python assignee = 'https://github.com/lisroach' closed_at = None created_at = labels = ['type-bug', 'library'] title = 'AsyncMock force always creating an AsyncMock for child mocks' updated_at = user = 'https://github.com/lisroach' ``` bugs.python.org fields: ```python activity = actor = 'pconnell' assignee = 'lisroach' closed = False closed_date = None closer = None components = ['Library (Lib)'] creation = creator = 'lisroach' dependencies = [] files = [] hgrepos = [] issue_num = 38122 keywords = ['patch'] message_count = 4.0 messages = ['351991', '352000', '352101', '352360'] nosy_count = 7.0 nosy_names = ['cjw296', 'ezio.melotti', 'michael.foord', 'pconnell', 'matrixise', 'lisroach', 'xtreak'] pr_nums = ['16099', '16137'] priority = 'low' resolution = None stage = 'patch review' status = 'open' superseder = None type = 'behavior' url = 'https://bugs.python.org/issue38122' versions = [] ```

    lisroach commented 5 years ago

    This idea has been brought up in person before and also discussed on AsyncTest: https://github.com/Martiusweb/asynctest/issues/100

    It could be useful if someone has a lot of attributes that are also async that need to be mocked.

    It could probably be done with a flag that gets passed on to _get_child_mock and overrides the if statement to always return an AsyncMock.

    Looking mostly for if people think this is a good idea/bad idea and help see around any corners that may be there.

    tirkarthi commented 5 years ago

    Sorry, is there an example of this use case. I went through the issue but have trouble understanding it since there are different suggestions. I guess child mock is always an AsyncMock irrespective of sync/async as I understand. We already had some reports over detecting async while patching to return AsyncMock and also had to document it to the users along with covering different ways of async functions.

    from unittest.mock import AsyncMock
    
    class Foo:
    
        def foo(self):
            pass
    
        async def bar(self):
            pass
    
    m = AsyncMock(Foo)
    f = m()
    print(m.foo)
    print(m.bar)
    $ python3.8 /tmp/bar.py
    <AsyncMock name='mock.foo' id='4313089744'>
    <AsyncMock name='mock.bar' id='4313395696'>
    sys:1: RuntimeWarning: coroutine 'AsyncMockMixin._mock_call' was never awaited
    voidspace commented 5 years ago

    That may change though, right?

    In general I dislike the proliferation of keyword arguments if it's at all possible to avoid. I added way too many of them originally and the mock API is really big.

    matrixise commented 5 years ago

    New changeset 14fd925a18fe3db0922a7d798e373102fe7a8a9c by Stéphane Wirtel (Michael Foord) in branch 'master': bpo-38122: minor fixes to AsyncMock spec handling (GH-16099) https://github.com/python/cpython/commit/14fd925a18fe3db0922a7d798e373102fe7a8a9c