Recovery the issue 659
This commit is contained in:
parent
472face796
commit
240f5b7c9f
|
@ -1,6 +1,8 @@
|
|||
from collections import defaultdict, namedtuple
|
||||
from types import MethodType
|
||||
|
||||
from sanic.constants import HTTP_METHODS
|
||||
from sanic.exceptions import SanicTypeException
|
||||
from sanic.views import CompositionView
|
||||
|
||||
FutureRoute = namedtuple('Route',
|
||||
|
@ -48,7 +50,7 @@ class Blueprint:
|
|||
methods=future.methods,
|
||||
host=future.host or self.host,
|
||||
strict_slashes=future.strict_slashes
|
||||
)(future.handler)
|
||||
)(future.handler)
|
||||
|
||||
for future in self.websocket_routes:
|
||||
# attach the blueprint name to the handler so that it can be
|
||||
|
@ -60,7 +62,7 @@ class Blueprint:
|
|||
uri=uri,
|
||||
host=future.host or self.host,
|
||||
strict_slashes=future.strict_slashes
|
||||
)(future.handler)
|
||||
)(future.handler)
|
||||
|
||||
# Middleware
|
||||
for future in self.middlewares:
|
||||
|
@ -93,10 +95,14 @@ class Blueprint:
|
|||
:param uri: endpoint at which the route will be accessible.
|
||||
:param methods: list of acceptable HTTP methods.
|
||||
"""
|
||||
|
||||
def decorator(handler):
|
||||
if isinstance(handler, MethodType):
|
||||
raise SanicTypeException("You can`t add a instance method as a blueprint router hander")
|
||||
route = FutureRoute(handler, uri, methods, host, strict_slashes)
|
||||
self.routes.append(route)
|
||||
return handler
|
||||
|
||||
return decorator
|
||||
|
||||
def add_route(self, handler, uri, methods=frozenset({'GET'}), host=None,
|
||||
|
@ -120,6 +126,8 @@ class Blueprint:
|
|||
# handle composition view differently
|
||||
if isinstance(handler, CompositionView):
|
||||
methods = handler.handlers.keys()
|
||||
if isinstance(handler, MethodType):
|
||||
raise SanicTypeException("You can`t add a instance method as a blueprint router hander")
|
||||
|
||||
self.route(uri=uri, methods=methods, host=host,
|
||||
strict_slashes=strict_slashes)(handler)
|
||||
|
@ -130,10 +138,12 @@ class Blueprint:
|
|||
|
||||
:param uri: endpoint at which the route will be accessible.
|
||||
"""
|
||||
|
||||
def decorator(handler):
|
||||
route = FutureRoute(handler, uri, [], host, strict_slashes)
|
||||
self.websocket_routes.append(route)
|
||||
return handler
|
||||
|
||||
return decorator
|
||||
|
||||
def add_websocket_route(self, handler, uri, host=None):
|
||||
|
@ -152,13 +162,16 @@ class Blueprint:
|
|||
|
||||
:param event: Event to listen to.
|
||||
"""
|
||||
|
||||
def decorator(listener):
|
||||
self.listeners[event].append(listener)
|
||||
return listener
|
||||
|
||||
return decorator
|
||||
|
||||
def middleware(self, *args, **kwargs):
|
||||
"""Create a blueprint middleware from a decorated function."""
|
||||
|
||||
def register_middleware(_middleware):
|
||||
future_middleware = FutureMiddleware(_middleware, args, kwargs)
|
||||
self.middlewares.append(future_middleware)
|
||||
|
@ -174,10 +187,12 @@ class Blueprint:
|
|||
|
||||
def exception(self, *args, **kwargs):
|
||||
"""Create a blueprint exception from a decorated function."""
|
||||
|
||||
def decorator(handler):
|
||||
exception = FutureException(handler, args, kwargs)
|
||||
self.exceptions.append(exception)
|
||||
return handler
|
||||
|
||||
return decorator
|
||||
|
||||
def static(self, uri, file_or_directory, *args, **kwargs):
|
||||
|
|
|
@ -97,7 +97,6 @@ INTERNAL_SERVER_ERROR_HTML = '''
|
|||
|
||||
|
||||
class SanicException(Exception):
|
||||
|
||||
def __init__(self, message, status_code=None):
|
||||
super().__init__(message)
|
||||
|
||||
|
@ -105,6 +104,10 @@ class SanicException(Exception):
|
|||
self.status_code = status_code
|
||||
|
||||
|
||||
class SanicTypeException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class NotFound(SanicException):
|
||||
status_code = 404
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import asyncio
|
||||
import inspect
|
||||
|
||||
from sanic import Sanic
|
||||
import pytest
|
||||
|
||||
from sanic import Sanic, response
|
||||
from sanic.blueprints import Blueprint
|
||||
from sanic.response import json, text
|
||||
from sanic.exceptions import NotFound, ServerError, InvalidUsage
|
||||
from sanic.exceptions import NotFound, ServerError, InvalidUsage, SanicTypeException
|
||||
from sanic.response import text
|
||||
|
||||
|
||||
# ------------------------------------------------------------ #
|
||||
|
@ -134,7 +136,6 @@ def test_several_bp_with_host():
|
|||
def handler2(request):
|
||||
return text('Hello3')
|
||||
|
||||
|
||||
app.blueprint(bp)
|
||||
app.blueprint(bp2)
|
||||
|
||||
|
@ -201,7 +202,6 @@ def test_bp_exception_handler():
|
|||
request, response = app.test_client.get('/1')
|
||||
assert response.status == 400
|
||||
|
||||
|
||||
request, response = app.test_client.get('/2')
|
||||
assert response.status == 200
|
||||
assert response.text == 'OK'
|
||||
|
@ -349,3 +349,25 @@ def test_bp_shorthand():
|
|||
'Sec-WebSocket-Version': '13'})
|
||||
assert response.status == 101
|
||||
assert ev.is_set()
|
||||
|
||||
|
||||
def test_blueprint_handler_type_error():
|
||||
class Manage(object):
|
||||
def __init__(self):
|
||||
self.blueprint = Blueprint(str(type(self).__name__))
|
||||
self.blueprint.add_route(self.info, '/info')
|
||||
|
||||
async def info(self, request):
|
||||
return response.json({'id': id(self)})
|
||||
|
||||
def register(self, app: Sanic):
|
||||
app.blueprint(self.blueprint)
|
||||
|
||||
def myfunc():
|
||||
app = Sanic()
|
||||
manager = Manage()
|
||||
manager.register(app)
|
||||
|
||||
with pytest.raises(SanicTypeException) as execinfo:
|
||||
myfunc()
|
||||
execinfo.match(r'.*?instance method.*?')
|
||||
|
|
Loading…
Reference in New Issue
Block a user