Skip to content

Commit 39d01b2

Browse files
agronholmpquentin
andauthored
Drop Python 3.6 support (#2210)
* 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 <[email protected]>
1 parent 4edfd41 commit 39d01b2

23 files changed

+39
-267
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
strategy:
1515
fail-fast: false
1616
matrix:
17-
python: ['3.6', '3.7', '3.8', '3.9', '3.10']
17+
python: ['3.7', '3.8', '3.9', '3.10']
1818
arch: ['x86', 'x64']
1919
lsp: ['']
2020
lsp_extract_file: ['']
@@ -51,7 +51,7 @@ jobs:
5151
# This avoids the need to update for each new alpha, beta, release candidate,
5252
# and then finally an actual release version. actions/setup-python doesn't
5353
# support this for PyPy presently so we get no help there.
54-
#
54+
#
5555
# CPython -> 3.9.0-alpha - 3.9.X
5656
# PyPy -> pypy-3.7
5757
python-version: ${{ fromJSON(format('["{0}", "{1}"]', format('{0}.0-alpha - {0}.X', matrix.python), matrix.python))[startsWith(matrix.python, 'pypy')] }}
@@ -72,7 +72,7 @@ jobs:
7272
strategy:
7373
fail-fast: false
7474
matrix:
75-
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']
75+
python: ['pypy-3.7', 'pypy-3.8', '3.7', '3.8', '3.9', '3.10', '3.8-dev', '3.9-dev', '3.10-dev']
7676
check_formatting: ['0']
7777
pypy_nightly_branch: ['']
7878
extra_name: ['']
@@ -114,7 +114,7 @@ jobs:
114114
strategy:
115115
fail-fast: false
116116
matrix:
117-
python: ['3.6', '3.7', '3.8', '3.9', '3.10']
117+
python: ['3.7', '3.8', '3.9', '3.10']
118118
include:
119119
- python: '3.8' # <- not actually used
120120
arch: 'x64'

README.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
.. image:: https://img.shields.io/badge/docs-read%20now-blue.svg
1010
:target: https://trio.readthedocs.io
1111
:alt: Documentation
12-
12+
1313
.. image:: https://img.shields.io/pypi/v/trio.svg
1414
:target: https://pypi.org/project/trio
1515
:alt: Latest PyPi version
1616

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

2121
.. image:: https://codecov.io/gh/python-trio/trio/branch/master/graph/badge.svg
2222
:target: https://codecov.io/gh/python-trio/trio
@@ -92,7 +92,7 @@ demonstration of implementing the "Happy Eyeballs" algorithm in an
9292
older library versus Trio.
9393

9494
**Cool, but will it work on my system?** Probably! As long as you have
95-
some kind of Python 3.6-or-better (CPython or the latest PyPy3 are
95+
some kind of Python 3.7-or-better (CPython or the latest PyPy3 are
9696
both fine), and are using Linux, macOS, Windows, or FreeBSD, then Trio
9797
will work. Other environments might work too, but those
9898
are the ones we test on. And all of our dependencies are pure Python,

ci.sh

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,6 @@ python -m pip --version
7272
python setup.py sdist --formats=zip
7373
python -m pip install dist/*.zip
7474

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-
8375
if [ "$CHECK_FORMATTING" = "1" ]; then
8476
python -m pip install -r test-requirements.txt
8577
source check.sh

docs/source/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Vital statistics:
4545

4646
* Supported environments: We test on
4747

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

5151
Other environments might also work; give it a try and see.

docs/source/reference-io.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,7 @@ other constants and functions in the :mod:`ssl` module.
237237

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

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

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

728727

docs/source/tutorial.rst

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ Tutorial
3434
print(response)
3535
and then again with /delay/10
3636
37-
(note that asks needs cpython 3.6 though. maybe just for one async
38-
generator?)
39-
4037
value of async/await: show you where the cancellation exceptions
4138
can happen -- see pillar re: explicit cancel points
4239
@@ -94,7 +91,7 @@ Okay, ready? Let's get started.
9491
Before you begin
9592
----------------
9693

97-
1. Make sure you're using Python 3.6 or newer.
94+
1. Make sure you're using Python 3.7 or newer.
9895

9996
2. ``python3 -m pip install --upgrade trio`` (or on Windows, maybe
10097
``py -3 -m pip install --upgrade trio`` – `details

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tool.black]
2-
target-version = ['py36']
2+
target-version = ['py37']
33

44

55
[tool.towncrier]

setup.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
Vital statistics:
4545
4646
* Supported environments: Linux, macOS, or Windows running some kind of Python
47-
3.6-or-better (either CPython or PyPy3 is fine). \\*BSD and illumos likely
47+
3.7-or-better (either CPython or PyPy3 is fine). \\*BSD and illumos likely
4848
work too, but are not tested.
4949
5050
* Install: ``python3 -m pip install -U trio`` (or on Windows, maybe
@@ -89,12 +89,11 @@
8989
# cffi 1.14 fixes memory leak inside ffi.getwinerror()
9090
# cffi is required on Windows, except on PyPy where it is built-in
9191
"cffi>=1.14; os_name == 'nt' and implementation_name != 'pypy'",
92-
"contextvars>=2.1; python_version < '3.7'",
9392
],
9493
# This means, just install *everything* you see under trio/, even if it
9594
# doesn't look like a source file, so long as it appears in MANIFEST.in:
9695
include_package_data=True,
97-
python_requires=">=3.6",
96+
python_requires=">=3.7",
9897
keywords=["async", "io", "networking", "trio"],
9998
classifiers=[
10099
"Development Status :: 3 - Alpha",
@@ -108,10 +107,11 @@
108107
"Programming Language :: Python :: Implementation :: CPython",
109108
"Programming Language :: Python :: Implementation :: PyPy",
110109
"Programming Language :: Python :: 3 :: Only",
111-
"Programming Language :: Python :: 3.6",
112110
"Programming Language :: Python :: 3.7",
113111
"Programming Language :: Python :: 3.8",
114112
"Programming Language :: Python :: 3.9",
113+
"Programming Language :: Python :: 3.10",
114+
"Programming Language :: Python :: 3.11",
115115
"Topic :: System :: Networking",
116116
"Framework :: Trio",
117117
],

test-requirements.in

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,9 @@ typing-extensions; implementation_name == "cpython"
2222

2323
# Trio's own dependencies
2424
cffi; os_name == "nt"
25-
contextvars; python_version < "3.7"
2625
attrs >= 19.2.0
2726
sortedcontainers
2827
async_generator >= 1.9
2928
idna
3029
outcome
3130
sniffio
32-
33-
# Required by contextvars, but harmless to install everywhere.
34-
# dependabot drops the contextvars dependency because it runs
35-
# on 3.7.
36-
immutables >= 0.6

trio/_core/_entry_queue.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ class EntryQueue:
1515
# not signal-safe. deque is implemented in C, so each operation is atomic
1616
# WRT threads (and this is guaranteed in the docs), AND each operation is
1717
# atomic WRT signal delivery (signal handlers can run on either side, but
18-
# not *during* a deque operation). dict makes similar guarantees - and on
19-
# CPython 3.6 and PyPy, it's even ordered!
18+
# not *during* a deque operation). dict makes similar guarantees - and
19+
# it's even ordered!
2020
queue = attr.ib(factory=deque)
2121
idempotent_queue = attr.ib(factory=dict)
2222

trio/_core/_multierror.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,6 @@
55

66
import attr
77

8-
# python traceback.TracebackException < 3.6.4 does not support unhashable exceptions
9-
# see https://github.com/python/cpython/pull/4014 for details
10-
if sys.version_info < (3, 6, 4):
11-
exc_key = lambda exc: exc
12-
else:
13-
exc_key = id
14-
158
################################################################
169
# MultiError
1710
################################################################
@@ -419,7 +412,7 @@ def traceback_exception_init(
419412
if isinstance(exc_value, MultiError):
420413
embedded = []
421414
for exc in exc_value.exceptions:
422-
if exc_key(exc) not in _seen:
415+
if id(exc) not in _seen:
423416
embedded.append(
424417
traceback.TracebackException.from_exception(
425418
exc,

trio/_core/_run.py

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
1-
# coding: utf-8
2-
31
import functools
42
import itertools
5-
import logging
6-
import os
73
import random
84
import select
95
import sys
106
import threading
117
from collections import deque
12-
import collections.abc
138
from contextlib import contextmanager
149
import warnings
15-
import weakref
1610
import enum
1711

1812
from contextvars import copy_context
@@ -47,7 +41,6 @@
4741
from ._thread_cache import start_thread_soon
4842
from ._instrumentation import Instruments
4943
from .. import _core
50-
from .._deprecate import warn_deprecated
5144
from .._util import Final, NoPublicConstructor, coroutine_or_error
5245

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

7265

73-
# On 3.7+, Context.run() is implemented in C and doesn't show up in
74-
# tracebacks. On 3.6, we use the contextvars backport, which is
75-
# currently implemented in Python and adds 1 frame to tracebacks. So this
76-
# function is a super-overkill version of "0 if sys.version_info >= (3, 7)
77-
# else 1". But if Context.run ever changes, we'll be ready!
78-
#
79-
# This can all be removed once we drop support for 3.6.
66+
# On CPython, Context.run() is implemented in C and doesn't show up in
67+
# tracebacks. On PyPy, it is implemented in Python and adds 1 frame to tracebacks.
8068
def _count_context_run_tb_frames():
8169
def function_with_unique_name_xyzzy():
8270
1 / 0
@@ -2172,7 +2160,7 @@ def unrolled_run(runner, async_fn, args, host_uses_signal_set_wakeup_fd=False):
21722160
try:
21732161
# We used to unwrap the Outcome object here and send/throw
21742162
# its contents in directly, but it turns out that .throw()
2175-
# is buggy, at least on CPython 3.6:
2163+
# is buggy, at least before CPython 3.9:
21762164
# https://bugs.python.org/issue29587
21772165
# https://bugs.python.org/issue29590
21782166
# So now we send in the Outcome object and unwrap it on the

trio/_core/_wakeup_socketpair.py

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,11 @@
11
import socket
2-
import sys
32
import signal
43
import warnings
54

65
from .. import _core
76
from .._util import is_main_thread
87

98

10-
def _has_warn_on_full_buffer():
11-
if sys.version_info < (3, 7):
12-
return False
13-
14-
if "__pypy__" not in sys.builtin_module_names:
15-
# CPython has warn_on_full_buffer. Don't need to inspect.
16-
# Also, CPython doesn't support inspecting built-in functions.
17-
return True
18-
19-
import inspect
20-
21-
args_spec = inspect.getfullargspec(signal.set_wakeup_fd)
22-
return "warn_on_full_buffer" in args_spec.kwonlyargs
23-
24-
25-
HAVE_WARN_ON_FULL_BUFFER = _has_warn_on_full_buffer()
26-
27-
289
class WakeupSocketpair:
2910
def __init__(self):
3011
self.wakeup_sock, self.write_sock = socket.socketpair()
@@ -38,13 +19,8 @@ def __init__(self):
3819
# Windows 10: 525347
3920
# Windows you're weird. (And on Windows setting SNDBUF to 0 makes send
4021
# blocking, even on non-blocking sockets, so don't do that.)
41-
#
42-
# But, if we're on an old Python and can't control the signal module's
43-
# warn-on-full-buffer behavior, then we need to leave things alone, so
44-
# the signal module won't spam the console with spurious warnings.
45-
if HAVE_WARN_ON_FULL_BUFFER:
46-
self.wakeup_sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1)
47-
self.write_sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1)
22+
self.wakeup_sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1)
23+
self.write_sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1)
4824
# On Windows this is a TCP socket so this might matter. On other
4925
# platforms this fails b/c AF_UNIX sockets aren't actually TCP.
5026
try:
@@ -75,10 +51,7 @@ def wakeup_on_signals(self):
7551
if not is_main_thread():
7652
return
7753
fd = self.write_sock.fileno()
78-
if HAVE_WARN_ON_FULL_BUFFER:
79-
self.old_wakeup_fd = signal.set_wakeup_fd(fd, warn_on_full_buffer=False)
80-
else:
81-
self.old_wakeup_fd = signal.set_wakeup_fd(fd)
54+
self.old_wakeup_fd = signal.set_wakeup_fd(fd, warn_on_full_buffer=False)
8255
if self.old_wakeup_fd != -1:
8356
warnings.warn(
8457
RuntimeWarning(

trio/_core/tests/test_guest_mode.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ async def trio_main(in_host):
504504

505505
@pytest.mark.skipif(buggy_pypy_asyncgens, reason="PyPy 7.2 is buggy")
506506
@pytest.mark.xfail(
507-
sys.implementation.name == "pypy" and sys.version_info >= (3, 7),
507+
sys.implementation.name == "pypy",
508508
reason="async generator issue under investigation",
509509
)
510510
@restore_unraisablehook()

0 commit comments

Comments
 (0)