未验证 提交 2889da67 编写于 作者: P pgjones 提交者: David Lord

Remove the async helper method

It is better to encourage users to utilise the app ensure_sync method
(or the newely added async_to_sync method) so that any extensions that
alter these methods take affect throughout the users code.

With the helper method users code fix parts of their code to the
asgiref async_to_sync ignoring any extension changes.
上级 7f87f3dd
......@@ -16,6 +16,7 @@ from werkzeug.exceptions import BadRequest
from werkzeug.exceptions import BadRequestKeyError
from werkzeug.exceptions import HTTPException
from werkzeug.exceptions import InternalServerError
from werkzeug.local import ContextVar
from werkzeug.routing import BuildError
from werkzeug.routing import Map
from werkzeug.routing import MapAdapter
......@@ -35,7 +36,6 @@ from .globals import _request_ctx_stack
from .globals import g
from .globals import request
from .globals import session
from .helpers import async_to_sync
from .helpers import get_debug_flag
from .helpers import get_env
from .helpers import get_flashed_messages
......@@ -1579,10 +1579,40 @@ class Flask(Scaffold):
.. versionadded:: 2.0
"""
if iscoroutinefunction(func):
return async_to_sync(func)
return self.async_to_sync(func)
return func
def async_to_sync(
self, func: t.Callable[..., t.Coroutine]
) -> t.Callable[..., t.Any]:
"""Return a sync function that will run the coroutine function.
.. code-block:: python
result = app.async_to_sync(func)(*args, **kwargs)
Override this method to change how the app converts async code
to be synchronously callable.
.. versionadded:: 2.0
"""
try:
from asgiref.sync import async_to_sync as asgiref_async_to_sync
except ImportError:
raise RuntimeError(
"Install Flask with the 'async' extra in order to use async views."
)
# Check that Werkzeug isn't using its fallback ContextVar class.
if ContextVar.__module__ == "werkzeug.local":
raise RuntimeError(
"Async cannot be used with this combination of Python "
"and Greenlet versions."
)
return asgiref_async_to_sync(func)
def make_response(self, rv: ResponseReturnValue) -> Response:
"""Convert the return value from a view function to an instance of
:attr:`response_class`.
......
......@@ -10,7 +10,6 @@ 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
......@@ -800,26 +799,3 @@ def is_ip(value: str) -> bool:
return True
return False
def async_to_sync(func: t.Callable[..., t.Coroutine]) -> t.Callable[..., t.Any]:
"""Return a sync function that will run the coroutine function *func*.
This can be used as so
result = async_to_async(func)(*args, **kwargs)
"""
try:
from asgiref.sync import async_to_sync as asgiref_async_to_sync
except ImportError:
raise RuntimeError(
"Install Flask with the 'async' extra in order to use async views."
)
# Check that Werkzeug isn't using its fallback ContextVar class.
if ContextVar.__module__ == "werkzeug.local":
raise RuntimeError(
"Async cannot be used with this combination of Python & Greenlet versions."
)
return asgiref_async_to_sync(func)
......@@ -6,7 +6,6 @@ import pytest
from flask import Blueprint
from flask import Flask
from flask import request
from flask.helpers import async_to_sync
pytest.importorskip("asgiref")
......@@ -136,5 +135,6 @@ def test_async_before_after_request():
@pytest.mark.skipif(sys.version_info >= (3, 7), reason="should only raise Python < 3.7")
def test_async_runtime_error():
app = Flask(__name__)
with pytest.raises(RuntimeError):
async_to_sync(None)
app.async_to_sync(None)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册