Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop Python 3.5 (third take) #1481

Merged
merged 20 commits into from
Apr 30, 2020
Merged
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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ['3.5', '3.6', '3.7', '3.8']
python: ['3.6', '3.7', '3.8']
arch: ['x86', 'x64']
lsp: ['']
extra_name: ['']
Expand Down Expand Up @@ -46,7 +46,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ['3.5', '3.6', '3.7', '3.8']
python: ['3.6', '3.7', '3.8']
check_docs: ['0']
check_formatting: ['0']
extra_name: ['']
Expand Down Expand Up @@ -79,7 +79,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ['3.5', '3.6', '3.7', '3.8']
python: ['3.6', '3.7', '3.8']
steps:
- name: Checkout
uses: actions/checkout@v2
Expand Down
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific motivation for this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, I think I just mirrored the fact that we were supporting early versions of Python 3.5. In fact it looks like test_ki_wakes_us_up could be simplified if we decide to only support 3.6.2+.

- 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
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
1 change: 1 addition & 0 deletions newsfragments/75.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Remove support for Python 3.5.
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ xfail_strict = true
faulthandler_timeout=60
markers =
redistributors_should_skip: tests that should be skipped by downstream redistributors
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 @@ -93,7 +93,7 @@
# This means, just install *everything* you see under trio/, even if it
# doesn't look like a source file, so long as it appears in MANIFEST.in:
include_package_data=True,
python_requires=">=3.5",
python_requires=">=3.6",
keywords=["async", "io", "networking", "trio"],
classifiers=[
"Development Status :: 3 - Alpha",
Expand All @@ -107,8 +107,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
7 changes: 0 additions & 7 deletions trio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,3 @@
__name__ + ".subprocess", _deprecated_subprocess_reexports.__dict__
)
del fixup_module_metadata

import sys
if sys.version_info < (3, 6):
_deprecate.warn_deprecated(
"Support for Python 3.5", "0.14", issue=75, instead="Python 3.6+"
)
del sys
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 @@ -1256,12 +1256,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 @@ -1909,7 +1906,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
23 changes: 20 additions & 3 deletions trio/_core/tests/test_ki.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,30 @@ async def agen_unprotected2():
finally:
assert not _core.currently_ki_protected()

# Native async generators
@_core.enable_ki_protection
async def agen_protected3():
assert _core.currently_ki_protected()
try:
yield
finally:
assert _core.currently_ki_protected()

@_core.disable_ki_protection
async def agen_unprotected3():
assert not _core.currently_ki_protected()
try:
yield
finally:
assert not _core.currently_ki_protected()

for agen_fn in [
agen_protected1,
agen_protected2,
agen_protected3,
agen_unprotected1,
agen_unprotected2,
agen_unprotected3,
]:
async for _ in agen_fn(): # noqa
assert not _core.currently_ki_protected()
Expand Down Expand Up @@ -504,9 +523,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
39 changes: 7 additions & 32 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 @@ -1380,13 +1376,7 @@ 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
# We guarantee FIFO
assert record == list(range(100))


Expand Down Expand Up @@ -1762,9 +1752,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 @@ -2049,7 +2038,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 @@ -2389,23 +2377,10 @@ def test_async_function_implemented_in_C():
# These used to crash because we'd try to mutate the coroutine object's
# 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"]
async def agen_fn(record):
assert not _core.currently_ki_protected()
record.append("the generator ran")
yield

run_record = []
agen = agen_fn(run_record)
Expand Down
9 changes: 2 additions & 7 deletions trio/_deprecated_ssl_reexports.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,10 @@
cert_time_to_seconds, CertificateError, create_default_context,
DER_cert_to_PEM_cert, get_default_verify_paths, match_hostname,
PEM_cert_to_DER_cert, Purpose, SSLEOFError, SSLError, SSLSyscallError,
SSLZeroReturnError
SSLZeroReturnError, AlertDescription, SSLErrorNumber, SSLSession,
VerifyFlags, VerifyMode, Options
)

# Added in python 3.6
try:
from ssl import AlertDescription, SSLErrorNumber, SSLSession, VerifyFlags, VerifyMode, Options # noqa
except ImportError:
pass

# Added in python 3.7
try:
from ssl import SSLCertVerificationError, TLSVersion # noqa
Expand Down
Loading