Skip to content

Commit 4d1c696

Browse files
authored
Merge branch 'master' into update-copyright
2 parents 62aacbd + b231ec4 commit 4d1c696

File tree

9 files changed

+219
-11
lines changed

9 files changed

+219
-11
lines changed

.github/workflows/ci.yml

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
tags:
8+
- v*
9+
pull_request:
10+
branches:
11+
- "*"
12+
13+
jobs:
14+
test:
15+
name: ${{ matrix.os.name }} ${{ matrix.python.name }} ${{ matrix.reactor.name }}
16+
runs-on: ${{ matrix.os.runs-on }}
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
os:
21+
- name: Linux
22+
runs-on: ubuntu-latest
23+
- name: Windows
24+
runs-on: windows-latest
25+
- name: macOS
26+
runs-on: macos-latest
27+
python:
28+
- name: CPython 2.7
29+
tox: py27
30+
action: 2.7
31+
- name: CPython 3.5
32+
tox: py35
33+
action: 3.5
34+
- name: CPython 3.6
35+
tox: py36
36+
action: 3.6
37+
- name: CPython 3.7
38+
tox: py37
39+
action: 3.7
40+
- name: CPython 3.8
41+
tox: py38
42+
action: 3.8
43+
reactor:
44+
- name: default
45+
tox: default
46+
- name: Qt5
47+
tox: qt5
48+
- name: asyncio
49+
tox: asyncio
50+
exclude:
51+
- python:
52+
tox: py27
53+
reactor:
54+
tox: qt5
55+
- python:
56+
tox: py27
57+
reactor:
58+
tox: asyncio
59+
steps:
60+
- uses: actions/checkout@v2
61+
- name: Set up ${{ matrix.python.name }}
62+
uses: actions/setup-python@v1
63+
with:
64+
python-version: ${{ matrix.python.action }}
65+
architecture: x64
66+
- name: Install
67+
run: |
68+
pip install tox
69+
- name: Test
70+
run: |
71+
tox -v -e "${{ matrix.python.tox }}-${{ matrix.reactor.tox }}reactor"
72+
linting:
73+
name: Linting
74+
runs-on: ubuntu-latest
75+
strategy:
76+
matrix:
77+
python:
78+
- short: 37
79+
dotted: 3.7
80+
steps:
81+
- uses: actions/checkout@v2
82+
- name: Set up Python ${{ matrix.python.dotted }}
83+
uses: actions/setup-python@v1
84+
with:
85+
python-version: ${{ matrix.python.dotted }}
86+
architecture: x64
87+
- name: Install
88+
run: |
89+
pip install tox
90+
- name: Test
91+
run: |
92+
tox -v -e linting

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ matrix:
88
- python: 3.7
99
dist: xenial
1010
sudo: true
11+
- python: 3.8
12+
dist: xenial
13+
sudo: true
1114

1215
addons:
1316
apt:

README.rst

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,59 @@ which uses the twisted framework. test functions can return Deferred
1818
objects and pytest will wait for their completion with this plugin.
1919

2020

