]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-120388: Improve deprecation warning message, when test returns non-None (#120401)
authorNikita Sobolev <mail@sobolevn.me>
Wed, 12 Jun 2024 14:50:58 +0000 (17:50 +0300)
committerGitHub <noreply@github.com>
Wed, 12 Jun 2024 14:50:58 +0000 (14:50 +0000)
Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/test/test_unittest/test_async_case.py
Lib/test/test_unittest/test_case.py
Lib/unittest/async_case.py
Lib/unittest/case.py
Misc/NEWS.d/next/Library/2024-06-12-15-07-58.gh-issue-120388.VuTQMT.rst [new file with mode: 0644]

index ba1ab838cd4a223309c9f597219cfa4e74fc7209..00ef55bdf9bc832d86628c8359fa6da372c855f4 100644 (file)
@@ -312,18 +312,21 @@ class TestAsyncCase(unittest.TestCase):
         self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
         self.assertIn('test1', str(w.warning))
         self.assertEqual(w.filename, __file__)
+        self.assertIn("returned 'int'", str(w.warning))
 
         with self.assertWarns(DeprecationWarning) as w:
             Test('test2').run()
         self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
         self.assertIn('test2', str(w.warning))
         self.assertEqual(w.filename, __file__)
+        self.assertIn("returned 'async_generator'", str(w.warning))
 
         with self.assertWarns(DeprecationWarning) as w:
             Test('test3').run()
         self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
         self.assertIn('test3', str(w.warning))
         self.assertEqual(w.filename, __file__)
+        self.assertIn(f'returned {Nothing.__name__!r}', str(w.warning))
 
     def test_cleanups_interleave_order(self):
         events = []
index ed5eb5609a5dd10ff26ba42b82f38102c9df561e..174209094021071cef374c518e9ef7b86c5f213b 100644 (file)
@@ -325,18 +325,37 @@ class Test_TestCase(unittest.TestCase, TestEquality, TestHashing):
         self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
         self.assertIn('test1', str(w.warning))
         self.assertEqual(w.filename, __file__)
+        self.assertIn("returned 'int'", str(w.warning))
 
         with self.assertWarns(DeprecationWarning) as w:
             Foo('test2').run()
         self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
         self.assertIn('test2', str(w.warning))
         self.assertEqual(w.filename, __file__)
+        self.assertIn("returned 'generator'", str(w.warning))
 
         with self.assertWarns(DeprecationWarning) as w:
             Foo('test3').run()
         self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
         self.assertIn('test3', str(w.warning))
         self.assertEqual(w.filename, __file__)
+        self.assertIn(f'returned {Nothing.__name__!r}', str(w.warning))
+
+    def test_deprecation_of_return_val_from_test_async_method(self):
+        class Foo(unittest.TestCase):
+            async def test1(self):
+                return 1
+
+        with self.assertWarns(DeprecationWarning) as w:
+            Foo('test1').run()
+        self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
+        self.assertIn('test1', str(w.warning))
+        self.assertEqual(w.filename, __file__)
+        self.assertIn("returned 'coroutine'", str(w.warning))
+        self.assertIn(
+            'Maybe you forgot to use IsolatedAsyncioTestCase as the base class?',
+            str(w.warning),
+        )
 
     def _check_call_order__subtests(self, result, events, expected_events):
         class Foo(Test.LoggingTestCase):
index 63ff6a5d1f8b611f4a69088d7dc6d5e84d8de8f3..bd06eb3207697a74f0113c233385c275b93778ca 100644 (file)
@@ -90,9 +90,13 @@ class IsolatedAsyncioTestCase(TestCase):
         self._callAsync(self.asyncSetUp)
 
     def _callTestMethod(self, method):
-        if self._callMaybeAsync(method) is not None:
-            warnings.warn(f'It is deprecated to return a value that is not None from a '
-                          f'test case ({method})', DeprecationWarning, stacklevel=4)
+        result = self._callMaybeAsync(method)
+        if result is not None:
+            msg = (
+                f'It is deprecated to return a value that is not None '
+                f'from a test case ({method} returned {type(result).__name__!r})',
+            )
+            warnings.warn(msg, DeprecationWarning, stacklevel=4)
 
     def _callTearDown(self):
         self._callAsync(self.asyncTearDown)
index 36daa61fa31adb829d9fdfb06f5498b14be2c5f8..55c79d353539ca90176c2a43c2d4e1a960c013e6 100644 (file)
@@ -603,9 +603,18 @@ class TestCase(object):
         self.setUp()
 
     def _callTestMethod(self, method):
-        if method() is not None:
-            warnings.warn(f'It is deprecated to return a value that is not None from a '
-                          f'test case ({method})', DeprecationWarning, stacklevel=3)
+        result = method()
+        if result is not None:
+            import inspect
+            msg = (
+                f'It is deprecated to return a value that is not None '
+                f'from a test case ({method} returned {type(result).__name__!r})'
+            )
+            if inspect.iscoroutine(result):
+                msg += (
+                    '. Maybe you forgot to use IsolatedAsyncioTestCase as the base class?'
+                )
+            warnings.warn(msg, DeprecationWarning, stacklevel=3)
 
     def _callTearDown(self):
         self.tearDown()
diff --git a/Misc/NEWS.d/next/Library/2024-06-12-15-07-58.gh-issue-120388.VuTQMT.rst b/Misc/NEWS.d/next/Library/2024-06-12-15-07-58.gh-issue-120388.VuTQMT.rst
new file mode 100644 (file)
index 0000000..d13df7d
--- /dev/null
@@ -0,0 +1,3 @@
+Improve a warning message when a test method in :mod:`unittest` returns
+something other than ``None``. Now we show the returned object type and
+optional asyncio-related tip.