From 45f85dad44585d8405c580c7640d47662fccc424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Sat, 15 Jan 2022 19:47:15 +0200 Subject: [PATCH 1/9] Drop Python 3.6 support --- .github/workflows/ci.yml | 8 ++++---- README.rst | 6 +++--- docs/source/index.rst | 2 +- docs/source/tutorial.rst | 5 +---- pyproject.toml | 2 +- setup.py | 6 +++--- trio/_core/_wakeup_socketpair.py | 3 --- trio/_core/tests/test_guest_mode.py | 2 +- trio/_core/tests/test_ki.py | 7 ------- trio/_core/tests/test_multierror.py | 6 +----- trio/tests/test_ssl.py | 5 +---- 11 files changed, 16 insertions(+), 36 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 606e64977b..65fa899179 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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: [''] @@ -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')] }} @@ -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: [''] @@ -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' diff --git a/README.rst b/README.rst index c4b84c1711..4e096eddf3 100644 --- a/README.rst +++ b/README.rst @@ -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 @@ -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, diff --git a/docs/source/index.rst b/docs/source/index.rst index e3adddaee8..84d81880af 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -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. diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst index aedba8244a..08206569f5 100644 --- a/docs/source/tutorial.rst +++ b/docs/source/tutorial.rst @@ -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 @@ -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 diff --git a/pyproject.toml b/pyproject.toml index 1378e5df7b..944440661f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.black] -target-version = ['py36'] +target-version = ['py37'] [tool.towncrier] diff --git a/setup.py b/setup.py index 11eda8e96f..a832efcd85 100644 --- a/setup.py +++ b/setup.py @@ -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", @@ -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", ], diff --git a/trio/_core/_wakeup_socketpair.py b/trio/_core/_wakeup_socketpair.py index 121cec584e..8115eba3db 100644 --- a/trio/_core/_wakeup_socketpair.py +++ b/trio/_core/_wakeup_socketpair.py @@ -8,9 +8,6 @@ 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. diff --git a/trio/_core/tests/test_guest_mode.py b/trio/_core/tests/test_guest_mode.py index b06849a836..564b65d88a 100644 --- a/trio/_core/tests/test_guest_mode.py +++ b/trio/_core/tests/test_guest_mode.py @@ -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() diff --git a/trio/_core/tests/test_ki.py b/trio/_core/tests/test_ki.py index 0e4db4af49..8962003c84 100644 --- a/trio/_core/tests/test_ki.py +++ b/trio/_core/tests/test_ki.py @@ -543,10 +543,6 @@ def test_ki_wakes_us_up(): # https://bitbucket.org/pypy/pypy/issues/2623 import platform - buggy_wakeup_fd = ( - sys.version_info < (3, 6, 2) and platform.python_implementation() == "CPython" - ) - # lock is only needed to avoid an annoying race condition where the # *second* ki_self() call arrives *after* the first one woke us up and its # KeyboardInterrupt was caught, and then generates a second @@ -571,9 +567,6 @@ def kill_soon(): with lock: print("thread doing ki_self()") ki_self() - if buggy_wakeup_fd: - print("buggy_wakeup_fd =", buggy_wakeup_fd) - ki_self() async def main(): thread = threading.Thread(target=kill_soon) diff --git a/trio/_core/tests/test_multierror.py b/trio/_core/tests/test_multierror.py index 70d763e652..858d1652ae 100644 --- a/trio/_core/tests/test_multierror.py +++ b/trio/_core/tests/test_multierror.py @@ -164,11 +164,7 @@ def test_traceback_recursion(): exc1.__cause__ = MultiError([exc1, exc2, exc3]) # python traceback.TracebackException < 3.6.4 does not support unhashable exceptions # and raises a TypeError exception - if sys.version_info < (3, 6, 4): - with pytest.raises(TypeError): - format_exception(*einfo(exc1)) - else: - format_exception(*einfo(exc1)) + format_exception(*einfo(exc1)) def make_tree(): diff --git a/trio/tests/test_ssl.py b/trio/tests/test_ssl.py index f3bff42195..907d04b809 100644 --- a/trio/tests/test_ssl.py +++ b/trio/tests/test_ssl.py @@ -87,10 +87,7 @@ def client_ctx(request): if request.param in ["default", "tls13"]: return ctx elif request.param == "tls12": - if sys.version_info >= (3, 7): - ctx.maximum_version = ssl.TLSVersion.TLSv1_2 - else: - ctx.options |= ssl.OP_NO_TLSv1_3 + ctx.maximum_version = ssl.TLSVersion.TLSv1_2 return ctx else: # pragma: no cover assert False From dedee6e35c53c0633615c2182ebdf00cfda82efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Sat, 15 Jan 2022 22:10:01 +0200 Subject: [PATCH 2/9] Drop dependency on async_generator The only thing left missing is aclosing() on Python < 3.10 which is now provided by contextlib2. --- setup.py | 2 +- trio/_core/_ki.py | 4 +--- trio/_core/tests/test_asyncgen.py | 7 +++++-- trio/_core/tests/test_ki.py | 25 ++++++++----------------- trio/_util.py | 7 ++----- trio/testing/_sequencer.py | 2 +- trio/tests/test_ssl.py | 3 +-- trio/tests/test_subprocess.py | 2 +- 8 files changed, 20 insertions(+), 32 deletions(-) diff --git a/setup.py b/setup.py index a832efcd85..2364aac4d3 100644 --- a/setup.py +++ b/setup.py @@ -81,7 +81,7 @@ install_requires=[ "attrs >= 19.2.0", # for eq "sortedcontainers", - "async_generator >= 1.9", + "contextlib2; python_version < '3.10'", "idna", "outcome", "sniffio", diff --git a/trio/_core/_ki.py b/trio/_core/_ki.py index 36aacecd96..fdf396a3a3 100644 --- a/trio/_core/_ki.py +++ b/trio/_core/_ki.py @@ -4,8 +4,6 @@ from functools import wraps import attr -import async_generator - from .._util import is_main_thread if False: @@ -141,7 +139,7 @@ def wrapper(*args, **kwargs): return gen return wrapper - elif async_generator.isasyncgenfunction(fn): + elif inspect.isasyncgenfunction(fn): @wraps(fn) def wrapper(*args, **kwargs): diff --git a/trio/_core/tests/test_asyncgen.py b/trio/_core/tests/test_asyncgen.py index 6ce0af366f..983c2852c1 100644 --- a/trio/_core/tests/test_asyncgen.py +++ b/trio/_core/tests/test_asyncgen.py @@ -2,11 +2,14 @@ import weakref import pytest from math import inf -from functools import partial -from async_generator import aclosing from ... import _core from .tutil import gc_collect_harder, buggy_pypy_asyncgens, restore_unraisablehook +if sys.version_info >= (3, 10): + from contextlib import aclosing +else: + from contextlib2 import aclosing + def test_asyncgen_basics(): collected = [] diff --git a/trio/_core/tests/test_ki.py b/trio/_core/tests/test_ki.py index 8962003c84..78a0db6237 100644 --- a/trio/_core/tests/test_ki.py +++ b/trio/_core/tests/test_ki.py @@ -1,3 +1,5 @@ +from inspect import isasyncgenfunction + import outcome import pytest import sys @@ -7,13 +9,6 @@ import contextlib import time -from async_generator import ( - async_generator, - yield_, - isasyncgenfunction, - asynccontextmanager, -) - from ... import _core from ...testing import wait_all_tasks_blocked from ..._util import signal_raise, is_main_thread @@ -144,39 +139,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() @@ -211,13 +202,13 @@ async def agen_unprotected3(): # asynccontextmanager insists that the function passed must itself be an # async gen function, not a wrapper around one if isasyncgenfunction(agen_fn): - async with asynccontextmanager(agen_fn)(): + async with contextlib.asynccontextmanager(agen_fn)(): assert not _core.currently_ki_protected() # Another case that's tricky due to: # https://bugs.python.org/issue29590 with pytest.raises(KeyError): - async with asynccontextmanager(agen_fn)(): + async with contextlib.asynccontextmanager(agen_fn)(): raise KeyError diff --git a/trio/_util.py b/trio/_util.py index ec0350b305..cbcc6255cd 100644 --- a/trio/_util.py +++ b/trio/_util.py @@ -5,14 +5,11 @@ from abc import ABCMeta import os import signal -import sys -import pathlib -from functools import wraps, update_wrapper +from functools import update_wrapper import typing as t import threading import collections - -from async_generator import isasyncgen +from inspect import isasyncgen import trio diff --git a/trio/testing/_sequencer.py b/trio/testing/_sequencer.py index a7e6e50ff0..c4e34717a1 100644 --- a/trio/testing/_sequencer.py +++ b/trio/testing/_sequencer.py @@ -1,7 +1,7 @@ from collections import defaultdict +from contextlib import asynccontextmanager import attr -from async_generator import asynccontextmanager from .. import _core from .. import _util diff --git a/trio/tests/test_ssl.py b/trio/tests/test_ssl.py index 907d04b809..339ef183a4 100644 --- a/trio/tests/test_ssl.py +++ b/trio/tests/test_ssl.py @@ -6,12 +6,11 @@ import threading import socket as stdlib_socket import ssl -from contextlib import contextmanager +from contextlib import asynccontextmanager, contextmanager from functools import partial from OpenSSL import SSL import trustme -from async_generator import asynccontextmanager import trio from .. import _core diff --git a/trio/tests/test_subprocess.py b/trio/tests/test_subprocess.py index 65abe13e50..6065c3f11c 100644 --- a/trio/tests/test_subprocess.py +++ b/trio/tests/test_subprocess.py @@ -3,11 +3,11 @@ import signal import subprocess import sys +from contextlib import asynccontextmanager from functools import partial from pathlib import Path as SyncPath import pytest -from async_generator import asynccontextmanager from .. import ( ClosedResourceError, From 00f6662ce8d6f5bb9fe2e6a0ec549a8c39aca1b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Mon, 24 Jan 2022 23:29:38 +0200 Subject: [PATCH 3/9] Removed testing against the async generator wrapper --- trio/_core/tests/test_ki.py | 57 +++---------------------------------- 1 file changed, 4 insertions(+), 53 deletions(-) diff --git a/trio/_core/tests/test_ki.py b/trio/_core/tests/test_ki.py index 3636c34d70..2a4dd1d43d 100644 --- a/trio/_core/tests/test_ki.py +++ b/trio/_core/tests/test_ki.py @@ -138,42 +138,9 @@ def protected_manager(): async def test_agen_protection(): - @_core.enable_ki_protection - async def agen_protected1(): - assert _core.currently_ki_protected() - try: - yield - finally: - assert _core.currently_ki_protected() - - @_core.disable_ki_protection - async def agen_unprotected1(): - assert not _core.currently_ki_protected() - try: - yield - finally: - assert not _core.currently_ki_protected() - - # Swap the order of the decorators: - @_core.enable_ki_protection - async def agen_protected2(): - assert _core.currently_ki_protected() - try: - yield - finally: - assert _core.currently_ki_protected() - - @_core.disable_ki_protection - async def agen_unprotected2(): - assert not _core.currently_ki_protected() - try: - yield - finally: - assert not _core.currently_ki_protected() - # Native async generators @_core.enable_ki_protection - async def agen_protected3(): + async def agen_protected(): assert _core.currently_ki_protected() try: yield @@ -181,7 +148,7 @@ async def agen_protected3(): assert _core.currently_ki_protected() @_core.disable_ki_protection - async def agen_unprotected3(): + async def agen_unprotected(): assert not _core.currently_ki_protected() try: yield @@ -189,28 +156,12 @@ async def agen_unprotected3(): assert not _core.currently_ki_protected() for agen_fn in [ - agen_protected1, - agen_protected2, - agen_protected3, - agen_unprotected1, - agen_unprotected2, - agen_unprotected3, + agen_protected, + agen_unprotected, ]: async for _ in agen_fn(): # noqa assert not _core.currently_ki_protected() - # asynccontextmanager insists that the function passed must itself be an - # async gen function, not a wrapper around one - if isasyncgenfunction(agen_fn): - async with contextlib.asynccontextmanager(agen_fn)(): - assert not _core.currently_ki_protected() - - # Another case that's tricky due to: - # https://bugs.python.org/issue29590 - with pytest.raises(KeyError): - async with contextlib.asynccontextmanager(agen_fn)(): - raise KeyError - # Test the case where there's no magic local anywhere in the call stack def test_ki_disabled_out_of_context(): From 8cc13d8e022349494bef2db6201b9c78347aae49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Mon, 24 Jan 2022 23:31:48 +0200 Subject: [PATCH 4/9] Removed obsolete check --- trio/_util.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/trio/_util.py b/trio/_util.py index 602df0d7bf..deebd66a7e 100644 --- a/trio/_util.py +++ b/trio/_util.py @@ -331,8 +331,4 @@ def name_asyncgen(agen): module = agen.ag_frame.f_globals["__name__"] except (AttributeError, KeyError): module = "<{}>".format(agen.ag_code.co_filename) - try: - qualname = agen.__qualname__ - except AttributeError: - qualname = agen.ag_code.co_name - return f"{module}.{qualname}" + return f"{module}.{agen.__qualname__}" From 6341247b3f509c933c4b8ecc5b6d00aa5ae7c9fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Tue, 25 Jan 2022 00:42:31 +0200 Subject: [PATCH 5/9] Removed async_generator from test-requirements --- test-requirements.in | 2 +- test-requirements.txt | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/test-requirements.in b/test-requirements.in index 99854204d6..833b1e9295 100644 --- a/test-requirements.in +++ b/test-requirements.in @@ -24,7 +24,7 @@ typing-extensions; implementation_name == "cpython" cffi; os_name == "nt" attrs >= 19.2.0 sortedcontainers -async_generator >= 1.9 +contextlib2; python_version < '3.10' idna outcome sniffio diff --git a/test-requirements.txt b/test-requirements.txt index f1162efdb0..ec25dda574 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -8,8 +8,6 @@ astor==0.8.1 # via -r test-requirements.in astroid==2.8.4 # via pylint -async-generator==1.10 - # via -r test-requirements.in attrs==21.2.0 # via # -r test-requirements.in @@ -23,6 +21,8 @@ cffi==1.15.0 # via cryptography click==8.0.3 # via black +contextlib2==21.6.0 ; python_version < "3.10" + # via -r test-requirements.in coverage[toml]==6.0.2 # via pytest-cov cryptography==36.0.1 @@ -38,8 +38,6 @@ idna==3.3 # via # -r test-requirements.in # trustme -immutables==0.16 - # via -r test-requirements.in importlib-metadata==4.2.0 # via # click @@ -149,7 +147,6 @@ typing-extensions==3.10.0.2 ; implementation_name == "cpython" # -r test-requirements.in # astroid # black - # immutables # importlib-metadata # mypy # pylint From 536462376548220db1451ceb0b032d4176a5c902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Tue, 25 Jan 2022 11:09:08 +0200 Subject: [PATCH 6/9] Revert "Removed async_generator from test-requirements" This reverts commit 6341247b3f509c933c4b8ecc5b6d00aa5ae7c9fb. --- test-requirements.in | 2 +- test-requirements.txt | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/test-requirements.in b/test-requirements.in index 833b1e9295..99854204d6 100644 --- a/test-requirements.in +++ b/test-requirements.in @@ -24,7 +24,7 @@ typing-extensions; implementation_name == "cpython" cffi; os_name == "nt" attrs >= 19.2.0 sortedcontainers -contextlib2; python_version < '3.10' +async_generator >= 1.9 idna outcome sniffio diff --git a/test-requirements.txt b/test-requirements.txt index ec25dda574..f1162efdb0 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -8,6 +8,8 @@ astor==0.8.1 # via -r test-requirements.in astroid==2.8.4 # via pylint +async-generator==1.10 + # via -r test-requirements.in attrs==21.2.0 # via # -r test-requirements.in @@ -21,8 +23,6 @@ cffi==1.15.0 # via cryptography click==8.0.3 # via black -contextlib2==21.6.0 ; python_version < "3.10" - # via -r test-requirements.in coverage[toml]==6.0.2 # via pytest-cov cryptography==36.0.1 @@ -38,6 +38,8 @@ idna==3.3 # via # -r test-requirements.in # trustme +immutables==0.16 + # via -r test-requirements.in importlib-metadata==4.2.0 # via # click @@ -147,6 +149,7 @@ typing-extensions==3.10.0.2 ; implementation_name == "cpython" # -r test-requirements.in # astroid # black + # immutables # importlib-metadata # mypy # pylint From 19b369daad34c9a1bbfba34d841b31783fe2c88a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Tue, 25 Jan 2022 11:13:17 +0200 Subject: [PATCH 7/9] Revert "Removed testing against the async generator wrapper" This reverts commit 00f6662ce8d6f5bb9fe2e6a0ec549a8c39aca1b2. --- trio/_core/tests/test_ki.py | 57 ++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/trio/_core/tests/test_ki.py b/trio/_core/tests/test_ki.py index 2a4dd1d43d..3636c34d70 100644 --- a/trio/_core/tests/test_ki.py +++ b/trio/_core/tests/test_ki.py @@ -138,9 +138,42 @@ def protected_manager(): async def test_agen_protection(): + @_core.enable_ki_protection + async def agen_protected1(): + assert _core.currently_ki_protected() + try: + yield + finally: + assert _core.currently_ki_protected() + + @_core.disable_ki_protection + async def agen_unprotected1(): + assert not _core.currently_ki_protected() + try: + yield + finally: + assert not _core.currently_ki_protected() + + # Swap the order of the decorators: + @_core.enable_ki_protection + async def agen_protected2(): + assert _core.currently_ki_protected() + try: + yield + finally: + assert _core.currently_ki_protected() + + @_core.disable_ki_protection + async def agen_unprotected2(): + assert not _core.currently_ki_protected() + try: + yield + finally: + assert not _core.currently_ki_protected() + # Native async generators @_core.enable_ki_protection - async def agen_protected(): + async def agen_protected3(): assert _core.currently_ki_protected() try: yield @@ -148,7 +181,7 @@ async def agen_protected(): assert _core.currently_ki_protected() @_core.disable_ki_protection - async def agen_unprotected(): + async def agen_unprotected3(): assert not _core.currently_ki_protected() try: yield @@ -156,12 +189,28 @@ async def agen_unprotected(): assert not _core.currently_ki_protected() for agen_fn in [ - agen_protected, - agen_unprotected, + agen_protected1, + agen_protected2, + agen_protected3, + agen_unprotected1, + agen_unprotected2, + agen_unprotected3, ]: async for _ in agen_fn(): # noqa assert not _core.currently_ki_protected() + # asynccontextmanager insists that the function passed must itself be an + # async gen function, not a wrapper around one + if isasyncgenfunction(agen_fn): + async with contextlib.asynccontextmanager(agen_fn)(): + assert not _core.currently_ki_protected() + + # Another case that's tricky due to: + # https://bugs.python.org/issue29590 + with pytest.raises(KeyError): + async with contextlib.asynccontextmanager(agen_fn)(): + raise KeyError + # Test the case where there's no magic local anywhere in the call stack def test_ki_disabled_out_of_context(): From 250b2390a0d8e72bb56caea299d9565a2e53aa82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Tue, 25 Jan 2022 11:15:29 +0200 Subject: [PATCH 8/9] Put contextlib2 and async_generator in the proper places in test-requirements --- test-requirements.in | 17 +++++++++-------- test-requirements.txt | 5 ++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/test-requirements.in b/test-requirements.in index 99854204d6..16463dcb47 100644 --- a/test-requirements.in +++ b/test-requirements.in @@ -1,12 +1,13 @@ # For tests -pytest >= 5.0 # for faulthandler in core +pytest >= 5.0 # for faulthandler in core pytest-cov >= 2.6.0 -ipython # for the IPython traceback integration tests -pyOpenSSL # for the ssl tests -trustme # for the ssl tests -pylint # for pylint finding all symbols tests -jedi # for jedi code completion tests -cryptography>=36.0.0 # 35.0.0 is transitive but fails +ipython # for the IPython traceback integration tests +pyOpenSSL # for the ssl tests +trustme # for the ssl tests +pylint # for pylint finding all symbols tests +jedi # for jedi code completion tests +cryptography>=36.0.0 # 35.0.0 is transitive but fails +async_generator >= 1.9 # for testing against py3.5 style async generator wrappers # Tools black; implementation_name == "cpython" @@ -24,7 +25,7 @@ typing-extensions; implementation_name == "cpython" cffi; os_name == "nt" attrs >= 19.2.0 sortedcontainers -async_generator >= 1.9 +contextlib2; python_version < '3.10' idna outcome sniffio diff --git a/test-requirements.txt b/test-requirements.txt index f1162efdb0..974d3862fd 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -23,6 +23,8 @@ cffi==1.15.0 # via cryptography click==8.0.3 # via black +contextlib2==21.6.0 ; python_version < "3.10" + # via -r test-requirements.in coverage[toml]==6.0.2 # via pytest-cov cryptography==36.0.1 @@ -38,8 +40,6 @@ idna==3.3 # via # -r test-requirements.in # trustme -immutables==0.16 - # via -r test-requirements.in importlib-metadata==4.2.0 # via # click @@ -149,7 +149,6 @@ typing-extensions==3.10.0.2 ; implementation_name == "cpython" # -r test-requirements.in # astroid # black - # immutables # importlib-metadata # mypy # pylint From 9dc125167d52a8c9880d350728e4906f6add28e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Tue, 25 Jan 2022 11:25:29 +0200 Subject: [PATCH 9/9] Fully restored the previous asyncgen tests --- trio/_core/tests/test_ki.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/trio/_core/tests/test_ki.py b/trio/_core/tests/test_ki.py index 3636c34d70..430352ab6d 100644 --- a/trio/_core/tests/test_ki.py +++ b/trio/_core/tests/test_ki.py @@ -1,5 +1,3 @@ -from inspect import isasyncgenfunction - import outcome import pytest import sys @@ -9,6 +7,13 @@ import contextlib import time +from async_generator import ( + async_generator, + yield_, + isasyncgenfunction, + asynccontextmanager, +) + from ... import _core from ...testing import wait_all_tasks_blocked from ..._util import signal_raise, is_main_thread @@ -139,35 +144,39 @@ def protected_manager(): async def test_agen_protection(): @_core.enable_ki_protection + @async_generator async def agen_protected1(): assert _core.currently_ki_protected() try: - yield + await yield_() finally: assert _core.currently_ki_protected() @_core.disable_ki_protection + @async_generator async def agen_unprotected1(): assert not _core.currently_ki_protected() try: - yield + await 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: - yield + await yield_() finally: assert _core.currently_ki_protected() + @async_generator @_core.disable_ki_protection async def agen_unprotected2(): assert not _core.currently_ki_protected() try: - yield + await yield_() finally: assert not _core.currently_ki_protected() @@ -202,13 +211,13 @@ async def agen_unprotected3(): # asynccontextmanager insists that the function passed must itself be an # async gen function, not a wrapper around one if isasyncgenfunction(agen_fn): - async with contextlib.asynccontextmanager(agen_fn)(): + async with asynccontextmanager(agen_fn)(): assert not _core.currently_ki_protected() # Another case that's tricky due to: # https://bugs.python.org/issue29590 with pytest.raises(KeyError): - async with contextlib.asynccontextmanager(agen_fn)(): + async with asynccontextmanager(agen_fn)(): raise KeyError