Skip to content

Commit 3944bc4

Browse files
authored
Merge pull request #62 from agronholm/async_generator
Added support for the async_generator library
2 parents 1ec9287 + 96f931a commit 3944bc4

File tree

5 files changed

+66
-11
lines changed

5 files changed

+66
-11
lines changed

README.rst

+15-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ Async fixtures
114114
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
115115
Asynchronous fixtures are defined just like ordinary pytest fixtures, except they should be coroutines or asynchronous generators.
116116

117-
.. code-block:: python
117+
.. code-block:: python3
118118
119119
@pytest.fixture
120120
async def async_gen_fixture():
@@ -130,6 +130,20 @@ to redefine the ``event_loop`` fixture to have the same or broader scope.
130130
Async fixtures need the event loop, and so must have the same or narrower scope
131131
than the ``event_loop`` fixture.
132132

133+
If you want to do this with Python 3.5, the ``yield`` statement must be replaced with ``await yield_()`` and the coroutine
134+
function must be decorated with ``@async_generator``, like so:
135+
136+
.. code-block:: python3
137+
138+
from async_generator import yield_, async_generator
139+
140+
@pytest.fixture
141+
@async_generator
142+
async def async_gen_fixture():
143+
await asyncio.sleep(0.1)
144+
await yield_('a value')
145+
146+
133147
Markers
134148
-------
135149

pytest_asyncio/plugin.py

+5-8
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,22 @@
33
import contextlib
44
import inspect
55
import socket
6-
import sys
76
from concurrent.futures import ProcessPoolExecutor
87

98
import pytest
109
from _pytest.python import transfer_markers
1110

11+
try:
12+
from async_generator import isasyncgenfunction
13+
except ImportError:
14+
from inspect import isasyncgenfunction
15+
1216

1317
def _is_coroutine(obj):
1418
"""Check to see if an object is really an asyncio coroutine."""
1519
return asyncio.iscoroutinefunction(obj) or inspect.isgeneratorfunction(obj)
1620

1721

18-
if sys.version_info[:2] < (3, 6):
19-
def isasyncgenfunction(_):
20-
return False
21-
else:
22-
from inspect import isasyncgenfunction
23-
24-
2522
def pytest_configure(config):
2623
"""Inject documentation."""
2724
config.addinivalue_line("markers",

setup.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ def find_version(*file_paths):
4343
install_requires=[
4444
'pytest >= 3.0.6',
4545
],
46+
extras_require={
47+
':python_version == "3.5"': 'async_generator >= 1.3'
48+
},
4649
entry_points={
4750
'pytest11': ['asyncio = pytest_asyncio.plugin'],
48-
},
51+
}
4952
)

test_requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
coverage==4.1
2-
tox==2.5.0
2+
tox==2.5.0
3+
async_generator==1.8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import unittest.mock
2+
3+
import pytest
4+
from async_generator import yield_, async_generator
5+
6+
START = object()
7+
END = object()
8+
RETVAL = object()
9+
10+
11+
@pytest.fixture(scope='module')
12+
def mock():
13+
return unittest.mock.Mock(return_value=RETVAL)
14+
15+
16+
@pytest.fixture
17+
@async_generator
18+
async def async_gen_fixture(mock):
19+
try:
20+
await yield_(mock(START))
21+
except Exception as e:
22+
mock(e)
23+
else:
24+
mock(END)
25+
26+
27+
@pytest.mark.asyncio
28+
async def test_async_gen_fixture(async_gen_fixture, mock):
29+
assert mock.called
30+
assert mock.call_args_list[-1] == unittest.mock.call(START)
31+
assert async_gen_fixture is RETVAL
32+
33+
34+
@pytest.mark.asyncio
35+
async def test_async_gen_fixture_finalized(mock):
36+
try:
37+
assert mock.called
38+
assert mock.call_args_list[-1] == unittest.mock.call(END)
39+
finally:
40+
mock.reset_mock()

0 commit comments

Comments
 (0)