mirror of https://github.com/pallets/flask.git
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.
This commit is contained in:
parent
7f87f3dd93
commit
2889da67cb
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue