Skip to content

Fix internal error with module level skips #656

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

Closed
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
5 changes: 5 additions & 0 deletions docs/source/reference/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
Changelog
=========

0.22.1 (UNRELEASED)
===================
- Fixes a bug that caused an internal pytest error when using module-level skips `#655 <https://github.com/pytest-dev/pytest-asyncio/pull/655>`_


0.22.0 (2023-10-31)
===================
- Class-scoped and module-scoped event loops can be requested
Expand Down
11 changes: 10 additions & 1 deletion pytest_asyncio/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import pytest
from _pytest.mark.structures import get_unpacked_marks
from _pytest.outcomes import OutcomeException
from pytest import (
Collector,
Config,
Expand Down Expand Up @@ -549,7 +550,15 @@ def pytest_collectstart(collector: pytest.Collector):
return
# pytest.Collector.own_markers is empty at this point,
# so we rely on _pytest.mark.structures.get_unpacked_marks
marks = get_unpacked_marks(collector.obj, consider_mro=True)
# The function imports the collected object if it's a module.
# This can lead to issues, when the module contains statements specifying
# test outcomes, such as "pytest.skip(allow_module_level=True)". These cases
# are handled correctly when they happen inside Collector.collect(), but this hook
# runs before the actual collect call.
try:
marks = get_unpacked_marks(collector.obj, consider_mro=True)
except (OutcomeException, Collector.CollectError):
marks = []
for mark in marks:
if not mark.name == "asyncio_event_loop":
continue
Expand Down
90 changes: 90 additions & 0 deletions tests/test_pytest_skip.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from textwrap import dedent

from pytest import Pytester


def test_asyncio_strict_mode_skip(pytester: Pytester):
pytester.makepyfile(
dedent(
"""\
import pytest

pytest_plugins = "pytest_asyncio"

@pytest.mark.asyncio
async def test_no_warning_on_skip():
pytest.skip("Test a skip error inside asyncio")
"""
)
)
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(skipped=1)


def test_asyncio_auto_mode_skip(pytester: Pytester):
pytester.makepyfile(
dedent(
"""\
import pytest

pytest_plugins = "pytest_asyncio"

async def test_no_warning_on_skip():
pytest.skip("Test a skip error inside asyncio")
"""
)
)
result = pytester.runpytest("--asyncio-mode=auto")
result.assert_outcomes(skipped=1)


def test_asyncio_strict_mode_module_level_skip(pytester: Pytester):
pytester.makepyfile(
dedent(
"""\
import pytest

pytest.skip("Skip all tests", allow_module_level=True)

@pytest.mark.asyncio
async def test_is_skipped():
pass
"""
)
)
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(skipped=1)


def test_asyncio_auto_mode_module_level_skip(pytester: Pytester):
pytester.makepyfile(
dedent(
"""\
import pytest

pytest.skip("Skip all tests", allow_module_level=True)

async def test_is_skipped():
pass
"""
)
)
result = pytester.runpytest("--asyncio-mode=auto")
result.assert_outcomes(skipped=1)


def test_asyncio_auto_mode_wrong_skip_usage(pytester: Pytester):
pytester.makepyfile(
dedent(
"""\
import pytest

pytest.skip("Skip all tests")

async def test_is_skipped():
pass
"""
)
)
result = pytester.runpytest("--asyncio-mode=auto")
result.assert_outcomes(errors=1)
35 changes: 0 additions & 35 deletions tests/test_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,41 +260,6 @@ async def test_event_loop_before_fixture(self, loop):
assert await loop.run_in_executor(None, self.foo) == 1


def test_asyncio_marker_compatibility_with_skip(pytester: Pytester):
pytester.makepyfile(
dedent(
"""\
import pytest

pytest_plugins = "pytest_asyncio"

@pytest.mark.asyncio
async def test_no_warning_on_skip():
pytest.skip("Test a skip error inside asyncio")
"""
)
)
result = pytester.runpytest("--asyncio-mode=strict")
result.assert_outcomes(skipped=1)


def test_asyncio_auto_mode_compatibility_with_skip(pytester: Pytester):
pytester.makepyfile(
dedent(
"""\
import pytest

pytest_plugins = "pytest_asyncio"

async def test_no_warning_on_skip():
pytest.skip("Test a skip error inside asyncio")
"""
)
)
result = pytester.runpytest("--asyncio-mode=auto")
result.assert_outcomes(skipped=1)


def test_invalid_asyncio_mode(testdir):
result = testdir.runpytest("-o", "asyncio_mode=True")
result.stderr.no_fnmatch_line("INTERNALERROR> *")
Expand Down