python38/99366-patch.dict-can-decorate-async.patch
Matej Cepl bb69159320 - Add 99366-patch.dict-can-decorate-async.patch fixing
gh#python/cpython#98086 (backport from Python 3.10 patch in
  gh#python/cpython!99366), fixing bsc#1211158.

- Add CVE-2007-4559-filter-tarfile_extractall.patch to fix
  CVE-2007-4559 (bsc#1203750) by adding the filter for
  tarfile.extractall (PEP 706).

- Why in the world we download from HTTP?

OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python38?expand=0&rev=128
2023-06-03 08:20:52 +00:00

80 lines
2.6 KiB
Diff

From c0dea0309b9a0a7cbc87727c9957f0a388fb9b0f Mon Sep 17 00:00:00 2001
From: Nikita Sobolev <mail@sobolevn.me>
Date: Fri, 11 Nov 2022 11:04:30 +0300
Subject: [PATCH] gh-98086: Now ``patch.dict`` can decorate async functions
(GH-98095) (cherry picked from commit
67b4d2772c5124b908f8ed9b13166a79bbeb88d2)
Co-authored-by: Nikita Sobolev <mail@sobolevn.me>
---
Lib/unittest/mock.py | 18 ++++++++++
Lib/unittest/test/testmock/testasync.py | 17 +++++++++
Misc/NEWS.d/next/Library/2022-10-08-19-39-27.gh-issue-98086.y---WC.rst | 1
3 files changed, 36 insertions(+)
create mode 100644 Misc/NEWS.d/next/Library/2022-10-08-19-39-27.gh-issue-98086.y---WC.rst
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1749,6 +1749,12 @@ class _patch_dict(object):
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()
@@ -1757,6 +1763,18 @@ class _patch_dict(object):
finally:
self._unpatch_dict()
+ 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
--- a/Lib/unittest/test/testmock/testasync.py
+++ b/Lib/unittest/test/testmock/testasync.py
@@ -143,6 +143,23 @@ class AsyncPatchCMTest(unittest.TestCase
asyncio.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(inspect.iscoroutinefunction(test_async))
+ asyncio.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')
+
+ asyncio.run(test_async())
+
class AsyncMockTest(unittest.TestCase):
def test_iscoroutinefunction_default(self):
--- /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.