Skip to content

Commit 88b101f

Browse files
miss-islingtonsobolevncjw296
authored
[3.10] pythongh-98086: Now patch.dict can decorate async functions (pythonGH-98095) (pythonGH-99366)
pythongh-98086: Now ``patch.dict`` can decorate async functions (pythonGH-98095) (cherry picked from commit 67b4d27) Co-authored-by: Nikita Sobolev <[email protected]> Co-authored-by: Chris Withers <[email protected]>
1 parent 42b7b21 commit 88b101f

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

Lib/unittest/mock.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1820,6 +1820,12 @@ def __init__(self, in_dict, values=(), clear=False, **kwargs):
18201820
def __call__(self, f):
18211821
if isinstance(f, type):
18221822
return self.decorate_class(f)
1823+
if inspect.iscoroutinefunction(f):
1824+
return self.decorate_async_callable(f)
1825+
return self.decorate_callable(f)
1826+
1827+
1828+
def decorate_callable(self, f):
18231829
@wraps(f)
18241830
def _inner(*args, **kw):
18251831
self._patch_dict()
@@ -1831,6 +1837,18 @@ def _inner(*args, **kw):
18311837
return _inner
18321838

18331839

1840+
def decorate_async_callable(self, f):
1841+
@wraps(f)
1842+
async def _inner(*args, **kw):
1843+
self._patch_dict()
1844+
try:
1845+
return await f(*args, **kw)
1846+
finally:
1847+
self._unpatch_dict()
1848+
1849+
return _inner
1850+
1851+
18341852
def decorate_class(self, klass):
18351853
for attr in dir(klass):
18361854
attr_value = getattr(klass, attr)

Lib/unittest/test/testmock/testasync.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,23 @@ async def test_async():
146146

147147
run(test_async())
148148

149+
def test_patch_dict_async_def(self):
150+
foo = {'a': 'a'}
151+
@patch.dict(foo, {'a': 'b'})
152+
async def test_async():
153+
self.assertEqual(foo['a'], 'b')
154+
155+
self.assertTrue(iscoroutinefunction(test_async))
156+
run(test_async())
157+
158+
def test_patch_dict_async_def_context(self):
159+
foo = {'a': 'a'}
160+
async def test_async():
161+
with patch.dict(foo, {'a': 'b'}):
162+
self.assertEqual(foo['a'], 'b')
163+
164+
run(test_async())
165+
149166

150167
class AsyncMockTest(unittest.TestCase):
151168
def test_iscoroutinefunction_default(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make sure ``patch.dict()`` can be applied on async functions.

0 commit comments

Comments
 (0)