summaryrefslogtreecommitdiffstats
path: root/Lib/unittest
diff options
context:
space:
mode:
authorThomas Grainger <tagrain@gmail.com>2023-06-09 13:29:09 (GMT)
committerGitHub <noreply@github.com>2023-06-09 13:29:09 (GMT)
commit9bf8d825a66ea2a76169b917c12c237a6af2ed75 (patch)
tree03c736e98430b87b7c58bc76c67ee36d1e681046 /Lib/unittest
parent0f885ffa94aa9b69ff556e119cb17deb23a5a4b3 (diff)
downloadcpython-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.py32
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)