[3.8] bpo-38163: Child mocks detect their type as sync or async (GH-16471) (GH-16484)

diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 5d32f88..488ab1c 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -997,8 +997,9 @@
             # Any asynchronous magic becomes an AsyncMock
             klass = AsyncMock
         elif issubclass(_type, AsyncMockMixin):
-            if _new_name in _all_sync_magics:
-                # Any synchronous magic becomes a MagicMock
+            if (_new_name in _all_sync_magics or
+                    self._mock_methods and _new_name in self._mock_methods):
+                # Any synchronous method on AsyncMock becomes a MagicMock
                 klass = MagicMock
             else:
                 klass = AsyncMock
diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py
index ed8aefc..7671d55 100644
--- a/Lib/unittest/test/testmock/testasync.py
+++ b/Lib/unittest/test/testmock/testasync.py
@@ -3,7 +3,7 @@
 import re
 import unittest
 
-from unittest.mock import (ANY, call, AsyncMock, patch, MagicMock,
+from unittest.mock import (ANY, call, AsyncMock, patch, MagicMock, Mock,
                            create_autospec, sentinel, _CallList)
 
 
@@ -228,33 +228,50 @@
 
 
 class AsyncSpecTest(unittest.TestCase):
-    def test_spec_as_async_positional_magicmock(self):
-        mock = MagicMock(async_func)
-        self.assertIsInstance(mock, MagicMock)
-        m = mock()
-        self.assertTrue(inspect.isawaitable(m))
-        asyncio.run(m)
+    def test_spec_normal_methods_on_class(self):
+        def inner_test(mock_type):
+            mock = mock_type(AsyncClass)
+            self.assertIsInstance(mock.async_method, AsyncMock)
+            self.assertIsInstance(mock.normal_method, MagicMock)
 
-    def test_spec_as_async_kw_magicmock(self):
-        mock = MagicMock(spec=async_func)
-        self.assertIsInstance(mock, MagicMock)
-        m = mock()
-        self.assertTrue(inspect.isawaitable(m))
-        asyncio.run(m)
+        for mock_type in [AsyncMock, MagicMock]:
+            with self.subTest(f"test method types with {mock_type}"):
+                inner_test(mock_type)
 
-    def test_spec_as_async_kw_AsyncMock(self):
-        mock = AsyncMock(spec=async_func)
-        self.assertIsInstance(mock, AsyncMock)
-        m = mock()
-        self.assertTrue(inspect.isawaitable(m))
-        asyncio.run(m)
+    def test_spec_normal_methods_on_class_with_mock(self):
+        mock = Mock(AsyncClass)
+        self.assertIsInstance(mock.async_method, AsyncMock)
+        self.assertIsInstance(mock.normal_method, Mock)
 
-    def test_spec_as_async_positional_AsyncMock(self):
-        mock = AsyncMock(async_func)
-        self.assertIsInstance(mock, AsyncMock)
-        m = mock()
-        self.assertTrue(inspect.isawaitable(m))
-        asyncio.run(m)
+    def test_spec_mock_type_kw(self):
+        def inner_test(mock_type):
+            async_mock = mock_type(spec=async_func)
+            self.assertIsInstance(async_mock, mock_type)
+            with self.assertWarns(RuntimeWarning):
+                # Will raise a warning because never awaited
+                self.assertTrue(inspect.isawaitable(async_mock()))
+
+            sync_mock = mock_type(spec=normal_func)
+            self.assertIsInstance(sync_mock, mock_type)
+
+        for mock_type in [AsyncMock, MagicMock, Mock]:
+            with self.subTest(f"test spec kwarg with {mock_type}"):
+                inner_test(mock_type)
+
+    def test_spec_mock_type_positional(self):
+        def inner_test(mock_type):
+            async_mock = mock_type(async_func)
+            self.assertIsInstance(async_mock, mock_type)
+            with self.assertWarns(RuntimeWarning):
+                # Will raise a warning because never awaited
+                self.assertTrue(inspect.isawaitable(async_mock()))
+
+            sync_mock = mock_type(normal_func)
+            self.assertIsInstance(sync_mock, mock_type)
+
+        for mock_type in [AsyncMock, MagicMock, Mock]:
+            with self.subTest(f"test spec positional with {mock_type}"):
+                inner_test(mock_type)
 
     def test_spec_as_normal_kw_AsyncMock(self):
         mock = AsyncMock(spec=normal_func)