Skip to content

Commit

Permalink
Drop Python 3.6 support (#2210)
Browse files Browse the repository at this point in the history
* Remove Python 3.6 IPython hack in CI script
* Remove exc_key compatibility hack in MultiError
* Remove KI test that is no longer required
* Update a number of comments referring to Python 3.6
* Stop checking for warn_on_full_buffer (this is always available now)
* Stop installing contextvars since we dropped 3.6 support
* Remove TCP_NOTSENT_LOWAT definitions (they always exist in Python 3.7+)
* Remove obsolete check for GenericMeta
* Remove check for ssl.OP_NO_TLSv1_3 (this flag was introduced in Python 3.7 so it's always there now)

Co-authored-by: Quentin Pradet <quentin.pradet@gmail.com>
  • Loading branch information
agronholm and pquentin authored Jan 24, 2022
1 parent 4edfd41 commit 39d01b2
Show file tree
Hide file tree
Showing 23 changed files with 39 additions and 267 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ['3.6', '3.7', '3.8', '3.9', '3.10']
python: ['3.7', '3.8', '3.9', '3.10']
arch: ['x86', 'x64']
lsp: ['']
lsp_extract_file: ['']
Expand Down Expand Up @@ -51,7 +51,7 @@ jobs:
# This avoids the need to update for each new alpha, beta, release candidate,
# and then finally an actual release version. actions/setup-python doesn't
# support this for PyPy presently so we get no help there.
#
#
# CPython -> 3.9.0-alpha - 3.9.X
# PyPy -> pypy-3.7
python-version: ${{ fromJSON(format('["{0}", "{1}"]', format('{0}.0-alpha - {0}.X', matrix.python), matrix.python))[startsWith(matrix.python, 'pypy')] }}
Expand All @@ -72,7 +72,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ['pypy-3.6', 'pypy-3.7', 'pypy-3.8', '3.6', '3.7', '3.8', '3.9', '3.10', '3.8-dev', '3.9-dev', '3.10-dev']
python: ['pypy-3.7', 'pypy-3.8', '3.7', '3.8', '3.9', '3.10', '3.8-dev', '3.9-dev', '3.10-dev']
check_formatting: ['0']
pypy_nightly_branch: ['']
extra_name: ['']
Expand Down Expand Up @@ -114,7 +114,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ['3.6', '3.7', '3.8', '3.9', '3.10']
python: ['3.7', '3.8', '3.9', '3.10']
include:
- python: '3.8' # <- not actually used
arch: 'x64'
Expand Down
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
.. image:: https://img.shields.io/badge/docs-read%20now-blue.svg
:target: https://trio.readthedocs.io
:alt: Documentation

.. image:: https://img.shields.io/pypi/v/trio.svg
:target: https://pypi.org/project/trio
:alt: Latest PyPi version

.. image:: https://img.shields.io/conda/vn/conda-forge/trio.svg
:target: https://anaconda.org/conda-forge/trio
:alt: Latest conda-forge version
:alt: Latest conda-forge version

.. image:: https://codecov.io/gh/python-trio/trio/branch/master/graph/badge.svg
:target: https://codecov.io/gh/python-trio/trio
Expand Down Expand Up @@ -92,7 +92,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.6-or-better (CPython or the latest PyPy3 are
some kind of Python 3.7-or-better (CPython or the latest PyPy3 are
both fine), and are using Linux, macOS, Windows, or FreeBSD, then Trio
will work. Other environments might work too, but those
are the ones we test on. And all of our dependencies are pure Python,
Expand Down
8 changes: 0 additions & 8 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,6 @@ python -m pip --version
python setup.py sdist --formats=zip
python -m pip install dist/*.zip

if python -c 'import sys; sys.exit(sys.version_info >= (3, 7))'; then
# Python < 3.7, select last ipython with 3.6 support
# macOS requires the suffix for --in-place or you get an undefined label error
sed -i'.bak' 's/ipython==[^ ]*/ipython==7.16.1/' test-requirements.txt
sed -i'.bak' 's/traitlets==[^ ]*/traitlets==4.3.3/' test-requirements.txt
git diff test-requirements.txt
fi

if [ "$CHECK_FORMATTING" = "1" ]; then
python -m pip install -r test-requirements.txt
source check.sh
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Vital statistics:

* Supported environments: We test on

- Python: 3.6+ (CPython and PyPy)
- Python: 3.7+ (CPython and PyPy)
- Windows, macOS, Linux (glibc and musl), FreeBSD

Other environments might also work; give it a try and see.
Expand Down
5 changes: 2 additions & 3 deletions docs/source/reference-io.rst
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,7 @@ other constants and functions in the :mod:`ssl` module.

.. warning:: Avoid instantiating :class:`ssl.SSLContext` directly.
A newly constructed :class:`~ssl.SSLContext` has less secure
defaults than one returned by :func:`ssl.create_default_context`,
dramatically so before Python 3.6.
defaults than one returned by :func:`ssl.create_default_context`.

Instead of using :meth:`ssl.SSLContext.wrap_socket`, you
create a :class:`SSLStream`:
Expand Down Expand Up @@ -722,7 +721,7 @@ subprocess`` in order to access constants such as ``PIPE`` or

Currently, Trio always uses unbuffered byte streams for communicating
with a process, so it does not support the ``encoding``, ``errors``,
``universal_newlines`` (alias ``text`` in 3.7+), and ``bufsize``
``universal_newlines`` (alias ``text``), and ``bufsize``
options.


Expand Down
5 changes: 1 addition & 4 deletions docs/source/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ Tutorial
print(response)
and then again with /delay/10
(note that asks needs cpython 3.6 though. maybe just for one async
generator?)
value of async/await: show you where the cancellation exceptions
can happen -- see pillar re: explicit cancel points
Expand Down Expand Up @@ -94,7 +91,7 @@ Okay, ready? Let's get started.
Before you begin
----------------

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

2. ``python3 -m pip install --upgrade trio`` (or on Windows, maybe
``py -3 -m pip install --upgrade trio`` – `details
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tool.black]
target-version = ['py36']
target-version = ['py37']


[tool.towncrier]
Expand Down
8 changes: 4 additions & 4 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.6-or-better (either CPython or PyPy3 is fine). \\*BSD and illumos likely
3.7-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 @@ -89,12 +89,11 @@
# cffi 1.14 fixes memory leak inside ffi.getwinerror()
# cffi is required on Windows, except on PyPy where it is built-in
"cffi>=1.14; os_name == 'nt' and implementation_name != 'pypy'",
"contextvars>=2.1; python_version < '3.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.6",
python_requires=">=3.7",
keywords=["async", "io", "networking", "trio"],
classifiers=[
"Development Status :: 3 - Alpha",
Expand All @@ -108,10 +107,11 @@
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Topic :: System :: Networking",
"Framework :: Trio",
],
Expand Down
6 changes: 0 additions & 6 deletions test-requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,9 @@ typing-extensions; implementation_name == "cpython"

# Trio's own dependencies
cffi; os_name == "nt"
contextvars; python_version < "3.7"
attrs >= 19.2.0
sortedcontainers
async_generator >= 1.9
idna
outcome
sniffio

# Required by contextvars, but harmless to install everywhere.
# dependabot drops the contextvars dependency because it runs
# on 3.7.
immutables >= 0.6
4 changes: 2 additions & 2 deletions trio/_core/_entry_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class EntryQueue:
# not signal-safe. deque is implemented in C, so each operation is atomic
# WRT threads (and this is guaranteed in the docs), AND each operation is
# atomic WRT signal delivery (signal handlers can run on either side, but
# not *during* a deque operation). dict makes similar guarantees - and on
# CPython 3.6 and PyPy, it's even ordered!
# not *during* a deque operation). dict makes similar guarantees - and
# it's even ordered!
queue = attr.ib(factory=deque)
idempotent_queue = attr.ib(factory=dict)

Expand Down
9 changes: 1 addition & 8 deletions trio/_core/_multierror.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,6 @@

import attr

# python traceback.TracebackException < 3.6.4 does not support unhashable exceptions
# see https://github.com/python/cpython/pull/4014 for details
if sys.version_info < (3, 6, 4):
exc_key = lambda exc: exc
else:
exc_key = id

################################################################
# MultiError
################################################################
Expand Down Expand Up @@ -419,7 +412,7 @@ def traceback_exception_init(
if isinstance(exc_value, MultiError):
embedded = []
for exc in exc_value.exceptions:
if exc_key(exc) not in _seen:
if id(exc) not in _seen:
embedded.append(
traceback.TracebackException.from_exception(
exc,
Expand Down
18 changes: 3 additions & 15 deletions trio/_core/_run.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
# coding: utf-8

import functools
import itertools
import logging
import os
import random
import select
import sys
import threading
from collections import deque
import collections.abc
from contextlib import contextmanager
import warnings
import weakref
import enum

from contextvars import copy_context
Expand Down Expand Up @@ -47,7 +41,6 @@
from ._thread_cache import start_thread_soon
from ._instrumentation import Instruments
from .. import _core
from .._deprecate import warn_deprecated
from .._util import Final, NoPublicConstructor, coroutine_or_error

DEADLINE_HEAP_MIN_PRUNE_THRESHOLD = 1000
Expand All @@ -70,13 +63,8 @@ def _public(fn):
_r = random.Random()


# On 3.7+, Context.run() is implemented in C and doesn't show up in
# 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!
#
# This can all be removed once we drop support for 3.6.
# On CPython, Context.run() is implemented in C and doesn't show up in
# tracebacks. On PyPy, it is implemented in Python and adds 1 frame to tracebacks.
def _count_context_run_tb_frames():
def function_with_unique_name_xyzzy():
1 / 0
Expand Down Expand Up @@ -2172,7 +2160,7 @@ def unrolled_run(runner, async_fn, args, host_uses_signal_set_wakeup_fd=False):
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:
# is buggy, at least before CPython 3.9:
# 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
33 changes: 3 additions & 30 deletions trio/_core/_wakeup_socketpair.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,11 @@
import socket
import sys
import signal
import warnings

from .. import _core
from .._util import is_main_thread


def _has_warn_on_full_buffer():
if sys.version_info < (3, 7):
return False

if "__pypy__" not in sys.builtin_module_names:
# CPython has warn_on_full_buffer. Don't need to inspect.
# Also, CPython doesn't support inspecting built-in functions.
return True

import inspect

args_spec = inspect.getfullargspec(signal.set_wakeup_fd)
return "warn_on_full_buffer" in args_spec.kwonlyargs


HAVE_WARN_ON_FULL_BUFFER = _has_warn_on_full_buffer()


class WakeupSocketpair:
def __init__(self):
self.wakeup_sock, self.write_sock = socket.socketpair()
Expand All @@ -38,13 +19,8 @@ def __init__(self):
# Windows 10: 525347
# Windows you're weird. (And on Windows setting SNDBUF to 0 makes send
# blocking, even on non-blocking sockets, so don't do that.)
#
# But, if we're on an old Python and can't control the signal module's
# warn-on-full-buffer behavior, then we need to leave things alone, so
# the signal module won't spam the console with spurious warnings.
if HAVE_WARN_ON_FULL_BUFFER:
self.wakeup_sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1)
self.write_sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1)
self.wakeup_sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1)
self.write_sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1)
# On Windows this is a TCP socket so this might matter. On other
# platforms this fails b/c AF_UNIX sockets aren't actually TCP.
try:
Expand Down Expand Up @@ -75,10 +51,7 @@ def wakeup_on_signals(self):
if not is_main_thread():
return
fd = self.write_sock.fileno()
if HAVE_WARN_ON_FULL_BUFFER:
self.old_wakeup_fd = signal.set_wakeup_fd(fd, warn_on_full_buffer=False)
else:
self.old_wakeup_fd = signal.set_wakeup_fd(fd)
self.old_wakeup_fd = signal.set_wakeup_fd(fd, warn_on_full_buffer=False)
if self.old_wakeup_fd != -1:
warnings.warn(
RuntimeWarning(
Expand Down
2 changes: 1 addition & 1 deletion trio/_core/tests/test_guest_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ async def trio_main(in_host):

@pytest.mark.skipif(buggy_pypy_asyncgens, reason="PyPy 7.2 is buggy")
@pytest.mark.xfail(
sys.implementation.name == "pypy" and sys.version_info >= (3, 7),
sys.implementation.name == "pypy",
reason="async generator issue under investigation",
)
@restore_unraisablehook()
Expand Down
Loading

0 comments on commit 39d01b2

Please sign in to comment.