Skip to content

Commit

Permalink
Merge pull request #17 from dirn/async-await
Browse files Browse the repository at this point in the history
Support coroutines with async and await syntax
  • Loading branch information
Tinche committed Dec 18, 2015
2 parents 34af0a1 + a4afe36 commit a2a8949
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 3 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
@@ -1,9 +1,10 @@
language: python
python: 3.3
python: 3.5

env:
- TOX_ENV=py33
- TOX_ENV=py34
- TOX_ENV=py35

install:
- pip install tox
Expand Down
7 changes: 6 additions & 1 deletion pytest_asyncio/plugin.py
Expand Up @@ -6,6 +6,11 @@
import pytest


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


def pytest_configure(config):
config.addinivalue_line("markers",
"asyncio: "
Expand All @@ -20,7 +25,7 @@ def pytest_configure(config):

@pytest.mark.tryfirst
def pytest_pycollect_makeitem(collector, name, obj):
if collector.funcnamefilter(name) and inspect.isgeneratorfunction(obj):
if collector.funcnamefilter(name) and _is_coroutine(obj):
item = pytest.Function(name, parent=collector)
if ('asyncio' in item.keywords or
'asyncio_process_pool' in item.keywords):
Expand Down
1 change: 1 addition & 0 deletions setup.py
Expand Up @@ -37,6 +37,7 @@ def find_version(*file_paths):
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Topic :: Software Development :: Testing",
],
install_requires=[
Expand Down
99 changes: 99 additions & 0 deletions tests/test_simple_35.py
@@ -0,0 +1,99 @@
"""Quick'n'dirty unit tests using async and await syntax."""

import asyncio
import sys

import pytest

pytestmark = pytest.mark.skipif(
sys.version_info[:2] < (3, 5),
reason='This syntax is only valid in 3.5 and newer')


@asyncio.coroutine
def async_coro(loop):
yield from asyncio.sleep(0, loop=loop)
return 'ok'


# PEP 492 added the syntax for these tests to Python 3.5. Older versions
# can't even parse the module to let skipif exclude the tests. To get
# around this, all tests are defined in a string which can be compiled
# and executed on appropriate versions of Python.
_possible_tests = '''
@pytest.mark.asyncio
async def test_asyncio_marker():
"""Test the asyncio pytest marker."""
@pytest.mark.asyncio
async def test_asyncio_marker_with_default_param(a_param=None):
"""Test the asyncio pytest marker."""
@pytest.mark.asyncio_process_pool
async def test_asyncio_process_pool_marker(event_loop):
ret = await async_coro(event_loop)
assert ret == 'ok'
@pytest.mark.asyncio
async def test_unused_port_fixture(unused_tcp_port, event_loop):
"""Test the unused TCP port fixture."""
async def closer(_, writer):
writer.close()
server1 = await asyncio.start_server(closer, host='localhost',
port=unused_tcp_port,
loop=event_loop)
server1.close()
await server1.wait_closed()
@pytest.mark.asyncio
async def test_unused_port_factory_fixture(unused_tcp_port_factory, event_loop):
"""Test the unused TCP port factory fixture."""
async def closer(_, writer):
writer.close()
port1, port2, port3 = (unused_tcp_port_factory(), unused_tcp_port_factory(),
unused_tcp_port_factory())
server1 = await asyncio.start_server(closer, host='localhost',
port=port1,
loop=event_loop)
server2 = await asyncio.start_server(closer, host='localhost',
port=port2,
loop=event_loop)
server3 = await asyncio.start_server(closer, host='localhost',
port=port3,
loop=event_loop)
for port in port1, port2, port3:
with pytest.raises(IOError):
await asyncio.start_server(closer, host='localhost',
port=port,
loop=event_loop)
server1.close()
await server1.wait_closed()
server2.close()
await server2.wait_closed()
server3.close()
await server3.wait_closed()
class Test:
"""Test that asyncio marked functions work in test methods."""
@pytest.mark.asyncio
async def test_asyncio_marker_method(self, event_loop):
"""Test the asyncio pytest marker in a Test class."""
ret = await async_coro(event_loop)
assert ret == 'ok'
'''

if sys.version_info[:2] >= (3, 5):
exec(compile(_possible_tests, __file__, 'exec'))
2 changes: 1 addition & 1 deletion tox.ini
@@ -1,5 +1,5 @@
[tox]
envlist = py33, py34
envlist = py33, py34, py35

[testenv]
deps =
Expand Down

0 comments on commit a2a8949

Please sign in to comment.