21+
NOTICE: Python 3.8 with asyncio support
22+
=======================================
23+
24+
In Python 3.8, asyncio changed the default loop implementation to use
25+
their proactor. The proactor does not implement some methods used by
26+
Twisted's asyncio support. The result is a ``NotImplementedError``
27+
exception such as below.
28+
29+
.. code-block:: pytb
30+
31+
<snip>
32+
File "c:\projects\pytest-twisted\.tox\py38-asyncioreactor\lib\site-packages\twisted\internet\asyncioreactor.py", line 320, in install
33+
reactor = AsyncioSelectorReactor(eventloop)
34+
File "c:\projects\pytest-twisted\.tox\py38-asyncioreactor\lib\site-packages\twisted\internet\asyncioreactor.py", line 69, in __init__
35+
super().__init__()
36+
File "c:\projects\pytest-twisted\.tox\py38-asyncioreactor\lib\site-packages\twisted\internet\base.py", line 571, in __init__
37+
self.installWaker()
38+
File "c:\projects\pytest-twisted\.tox\py38-asyncioreactor\lib\site-packages\twisted\internet\posixbase.py", line 286, in installWaker
39+
self.addReader(self.waker)
40+
File "c:\projects\pytest-twisted\.tox\py38-asyncioreactor\lib\site-packages\twisted\internet\asyncioreactor.py", line 151, in addReader
41+
self._asyncioEventloop.add_reader(fd, callWithLogger, reader,
42+
File "C:\Python38-x64\Lib\asyncio\events.py", line 501, in add_reader
43+
raise NotImplementedError
44+
NotImplementedError
45+
46+
The previous default, the selector loop, still works but you have to
47+
explicitly set it and do so early. The following ``conftest.py`` is provided
48+
for reference.
49+
50+
.. code-block:: python3
51+
52+
import sys
53+
54+
import pytest
55+
import pytest_twisted
56+
57+
58+
@pytest.hookimpl(tryfirst=True)
59+
def pytest_configure(config):
60+
# https://twistedmatrix.com/trac/ticket/9766
61+
# https://github.com/pytest-dev/pytest-twisted/issues/80
62+
63+
if (
64+
config.getoption("reactor", "default") == "asyncio"
65+
and sys.platform == 'win32'
66+
and sys.version_info >= (3, 8)
67+
):
68+
import asyncio
69+
70+
selector_policy = asyncio.WindowsSelectorEventLoopPolicy()
71+
asyncio.set_event_loop_policy(selector_policy)
72+
73+
2174
Python 2 support plans
2275
======================
2376

appveyor.yml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,30 @@ environment:
88
- TOXENV: py27-defaultreactor
99
PYTHON: "C:\\Python27-x64"
1010

11-
- TOXENV: py35-defaultreactor, win-py35-qt5reactor, py35-asyncioreactor
11+
- TOXENV: py35-defaultreactor, py35-qt5reactor, py35-asyncioreactor
1212
PYTHON: "C:\\Python35"
1313

14-
- TOXENV: py35-defaultreactor, win-py35-qt5reactor, py35-asyncioreactor
14+
- TOXENV: py35-defaultreactor, py35-qt5reactor, py35-asyncioreactor
1515
PYTHON: "C:\\Python35-x64"
1616

17-
- TOXENV: py36-defaultreactor, win-py36-qt5reactor, py36-asyncioreactor
17+
- TOXENV: py36-defaultreactor, py36-qt5reactor, py36-asyncioreactor
1818
PYTHON: "C:\\Python36"
1919

20-
- TOXENV: py36-defaultreactor, win-py36-qt5reactor, py36-asyncioreactor
20+
- TOXENV: py36-defaultreactor, py36-qt5reactor, py36-asyncioreactor
2121
PYTHON: "C:\\Python36-x64"
2222

23-
- TOXENV: py37-defaultreactor, win-py37-qt5reactor, py37-asyncioreactor
23+
- TOXENV: py37-defaultreactor, py37-qt5reactor, py37-asyncioreactor
2424
PYTHON: "C:\\Python37"
2525

26-
- TOXENV: py37-defaultreactor, win-py37-qt5reactor, py37-asyncioreactor
26+
- TOXENV: py37-defaultreactor, py37-qt5reactor, py37-asyncioreactor
2727
PYTHON: "C:\\Python37-x64"
2828

29+
- TOXENV: py38-defaultreactor, py38-qt5reactor, py38-asyncioreactor
30+
PYTHON: "C:\\Python38"
31+
32+
- TOXENV: py38-defaultreactor, py38-qt5reactor, py38-asyncioreactor
33+
PYTHON: "C:\\Python38-x64"
34+
2935
install:
3036
# https://github.com/pypa/virtualenv/issues/1050
3137
- pip install -U git+https://github.com/pypa/virtualenv@e8163e83a92c9098f51d390289323232ece15e3b

pytest_twisted.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import functools
22
import inspect
3+
import sys
34
import warnings
45

56
import decorator
@@ -326,3 +327,18 @@ def pytest_configure(config):
326327
)(blockon)
327328

