Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 0 additions & 4 deletions src/_pytest/config/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
from typing import final


@final
class UsageError(Exception):
"""Error in pytest usage or invocation."""
Comment thread
jakkdl marked this conversation as resolved.

Expand Down
16 changes: 14 additions & 2 deletions src/_pytest/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
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
Expand All @@ -77,7 +78,6 @@
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:
Expand Down Expand Up @@ -138,6 +138,16 @@ def pytest_configure(config: Config) -> None:
)


@final
class PytestUnhandledCoroutineError(UsageError):
"""An unraisable exception resulted in an error.
Comment thread
jakkdl marked this conversation as resolved.
Outdated

Unraisable exceptions are exceptions raised in :meth:`__del__ <object.__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 += (
Expand All @@ -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)")


Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/warning_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def simple(cls, apiname: str) -> "PytestExperimentalApiWarning":


@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
Expand Down
31 changes: 11 additions & 20 deletions testing/acceptance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -1249,23 +1249,19 @@ def test_3():
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():
Expand All @@ -1276,20 +1272,15 @@ def test_3():
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:
Expand Down
2 changes: 1 addition & 1 deletion testing/test_unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1309,7 +1309,7 @@ def test_1(self):
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")
Expand Down