Skip to content
Open
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
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ repos:
rev: v1.19.1
hooks:
- id: mypy
exclude: ^(docs|tests)/.*
exclude: ^docs/.*
additional_dependencies:
- pytest
- repo: https://github.com/pre-commit/pygrep-hooks
Expand Down
1 change: 1 addition & 0 deletions changelog.d/1090.fixed.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow `AsyncIterable` as a return type for asynchronous generator fixtures decorated with `pytest_asyncio.fixture`
3 changes: 2 additions & 1 deletion pytest_asyncio/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import warnings
from asyncio import AbstractEventLoop
from collections.abc import (
AsyncIterable,
AsyncIterator,
Awaitable,
Callable,
Expand Down Expand Up @@ -69,7 +70,7 @@
from asyncio import AbstractEventLoopPolicy

_ScopeName = Literal["session", "package", "module", "class", "function"]
_R = TypeVar("_R", bound=Awaitable[Any] | AsyncIterator[Any])
_R = TypeVar("_R", bound=Awaitable | AsyncIterable | AsyncIterator)
_P = ParamSpec("_P")
FixtureFunction = Callable[_P, _R]
LoopFactory: TypeAlias = Callable[[], AbstractEventLoop]
Expand Down
40 changes: 28 additions & 12 deletions tests/hypothesis/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

from textwrap import dedent

import pytest
from hypothesis import given, strategies as st
from pytest import Pytester


Expand All @@ -27,18 +25,36 @@ async def test_mark_inner(n):
result.assert_outcomes(passed=1)


@pytest.mark.asyncio
@given(st.integers())
async def test_mark_outer(n):
assert isinstance(n, int)
def test_hypothesis_given_decorator_after_asyncio_mark(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(dedent("""\
import pytest
from hypothesis import given, strategies as st

@pytest.mark.asyncio
@given(st.integers())
async def test_mark_outer(n):
assert isinstance(n, int)
"""))
result = pytester.runpytest("--asyncio-mode=strict", "-W default")
result.assert_outcomes(passed=1)

@pytest.mark.parametrize("y", [1, 2])
@given(x=st.none())
@pytest.mark.asyncio
async def test_mark_and_parametrize(x, y):
assert x is None
assert y in (1, 2)

def test_parametrization(pytester: Pytester):
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
pytester.makepyfile(dedent("""\
import pytest
from hypothesis import given, strategies as st

@pytest.mark.parametrize("y", [1, 2])
@given(x=st.none())
@pytest.mark.asyncio
async def test_mark_and_parametrize(x, y):
assert x is None
assert y in (1, 2)
"""))
result = pytester.runpytest("--asyncio-mode=strict", "-W default")
result.assert_outcomes(passed=2)


def test_async_auto_marked(pytester: Pytester):
Expand Down
27 changes: 27 additions & 0 deletions tests/typing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Code in this module does not perform any runtime assertions. It is solely intended
# to allow type checkers to report usage errors.
# This is necessary, because most other test code is hidden from type checkers
# through the use of pytest.Pytester
from collections.abc import AsyncGenerator, AsyncIterable, AsyncIterator

import pytest_asyncio


@pytest_asyncio.fixture
async def coroutine() -> None:
return None


@pytest_asyncio.fixture
async def async_generator0() -> AsyncGenerator:
yield


@pytest_asyncio.fixture
async def async_generator1() -> AsyncIterator:
yield


@pytest_asyncio.fixture
async def async_generator2() -> AsyncIterable:
yield
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ skip_install = false
deps =
pyright[nodejs]
pytest
commands = pyright pytest_asyncio/
commands = pyright pytest_asyncio/ tests/
skip_install = true

[gh-actions]
Expand Down
Loading