Skip to content

pytest_asyncio_loop_factories hook is not called when pytest.mark.asyncio is added via parametrization #1463

@francis-clairicia

Description

@francis-clairicia

Description

If pytest.mark.asyncio is added via parametrization (pytest.mark.parametrize() or pytest.fixture(params=...)), the test functions ignores the configured loop factories.

Steps to reproduce

In conftest.py:

from typing import Any
import uvloop


def pytest_asyncio_loop_factories() -> dict[str, Any]:
    return {"uvloop": uvloop.new_event_loop}

In test_async.py:

import asyncio
import uvloop
import pytest
import trio


@pytest.mark.parametrize(
    "backend",
    [
        pytest.param("asyncio", marks=pytest.mark.asyncio),
        pytest.param("trio", marks=pytest.mark.trio),  # <- Come from pytest-trio
    ]
)
async def test_async(backend: str) -> None:
    match backend:
        case "asyncio":
            assert isinstance(asyncio.get_running_loop(), uvloop.Loop)
        case "trio":
            assert trio.lowlevel.current_root_task() is not None

Expected the runner to be uvloop.Loop but it uses the default loop.

Workaround

There is a workaround possible to avoid the issue by using the test inheritance:

import asyncio
import uvloop
import pytest
import trio


class _BaseTestAsync:

    async def test_async(self, backend: str) -> None:
        match backend:
            case "asyncio":
                assert isinstance(asyncio.get_running_loop(), uvloop.Loop)
            case "trio":
                assert trio.lowlevel.current_root_task() is not None


@pytest.mark.asyncio
class TestAsyncIO(_BaseTestAsync):

    @pytest.fixture
    @staticmethod
    def backend() -> str:
        return "asyncio"

@pytest.mark.trio
class TestTrio(_BaseTestAsync):

    @pytest.fixture
    @staticmethod
    def backend() -> str:
        return "trio"

But compared to fixture parametrization, it is a bit complicated.

Use case

I have a project which must run with asyncio and trio but do not rely on anyio, therefore I use the fixture parametrization to test on all supported runners.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions