Skip to content

Commit 3967dbf

Browse files
authored
Merge pull request pytest-dev#88 from jonafato/python-3.7
Python 3.7 support
2 parents a9a8db2 + d2dc635 commit 3967dbf

12 files changed

+72
-124
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

README.rst

+4-12
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,6 @@ If the ``pytest.mark.asyncio`` marker is applied, a pytest hook will
8888
ensure the produced loop is set as the default global loop.
8989
Fixtures depending on the ``event_loop`` fixture can expect the policy to be properly modified when they run.
9090

91-
``event_loop_process_pool``
92-
~~~~~~~~~~~~~~~~~~~~~~~~~~~
93-
The ``event_loop_process_pool`` fixture is almost identical to the
94-
``event_loop`` fixture, except the created event loop will have a
95-
``concurrent.futures.ProcessPoolExecutor`` set as the default executor.
96-
9791
``unused_tcp_port``
9892
~~~~~~~~~~~~~~~~~~~
9993
Finds and yields a single unused TCP port on the localhost interface. Useful for
@@ -176,17 +170,15 @@ Only test coroutines will be affected (by default, coroutines prefixed by
176170
.. |pytestmark| replace:: ``pytestmark``
177171
.. _pytestmark: http://doc.pytest.org/en/latest/example/markers.html#marking-whole-classes-or-modules
178172

179-
``pytest.mark.asyncio_process_pool``
180-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
181-
The ``asyncio_process_pool`` marker is almost identical to the ``asyncio``
182-
marker, except the event loop used will have a
183-
``concurrent.futures.ProcessPoolExecutor`` set as the default executor.
184-
185173
Changelog
186174
---------
187175

188176
0.9.0 (UNRELEASED)
189177
~~~~~~~~~~~~~~~~~~
178+
- Python 3.7 support
179+
- Remove ``event_loop_process_pool`` fixture and
180+
``pytest.mark.asyncio_process_pool`` marker (see
181+
https://bugs.python.org/issue34075 for deprecation and removal details)
190182

191183
0.8.0 (2017-09-23)
192184
~~~~~~~~~~~~~~~~~~

pytest_asyncio/plugin.py

+1-18
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import contextlib
44
import inspect
55
import socket
6-
from concurrent.futures import ProcessPoolExecutor
76

87
import pytest
98
from _pytest.python import transfer_markers
@@ -25,11 +24,6 @@ def pytest_configure(config):
2524
"asyncio: "
2625
"mark the test as a coroutine, it will be "
2726
"run using an asyncio event loop")
28-
config.addinivalue_line("markers",
29-
"asyncio_process_pool: "
30-
"mark the test as a coroutine, it will be "
31-
"run using an asyncio event loop with a process "
32-
"pool")
3327

3428

3529
@pytest.mark.tryfirst
@@ -44,8 +38,7 @@ def pytest_pycollect_makeitem(collector, name, obj):
4438
transfer_markers(obj, item.cls, item.module)
4539
item = pytest.Function(name, parent=collector) # To reload keywords.
4640

47-
if ('asyncio' in item.keywords or
48-
'asyncio_process_pool' in item.keywords):
41+
if 'asyncio' in item.keywords:
4942
return list(collector._genfunctions(name, obj))
5043

5144

@@ -170,7 +163,6 @@ def pytest_runtest_setup(item):
170163
# to marked test functions
171164
_markers_2_fixtures = {
172165
'asyncio': 'event_loop',
173-
'asyncio_process_pool': 'event_loop_process_pool',
174166
}
175167

176168

@@ -182,15 +174,6 @@ def event_loop(request):
182174
loop.close()
183175

184176

185-
@pytest.fixture
186-
def event_loop_process_pool(event_loop):
187-
"""Create a fresh instance of the default event loop.
188-
189-
The event loop will have a process pool set as the default executor."""
190-
event_loop.set_default_executor(ProcessPoolExecutor())
191-
return event_loop
192-
193-
194177
@pytest.fixture
195178
def unused_tcp_port():
196179
"""Find an unused localhost TCP port from 1024-65535 and return it."""

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

+32-56
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

@@ -20,20 +19,6 @@ def test_event_loop_fixture(event_loop):
2019
assert ret == 'ok'
2120

2221

23-
def test_event_loop_processpool_fixture(event_loop_process_pool):
24-
"""Test the injection of the event_loop with a process pool fixture."""
25-
assert event_loop_process_pool
26-
27-
ret = event_loop_process_pool.run_until_complete(
28-
async_coro(event_loop_process_pool))
29-
assert ret == 'ok'
30-
31-
this_pid = os.getpid()
32-
future = event_loop_process_pool.run_in_executor(None, os.getpid)
33-
pool_pid = event_loop_process_pool.run_until_complete(future)
34-
assert this_pid != pool_pid
35-
36-
3722
@pytest.mark.asyncio
3823
def test_asyncio_marker():
3924
"""Test the asyncio pytest marker."""
@@ -52,67 +37,58 @@ def test_asyncio_marker_with_default_param(a_param=None):
5237
yield # sleep(0)
5338

5439

55-
@pytest.mark.asyncio_process_pool
56-
def test_asyncio_process_pool_marker(event_loop):
57-
"""Test the asyncio pytest marker."""
58-
ret = yield from async_coro(event_loop)
59-
assert ret == 'ok'
60-
61-
6240
@pytest.mark.asyncio
63-
def test_unused_port_fixture(unused_tcp_port, event_loop):
41+
async def test_unused_port_fixture(unused_tcp_port, event_loop):
6442
"""Test the unused TCP port fixture."""
6543

66-
@asyncio.coroutine
67-
def closer(_, writer):
44+
async def closer(_, writer):
6845
writer.close()
6946

70-
server1 = yield from asyncio.start_server(closer, host='localhost',
71-
port=unused_tcp_port,
72-
loop=event_loop)
47+
server1 = await asyncio.start_server(closer, host='localhost',
48+
port=unused_tcp_port,
49+
loop=event_loop)
7350

7451
with pytest.raises(IOError):
75-
yield from asyncio.start_server(closer, host='localhost',
76-
port=unused_tcp_port,
77-
loop=event_loop)
52+
await asyncio.start_server(closer, host='localhost',
53+
port=unused_tcp_port,
54+
loop=event_loop)
7855

7956
server1.close()
80-
yield from server1.wait_closed()
57+
await server1.wait_closed()
8158

8259

8360
@pytest.mark.asyncio
84-
def test_unused_port_factory_fixture(unused_tcp_port_factory, event_loop):
61+
async def test_unused_port_factory_fixture(unused_tcp_port_factory, event_loop):
8562
"""Test the unused TCP port factory fixture."""
8663

87-
@asyncio.coroutine
88-
def closer(_, writer):
64+
async def closer(_, writer):
8965
writer.close()
9066

9167
port1, port2, port3 = (unused_tcp_port_factory(), unused_tcp_port_factory(),
9268
unused_tcp_port_factory())
9369

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)
70+
server1 = await asyncio.start_server(closer, host='localhost',
71+
port=port1,
72+
loop=event_loop)
73+
server2 = await asyncio.start_server(closer, host='localhost',
74+
port=port2,
75+
loop=event_loop)
76+
server3 = await asyncio.start_server(closer, host='localhost',
77+
port=port3,
78+
loop=event_loop)
10379

