Skip to content

Prevent INTERNALERROR in pytest_collectstart when accessing module with pytest.skip #11662

@seifertm

Description

@seifertm

What's the problem this feature will solve?

Accessing pytest.Module.obj triggers a module import. If this happens during pytest_collectstart and the module that is about to be collected contains a pytest.skip statement, the result will be an INTERNALERROR. This is either caused by the Skipped exception or by Collector.CollectError if the allow_module_level keyword is missing in the pytest.skip call.

There's no good way to deal with this in the hook, because test outcomes, such as the Skipped exception are not part of the public API.

Describe the solution you'd like

I would like that no INTERNALERROR is triggered when accessing Module.obj in pytest_collectstart

Real world use case: Dynamically attaching a fixture to a module, similar to what's done in Module._inject_setup_module_fixture:

@fixtures.fixture(
autouse=True,
scope="module",
# Use a unique name to speed up lookup.
name=f"_xunit_setup_module_fixture_{self.obj.__name__}",
)
def xunit_setup_module_fixture(request) -> Generator[None, None, None]:
if setup_module is not None:
_call_with_optional_argument(setup_module, request.module)
yield
if teardown_module is not None:
_call_with_optional_argument(teardown_module, request.module)
self.obj.__pytest_setup_module = xunit_setup_module_fixture

Alternative Solutions

A workaround is to surround the access to Module.obj with a try-except. This forces the import of a non public symbol:

from pytest import Collector
from _pytest.outcomes import OutcomeException

def pytest_collectstart(collector):
    try:
        collector.obj
    except (OutcomeException, Collector.CollectError):
        pass

https://github.com/pytest-dev/pytest-asyncio/blob/a214c3e77149608d427ccab69140edb509c67697/pytest_asyncio/plugin.py#L592-L619

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: collectionrelated to the collection phasetopic: fixturesanything involving fixtures directly or indirectlytype: enhancementnew feature or API change, should be merged into features branch

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions