Skip to content

Commit 0a10ae8

Browse files
committed
Modernize and fix CI
Test on 3.10, 3.11, 3.12-dev, and recent pypy. Port from MultiError to ExceptionGroup, thus supporting (and requiring) Trio v0.22.0+. Drop support for 3.6 (required by ExceptionGroup support).
1 parent 308dd76 commit 0a10ae8

File tree

14 files changed

+235
-258
lines changed

14 files changed

+235
-258
lines changed

.github/workflows/ci.yml

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,40 @@ jobs:
1414
strategy:
1515
fail-fast: false
1616
matrix:
17-
python: ['3.6', '3.7', '3.8', '3.9']
17+
python: ['3.7', '3.8', '3.9', '3.10', '3.11', 'pypy-3.8-nightly', 'pypy-3.9-nightly']
1818
arch: ['x86', 'x64']
19+
exclude:
20+
- python: 'pypy-3.8-nightly'
21+
arch: 'x86'
22+
- python: 'pypy-3.9-nightly'
23+
arch: 'x86'
1924
steps:
2025
- name: Checkout
21-
uses: actions/checkout@v2
26+
uses: actions/checkout@v3
2227
- name: Setup python
23-
uses: actions/setup-python@v2
28+
uses: actions/setup-python@v4
2429
with:
25-
python-version: '${{ matrix.python }}'
30+
# This allows the matrix to specify just the major.minor version while still
31+
# expanding it to get the latest patch version including alpha releases.
32+
# This avoids the need to update for each new alpha, beta, release candidate,
33+
# and then finally an actual release version. actions/setup-python doesn't
34+
# support this for PyPy presently so we get no help there.
35+
#
36+
# CPython -> 3.9.0-alpha - 3.9.X
37+
# PyPy -> pypy-3.7
38+
python-version: ${{ fromJSON(format('["{0}", "{1}"]', format('{0}.0-alpha - {0}.X', matrix.python), matrix.python))[startsWith(matrix.python, 'pypy')] }}
2639
architecture: '${{ matrix.arch }}'
40+
cache: pip
41+
cache-dependency-path: test-requirements.txt
2742
- name: Run tests
2843
run: ./ci.sh
2944
shell: bash
30-
env:
31-
# Should match 'name:' up above
32-
JOB_NAME: 'Windows (${{ matrix.python }}, ${{ matrix.arch }}${{ matrix.extra_name }})'
45+
- if: always()
46+
uses: codecov/codecov-action@v3
47+
with:
48+
directory: empty
49+
name: Windows (${{ matrix.python }}, ${{ matrix.arch }}${{ matrix.extra_name }})
50+
flags: Windows,${{ matrix.python }}
3351

3452
Ubuntu:
3553
name: 'Ubuntu (${{ matrix.python }}${{ matrix.extra_name }})'
@@ -38,29 +56,23 @@ jobs:
3856
strategy:
3957
fail-fast: false
4058
matrix:
41-
# No pypy-3.7 because Trio doesn't support it (nightly is fine, it has a fix we need)
42-
python: ['pypy-3.6', '3.6', '3.7', '3.8', '3.9', '3.6-dev', '3.7-dev', '3.8-dev', '3.9-dev']
59+
python: ['pypy-3.7', 'pypy-3.8', 'pypy-3.9', '3.7', '3.8', '3.9', '3.10', '3.11', '3.12-dev', 'pypy-3.8-nightly', 'pypy-3.9-nightly']
4360
check_formatting: ['0']
44-
check_docs: ['0']
45-
pypy_nightly_branch: ['']
4661
extra_name: ['']
4762
include:
4863
- python: '3.8'
4964
check_formatting: '1'
5065
extra_name: ', check formatting'
51-
# pypy3.7-nightly produces an "OSError: handle is closed" in the
52-
# bowels of multiprocessing after all tests appear to complete successfully
53-
# - python: '3.7' # <- not actually used
54-
# pypy_nightly_branch: 'py3.7'
55-
# extra_name: ', pypy 3.7 nightly'
5666
steps:
5767
- name: Checkout
58-
uses: actions/checkout@v2
68+
uses: actions/checkout@v3
5969
- name: Setup python
60-
uses: actions/setup-python@v2
70+
uses: actions/setup-python@v4
6171
if: "!endsWith(matrix.python, '-dev')"
6272
with:
63-
python-version: '${{ matrix.python }}'
73+
python-version: ${{ fromJSON(format('["{0}", "{1}"]', format('{0}.0-alpha - {0}.X', matrix.python), matrix.python))[startsWith(matrix.python, 'pypy')] }}
74+
cache: pip
75+
cache-dependency-path: test-requirements.txt
6476
- name: Setup python (dev)
6577
uses: deadsnakes/action@v2.0.2
6678
if: endsWith(matrix.python, '-dev')
@@ -76,11 +88,13 @@ jobs:
7688
- name: Run tests
7789
run: ./ci.sh
7890
env:
79-
PYPY_NIGHTLY_BRANCH: '${{ matrix.pypy_nightly_branch }}'
8091
CHECK_FORMATTING: '${{ matrix.check_formatting }}'
81-
CHECK_DOCS: '${{ matrix.check_docs }}'
82-
# Should match 'name:' up above
83-
JOB_NAME: 'Ubuntu (${{ matrix.python }}${{ matrix.extra_name }})'
92+
- if: always()
93+
uses: codecov/codecov-action@v3
94+
with:
95+
directory: empty
96+
name: Ubuntu (${{ matrix.python }}${{ matrix.extra_name }})
97+
flags: Ubuntu,${{ matrix.python }}
8498

8599
macOS:
86100
name: 'macOS (${{ matrix.python }})'
@@ -89,16 +103,21 @@ jobs:
89103
strategy:
90104
fail-fast: false
91105
matrix:
92-
python: ['3.6', '3.7', '3.8', '3.9']
106+
python: ['3.7', '3.8', '3.9', '3.10', '3.11', 'pypy-3.8-nightly', 'pypy-3.9-nightly']
93107
steps:
94108
- name: Checkout
95-
uses: actions/checkout@v2
109+
uses: actions/checkout@v3
96110
- name: Setup python
97-
uses: actions/setup-python@v2
111+
uses: actions/setup-python@v4
98112
with:
99-
python-version: '${{ matrix.python }}'
113+
python-version: ${{ fromJSON(format('["{0}", "{1}"]', format('{0}.0-alpha - {0}.X', matrix.python), matrix.python))[startsWith(matrix.python, 'pypy')] }}
114+
cache: pip
115+
cache-dependency-path: test-requirements.txt
100116
- name: Run tests
101117
run: ./ci.sh
102-
env:
103-
# Should match 'name:' up above
104-
JOB_NAME: 'macOS (${{ matrix.python }})'
118+
- if: always()
119+
uses: codecov/codecov-action@v3
120+
with:
121+
directory: empty
122+
name: macOS (${{ matrix.python }})
123+
flags: macOS,${{ matrix.python }}

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
**trio-asyncio** is a re-implementation of the ``asyncio`` mainloop on top of
2727
Trio.
2828

29-
Trio-Asyncio requires at least Python 3.6. It is tested on recent versions of
30-
3.6, 3.7, 3.8, and nightly.
29+
Trio-Asyncio requires at least Python 3.7. It is tested on recent versions of
30+
3.7 through 3.11, plus 3.12-dev.
3131

3232
+++++++++++
3333
Rationale

ci.sh

Lines changed: 10 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -26,40 +26,6 @@ function curl-harder() {
2626
return 1
2727
}
2828

