Add config option to skip Touchup step, for debugging purposes (#2361)

Co-authored-by: Adam Hopkins <adam@amhopkins.com>
This commit is contained in:
Ashley Sommer 2022-03-24 21:52:05 +10:00 committed by GitHub
parent f6fdc80b40
commit 030987480c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 4 deletions

View File

@ -1511,7 +1511,8 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
if not Sanic.test_mode:
raise e
def signalize(self):
def signalize(self, allow_fail_builtin=True):
self.signal_router.allow_fail_builtin = allow_fail_builtin
try:
self.signal_router.finalize()
except FinalizationError as e:
@ -1526,8 +1527,11 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
if hasattr(self, "_ext"):
self.ext._display()
if self.state.is_debug:
self.config.TOUCHUP = False
# Setup routers
self.signalize()
self.signalize(self.config.TOUCHUP)
self.finalize()
# TODO: Replace in v22.6 to check against apps in app registry
@ -1547,7 +1551,8 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
# TODO:
# - Raise warning if secondary apps have error handler config
ErrorHandler.finalize(self.error_handler, config=self.config)
TouchUp.run(self)
if self.config.TOUCHUP:
TouchUp.run(self)
self.state.is_started = True

View File

@ -38,6 +38,7 @@ DEFAULT_CONFIG = {
"REQUEST_MAX_SIZE": 100000000, # 100 megabytes
"REQUEST_TIMEOUT": 60, # 60 seconds
"RESPONSE_TIMEOUT": 60, # 60 seconds
"TOUCHUP": True,
"USE_UVLOOP": _default,
"WEBSOCKET_MAX_SIZE": 2**20, # 1 megabyte
"WEBSOCKET_PING_INTERVAL": 20,
@ -81,6 +82,7 @@ class Config(dict, metaclass=DescriptorMeta):
REQUEST_TIMEOUT: int
RESPONSE_TIMEOUT: int
SERVER_NAME: str
TOUCHUP: bool
USE_UVLOOP: Union[Default, bool]
WEBSOCKET_MAX_SIZE: int
WEBSOCKET_PING_INTERVAL: int

View File

@ -80,6 +80,7 @@ class SignalRouter(BaseRouter):
group_class=SignalGroup,
stacking=True,
)
self.allow_fail_builtin = True
self.ctx.loop = None
def get( # type: ignore
@ -129,7 +130,8 @@ class SignalRouter(BaseRouter):
try:
group, handlers, params = self.get(event, condition=condition)
except NotFound as e:
if fail_not_found:
is_reserved = event.split(".", 1)[0] in RESERVED_NAMESPACES
if fail_not_found and (not is_reserved or self.allow_fail_builtin):
raise e
else:
if self.ctx.app.debug and self.ctx.app.state.verbosity >= 1:

View File

@ -2,6 +2,8 @@ import logging
import pytest
from sanic_routing.exceptions import NotFound
from sanic.signals import RESERVED_NAMESPACES
from sanic.touchup import TouchUp
@ -28,3 +30,50 @@ async def test_ode_removes_dispatch_events(app, caplog, verbosity, result):
)
in logs
) is result
@pytest.mark.parametrize("skip_it,result", ((False, True), (True, False)))
async def test_skip_touchup(app, caplog, skip_it, result):
app.config.TOUCHUP = not skip_it
with caplog.at_level(logging.DEBUG, logger="sanic.root"):
app.state.verbosity = 2
await app._startup()
assert app.signal_router.allow_fail_builtin is (not skip_it)
logs = caplog.record_tuples
for signal in RESERVED_NAMESPACES["http"]:
assert (
(
"sanic.root",
logging.DEBUG,
f"Disabling event: {signal}",
)
in logs
) is result
not_found_exceptions = 0
# Skip-touchup disables NotFound exceptions on the dispatcher
for signal in RESERVED_NAMESPACES["http"]:
try:
await app.dispatch(event=signal, inline=True)
except NotFound:
not_found_exceptions += 1
assert (not_found_exceptions > 0) is result
@pytest.mark.parametrize("skip_it,result", ((False, True), (True, True)))
async def test_skip_touchup_non_reserved(app, caplog, skip_it, result):
app.config.TOUCHUP = not skip_it
@app.signal("foo.bar.one")
def sync_signal(*_):
...
await app._startup()
assert app.signal_router.allow_fail_builtin is (not skip_it)
not_found_exception = False
# Skip-touchup doesn't disable NotFound exceptions for user-defined signals
try:
await app.dispatch(event="foo.baz.two", inline=True)
except NotFound:
not_found_exception = True
assert not_found_exception is result