Skip to content

Commit 50337c8

Browse files
committed
Python 3.7 support
- Enable tests and declare support for Python 3.7 - Use `async` and `await` in all tests Note: this change may be blocked by pytest-dev#87. The behavior of the `ProcessPoolExecutor` tests is somewhat flaky in 3.7 and may cause the test suite to hang.
1 parent a9a8db2 commit 50337c8

10 files changed

+69
-69
lines changed

.travis.yml

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
language: python
2-
python:
3-
- "3.5"
4-
- "3.6"
2+
matrix:
3+
include:
4+
- python: 3.5
5+
env: TOX_ENV=py35
6+
- python: 3.6
7+
env: TOX_ENV=py36
8+
- python: 3.7
9+
env: TOX_ENV=py37
10+
# TODO: the dist and sudo keys are currently needed to use Python 3.7.
11+
# They should be removed once Travis-CI supports 3.7 on the default image.
12+
dist: xenial
13+
sudo: true
514

615
install: pip install tox-travis coveralls
716

8-
script: tox
17+
script: tox -e $TOX_ENV
918

1019
after_success:
1120
- tox -e coverage-report

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def find_version():
3030
"License :: OSI Approved :: Apache Software License",
3131
"Programming Language :: Python :: 3.5",
3232
"Programming Language :: Python :: 3.6",
33+
"Programming Language :: Python :: 3.7",
3334
"Topic :: Software Development :: Testing",
3435
"Framework :: Pytest",
3536
],

tests/async_fixtures/test_coroutine_fixtures.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,12 @@ def mock():
1616

1717

1818
@pytest.fixture
19-
@asyncio.coroutine
20-
def coroutine_fixture(mock):
21-
yield from asyncio.sleep(0.1, result=mock(START))
19+
async def coroutine_fixture(mock):
20+
await asyncio.sleep(0.1, result=mock(START))
2221

2322

2423
@pytest.mark.asyncio
25-
@asyncio.coroutine
26-
def test_coroutine_fixture(coroutine_fixture, mock):
24+
async def test_coroutine_fixture(coroutine_fixture, mock):
2725
assert mock.call_count == 1
2826
assert mock.call_args_list[-1] == unittest.mock.call(START)
29-
assert coroutine_fixture is RETVAL
27+
assert coroutine_fixture is RETVAL

tests/conftest.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ def dependent_fixture(event_loop):
1414
"""A fixture dependent on the event_loop fixture, doing some cleanup."""
1515
counter = 0
1616

17-
@asyncio.coroutine
18-
def just_a_sleep():
17+
async def just_a_sleep():
1918
"""Just sleep a little while."""
2019
nonlocal event_loop
21-
yield from asyncio.sleep(0.1, loop=event_loop)
20+
await asyncio.sleep(0.1, loop=event_loop)
2221
nonlocal counter
2322
counter += 1
2423

tests/multiloop/test_alternative_loops.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@
55

66

77
@pytest.mark.asyncio
8-
def test_for_custom_loop():
8+
async def test_for_custom_loop():
99
"""This test should be executed using the custom loop."""
10-
yield from asyncio.sleep(0.01)
10+
await asyncio.sleep(0.01)
1111
assert type(asyncio.get_event_loop()).__name__ == "CustomSelectorLoop"
1212

1313

1414
@pytest.mark.asyncio
15-
@asyncio.coroutine
16-
def test_dependent_fixture(dependent_fixture):
17-
yield from asyncio.sleep(0.1)
15+
async def test_dependent_fixture(dependent_fixture):
16+
await asyncio.sleep(0.1)

tests/test_dependent_fixtures.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44

55
@pytest.mark.asyncio
6-
@asyncio.coroutine
7-
def test_dependent_fixture(dependent_fixture):
6+
async def test_dependent_fixture(dependent_fixture):
87
"""Test a dependent fixture."""
9-
yield from asyncio.sleep(0.1)
8+
await asyncio.sleep(0.1)

tests/test_simple.py

+34-37
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
import pytest_asyncio.plugin
77

88

9-
@asyncio.coroutine
10-
def async_coro(loop=None):
9+
async def async_coro(loop=None):
1110
"""A very simple coroutine."""
12-
yield from asyncio.sleep(0, loop=loop)
11+
await asyncio.sleep(0, loop=loop)
1312
return 'ok'
1413

1514

@@ -53,66 +52,64 @@ def test_asyncio_marker_with_default_param(a_param=None):
5352

5453

5554
@pytest.mark.asyncio_process_pool
56-
def test_asyncio_process_pool_marker(event_loop):
55+
async def test_asyncio_process_pool_marker(event_loop):
5756
"""Test the asyncio pytest marker."""
58-
ret = yield from async_coro(event_loop)
57+
ret = await async_coro(event_loop)
5958
assert ret == 'ok'
6059

6160

6261
@pytest.mark.asyncio
63-
def test_unused_port_fixture(unused_tcp_port, event_loop):
62+
async def test_unused_port_fixture(unused_tcp_port, event_loop):
6463
"""Test the unused TCP port fixture."""
6564

66-
@asyncio.coroutine
67-
def closer(_, writer):
65+
async def closer(_, writer):
6866
writer.close()
6967

70-
server1 = yield from asyncio.start_server(closer, host='localhost',
71-
port=unused_tcp_port,
72-
loop=event_loop)
68+
server1 = await asyncio.start_server(closer, host='localhost',
69+
port=unused_tcp_port,
70+
loop=event_loop)
7371