29-
################################################################
30-
# Bootstrap python environment, if necessary
31-
################################################################
32-
33-
### PyPy nightly (currently on Travis) ###
34-
35-
if [ "$PYPY_NIGHTLY_BRANCH" != "" ]; then
36-
JOB_NAME="pypy_nightly_${PYPY_NIGHTLY_BRANCH}"
37-
curl-harder -o pypy.tar.bz2 http://buildbot.pypy.org/nightly/${PYPY_NIGHTLY_BRANCH}/pypy-c-jit-latest-linux64.tar.bz2
38-
if [ ! -s pypy.tar.bz2 ]; then
39-
# We know:
40-
# - curl succeeded (200 response code)
41-
# - nonetheless, pypy.tar.bz2 does not exist, or contains no data
42-
# This isn't going to work, and the failure is not informative of
43-
# anything involving Trio.
44-
ls -l
45-
echo "PyPy3 nightly build failed to download – something is wrong on their end."
46-
echo "Skipping testing against the nightly build for right now."
47-
exit 0
48-
fi
49-
tar xaf pypy.tar.bz2
50-
# something like "pypy-c-jit-89963-748aa3022295-linux64"
51-
PYPY_DIR=$(echo pypy-c-jit-*)
52-
PYTHON_EXE=$PYPY_DIR/bin/pypy3
53-
54-
if ! ($PYTHON_EXE -m ensurepip \
55-
&& $PYTHON_EXE -m pip install virtualenv \
56-
&& $PYTHON_EXE -m virtualenv testenv); then
57-
echo "pypy nightly is broken; skipping tests"
58-
exit 0
59-
fi
60-
source testenv/bin/activate
61-
fi
62-
6329
################################################################
6430
# We have a Python environment!
6531
################################################################
@@ -72,14 +38,6 @@ python -m pip --version
7238
python setup.py sdist --formats=zip
7339
python -m pip install dist/*.zip
7440

75-
if python -c 'import sys; sys.exit(sys.version_info >= (3, 7))'; then
76-
# Python < 3.7, select last ipython with 3.6 support
77-
# macOS requires the suffix for --in-place or you get an undefined label error
78-
sed -i'.bak' 's/ipython==[^ ]*/ipython==7.16.1/' test-requirements.txt
79-
sed -i'.bak' 's/traitlets==[^ ]*/traitlets==4.3.3/' test-requirements.txt
80-
git diff test-requirements.txt
81-
fi
82-
8341
# See https://github.com/python-trio/trio/issues/334
8442
YAPF_VERSION=0.20.0
8543

@@ -113,24 +71,21 @@ else
11371
mkdir empty || true
11472
cd empty
11573

116-
# We have to copy .coveragerc into this directory, rather than passing
117-
# --cov-config=../.coveragerc to pytest, because codecov.sh will run
118-
# 'coverage xml' to generate the report that it uses, and that will only
119-
# apply the ignore patterns in the current directory's .coveragerc.
120-
cp ../.coveragerc .
121-
if pytest -ra --junitxml=../test-results.xml --cov=trio_asyncio --verbose ../tests; then
74+
INSTALLDIR=$(python -c "import os, trio_asyncio; print(os.path.dirname(trio_asyncio.__file__))")
75+
cp ../pyproject.toml $INSTALLDIR
76+
77+
# support subprocess spawning with coverage.py
78+
echo "import coverage; coverage.process_startup()" | tee -a "$INSTALLDIR/../sitecustomize.py"
79+
80+
if COVERAGE_PROCESS_START=$(pwd)/../.coveragerc coverage run --rcfile=../.coveragerc -m pytest -r a --junitxml=../test-results.xml --verbose ../tests; then
12281
PASSED=true
12382
else
12483
PASSED=false
12584
fi
12685

127-
# The codecov docs recommend something like 'bash <(curl ...)' to pipe the
128-
# script directly into bash as its being downloaded. But, the codecov
129-
# server is flaky, so we instead save to a temp file with retries, and
130-
# wait until we've successfully fetched the whole script before trying to
131-
# run it.
132-
curl-harder -o codecov.sh https://codecov.io/bash
133-
bash codecov.sh -n "${JOB_NAME}"
86+
coverage combine --rcfile ../.coveragerc
87+
coverage report -m --rcfile ../.coveragerc
88+
coverage xml --rcfile ../.coveragerc
13489

13590
$PASSED
13691
fi

