diff --git a/src/flask/helpers.py b/src/flask/helpers.py index 46244d29..5933f42a 100644 --- a/src/flask/helpers.py +++ b/src/flask/helpers.py @@ -7,6 +7,7 @@ from threading import RLock import werkzeug.utils from werkzeug.exceptions import NotFound +from werkzeug.local import ContextVar from werkzeug.routing import BuildError from werkzeug.urls import url_quote @@ -741,6 +742,11 @@ def run_async(func): "Install Flask with the 'async' extra in order to use async views." ) + if ContextVar.__module__ == "werkzeug.local": + raise RuntimeError( + "async cannot be used with this combination of Python & Greenlet versions" + ) + @wraps(func) def outer(*args, **kwargs): """This function grabs the current context for the inner function. diff --git a/tests/test_async.py b/tests/test_async.py index d47d36ce..12784c34 100644 --- a/tests/test_async.py +++ b/tests/test_async.py @@ -1,10 +1,12 @@ import asyncio +import sys import pytest from flask import abort from flask import Flask from flask import request +from flask.helpers import run_async @pytest.fixture(name="async_app") @@ -23,6 +25,7 @@ def _async_app(): return app +@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires Python >= 3.7") def test_async_request_context(async_app): test_client = async_app.test_client() response = test_client.get("/") @@ -31,3 +34,9 @@ def test_async_request_context(async_app): assert b"POST" in response.get_data() response = test_client.get("/error") assert response.status_code == 412 + + +@pytest.mark.skipif(sys.version_info >= (3, 7), reason="should only raise Python < 3.7") +def test_async_runtime_error(): + with pytest.raises(RuntimeError): + run_async(None) diff --git a/tox.ini b/tox.ini index e0f666d8..cf12c0eb 100644 --- a/tox.ini +++ b/tox.ini @@ -25,5 +25,8 @@ skip_install = true commands = pre-commit run --all-files --show-diff-on-failure [testenv:docs] -deps = -r requirements/docs.txt +deps = + -r requirements/docs.txt + + https://github.com/pallets/werkzeug/archive/master.tar.gz commands = sphinx-build -W -b html -d {envtmpdir}/doctrees docs {envtmpdir}/html