7472
with pytest.raises(IOError):
75-
yield from asyncio.start_server(closer, host='localhost',
76-
port=unused_tcp_port,
77-
loop=event_loop)
73+
await asyncio.start_server(closer, host='localhost',
74+
port=unused_tcp_port,
75+
loop=event_loop)
7876

7977
server1.close()
80-
yield from server1.wait_closed()
78+
await server1.wait_closed()
8179

8280

8381
@pytest.mark.asyncio
84-
def test_unused_port_factory_fixture(unused_tcp_port_factory, event_loop):
82+
async def test_unused_port_factory_fixture(unused_tcp_port_factory, event_loop):
8583
"""Test the unused TCP port factory fixture."""
8684

87-
@asyncio.coroutine
88-
def closer(_, writer):
85+
async def closer(_, writer):
8986
writer.close()
9087

9188
port1, port2, port3 = (unused_tcp_port_factory(), unused_tcp_port_factory(),
9289
unused_tcp_port_factory())
9390

94-
server1 = yield from asyncio.start_server(closer, host='localhost',
95-
port=port1,
96-
loop=event_loop)
97-
server2 = yield from asyncio.start_server(closer, host='localhost',
98-
port=port2,
99-
loop=event_loop)
100-
server3 = yield from asyncio.start_server(closer, host='localhost',
101-
port=port3,
102-
loop=event_loop)
91+
server1 = await asyncio.start_server(closer, host='localhost',
92+
port=port1,
93+
loop=event_loop)
94+
server2 = await asyncio.start_server(closer, host='localhost',
95+
port=port2,
96+
loop=event_loop)
97+
server3 = await asyncio.start_server(closer, host='localhost',
98+
port=port3,
99+
loop=event_loop)
103100

104101
for port in port1, port2, port3:
105102
with pytest.raises(IOError):
106-
yield from asyncio.start_server(closer, host='localhost',
107-
port=port,
108-
loop=event_loop)
103+
await asyncio.start_server(closer, host='localhost',
104+
port=port,
105+
loop=event_loop)
109106

110107
server1.close()
111-
yield from server1.wait_closed()
108+
await server1.wait_closed()
112109
server2.close()
113-
yield from server2.wait_closed()
110+
await server2.wait_closed()
114111
server3.close()
115-
yield from server3.wait_closed()
112+
await server3.wait_closed()
116113

117114

118115
def test_unused_port_factory_duplicate(unused_tcp_port_factory, monkeypatch):
@@ -139,9 +136,9 @@ class Test:
139136
"""Test that asyncio marked functions work in test methods."""
140137

141138
@pytest.mark.asyncio
142-
def test_asyncio_marker_method(self, event_loop):
139+
async def test_asyncio_marker_method(self, event_loop):
143140
"""Test the asyncio pytest marker in a Test class."""
144-
ret = yield from async_coro(event_loop)
141+
ret = await async_coro(event_loop)
145142
assert ret == 'ok'
146143

147144

@@ -154,7 +151,7 @@ def remove_loop(self):
154151
asyncio.set_event_loop(old_loop)
155152

156153
@pytest.mark.asyncio
157-
def test_asyncio_marker_without_loop(self, remove_loop):
154+
async def test_asyncio_marker_without_loop(self, remove_loop):
158155
"""Test the asyncio pytest marker in a Test class."""
159-
ret = yield from async_coro()
156+
ret = await async_coro()
160157
assert ret == 'ok'

tests/test_simple_35.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import pytest
55

66

7-
@asyncio.coroutine
7+
@pytest.mark.asyncio
88
async def async_coro(loop):
99
await asyncio.sleep(0, loop=loop)
1010
return 'ok'

tests/test_subprocess.py

+6-8
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,18 @@
77

88

99
@pytest.mark.asyncio(forbid_global_loop=False)
10-
@asyncio.coroutine
11-
def test_subprocess(event_loop):
10+
async def test_subprocess(event_loop):
1211
"""Starting a subprocess should be possible."""
13-
proc = yield from asyncio.subprocess.create_subprocess_exec(
12+
proc = await asyncio.subprocess.create_subprocess_exec(
1413
sys.executable, '--version', stdout=asyncio.subprocess.PIPE,
1514
loop=event_loop)
16-
yield from proc.communicate()
15+
await proc.communicate()
1716

1817

1918
@pytest.mark.asyncio(forbid_global_loop=True)
20-
@asyncio.coroutine
21-
def test_subprocess_forbid(event_loop):
19+
async def test_subprocess_forbid(event_loop):
2220
"""Starting a subprocess should be possible."""
23-
proc = yield from asyncio.subprocess.create_subprocess_exec(
21+
proc = await asyncio.subprocess.create_subprocess_exec(
2422
sys.executable, '--version', stdout=asyncio.subprocess.PIPE,
2523
loop=event_loop)
26-
yield from proc.communicate()
24+
await proc.communicate()

tox.ini

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tox]
2-
envlist = py35, py36
2+
envlist = py35, py36, py37
33
minversion = 2.5.0
44

55
[testenv]
@@ -11,4 +11,4 @@ deps = coverage
1111
skip_install = true
1212
commands =
1313
coverage combine
14-
coverage report
14+
coverage report

0 commit comments

Comments
 (0)