[Python-checkins] [3.11] gh-98086: Now ``patch.dict`` can decorate async functions (GH-98095) (#99365)

cjw296 webhook-mailer at python.org
Sat Nov 19 05:11:01 EST 2022


https://github.com/python/cpython/commit/7e742379af27758a48a464b4f51eecabdc7f816a
commit: 7e742379af27758a48a464b4f51eecabdc7f816a
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: cjw296 <chris at withers.org>
date: 2022年11月19日T10:10:42Z
summary:
[3.11] gh-98086: Now ``patch.dict`` can decorate async functions (GH-98095) (#99365)
gh-98086: Now ``patch.dict`` can decorate async functions (GH-98095)
(cherry picked from commit 67b4d2772c5124b908f8ed9b13166a79bbeb88d2)
Co-authored-by: Nikita Sobolev <mail at sobolevn.me>
Co-authored-by: Nikita Sobolev <mail at sobolevn.me>
files:
A Misc/NEWS.d/next/Library/2022-10-08-19-39-27.gh-issue-98086.y---WC.rst
M Lib/unittest/mock.py
M Lib/unittest/test/testmock/testasync.py
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index b8f4e57f0b49..6720e5bc22dc 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1809,6 +1809,12 @@ def __init__(self, in_dict, values=(), clear=False, **kwargs):
 def __call__(self, f):
 if isinstance(f, type):
 return self.decorate_class(f)
+ if inspect.iscoroutinefunction(f):
+ return self.decorate_async_callable(f)
+ return self.decorate_callable(f)
+
+
+ def decorate_callable(self, f):
 @wraps(f)
 def _inner(*args, **kw):
 self._patch_dict()
@@ -1820,6 +1826,18 @@ def _inner(*args, **kw):
 return _inner
 
 
+ def decorate_async_callable(self, f):
+ @wraps(f)
+ async def _inner(*args, **kw):
+ self._patch_dict()
+ try:
+ return await f(*args, **kw)
+ finally:
+ self._unpatch_dict()
+
+ return _inner
+
+
 def decorate_class(self, klass):
 for attr in dir(klass):
 attr_value = getattr(klass, attr)
diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py
index 1bab671acdef..e05a22861d47 100644
--- a/Lib/unittest/test/testmock/testasync.py
+++ b/Lib/unittest/test/testmock/testasync.py
@@ -149,6 +149,23 @@ async def test_async():
 
 run(test_async())
 
+ def test_patch_dict_async_def(self):
+ foo = {'a': 'a'}
+ @patch.dict(foo, {'a': 'b'})
+ async def test_async():
+ self.assertEqual(foo['a'], 'b')
+
+ self.assertTrue(iscoroutinefunction(test_async))
+ run(test_async())
+
+ def test_patch_dict_async_def_context(self):
+ foo = {'a': 'a'}
+ async def test_async():
+ with patch.dict(foo, {'a': 'b'}):
+ self.assertEqual(foo['a'], 'b')
+
+ run(test_async())
+
 
 class AsyncMockTest(unittest.TestCase):
 def test_iscoroutinefunction_default(self):
diff --git a/Misc/NEWS.d/next/Library/2022-10-08-19-39-27.gh-issue-98086.y---WC.rst b/Misc/NEWS.d/next/Library/2022-10-08-19-39-27.gh-issue-98086.y---WC.rst
new file mode 100644
index 000000000000..f4a1d272e13b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-10-08-19-39-27.gh-issue-98086.y---WC.rst
@@ -0,0 +1 @@
+Make sure ``patch.dict()`` can be applied on async functions.


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /