Skip to content

Commit

Permalink
pythongh-120388: Improve deprecation warning message, when test retur…
Browse files Browse the repository at this point in the history
…ns non-None (python#120401)

Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
  • Loading branch information
3 people authored and noahbkim committed Jul 11, 2024
1 parent 8873942 commit c1877da
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 6 deletions.
3 changes: 3 additions & 0 deletions Lib/test/test_unittest/test_async_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,18 +312,21 @@ async def test3(self):
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 = []
Expand Down
19 changes: 19 additions & 0 deletions Lib/test/test_unittest/test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,18 +325,37 @@ def test3(self):
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):
Expand Down
10 changes: 7 additions & 3 deletions Lib/unittest/async_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,13 @@ def _callSetUp(self):
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)
Expand Down
15 changes: 12 additions & 3 deletions Lib/unittest/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,9 +603,18 @@ def _callSetUp(self):
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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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.

0 comments on commit c1877da

Please sign in to comment.