classification
Title: AsyncMock child mocks should detect their type
Type: Stage: resolved
Components: Versions:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: lisroach, xtreak
Priority: normal Keywords: patch

Created on 2019-09-13 17:05 by lisroach, last changed 2019-09-30 05:23 by lisroach. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 16471 merged lisroach, 2019-09-29 03:24
PR 16484 merged lisroach, 2019-09-30 05:02
Messages (5)
msg352369 - (view) Author: Lisa Roach (lisroach) * (Python committer) Date: 2019-09-13 17:05
We want child mocks to match their "type" (async or sync). 

Ex:

class Prod:
   async def foo():
      pass
    def bar():
       pass

a_mock = AsyncMock(Prod)
isinstance(a_mock.foo(), AsyncMock) == True
isinstance(a_mock.bar(), MagicMock) == True

Also this should include magic methods:

int(a_mock) should work and return 1 like MagicMocks do.
a_mock.__enter__ should exist and be a MagicMock, just as a_mock.__aenter__ exists and is an AsyncMock.
msg353263 - (view) Author: Lisa Roach (lisroach) * (Python committer) Date: 2019-09-26 05:02
This should be simple to do, after https://github.com/python/cpython/pull/16060 we can add:

            elif self._mock_methods and _new_name in self._mock_methods:
                # Methods that are not in _spec_asyncs are normal methods
                klass = MagicMock

to _get_child_mocks and test with:

    def test_normal_methods_on_class(self):
        am = AsyncMock(AsyncClass)
        self.assertIsInstance(am.async_method, AsyncMock)
        self.assertIsInstance(am.normal_method, MagicMock)

This might be starting to make _get_child_mocks too complicated, and no longer follows the default "child mocks are the same as their parent". I am not sure how to redefine _get_child_mocks without needing to double up a lot of code to support MagicMocks having AsyncMock child_mocks as well.
msg353264 - (view) Author: Lisa Roach (lisroach) * (Python committer) Date: 2019-09-26 05:05
Lately I have been having my doubts around having MagicMocks also create AsyncMocks as children. 

Should a MagicMock really have a __aenter__ magic method? 
Is this too far from the original MagicMock if we change child mocks to default not to their parent type, but to their parent type *or* AsyncMock if asynchronous?

It makes the using the mocks easier, since you can just use MagicMock or AsyncMock for whatever you are doing and not think about when to use which. But it also might make the code more confusing, since it isn't as clear when to use one or the other.
msg353534 - (view) Author: Lisa Roach (lisroach) * (Python committer) Date: 2019-09-30 04:56
New changeset 3667e1ee6c90e6d3b6a745cd590ece87118f81ad by Lisa Roach in branch 'master':
bpo-38163: Child mocks detect their type as sync or async (GH-16471)
https://github.com/python/cpython/commit/3667e1ee6c90e6d3b6a745cd590ece87118f81ad
msg353537 - (view) Author: Lisa Roach (lisroach) * (Python committer) Date: 2019-09-30 05:22
New changeset 21f24ead90c22d0e2c2ebf14a64b37d99de54b33 by Lisa Roach in branch '3.8':
[3.8] bpo-38163: Child mocks detect their type as sync or async (GH-16471) (GH-16484)
https://github.com/python/cpython/commit/21f24ead90c22d0e2c2ebf14a64b37d99de54b33
History
Date User Action Args
2019-09-30 05:23:09lisroachsetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2019-09-30 05:22:47lisroachsetmessages: + msg353537
2019-09-30 05:02:28lisroachsetpull_requests: + pull_request16069
2019-09-30 04:56:50lisroachsetmessages: + msg353534
2019-09-29 03:24:01lisroachsetkeywords: + patch
stage: patch review
pull_requests: + pull_request16054
2019-09-26 05:05:17lisroachsetmessages: + msg353264
2019-09-26 05:02:10lisroachsetmessages: + msg353263
2019-09-13 17:13:43xtreaksetnosy: + xtreak
2019-09-13 17:05:04lisroachcreate