diff options
author | Thomas Grainger <tagrain@gmail.com> | 2023-06-09 13:29:09 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-09 13:29:09 (GMT) |
commit | 9bf8d825a66ea2a76169b917c12c237a6af2ed75 (patch) | |
tree | 03c736e98430b87b7c58bc76c67ee36d1e681046 /Lib/unittest | |
parent | 0f885ffa94aa9b69ff556e119cb17deb23a5a4b3 (diff) | |
download | cpython-9bf8d825a66ea2a76169b917c12c237a6af2ed75.zip cpython-9bf8d825a66ea2a76169b917c12c237a6af2ed75.tar.gz cpython-9bf8d825a66ea2a76169b917c12c237a6af2ed75.tar.bz2 |
gh-94924: support `inspect.iscoroutinefunction` in `create_autospec(async_def)` (#94962)
* support inspect.iscoroutinefunction in create_autospec(async_def)
* test create_autospec with inspect.iscoroutine and inspect.iscoroutinefunction
* test when create_autospec functions check their signature
Diffstat (limited to 'Lib/unittest')
-rw-r--r-- | Lib/unittest/mock.py | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 22f81e5..4ca7062 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -204,6 +204,33 @@ def _set_signature(mock, original, instance=False): _setup_func(funcopy, mock, sig) return funcopy +def _set_async_signature(mock, original, instance=False, is_async_mock=False): + # creates an async function with signature (*args, **kwargs) that delegates to a + # mock. It still does signature checking by calling a lambda with the same + # signature as the original. + + skipfirst = isinstance(original, type) + result = _get_signature_object(original, instance, skipfirst) + if result is None: + return mock + func, sig = result + def checksig(*args, **kwargs): + sig.bind(*args, **kwargs) + _copy_func_details(func, checksig) + + name = original.__name__ + if not name.isidentifier(): + name = 'funcopy' + context = {'_checksig_': checksig, 'mock': mock} + src = """async def %s(*args, **kwargs): + _checksig_(*args, **kwargs) + return await mock(*args, **kwargs)""" % name + exec (src, context) + funcopy = context[name] + _setup_func(funcopy, mock, sig) + _setup_async_mock(funcopy) + return funcopy + def _setup_func(funcopy, mock, sig): funcopy.mock = mock @@ -2745,9 +2772,10 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, if isinstance(spec, FunctionTypes): # should only happen at the top level because we don't # recurse for functions - mock = _set_signature(mock, spec) if is_async_func: - _setup_async_mock(mock) + mock = _set_async_signature(mock, spec) + else: + mock = _set_signature(mock, spec) else: _check_signature(spec, mock, is_type, instance) |