Skip to content

Commit fabcf6b

Browse files
sobolevnAlexWaygoodserhiy-storchaka
authored
pythongh-120388: Improve deprecation warning message, when test returns non-None (python#120401)
Co-authored-by: Alex Waygood <[email protected]> Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent 92c9c6a commit fabcf6b

File tree

5 files changed

+44
-6
lines changed

5 files changed

+44
-6
lines changed

Lib/test/test_unittest/test_async_case.py

+3
Original file line numberDiff line numberDiff line change
@@ -312,18 +312,21 @@ async def test3(self):
312312
self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
313313
self.assertIn('test1', str(w.warning))
314314
self.assertEqual(w.filename, __file__)
315+
self.assertIn("returned 'int'", str(w.warning))
315316

316317
with self.assertWarns(DeprecationWarning) as w:
317318
Test('test2').run()
318319
self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
319320
self.assertIn('test2', str(w.warning))
320321
self.assertEqual(w.filename, __file__)
322+
self.assertIn("returned 'async_generator'", str(w.warning))
321323

322324
with self.assertWarns(DeprecationWarning) as w:
323325
Test('test3').run()
324326
self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
325327
self.assertIn('test3', str(w.warning))
326328
self.assertEqual(w.filename, __file__)
329+
self.assertIn(f'returned {Nothing.__name__!r}', str(w.warning))
327330

328331
def test_cleanups_interleave_order(self):
329332
events = []

Lib/test/test_unittest/test_case.py

+19
Original file line numberDiff line numberDiff line change
@@ -325,18 +325,37 @@ def test3(self):
325325
self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
326326
self.assertIn('test1', str(w.warning))
327327
self.assertEqual(w.filename, __file__)
328+
self.assertIn("returned 'int'", str(w.warning))
328329

329330
with self.assertWarns(DeprecationWarning) as w:
330331
Foo('test2').run()
331332
self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
332333
self.assertIn('test2', str(w.warning))
333334
self.assertEqual(w.filename, __file__)
335+
self.assertIn("returned 'generator'", str(w.warning))
334336

335337
with self.assertWarns(DeprecationWarning) as w:
336338
Foo('test3').run()
337339
self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
338340
self.assertIn('test3', str(w.warning))
339341
self.assertEqual(w.filename, __file__)
342+
self.assertIn(f'returned {Nothing.__name__!r}', str(w.warning))
343+
344+
def test_deprecation_of_return_val_from_test_async_method(self):
345+
class Foo(unittest.TestCase):
346+
async def test1(self):
347+
return 1
348+
349+
with self.assertWarns(DeprecationWarning) as w:
350+
Foo('test1').run()
351+
self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
352+
self.assertIn('test1', str(w.warning))
353+
self.assertEqual(w.filename, __file__)
354+
self.assertIn("returned 'coroutine'", str(w.warning))
355+
self.assertIn(
356+
'Maybe you forgot to use IsolatedAsyncioTestCase as the base class?',
357+
str(w.warning),
358+
)
340359

341360
def _check_call_order__subtests(self, result, events, expected_events):
342361
class Foo(Test.LoggingTestCase):

Lib/unittest/async_case.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,13 @@ def _callSetUp(self):
9090
self._callAsync(self.asyncSetUp)
9191

9292
def _callTestMethod(self, method):
93-
if self._callMaybeAsync(method) is not None:
94-
warnings.warn(f'It is deprecated to return a value that is not None from a '
95-
f'test case ({method})', DeprecationWarning, stacklevel=4)
93+
result = self._callMaybeAsync(method)
94+
if result is not None:
95+
msg = (
96+
f'It is deprecated to return a value that is not None '
97+
f'from a test case ({method} returned {type(result).__name__!r})',
98+
)
99+
warnings.warn(msg, DeprecationWarning, stacklevel=4)
96100

97101
def _callTearDown(self):
98102
self._callAsync(self.asyncTearDown)

Lib/unittest/case.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -603,9 +603,18 @@ def _callSetUp(self):
603603
self.setUp()
604604

605605
def _callTestMethod(self, method):
606-
if method() is not None:
607-
warnings.warn(f'It is deprecated to return a value that is not None from a '
608-
f'test case ({method})', DeprecationWarning, stacklevel=3)
606+
result = method()
607+
if result is not None:
608+
import inspect
609+
msg = (
610+
f'It is deprecated to return a value that is not None '
611+
f'from a test case ({method} returned {type(result).__name__!r})'
612+
)
613+
if inspect.iscoroutine(result):
614+
msg += (
615+
'. Maybe you forgot to use IsolatedAsyncioTestCase as the base class?'
616+
)
617+
warnings.warn(msg, DeprecationWarning, stacklevel=3)
609618

610619
def _callTearDown(self):
611620
self.tearDown()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Improve a warning message when a test method in :mod:`unittest` returns
2+
something other than ``None``. Now we show the returned object type and
3+
optional asyncio-related tip.

0 commit comments

Comments
 (0)