10480
for port in port1, port2, port3:
10581
with pytest.raises(IOError):
106-
yield from asyncio.start_server(closer, host='localhost',
107-
port=port,
108-
loop=event_loop)
82+
await asyncio.start_server(closer, host='localhost',
83+
port=port,
84+
loop=event_loop)
10985

11086
server1.close()
111-
yield from server1.wait_closed()
87+
await server1.wait_closed()
11288
server2.close()
113-
yield from server2.wait_closed()
89+
await server2.wait_closed()
11490
server3.close()
115-
yield from server3.wait_closed()
91+
await server3.wait_closed()
11692

11793

11894
def test_unused_port_factory_duplicate(unused_tcp_port_factory, monkeypatch):
@@ -139,9 +115,9 @@ class Test:
139115
"""Test that asyncio marked functions work in test methods."""
140116

141117
@pytest.mark.asyncio
142-
def test_asyncio_marker_method(self, event_loop):
118+
async def test_asyncio_marker_method(self, event_loop):
143119
"""Test the asyncio pytest marker in a Test class."""
144-
ret = yield from async_coro(event_loop)
120+
ret = await async_coro(event_loop)
145121
assert ret == 'ok'
146122

147123

@@ -154,7 +130,7 @@ def remove_loop(self):
154130
asyncio.set_event_loop(old_loop)
155131

156132
@pytest.mark.asyncio
157-
def test_asyncio_marker_without_loop(self, remove_loop):
133+
async def test_asyncio_marker_without_loop(self, remove_loop):
158134
"""Test the asyncio pytest marker in a Test class."""
159-
ret = yield from async_coro()
135+
ret = await async_coro()
160136
assert ret == 'ok'

tests/test_simple_35.py

+1-7
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'
@@ -20,12 +20,6 @@ async def test_asyncio_marker_with_default_param(a_param=None):
2020
"""Test the asyncio pytest marker."""
2121

2222

23-
@pytest.mark.asyncio_process_pool
24-
async def test_asyncio_process_pool_marker(event_loop):
25-
ret = await async_coro(event_loop)
26-
assert ret == 'ok'
27-
28-
2923
@pytest.mark.asyncio
3024
async def test_unused_port_fixture(unused_tcp_port, event_loop):
3125
"""Test the unused TCP port fixture."""

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)