Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,7 @@ jobs:
env:
- "JOB_NAME='Ubuntu 19.10, full VM'"
- "VM_IMAGE=https://cloud-images.ubuntu.com/eoan/current/eoan-server-cloudimg-amd64.img"
# 3.5.0 and 3.5.1 have different __aiter__ semantics than all
# other versions, so we need to test them specially. Travis's
# newer images only provide 3.5.2+, so we have to request the old
# 'trusty' images.
- python: 3.5.0
dist: trusty
- python: 3.5-dev
- python: 3.6.1 # earliest 3.6 version available on Travis
- python: 3.6-dev
- python: 3.7-dev
- python: 3.8-dev
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ demonstration of implementing the "Happy Eyeballs" algorithm in an
older library versus Trio.

**Cool, but will it work on my system?** Probably! As long as you have
some kind of Python 3.5-or-better (CPython or the latest PyPy3 are
some kind of Python 3.6-or-better (CPython or the latest PyPy3 are
both fine), and are using Linux, macOS, or Windows, then Trio should
absolutely work. *BSD and illumos likely work too, but we don't have
testing infrastructure for them. And all of our dependencies are pure
Expand Down
10 changes: 0 additions & 10 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,6 @@ jobs:
python.version: '3.7.5'
python.pkg: 'python'
lsp: 'http://download.pctools.com/mirror/updates/9.0.0.2308-SDavfree-lite_en.exe'
"Python 3.5, 32 bit":
python.version: '3.5.4'
python.pkg: 'pythonx86'
"Python 3.5, 64 bit":
python.version: '3.5.4'
python.pkg: 'python'
"Python 3.6, 32 bit":
python.version: '3.6.8'
python.pkg: 'pythonx86'
Expand Down Expand Up @@ -76,8 +70,6 @@ jobs:
"Formatting and linting":
python.version: '3.8'
CHECK_FORMATTING: 1
"Python 3.5":
python.version: '3.5'
"Python 3.6":
python.version: '3.6'
"Python 3.7":
Expand All @@ -104,8 +96,6 @@ jobs:
timeoutInMinutes: 10
strategy:
matrix:
"Python 3.5":
python.version: '3.5'
"Python 3.6":
python.version: '3.6'
"Python 3.7":
Expand Down
4 changes: 0 additions & 4 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,6 @@ if [ "$AGENT_OS" = "Windows_NT" ]; then

pydir="$PWD/pyinstall/${PYTHON_PKG}"
export PATH="${pydir}/tools:${pydir}/tools/scripts:$PATH"

# Fix an issue with the nuget python 3.5 packages
# https://github.com/python-trio/trio/pull/827#issuecomment-457433940
rm -f "${pydir}/tools/pyvenv.cfg" || true
fi

### Travis + macOS ###
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ chance to give feedback about any compatibility-breaking changes.
Vital statistics:

* Supported environments: Linux, macOS, or Windows running some kind of Python
3.5-or-better (either CPython or PyPy3 is fine). \*BSD and
3.6-or-better (either CPython or PyPy3 is fine). \*BSD and
illumos likely work too, but are untested.

* Install: ``python3 -m pip install -U trio`` (or on Windows, maybe
Expand Down
4 changes: 2 additions & 2 deletions docs/source/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Okay, ready? Let's get started.
Before you begin
----------------

1. Make sure you're using Python 3.5 or newer.
1. Make sure you're using Python 3.6 or newer.

2. ``python3 -m pip install --upgrade trio`` (or on Windows, maybe
``py -3 -m pip install --upgrade trio`` – `details
Expand Down Expand Up @@ -312,7 +312,7 @@ runs:
>>>> # but forcing a garbage collection gives us a warning:
>>>> import gc
>>>> gc.collect()
/home/njs/pypy-3.5-nightly/lib-python/3/importlib/_bootstrap.py:191: RuntimeWarning: coroutine 'sleep' was never awaited
/home/njs/pypy-3.8-nightly/lib-python/3/importlib/_bootstrap.py:191: RuntimeWarning: coroutine 'sleep' was never awaited
if _module_locks.get(name) is wr: # XXX PyPy fix?
0
>>>>
Expand Down
3 changes: 2 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[tool:pytest]
xfail_strict = true
faulthandler_timeout=60
faulthandler_timeout = 60
junit_family = xunit2
7 changes: 4 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
Vital statistics:

* Supported environments: Linux, macOS, or Windows running some kind of Python
3.5-or-better (either CPython or PyPy3 is fine). \\*BSD and illumos likely
3.6-or-better (either CPython or PyPy3 is fine). \\*BSD and illumos likely
work too, but are not tested.

* Install: ``python3 -m pip install -U trio`` (or on Windows, maybe
Expand Down Expand Up @@ -101,7 +101,7 @@
":os_name == 'nt'": ["cffi >= 1.12"], # "cffi is required on windows",
":python_version < '3.7'": ["contextvars>=2.1"]
},
python_requires=">=3.5",
python_requires=">=3.6",
keywords=["async", "io", "networking", "trio"],
classifiers=[
"Development Status :: 3 - Alpha",
Expand All @@ -115,8 +115,9 @@
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Topic :: System :: Networking",
"Framework :: Trio",
],
Expand Down
3 changes: 0 additions & 3 deletions trio/_abc.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from abc import ABCMeta, abstractmethod
from typing import Generic, TypeVar
from ._util import aiter_compat
import trio


Expand Down Expand Up @@ -414,7 +413,6 @@ async def receive_some(self, max_bytes=None):

"""

@aiter_compat
def __aiter__(self):
return self

Expand Down Expand Up @@ -629,7 +627,6 @@ async def receive(self) -> ReceiveType:

"""

@aiter_compat
def __aiter__(self):
return self

Expand Down
4 changes: 1 addition & 3 deletions trio/_core/_entry_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,7 @@ def run_sync_soon(self, sync_fn, *args, idempotent=False):
If ``idempotent=True``, then ``sync_fn`` and ``args`` must be
hashable, and Trio will make a best-effort attempt to discard any
call submission which is equal to an already-pending call. Trio
will make an attempt to process these in first-in first-out order,
but no guarantees. (Currently processing is FIFO on CPython 3.6 and
PyPy, but not CPython 3.5.)
will process these in first-in first-out order.

Any ordering guarantees apply separately to ``idempotent=False``
and ``idempotent=True`` calls; there's no rule for how calls in the
Expand Down
13 changes: 5 additions & 8 deletions trio/_core/_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def _public(fn):


# On 3.7+, Context.run() is implemented in C and doesn't show up in
# tracebacks. On 3.6 and earlier, we use the contextvars backport, which is
# tracebacks. On 3.6, we use the contextvars backport, which is
# currently implemented in Python and adds 1 frame to tracebacks. So this
# function is a super-overkill version of "0 if sys.version_info >= (3, 7)
# else 1". But if Context.run ever changes, we'll be ready!
Expand Down Expand Up @@ -1262,12 +1262,9 @@ def _return_value_looks_like_wrong_library(value):
# The protocol for detecting an asyncio Future-like object
if getattr(value, "_asyncio_future_blocking", None) is not None:
return True
# asyncio.Future doesn't have _asyncio_future_blocking until
# 3.5.3. We don't want to import asyncio, but this janky check
# should work well enough for our purposes. And it also catches
# tornado Futures and twisted Deferreds. By the time we're calling
# this function, we already know something has gone wrong, so a
# heuristic is pretty safe.
# This janky check catches tornado Futures and twisted Deferreds.
# By the time we're calling this function, we already know
# something has gone wrong, so a heuristic is pretty safe.
if value.__class__.__name__ in ("Future", "Deferred"):
return True
return False
Expand Down Expand Up @@ -1915,7 +1912,7 @@ def run_impl(runner, async_fn, args):
try:
# We used to unwrap the Outcome object here and send/throw its
# contents in directly, but it turns out that .throw() is
# buggy, at least on CPython 3.6 and earlier:
# buggy, at least on CPython 3.6:
# https://bugs.python.org/issue29587
# https://bugs.python.org/issue29590
# So now we send in the Outcome object and unwrap it on the
Expand Down
2 changes: 0 additions & 2 deletions trio/_core/_unbounded_queue.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import attr

from .. import _core
from .._util import aiter_compat
from .._deprecate import deprecated

__all__ = ["UnboundedQueue"]
Expand Down Expand Up @@ -146,7 +145,6 @@ def statistics(self):
tasks_waiting=self._lot.statistics().tasks_waiting
)

@aiter_compat
def __aiter__(self):
return self

Expand Down
8 changes: 2 additions & 6 deletions trio/_core/_windows_cffi.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import cffi
import re
import enum
try:
from enum import IntFlag
except ImportError: # python 3.5
from enum import IntEnum as IntFlag

################################################################
# Functions and types
Expand Down Expand Up @@ -264,7 +260,7 @@ class FileFlags(enum.IntEnum):
TRUNCATE_EXISTING = 5


class AFDPollFlags(IntFlag):
class AFDPollFlags(enum.IntFlag):
# These are drawn from a combination of:
# https://github.com/piscisaureus/wepoll/blob/master/src/afd.h
# https://github.com/reactos/reactos/blob/master/sdk/include/reactos/drivers/afd/shared.h
Expand All @@ -289,7 +285,7 @@ class WSAIoctls(enum.IntEnum):
SIO_BSP_HANDLE_SELECT = 0x4800001C


class CompletionModes(IntFlag):
class CompletionModes(enum.IntFlag):
FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 0x1
FILE_SKIP_SET_EVENT_ON_HANDLE = 0x2

Expand Down
20 changes: 6 additions & 14 deletions trio/_core/tests/test_ki.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
import contextlib
import time

from async_generator import (
async_generator, yield_, isasyncgenfunction, asynccontextmanager
)
from async_generator import isasyncgenfunction, asynccontextmanager

from ... import _core
from ...testing import wait_all_tasks_blocked
Expand Down Expand Up @@ -140,39 +138,35 @@ def protected_manager():

async def test_agen_protection():
@_core.enable_ki_protection
@async_generator
async def agen_protected1():
assert _core.currently_ki_protected()
try:
await yield_()
yield
finally:
assert _core.currently_ki_protected()

@_core.disable_ki_protection
@async_generator
async def agen_unprotected1():
assert not _core.currently_ki_protected()
try:
await yield_()
yield
finally:
assert not _core.currently_ki_protected()

# Swap the order of the decorators:
@async_generator
@_core.enable_ki_protection
async def agen_protected2():
assert _core.currently_ki_protected()
try:
await yield_()
yield
finally:
assert _core.currently_ki_protected()

@async_generator
@_core.disable_ki_protection
async def agen_unprotected2():
assert not _core.currently_ki_protected()
try:
await yield_()
yield
finally:
assert not _core.currently_ki_protected()

Expand Down Expand Up @@ -504,9 +498,7 @@ def test_ki_wakes_us_up():
#
# which contains the desired sequence.
#
# Affected version of CPython include:
# - all versions of 3.5 (fix will not be backported)
# - 3.6.1 and earlier
# Affected version of CPython include 3.6.1 and earlier.
# It's fixed in 3.6.2 and 3.7+
#
# PyPy was never affected.
Expand Down
44 changes: 14 additions & 30 deletions trio/_core/tests/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@
import outcome
import sniffio
import pytest
from async_generator import async_generator

from .tutil import slow, check_sequence_matches, gc_collect_harder
from ... import _core
from ..._threads import to_thread_run_sync
from ..._timeouts import sleep, fail_after
from ..._util import aiter_compat
from ...testing import (
wait_all_tasks_blocked,
Sequencer,
Expand All @@ -38,9 +36,7 @@ async def sleep_forever():
# Some of our tests need to leak coroutines, and thus trigger the
# "RuntimeWarning: coroutine '...' was never awaited" message. This context
# manager should be used anywhere this happens to hide those messages, because
# (a) when expected they're clutter, (b) on CPython 3.5.x where x < 3, this
# warning can trigger a segfault if we run with warnings turned into errors:
# https://bugs.python.org/issue27811
# when expected they're clutter.
@contextmanager
def ignore_coroutine_never_awaited_warnings():
with warnings.catch_warnings():
Expand Down Expand Up @@ -1387,12 +1383,6 @@ def cb(x):
for i in range(100):
token.run_sync_soon(cb, i, idempotent=True)
await wait_all_tasks_blocked()
if (
sys.version_info < (3, 6)
and platform.python_implementation() == "CPython"
):
# no order guarantees
record.sort()
# Otherwise, we guarantee FIFO
assert record == list(range(100))

Expand Down Expand Up @@ -1769,9 +1759,8 @@ def generator_based_coro(): # pragma: no cover
bad_call(len, [1, 2, 3])
assert "appears to be synchronous" in str(excinfo.value)

@async_generator
async def async_gen(arg): # pragma: no cover
pass
yield

with pytest.raises(TypeError) as excinfo:
bad_call(async_gen, 0)
Expand Down Expand Up @@ -2056,7 +2045,6 @@ def __init__(self, *largs):
async def _accumulate(self, f, items, i):
items[i] = await f()

@aiter_compat
def __aiter__(self):
return self

Expand Down Expand Up @@ -2397,22 +2385,18 @@ def test_async_function_implemented_in_C():
# cr_frame, but C functions don't have Python frames.

ns = {"_core": _core}
try:
exec(
dedent(
"""
async def agen_fn(record):
assert not _core.currently_ki_protected()
record.append("the generator ran")
yield
"""
),
ns,
)
except SyntaxError:
pytest.skip("Requires Python 3.6+")
else:
agen_fn = ns["agen_fn"]
exec(
dedent(
"""
async def agen_fn(record):
assert not _core.currently_ki_protected()
record.append("the generator ran")
yield
"""
),
ns,
)
agen_fn = ns["agen_fn"]

run_record = []
agen = agen_fn(run_record)
Expand Down
Loading