Merge pull request #5049 from pgjones/signals

support async signal subscribers
This commit is contained in:
David Lord 2023-04-13 08:08:27 -07:00 committed by GitHub
commit 59f81950fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 25 additions and 12 deletions

View File

@ -30,6 +30,7 @@ Unreleased
decorated function if locking is needed. :issue:`4993`
- Signals are always available. ``blinker>=1.6.2`` is a required dependency. The
``signals_available`` attribute is deprecated. :issue:`5056`
- Signals support ``async`` subscriber functions. :pr:`5049`
- Remove uses of locks that could cause requests to block each other very briefly.
:issue:`4993`
- Use modern packaging metadata with ``pyproject.toml`` instead of ``setup.cfg``.

View File

@ -1389,7 +1389,7 @@ class Flask(Scaffold):
.. versionadded:: 0.3
"""
exc_info = sys.exc_info()
got_request_exception.send(self, exception=e)
got_request_exception.send(self, _async_wrapper=self.ensure_sync, exception=e)
propagate = self.config["PROPAGATE_EXCEPTIONS"]
if propagate is None:
@ -1493,7 +1493,7 @@ class Flask(Scaffold):
self._got_first_request = True
try:
request_started.send(self)
request_started.send(self, _async_wrapper=self.ensure_sync)
rv = self.preprocess_request()
if rv is None:
rv = self.dispatch_request()
@ -1521,7 +1521,9 @@ class Flask(Scaffold):
response = self.make_response(rv)
try:
response = self.process_response(response)
request_finished.send(self, response=response)
request_finished.send(
self, _async_wrapper=self.ensure_sync, response=response
)
except Exception:
if not from_error_handler:
raise
@ -2052,7 +2054,7 @@ class Flask(Scaffold):
for func in reversed(self.teardown_request_funcs[name]):
self.ensure_sync(func)(exc)
request_tearing_down.send(self, exc=exc)
request_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc)
def do_teardown_appcontext(
self, exc: t.Optional[BaseException] = _sentinel # type: ignore
@ -2077,7 +2079,7 @@ class Flask(Scaffold):
for func in reversed(self.teardown_appcontext_funcs):
self.ensure_sync(func)(exc)
appcontext_tearing_down.send(self, exc=exc)
appcontext_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc)
def app_context(self) -> AppContext:
"""Create an :class:`~flask.ctx.AppContext`. Use as a ``with``

View File

@ -242,7 +242,7 @@ class AppContext:
def push(self) -> None:
"""Binds the app context to the current context."""
self._cv_tokens.append(_cv_app.set(self))
appcontext_pushed.send(self.app)
appcontext_pushed.send(self.app, _async_wrapper=self.app.ensure_sync)
def pop(self, exc: t.Optional[BaseException] = _sentinel) -> None: # type: ignore
"""Pops the app context."""
@ -260,7 +260,7 @@ class AppContext:
f"Popped wrong app context. ({ctx!r} instead of {self!r})"
)
appcontext_popped.send(self.app)
appcontext_popped.send(self.app, _async_wrapper=self.app.ensure_sync)
def __enter__(self) -> "AppContext":
self.push()

View File

@ -327,8 +327,10 @@ def flash(message: str, category: str = "message") -> None:
flashes = session.get("_flashes", [])
flashes.append((category, message))
session["_flashes"] = flashes
app = current_app._get_current_object() # type: ignore
message_flashed.send(
current_app._get_current_object(), # type: ignore
app,
_async_wrapper=app.ensure_sync,
message=message,
category=category,
)

View File

@ -126,9 +126,13 @@ class DispatchingJinjaLoader(BaseLoader):
def _render(app: "Flask", template: Template, context: t.Dict[str, t.Any]) -> str:
app.update_template_context(context)
before_render_template.send(app, template=template, context=context)
before_render_template.send(
app, _async_wrapper=app.ensure_sync, template=template, context=context
)
rv = template.render(context)
template_rendered.send(app, template=template, context=context)
template_rendered.send(
app, _async_wrapper=app.ensure_sync, template=template, context=context
)
return rv
@ -163,11 +167,15 @@ def _stream(
app: "Flask", template: Template, context: t.Dict[str, t.Any]
) -> t.Iterator[str]:
app.update_template_context(context)
before_render_template.send(app, template=template, context=context)
before_render_template.send(
app, _async_wrapper=app.ensure_sync, template=template, context=context
)
def generate() -> t.Iterator[str]:
yield from template.generate(context)
template_rendered.send(app, template=template, context=context)
template_rendered.send(
app, _async_wrapper=app.ensure_sync, template=template, context=context
)
rv = generate()