summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLisa Roach <lisaroach14@gmail.com>2019-09-10 11:18:40 (GMT)
committerGitHub <noreply@github.com>2019-09-10 11:18:40 (GMT)
commitf1a297acb60b88917712450ebd3cfa707e6efd6b (patch)
treec1307ca321b2aae7abc43f714a7310a38331c4a6
parent5a7d2e11aaea2dd32878dc5c6b1aae8caf56cb44 (diff)
downloadcpython-f1a297acb60b88917712450ebd3cfa707e6efd6b.zip
cpython-f1a297acb60b88917712450ebd3cfa707e6efd6b.tar.gz
cpython-f1a297acb60b88917712450ebd3cfa707e6efd6b.tar.bz2
bpo-37251: Removes __code__ check from _is_async_obj. (GH-15830)
-rw-r--r--Lib/unittest/mock.py5
-rw-r--r--Lib/unittest/test/testmock/testasync.py15
-rw-r--r--Misc/NEWS.d/next/Library/2019-09-10-10-59-50.bpo-37251.8zn2o3.rst3
3 files changed, 20 insertions, 3 deletions
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index c26b367..50e4959 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -46,10 +46,9 @@ FILTER_DIR = True
_safe_super = super
def _is_async_obj(obj):
- if getattr(obj, '__code__', None):
- return asyncio.iscoroutinefunction(obj) or inspect.isawaitable(obj)
- else:
+ if _is_instance_mock(obj) and not isinstance(obj, AsyncMock):
return False
+ return asyncio.iscoroutinefunction(obj) or inspect.isawaitable(obj)
def _is_async_func(func):
diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py
index 865cfdc..5502342 100644
--- a/Lib/unittest/test/testmock/testasync.py
+++ b/Lib/unittest/test/testmock/testasync.py
@@ -18,6 +18,10 @@ class AsyncClass:
def normal_method(self):
pass
+class AwaitableClass:
+ def __await__(self):
+ yield
+
async def async_func():
pass
@@ -160,6 +164,10 @@ class AsyncAutospecTest(unittest.TestCase):
with self.assertRaises(RuntimeError):
create_autospec(async_func, instance=True)
+ def test_create_autospec_awaitable_class(self):
+ awaitable_mock = create_autospec(spec=AwaitableClass())
+ self.assertIsInstance(create_autospec(awaitable_mock), AsyncMock)
+
def test_create_autospec(self):
spec = create_autospec(async_func_args)
awaitable = spec(1, 2, c=3)
@@ -321,6 +329,13 @@ class AsyncSpecSetTest(unittest.TestCase):
self.assertIsInstance(mock.normal_method, MagicMock)
self.assertIsInstance(mock, MagicMock)
+ def test_magicmock_lambda_spec(self):
+ mock_obj = MagicMock()
+ mock_obj.mock_func = MagicMock(spec=lambda x: x)
+
+ with patch.object(mock_obj, "mock_func") as cm:
+ self.assertIsInstance(cm, MagicMock)
+
class AsyncArguments(unittest.TestCase):
def test_add_return_value(self):
diff --git a/Misc/NEWS.d/next/Library/2019-09-10-10-59-50.bpo-37251.8zn2o3.rst b/Misc/NEWS.d/next/Library/2019-09-10-10-59-50.bpo-37251.8zn2o3.rst
new file mode 100644
index 0000000..27fd1e4
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-09-10-10-59-50.bpo-37251.8zn2o3.rst
@@ -0,0 +1,3 @@
+Remove `__code__` check in AsyncMock that incorrectly
+evaluated function specs as async objects but failed to evaluate classes
+with `__await__` but no `__code__` attribute defined as async objects.