Remove loop as required listener arg (#2414)

This commit is contained in:
Adam Hopkins 2022-03-23 11:02:39 +02:00 committed by GitHub
parent 44b108b564
commit c9dbc8ed26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 8 deletions

View File

@ -1131,7 +1131,10 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
async def _listener( async def _listener(
app: Sanic, loop: AbstractEventLoop, listener: ListenerType app: Sanic, loop: AbstractEventLoop, listener: ListenerType
): ):
maybe_coro = listener(app, loop) try:
maybe_coro = listener(app) # type: ignore
except TypeError:
maybe_coro = listener(app, loop) # type: ignore
if maybe_coro and isawaitable(maybe_coro): if maybe_coro and isawaitable(maybe_coro):
await maybe_coro await maybe_coro

View File

@ -548,12 +548,12 @@ class RunnerMixin(metaclass=SanicMeta):
and os.environ.get("SANIC_SERVER_RUNNING") != "true" and os.environ.get("SANIC_SERVER_RUNNING") != "true"
): # no cov ): # no cov
loop = new_event_loop() loop = new_event_loop()
trigger_events(reloader_start, loop) trigger_events(reloader_start, loop, primary)
reload_dirs: Set[Path] = primary.state.reload_dirs.union( reload_dirs: Set[Path] = primary.state.reload_dirs.union(
*(app.state.reload_dirs for app in apps) *(app.state.reload_dirs for app in apps)
) )
reloader_helpers.watchdog(1.0, reload_dirs) reloader_helpers.watchdog(1.0, reload_dirs)
trigger_events(reloader_stop, loop) trigger_events(reloader_stop, loop, primary)
return return
# This exists primarily for unit testing # This exists primarily for unit testing

View File

@ -18,8 +18,9 @@ ErrorMiddlewareType = Callable[
[Request, BaseException], Optional[Coroutine[Any, Any, None]] [Request, BaseException], Optional[Coroutine[Any, Any, None]]
] ]
MiddlewareType = Union[RequestMiddlewareType, ResponseMiddlewareType] MiddlewareType = Union[RequestMiddlewareType, ResponseMiddlewareType]
ListenerType = Callable[ ListenerType = Union[
[Sanic, AbstractEventLoop], Optional[Coroutine[Any, Any, None]] Callable[[Sanic], Optional[Coroutine[Any, Any, None]]],
Callable[[Sanic, AbstractEventLoop], Optional[Coroutine[Any, Any, None]]],
] ]
RouteHandler = Callable[..., Coroutine[Any, Any, Optional[HTTPResponse]]] RouteHandler = Callable[..., Coroutine[Any, Any, Optional[HTTPResponse]]]
SignalHandler = Callable[..., Coroutine[Any, Any, None]] SignalHandler = Callable[..., Coroutine[Any, Any, None]]

View File

@ -1,8 +1,18 @@
from __future__ import annotations
from inspect import isawaitable from inspect import isawaitable
from typing import Any, Callable, Iterable, Optional from typing import TYPE_CHECKING, Any, Callable, Iterable, Optional
def trigger_events(events: Optional[Iterable[Callable[..., Any]]], loop): if TYPE_CHECKING: # no cov
from sanic import Sanic
def trigger_events(
events: Optional[Iterable[Callable[..., Any]]],
loop,
app: Optional[Sanic] = None,
):
""" """
Trigger event callbacks (functions or async) Trigger event callbacks (functions or async)
@ -11,6 +21,9 @@ def trigger_events(events: Optional[Iterable[Callable[..., Any]]], loop):
""" """
if events: if events:
for event in events: for event in events:
result = event(loop) try:
result = event() if not app else event(app)
except TypeError:
result = event(loop) if not app else event(app, loop)
if isawaitable(result): if isawaitable(result):
loop.run_until_complete(result) loop.run_until_complete(result)

View File

@ -33,6 +33,14 @@ def create_listener(listener_name, in_list):
return _listener return _listener
def create_listener_no_loop(listener_name, in_list):
async def _listener(app):
print(f"DEBUG MESSAGE FOR PYTEST for {listener_name}")
in_list.insert(0, app.name + listener_name)
return _listener
def start_stop_app(random_name_app, **run_kwargs): def start_stop_app(random_name_app, **run_kwargs):
def stop_on_alarm(signum, frame): def stop_on_alarm(signum, frame):
random_name_app.stop() random_name_app.stop()
@ -56,6 +64,17 @@ def test_single_listener(app, listener_name):
assert app.name + listener_name == output.pop() assert app.name + listener_name == output.pop()
@skipif_no_alarm
@pytest.mark.parametrize("listener_name", AVAILABLE_LISTENERS)
def test_single_listener_no_loop(app, listener_name):
"""Test that listeners on their own work"""
output = []
# Register listener
app.listener(listener_name)(create_listener_no_loop(listener_name, output))
start_stop_app(app)
assert app.name + listener_name == output.pop()
@skipif_no_alarm @skipif_no_alarm
@pytest.mark.parametrize("listener_name", AVAILABLE_LISTENERS) @pytest.mark.parametrize("listener_name", AVAILABLE_LISTENERS)
def test_register_listener(app, listener_name): def test_register_listener(app, listener_name):