Skip to content

gh-120388: Improve deprecation warning message, when test returns non-None #120401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Loading