From 807c01451867cb107900a5a9ce0d07f261770d99 Mon Sep 17 00:00:00 2001 From: polkapolka <7219835+polkapolka@users.noreply.github.com> Date: Mon, 20 May 2024 22:14:51 +0000 Subject: [PATCH] changed warning raised by async def to error --- src/_pytest/config/exceptions.py | 4 ---- src/_pytest/python.py | 16 ++++++++++++++-- src/_pytest/warning_types.py | 2 +- testing/acceptance_test.py | 31 +++++++++++-------------------- testing/test_unittest.py | 2 +- 5 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/_pytest/config/exceptions.py b/src/_pytest/config/exceptions.py index 4031ea732..95c412734 100644 --- a/src/_pytest/config/exceptions.py +++ b/src/_pytest/config/exceptions.py @@ -1,7 +1,3 @@ -from typing import final - - -@final class UsageError(Exception): """Error in pytest usage or invocation.""" diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 4887614de..bf20ca31d 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -54,6 +54,7 @@ from _pytest.compat import safe_isclass from _pytest.config import Config from _pytest.config import hookimpl from _pytest.config.argparsing import Parser +from _pytest.config.exceptions import UsageError from _pytest.deprecated import check_ispytest from _pytest.fixtures import FixtureDef from _pytest.fixtures import FixtureRequest @@ -77,7 +78,6 @@ from _pytest.scope import Scope from _pytest.stash import StashKey from _pytest.warning_types import PytestCollectionWarning from _pytest.warning_types import PytestReturnNotNoneWarning -from _pytest.warning_types import PytestUnhandledCoroutineWarning if TYPE_CHECKING: @@ -138,6 +138,16 @@ def pytest_configure(config: Config) -> None: ) +@final +class PytestUnhandledCoroutineError(UsageError): + """An unraisable exception resulted in an error. + + Unraisable exceptions are exceptions raised in :meth:`__del__ ` + implementations and similar situations when the exception cannot be raised + as normal. + """ + + def async_warn_and_skip(nodeid: str) -> None: msg = "async def functions are not natively supported and have been skipped.\n" msg += ( @@ -148,7 +158,9 @@ def async_warn_and_skip(nodeid: str) -> None: msg += " - pytest-tornasync\n" msg += " - pytest-trio\n" msg += " - pytest-twisted" - warnings.warn(PytestUnhandledCoroutineWarning(msg.format(nodeid))) + raise PytestUnhandledCoroutineError( + msg.format(nodeid) + ) # TODO: This is the warning to look at skip(reason="async def function and no async plugin installed (see warnings)") diff --git a/src/_pytest/warning_types.py b/src/_pytest/warning_types.py index a5884f295..d2e542651 100644 --- a/src/_pytest/warning_types.py +++ b/src/_pytest/warning_types.py @@ -77,7 +77,7 @@ class PytestExperimentalApiWarning(PytestWarning, FutureWarning): @final -class PytestUnhandledCoroutineWarning(PytestReturnNotNoneWarning): +class PytestUnhandledCoroutineWarning(PytestReturnNotNoneWarning): # TODO: look at this """Warning emitted for an unhandled coroutine. A coroutine was encountered when collecting test functions, but was not diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index ac7fab3d2..12c8a50dd 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -1233,7 +1233,7 @@ def test_usage_error_code(pytester: Pytester) -> None: assert result.ret == ExitCode.USAGE_ERROR -def test_warn_on_async_function(pytester: Pytester) -> None: +def test_error_on_async_function(pytester: Pytester) -> None: # TODO: Change this # In the below we .close() the coroutine only to avoid # "RuntimeWarning: coroutine 'test_2' was never awaited" # which messes with other tests. @@ -1249,23 +1249,19 @@ def test_warn_on_async_function(pytester: Pytester) -> None: return coro """ ) - result = pytester.runpytest("-Wdefault") + result = pytester.runpytest() result.stdout.fnmatch_lines( [ - "test_async.py::test_1", - "test_async.py::test_2", - "test_async.py::test_3", + "*test_async.py::test_1*", + "*test_async.py::test_2*", + "*test_async.py::test_3*", "*async def functions are not natively supported*", - "*3 skipped, 3 warnings in*", ] ) - # ensure our warning message appears only once - assert ( - result.stdout.str().count("async def functions are not natively supported") == 1 - ) + result.assert_outcomes(failed=3) -def test_warn_on_async_gen_function(pytester: Pytester) -> None: +def test_error_on_async_gen_function(pytester: Pytester) -> None: # TODO: Change this pytester.makepyfile( test_async=""" async def test_1(): @@ -1276,20 +1272,15 @@ def test_warn_on_async_gen_function(pytester: Pytester) -> None: return test_2() """ ) - result = pytester.runpytest("-Wdefault") + result = pytester.runpytest() result.stdout.fnmatch_lines( [ - "test_async.py::test_1", - "test_async.py::test_2", - "test_async.py::test_3", + "*test_async.py::test_1*", + "*test_async.py::test_2*", + "*test_async.py::test_3*", "*async def functions are not natively supported*", - "*3 skipped, 3 warnings in*", ] ) - # ensure our warning message appears only once - assert ( - result.stdout.str().count("async def functions are not natively supported") == 1 - ) def test_pdb_can_be_rewritten(pytester: Pytester) -> None: diff --git a/testing/test_unittest.py b/testing/test_unittest.py index 003a74d38..e2a2904a3 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -1309,7 +1309,7 @@ def test_pdb_teardown_skipped_for_classes( assert tracked == [] -def test_async_support(pytester: Pytester) -> None: +def test_async_support(pytester: Pytester) -> None: # TODO: Change this pytest.importorskip("unittest.async_case") pytester.copy_example("unittest/test_unittest_asyncio.py")