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