328329
reactor_installers[config.getoption("reactor")]()
330+
331+
332+
def _use_asyncio_selector_if_required(config):
333+
# https://twistedmatrix.com/trac/ticket/9766
334+
# https://github.com/pytest-dev/pytest-twisted/issues/80
335+
336+
if (
337+
config.getoption("reactor", "default") == "asyncio"
338+
and sys.platform == 'win32'
339+
and sys.version_info >= (3, 8)
340+
):
341+
import asyncio
342+
343+
selector_policy = asyncio.WindowsSelectorEventLoopPolicy()
344+
asyncio.set_event_loop_policy(selector_policy)

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"Programming Language :: Python :: 3.5",
2929
"Programming Language :: Python :: 3.6",
3030
"Programming Language :: Python :: 3.7",
31+
"Programming Language :: Python :: 3.8",
3132
],
3233
entry_points={"pytest11": ["twisted = pytest_twisted"]},
3334
)

testing/conftest.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
1+
import pytest
2+
import pytest_twisted
3+
4+
15
pytest_plugins = "_pytest.pytester"
6+
7+
8+
@pytest.hookimpl(tryfirst=True)
9+
def pytest_configure(config):
10+
pytest_twisted._use_asyncio_selector_if_required(config=config)

testing/test_basic.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,19 @@ def format_run_result_output_for_assert(run_result):
4949
)
5050

5151

52+
@pytest.fixture(name="default_conftest", autouse=True)
53+
def _default_conftest(testdir):
54+
testdir.makeconftest(textwrap.dedent("""
55+
import pytest
56+
import pytest_twisted
57+
58+
59+
@pytest.hookimpl(tryfirst=True)
60+
def pytest_configure(config):
61+
pytest_twisted._use_asyncio_selector_if_required(config=config)
62+
"""))
63+
64+
5265
def skip_if_reactor_not(request, expected_reactor):
5366
actual_reactor = request.config.getoption("reactor", "default")
5467
if actual_reactor != expected_reactor:
@@ -334,7 +347,10 @@ def test_async_fixture(testdir, cmd_opts):
334347
import pytest
335348
import pytest_twisted
336349
337-
@pytest_twisted.async_fixture(scope="function", params=["fs", "imap", "web"])
350+
@pytest_twisted.async_fixture(
351+
scope="function",
352+
params=["fs", "imap", "web"],
353+
)
338354
@pytest.mark.redgreenblue
339355
async def foo(request):
340356
d1, d2 = defer.Deferred(), defer.Deferred()
@@ -627,10 +643,14 @@ def main():
627643
def test_blockon_in_hook_with_asyncio(testdir, cmd_opts, request):
628644
skip_if_reactor_not(request, "asyncio")
629645
conftest_file = """
646+
import pytest
630647
import pytest_twisted as pt
631648
from twisted.internet import defer
632649
650+
@pytest.hookimpl(tryfirst=True)
633651
def pytest_configure(config):
652+
pt._use_asyncio_selector_if_required(config=config)
653+
634654
pt.init_asyncio_reactor()
635655
d = defer.Deferred()
636656
@@ -656,6 +676,14 @@ def test_succeed():
656676
def test_wrong_reactor_with_asyncio(testdir, cmd_opts, request):
657677
skip_if_reactor_not(request, "asyncio")
658678
conftest_file = """
679+
import pytest
680+
import pytest_twisted
681+
682+
683+
@pytest.hookimpl(tryfirst=True)
684+
def pytest_configure(config):
685+
pytest_twisted._use_asyncio_selector_if_required(config=config)
686+
659687
def pytest_addhooks():
660688
import twisted.internet.default
661689
twisted.internet.default.install()

tox.ini

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
[tox]
22
envlist=
3-
py{27,35}-defaultreactor
4-
py{35,36,37}-{default,qt5,asyncio}reactor
5-
win-py{35,36,37}-qt5reactor
3+
py27-defaultreactor
4+
py{35,36,37,38}-{default,qt5,asyncio}reactor
5+
py{35,36,37,38}-qt5reactor
66
linting
77

88
[testenv]
99
deps=
1010
greenlet
1111
pytest
1212
twisted
13+
pywin32; sys_platform == 'win32'
1314
qt5reactor: pytest-qt
1415
qt5reactor: qt5reactor
1516
qt5reactor: pytest-xvfb
1617
qt5reactor: pyqt5
17-
win: pywin32
1818
commands=
1919
defaultreactor: pytest --reactor=default
2020
qt5reactor: pytest --reactor=qt5reactor

0 commit comments

Comments
 (0)