docs/source/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ asyncio libraries such as ``home-assistant``.
5151
Helpful facts:
5252

5353
* Supported environments: Linux, MacOS, or Windows running some kind of Python
54-
3.6-or-better (either CPython or PyPy3 is fine). \*BSD and illumOS likely
54+
3.7-or-better (either CPython or PyPy3 is fine). \*BSD and illumOS likely
5555
work too, but are untested.
5656

5757
* Install: ``python3 -m pip install -U trio-asyncio`` (or on Windows, maybe

setup.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
code (asyncio: ~8000) but passes the complete Python 3.6 test suite with no
4444
errors.
4545
46-
``trio_asyncio`` requires Python 3.6 or better.
46+
``trio_asyncio`` requires Python 3.7 or better.
4747
4848
Author
4949
======
@@ -52,15 +52,6 @@
5252
5353
"""
5454

55-
install_requires = [
56-
"trio >= 0.15.0",
57-
"outcome",
58-
"sniffio",
59-
]
60-
if sys.version_info < (3, 7):
61-
install_requires.append("contextvars >= 2.1")
62-
install_requires.append("async_generator >= 1.6")
63-
6455
setup(
6556
name="trio_asyncio",
6657
version=__version__, # noqa: F821
@@ -71,11 +62,16 @@
7162
url="https://github.com/python-trio/trio-asyncio",
7263
license="MIT -or- Apache License 2.0",
7364
packages=["trio_asyncio"],
74-
install_requires=install_requires,
65+
install_requires=[
66+
"trio >= 0.22.0",
67+
"outcome",
68+
"sniffio >= 1.3.0",
69+
"exceptiongroup >= 1.0.0rc9; python_version < '3.11'",
70+
]
7571
# This means, just install *everything* you see under trio/, even if it
7672
# doesn't look like a source file, so long as it appears in MANIFEST.in:
7773
include_package_data=True,
78-
python_requires=">=3.6", # temporary, for RTD
74+
python_requires=">=3.7",
7975
keywords=["async", "io", "trio", "asyncio", "trio-asyncio"],
8076
setup_requires=['pytest-runner'],
8177
tests_require=['pytest >= 5.4', 'pytest-trio >= 0.6', 'outcome'],
@@ -91,7 +87,6 @@
9187
"Programming Language :: Python :: Implementation :: CPython",
9288
"Programming Language :: Python :: Implementation :: PyPy",
9389
"Programming Language :: Python :: 3 :: Only",
94-
"Programming Language :: Python :: 3.6",
9590
"Programming Language :: Python :: 3.7",
9691
"Topic :: System :: Networking",
9792
"Framework :: Trio",

tests/conftest.py

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,6 @@
33
import trio_asyncio
44
import inspect
55

6-
# Hacks for <3.7
7-
if not hasattr(asyncio, 'run'):
8-
9-
def run(main, *, debug=False):
10-
loop = asyncio.new_event_loop()
11-
loop.set_debug(debug)
12-
return loop.run(main)
13-
14-
asyncio.run = run
15-
16-
if not hasattr(asyncio, 'current_task'):
17-
18-
def current_task(loop=None):
19-
return asyncio.Task.current_task(loop)
20-
21-
asyncio.current_task = current_task
22-
23-
if not hasattr(asyncio, 'all_tasks'):
24-
25-
def all_tasks(loop=None):
26-
return asyncio.Task.all_tasks(loop)
27-
28-
asyncio.all_tasks = all_tasks
29-
30-
if not hasattr(asyncio, 'create_task'):
31-
32-
if hasattr(asyncio.events, 'get_running_loop'):
33-
34-
def create_task(coro):
35-
loop = asyncio.events.get_running_loop()
36-
return loop.create_task(coro)
37-
else:
38-
39-
def create_task(coro):
40-
loop = asyncio.events._get_running_loop()
41-
return loop.create_task(coro)
42-
43-
asyncio.create_task = create_task
44-
456

467
@pytest.fixture
478
async def loop():

0 commit comments

Comments
 (0)