Merge pull request #4603 from f3ndot/use-correct-response-type-for-after-request-callable
Fix type annotation for `after_request` callable type
This commit is contained in:
commit
83e9680649
7 changed files with 85 additions and 98 deletions
|
|
@ -7,6 +7,7 @@ Unreleased
|
|||
|
||||
- Inline some optional imports that are only used for certain CLI
|
||||
commands. :pr:`4606`
|
||||
- Relax type annotation for ``after_request`` functions. :issue:`4600`
|
||||
|
||||
|
||||
Version 2.1.2
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ from werkzeug.wrappers import Response as BaseResponse
|
|||
|
||||
from . import cli
|
||||
from . import json
|
||||
from . import typing as ft
|
||||
from .config import Config
|
||||
from .config import ConfigAttribute
|
||||
from .ctx import _AppCtxGlobals
|
||||
|
|
@ -58,12 +59,6 @@ from .signals import request_started
|
|||
from .signals import request_tearing_down
|
||||
from .templating import DispatchingJinjaLoader
|
||||
from .templating import Environment
|
||||
from .typing import BeforeFirstRequestCallable
|
||||
from .typing import ResponseReturnValue
|
||||
from .typing import TeardownCallable
|
||||
from .typing import TemplateFilterCallable
|
||||
from .typing import TemplateGlobalCallable
|
||||
from .typing import TemplateTestCallable
|
||||
from .wrappers import Request
|
||||
from .wrappers import Response
|
||||
|
||||
|
|
@ -72,7 +67,6 @@ if t.TYPE_CHECKING:
|
|||
from .blueprints import Blueprint
|
||||
from .testing import FlaskClient
|
||||
from .testing import FlaskCliRunner
|
||||
from .typing import ErrorHandlerCallable
|
||||
|
||||
if sys.version_info >= (3, 8):
|
||||
iscoroutinefunction = inspect.iscoroutinefunction
|
||||
|
|
@ -436,7 +430,7 @@ class Flask(Scaffold):
|
|||
#: :meth:`before_first_request` decorator.
|
||||
#:
|
||||
#: .. versionadded:: 0.8
|
||||
self.before_first_request_funcs: t.List[BeforeFirstRequestCallable] = []
|
||||
self.before_first_request_funcs: t.List[ft.BeforeFirstRequestCallable] = []
|
||||
|
||||
#: A list of functions that are called when the application context
|
||||
#: is destroyed. Since the application context is also torn down
|
||||
|
|
@ -444,7 +438,7 @@ class Flask(Scaffold):
|
|||
#: from databases.
|
||||
#:
|
||||
#: .. versionadded:: 0.9
|
||||
self.teardown_appcontext_funcs: t.List[TeardownCallable] = []
|
||||
self.teardown_appcontext_funcs: t.List[ft.TeardownCallable] = []
|
||||
|
||||
#: A list of shell context processor functions that should be run
|
||||
#: when a shell context is created.
|
||||
|
|
@ -1096,7 +1090,7 @@ class Flask(Scaffold):
|
|||
@setupmethod
|
||||
def template_filter(
|
||||
self, name: t.Optional[str] = None
|
||||
) -> t.Callable[[TemplateFilterCallable], TemplateFilterCallable]:
|
||||
) -> t.Callable[[ft.TemplateFilterCallable], ft.TemplateFilterCallable]:
|
||||
"""A decorator that is used to register custom template filter.
|
||||
You can specify a name for the filter, otherwise the function
|
||||
name will be used. Example::
|
||||
|
|
@ -1109,7 +1103,7 @@ class Flask(Scaffold):
|
|||
function name will be used.
|
||||
"""
|
||||
|
||||
def decorator(f: TemplateFilterCallable) -> TemplateFilterCallable:
|
||||
def decorator(f: ft.TemplateFilterCallable) -> ft.TemplateFilterCallable:
|
||||
self.add_template_filter(f, name=name)
|
||||
return f
|
||||
|
||||
|
|
@ -1117,7 +1111,7 @@ class Flask(Scaffold):
|
|||
|
||||
@setupmethod
|
||||
def add_template_filter(
|
||||
self, f: TemplateFilterCallable, name: t.Optional[str] = None
|
||||
self, f: ft.TemplateFilterCallable, name: t.Optional[str] = None
|
||||
) -> None:
|
||||
"""Register a custom template filter. Works exactly like the
|
||||
:meth:`template_filter` decorator.
|
||||
|
|
@ -1130,7 +1124,7 @@ class Flask(Scaffold):
|
|||
@setupmethod
|
||||
def template_test(
|
||||
self, name: t.Optional[str] = None
|
||||
) -> t.Callable[[TemplateTestCallable], TemplateTestCallable]:
|
||||
) -> t.Callable[[ft.TemplateTestCallable], ft.TemplateTestCallable]:
|
||||
"""A decorator that is used to register custom template test.
|
||||
You can specify a name for the test, otherwise the function
|
||||
name will be used. Example::
|
||||
|
|
@ -1150,7 +1144,7 @@ class Flask(Scaffold):
|
|||
function name will be used.
|
||||
"""
|
||||
|
||||
def decorator(f: TemplateTestCallable) -> TemplateTestCallable:
|
||||
def decorator(f: ft.TemplateTestCallable) -> ft.TemplateTestCallable:
|
||||
self.add_template_test(f, name=name)
|
||||
return f
|
||||
|
||||
|
|
@ -1158,7 +1152,7 @@ class Flask(Scaffold):
|
|||
|
||||
@setupmethod
|
||||
def add_template_test(
|
||||
self, f: TemplateTestCallable, name: t.Optional[str] = None
|
||||
self, f: ft.TemplateTestCallable, name: t.Optional[str] = None
|
||||
) -> None:
|
||||
"""Register a custom template test. Works exactly like the
|
||||
:meth:`template_test` decorator.
|
||||
|
|
@ -1173,7 +1167,7 @@ class Flask(Scaffold):
|
|||
@setupmethod
|
||||
def template_global(
|
||||
self, name: t.Optional[str] = None
|
||||
) -> t.Callable[[TemplateGlobalCallable], TemplateGlobalCallable]:
|
||||
) -> t.Callable[[ft.TemplateGlobalCallable], ft.TemplateGlobalCallable]:
|
||||
"""A decorator that is used to register a custom template global function.
|
||||
You can specify a name for the global function, otherwise the function
|
||||
name will be used. Example::
|
||||
|
|
@ -1188,7 +1182,7 @@ class Flask(Scaffold):
|
|||
function name will be used.
|
||||
"""
|
||||
|
||||
def decorator(f: TemplateGlobalCallable) -> TemplateGlobalCallable:
|
||||
def decorator(f: ft.TemplateGlobalCallable) -> ft.TemplateGlobalCallable:
|
||||
self.add_template_global(f, name=name)
|
||||
return f
|
||||
|
||||
|
|
@ -1196,7 +1190,7 @@ class Flask(Scaffold):
|
|||
|
||||
@setupmethod
|
||||
def add_template_global(
|
||||
self, f: TemplateGlobalCallable, name: t.Optional[str] = None
|
||||
self, f: ft.TemplateGlobalCallable, name: t.Optional[str] = None
|
||||
) -> None:
|
||||
"""Register a custom template global function. Works exactly like the
|
||||
:meth:`template_global` decorator.
|
||||
|
|
@ -1210,8 +1204,8 @@ class Flask(Scaffold):
|
|||
|
||||
@setupmethod
|
||||
def before_first_request(
|
||||
self, f: BeforeFirstRequestCallable
|
||||
) -> BeforeFirstRequestCallable:
|
||||
self, f: ft.BeforeFirstRequestCallable
|
||||
) -> ft.BeforeFirstRequestCallable:
|
||||
"""Registers a function to be run before the first request to this
|
||||
instance of the application.
|
||||
|
||||
|
|
@ -1224,7 +1218,7 @@ class Flask(Scaffold):
|
|||
return f
|
||||
|
||||
@setupmethod
|
||||
def teardown_appcontext(self, f: TeardownCallable) -> TeardownCallable:
|
||||
def teardown_appcontext(self, f: ft.TeardownCallable) -> ft.TeardownCallable:
|
||||
"""Registers a function to be called when the application context
|
||||
ends. These functions are typically also called when the request
|
||||
context is popped.
|
||||
|
|
@ -1265,7 +1259,7 @@ class Flask(Scaffold):
|
|||
self.shell_context_processors.append(f)
|
||||
return f
|
||||
|
||||
def _find_error_handler(self, e: Exception) -> t.Optional["ErrorHandlerCallable"]:
|
||||
def _find_error_handler(self, e: Exception) -> t.Optional[ft.ErrorHandlerCallable]:
|
||||
"""Return a registered error handler for an exception in this order:
|
||||
blueprint handler for a specific code, app handler for a specific code,
|
||||
blueprint handler for an exception class, app handler for an exception
|
||||
|
|
@ -1290,7 +1284,7 @@ class Flask(Scaffold):
|
|||
|
||||
def handle_http_exception(
|
||||
self, e: HTTPException
|
||||
) -> t.Union[HTTPException, ResponseReturnValue]:
|
||||
) -> t.Union[HTTPException, ft.ResponseReturnValue]:
|
||||
"""Handles an HTTP exception. By default this will invoke the
|
||||
registered error handlers and fall back to returning the
|
||||
exception as response.
|
||||
|
|
@ -1360,7 +1354,7 @@ class Flask(Scaffold):
|
|||
|
||||
def handle_user_exception(
|
||||
self, e: Exception
|
||||
) -> t.Union[HTTPException, ResponseReturnValue]:
|
||||
) -> t.Union[HTTPException, ft.ResponseReturnValue]:
|
||||
"""This method is called whenever an exception occurs that
|
||||
should be handled. A special case is :class:`~werkzeug
|
||||
.exceptions.HTTPException` which is forwarded to the
|
||||
|
|
@ -1430,7 +1424,7 @@ class Flask(Scaffold):
|
|||
raise e
|
||||
|
||||
self.log_exception(exc_info)
|
||||
server_error: t.Union[InternalServerError, ResponseReturnValue]
|
||||
server_error: t.Union[InternalServerError, ft.ResponseReturnValue]
|
||||
server_error = InternalServerError(original_exception=e)
|
||||
handler = self._find_error_handler(server_error)
|
||||
|
||||
|
|
@ -1484,7 +1478,7 @@ class Flask(Scaffold):
|
|||
|
||||
raise FormDataRoutingRedirect(request)
|
||||
|
||||
def dispatch_request(self) -> ResponseReturnValue:
|
||||
def dispatch_request(self) -> ft.ResponseReturnValue:
|
||||
"""Does the request dispatching. Matches the URL and returns the
|
||||
return value of the view or error handler. This does not have to
|
||||
be a response object. In order to convert the return value to a
|
||||
|
|
@ -1527,7 +1521,7 @@ class Flask(Scaffold):
|
|||
|
||||
def finalize_request(
|
||||
self,
|
||||
rv: t.Union[ResponseReturnValue, HTTPException],
|
||||
rv: t.Union[ft.ResponseReturnValue, HTTPException],
|
||||
from_error_handler: bool = False,
|
||||
) -> Response:
|
||||
"""Given the return value from a view function this finalizes
|
||||
|
|
@ -1630,7 +1624,7 @@ class Flask(Scaffold):
|
|||
|
||||
return asgiref_async_to_sync(func)
|
||||
|
||||
def make_response(self, rv: ResponseReturnValue) -> Response:
|
||||
def make_response(self, rv: ft.ResponseReturnValue) -> Response:
|
||||
"""Convert the return value from a view function to an instance of
|
||||
:attr:`response_class`.
|
||||
|
||||
|
|
@ -1722,7 +1716,9 @@ class Flask(Scaffold):
|
|||
# evaluate a WSGI callable, or coerce a different response
|
||||
# class to the correct type
|
||||
try:
|
||||
rv = self.response_class.force_type(rv, request.environ) # type: ignore # noqa: B950
|
||||
rv = self.response_class.force_type(
|
||||
rv, request.environ # type: ignore[arg-type]
|
||||
)
|
||||
except TypeError as e:
|
||||
raise TypeError(
|
||||
f"{e}\nThe view function did not return a valid"
|
||||
|
|
@ -1838,7 +1834,7 @@ class Flask(Scaffold):
|
|||
|
||||
raise error
|
||||
|
||||
def preprocess_request(self) -> t.Optional[ResponseReturnValue]:
|
||||
def preprocess_request(self) -> t.Optional[ft.ResponseReturnValue]:
|
||||
"""Called before the request is dispatched. Calls
|
||||
:attr:`url_value_preprocessors` registered with the app and the
|
||||
current blueprint (if any). Then calls :attr:`before_request_funcs`
|
||||
|
|
|
|||
|
|
@ -3,23 +3,13 @@ import typing as t
|
|||
from collections import defaultdict
|
||||
from functools import update_wrapper
|
||||
|
||||
from . import typing as ft
|
||||
from .scaffold import _endpoint_from_view_func
|
||||
from .scaffold import _sentinel
|
||||
from .scaffold import Scaffold
|
||||
from .typing import AfterRequestCallable
|
||||
from .typing import BeforeFirstRequestCallable
|
||||
from .typing import BeforeRequestCallable
|
||||
from .typing import TeardownCallable
|
||||
from .typing import TemplateContextProcessorCallable
|
||||
from .typing import TemplateFilterCallable
|
||||
from .typing import TemplateGlobalCallable
|
||||
from .typing import TemplateTestCallable
|
||||
from .typing import URLDefaultCallable
|
||||
from .typing import URLValuePreprocessorCallable
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
from .app import Flask
|
||||
from .typing import ErrorHandlerCallable
|
||||
|
||||
DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable]
|
||||
|
||||
|
|
@ -419,7 +409,7 @@ class Blueprint(Scaffold):
|
|||
|
||||
def app_template_filter(
|
||||
self, name: t.Optional[str] = None
|
||||
) -> t.Callable[[TemplateFilterCallable], TemplateFilterCallable]:
|
||||
) -> t.Callable[[ft.TemplateFilterCallable], ft.TemplateFilterCallable]:
|
||||
"""Register a custom template filter, available application wide. Like
|
||||
:meth:`Flask.template_filter` but for a blueprint.
|
||||
|
||||
|
|
@ -427,14 +417,14 @@ class Blueprint(Scaffold):
|
|||
function name will be used.
|
||||
"""
|
||||
|
||||
def decorator(f: TemplateFilterCallable) -> TemplateFilterCallable:
|
||||
def decorator(f: ft.TemplateFilterCallable) -> ft.TemplateFilterCallable:
|
||||
self.add_app_template_filter(f, name=name)
|
||||
return f
|
||||
|
||||
return decorator
|
||||
|
||||
def add_app_template_filter(
|
||||
self, f: TemplateFilterCallable, name: t.Optional[str] = None
|
||||
self, f: ft.TemplateFilterCallable, name: t.Optional[str] = None
|
||||
) -> None:
|
||||
"""Register a custom template filter, available application wide. Like
|
||||
:meth:`Flask.add_template_filter` but for a blueprint. Works exactly
|
||||
|
|
@ -451,7 +441,7 @@ class Blueprint(Scaffold):
|
|||
|
||||
def app_template_test(
|
||||
self, name: t.Optional[str] = None
|
||||
) -> t.Callable[[TemplateTestCallable], TemplateTestCallable]:
|
||||
) -> t.Callable[[ft.TemplateTestCallable], ft.TemplateTestCallable]:
|
||||
"""Register a custom template test, available application wide. Like
|
||||
:meth:`Flask.template_test` but for a blueprint.
|
||||
|
||||
|
|
@ -461,14 +451,14 @@ class Blueprint(Scaffold):
|
|||
function name will be used.
|
||||
"""
|
||||
|
||||
def decorator(f: TemplateTestCallable) -> TemplateTestCallable:
|
||||
def decorator(f: ft.TemplateTestCallable) -> ft.TemplateTestCallable:
|
||||
self.add_app_template_test(f, name=name)
|
||||
return f
|
||||
|
||||
return decorator
|
||||
|
||||
def add_app_template_test(
|
||||
self, f: TemplateTestCallable, name: t.Optional[str] = None
|
||||
self, f: ft.TemplateTestCallable, name: t.Optional[str] = None
|
||||
) -> None:
|
||||
"""Register a custom template test, available application wide. Like
|
||||
:meth:`Flask.add_template_test` but for a blueprint. Works exactly
|
||||
|
|
@ -487,7 +477,7 @@ class Blueprint(Scaffold):
|
|||
|
||||
def app_template_global(
|
||||
self, name: t.Optional[str] = None
|
||||
) -> t.Callable[[TemplateGlobalCallable], TemplateGlobalCallable]:
|
||||
) -> t.Callable[[ft.TemplateGlobalCallable], ft.TemplateGlobalCallable]:
|
||||
"""Register a custom template global, available application wide. Like
|
||||
:meth:`Flask.template_global` but for a blueprint.
|
||||
|
||||
|
|
@ -497,14 +487,14 @@ class Blueprint(Scaffold):
|
|||
function name will be used.
|
||||
"""
|
||||
|
||||
def decorator(f: TemplateGlobalCallable) -> TemplateGlobalCallable:
|
||||
def decorator(f: ft.TemplateGlobalCallable) -> ft.TemplateGlobalCallable:
|
||||
self.add_app_template_global(f, name=name)
|
||||
return f
|
||||
|
||||
return decorator
|
||||
|
||||
def add_app_template_global(
|
||||
self, f: TemplateGlobalCallable, name: t.Optional[str] = None
|
||||
self, f: ft.TemplateGlobalCallable, name: t.Optional[str] = None
|
||||
) -> None:
|
||||
"""Register a custom template global, available application wide. Like
|
||||
:meth:`Flask.add_template_global` but for a blueprint. Works exactly
|
||||
|
|
@ -521,7 +511,9 @@ class Blueprint(Scaffold):
|
|||
|
||||
self.record_once(register_template)
|
||||
|
||||
def before_app_request(self, f: BeforeRequestCallable) -> BeforeRequestCallable:
|
||||
def before_app_request(
|
||||
self, f: ft.BeforeRequestCallable
|
||||
) -> ft.BeforeRequestCallable:
|
||||
"""Like :meth:`Flask.before_request`. Such a function is executed
|
||||
before each request, even if outside of a blueprint.
|
||||
"""
|
||||
|
|
@ -531,15 +523,15 @@ class Blueprint(Scaffold):
|
|||
return f
|
||||
|
||||
def before_app_first_request(
|
||||
self, f: BeforeFirstRequestCallable
|
||||
) -> BeforeFirstRequestCallable:
|
||||
self, f: ft.BeforeFirstRequestCallable
|
||||
) -> ft.BeforeFirstRequestCallable:
|
||||
"""Like :meth:`Flask.before_first_request`. Such a function is
|
||||
executed before the first request to the application.
|
||||
"""
|
||||
self.record_once(lambda s: s.app.before_first_request_funcs.append(f))
|
||||
return f
|
||||
|
||||
def after_app_request(self, f: AfterRequestCallable) -> AfterRequestCallable:
|
||||
def after_app_request(self, f: ft.AfterRequestCallable) -> ft.AfterRequestCallable:
|
||||
"""Like :meth:`Flask.after_request` but for a blueprint. Such a function
|
||||
is executed after each request, even if outside of the blueprint.
|
||||
"""
|
||||
|
|
@ -548,7 +540,7 @@ class Blueprint(Scaffold):
|
|||
)
|
||||
return f
|
||||
|
||||
def teardown_app_request(self, f: TeardownCallable) -> TeardownCallable:
|
||||
def teardown_app_request(self, f: ft.TeardownCallable) -> ft.TeardownCallable:
|
||||
"""Like :meth:`Flask.teardown_request` but for a blueprint. Such a
|
||||
function is executed when tearing down each request, even if outside of
|
||||
the blueprint.
|
||||
|
|
@ -559,8 +551,8 @@ class Blueprint(Scaffold):
|
|||
return f
|
||||
|
||||
def app_context_processor(
|
||||
self, f: TemplateContextProcessorCallable
|
||||
) -> TemplateContextProcessorCallable:
|
||||
self, f: ft.TemplateContextProcessorCallable
|
||||
) -> ft.TemplateContextProcessorCallable:
|
||||
"""Like :meth:`Flask.context_processor` but for a blueprint. Such a
|
||||
function is executed each request, even if outside of the blueprint.
|
||||
"""
|
||||
|
|
@ -574,22 +566,22 @@ class Blueprint(Scaffold):
|
|||
handler is used for all requests, even if outside of the blueprint.
|
||||
"""
|
||||
|
||||
def decorator(f: "ErrorHandlerCallable") -> "ErrorHandlerCallable":
|
||||
def decorator(f: ft.ErrorHandlerCallable) -> ft.ErrorHandlerCallable:
|
||||
self.record_once(lambda s: s.app.errorhandler(code)(f))
|
||||
return f
|
||||
|
||||
return decorator
|
||||
|
||||
def app_url_value_preprocessor(
|
||||
self, f: URLValuePreprocessorCallable
|
||||
) -> URLValuePreprocessorCallable:
|
||||
self, f: ft.URLValuePreprocessorCallable
|
||||
) -> ft.URLValuePreprocessorCallable:
|
||||
"""Same as :meth:`url_value_preprocessor` but application wide."""
|
||||
self.record_once(
|
||||
lambda s: s.app.url_value_preprocessors.setdefault(None, []).append(f)
|
||||
)
|
||||
return f
|
||||
|
||||
def app_url_defaults(self, f: URLDefaultCallable) -> URLDefaultCallable:
|
||||
def app_url_defaults(self, f: ft.URLDefaultCallable) -> ft.URLDefaultCallable:
|
||||
"""Same as :meth:`url_defaults` but application wide."""
|
||||
self.record_once(
|
||||
lambda s: s.app.url_default_functions.setdefault(None, []).append(f)
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ from types import TracebackType
|
|||
|
||||
from werkzeug.exceptions import HTTPException
|
||||
|
||||
from . import typing as ft
|
||||
from .globals import _app_ctx_stack
|
||||
from .globals import _request_ctx_stack
|
||||
from .signals import appcontext_popped
|
||||
from .signals import appcontext_pushed
|
||||
from .typing import AfterRequestCallable
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
from .app import Flask
|
||||
|
|
@ -109,7 +109,7 @@ class _AppCtxGlobals:
|
|||
return object.__repr__(self)
|
||||
|
||||
|
||||
def after_this_request(f: AfterRequestCallable) -> AfterRequestCallable:
|
||||
def after_this_request(f: ft.AfterRequestCallable) -> ft.AfterRequestCallable:
|
||||
"""Executes a function after this request. This is useful to modify
|
||||
response objects. The function is passed the response object and has
|
||||
to return the same or a new one.
|
||||
|
|
@ -341,7 +341,7 @@ class RequestContext:
|
|||
# Functions that should be executed after the request on the response
|
||||
# object. These will be called before the regular "after_request"
|
||||
# functions.
|
||||
self._after_request_functions: t.List[AfterRequestCallable] = []
|
||||
self._after_request_functions: t.List[ft.AfterRequestCallable] = []
|
||||
|
||||
@property
|
||||
def g(self) -> _AppCtxGlobals:
|
||||
|
|
|
|||
|
|
@ -12,23 +12,16 @@ from jinja2 import FileSystemLoader
|
|||
from werkzeug.exceptions import default_exceptions
|
||||
from werkzeug.exceptions import HTTPException
|
||||
|
||||
from . import typing as ft
|
||||
from .cli import AppGroup
|
||||
from .globals import current_app
|
||||
from .helpers import get_root_path
|
||||
from .helpers import locked_cached_property
|
||||
from .helpers import send_from_directory
|
||||
from .templating import _default_template_ctx_processor
|
||||
from .typing import AfterRequestCallable
|
||||
from .typing import AppOrBlueprintKey
|
||||
from .typing import BeforeRequestCallable
|
||||
from .typing import TeardownCallable
|
||||
from .typing import TemplateContextProcessorCallable
|
||||
from .typing import URLDefaultCallable
|
||||
from .typing import URLValuePreprocessorCallable
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
from .wrappers import Response
|
||||
from .typing import ErrorHandlerCallable
|
||||
|
||||
# a singleton sentinel value for parameter defaults
|
||||
_sentinel = object()
|
||||
|
|
@ -143,8 +136,8 @@ class Scaffold:
|
|||
#: This data structure is internal. It should not be modified
|
||||
#: directly and its format may change at any time.
|
||||
self.error_handler_spec: t.Dict[
|
||||
AppOrBlueprintKey,
|
||||
t.Dict[t.Optional[int], t.Dict[t.Type[Exception], "ErrorHandlerCallable"]],
|
||||
ft.AppOrBlueprintKey,
|
||||
t.Dict[t.Optional[int], t.Dict[t.Type[Exception], ft.ErrorHandlerCallable]],
|
||||
] = defaultdict(lambda: defaultdict(dict))
|
||||
|
||||
#: A data structure of functions to call at the beginning of
|
||||
|
|
@ -158,7 +151,7 @@ class Scaffold:
|
|||
#: This data structure is internal. It should not be modified
|
||||
#: directly and its format may change at any time.
|
||||
self.before_request_funcs: t.Dict[
|
||||
AppOrBlueprintKey, t.List[BeforeRequestCallable]
|
||||
ft.AppOrBlueprintKey, t.List[ft.BeforeRequestCallable]
|
||||
] = defaultdict(list)
|
||||
|
||||
#: A data structure of functions to call at the end of each
|
||||
|
|
@ -172,7 +165,7 @@ class Scaffold:
|
|||
#: This data structure is internal. It should not be modified
|
||||
#: directly and its format may change at any time.
|
||||
self.after_request_funcs: t.Dict[
|
||||
AppOrBlueprintKey, t.List[AfterRequestCallable]
|
||||
ft.AppOrBlueprintKey, t.List[ft.AfterRequestCallable]
|
||||
] = defaultdict(list)
|
||||
|
||||
#: A data structure of functions to call at the end of each
|
||||
|
|
@ -187,7 +180,7 @@ class Scaffold:
|
|||
#: This data structure is internal. It should not be modified
|
||||
#: directly and its format may change at any time.
|
||||
self.teardown_request_funcs: t.Dict[
|
||||
AppOrBlueprintKey, t.List[TeardownCallable]
|
||||
ft.AppOrBlueprintKey, t.List[ft.TeardownCallable]
|
||||
] = defaultdict(list)
|
||||
|
||||
#: A data structure of functions to call to pass extra context
|
||||
|
|
@ -202,7 +195,7 @@ class Scaffold:
|
|||
#: This data structure is internal. It should not be modified
|
||||
#: directly and its format may change at any time.
|
||||
self.template_context_processors: t.Dict[
|
||||
AppOrBlueprintKey, t.List[TemplateContextProcessorCallable]
|
||||
ft.AppOrBlueprintKey, t.List[ft.TemplateContextProcessorCallable]
|
||||
] = defaultdict(list, {None: [_default_template_ctx_processor]})
|
||||
|
||||
#: A data structure of functions to call to modify the keyword
|
||||
|
|
@ -217,8 +210,8 @@ class Scaffold:
|
|||
#: This data structure is internal. It should not be modified
|
||||
#: directly and its format may change at any time.
|
||||
self.url_value_preprocessors: t.Dict[
|
||||
AppOrBlueprintKey,
|
||||
t.List[URLValuePreprocessorCallable],
|
||||
ft.AppOrBlueprintKey,
|
||||
t.List[ft.URLValuePreprocessorCallable],
|
||||
] = defaultdict(list)
|
||||
|
||||
#: A data structure of functions to call to modify the keyword
|
||||
|
|
@ -233,7 +226,7 @@ class Scaffold:
|
|||
#: This data structure is internal. It should not be modified
|
||||
#: directly and its format may change at any time.
|
||||
self.url_default_functions: t.Dict[
|
||||
AppOrBlueprintKey, t.List[URLDefaultCallable]
|
||||
ft.AppOrBlueprintKey, t.List[ft.URLDefaultCallable]
|
||||
] = defaultdict(list)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
|
|
@ -534,7 +527,7 @@ class Scaffold:
|
|||
return decorator
|
||||
|
||||
@setupmethod
|
||||
def before_request(self, f: BeforeRequestCallable) -> BeforeRequestCallable:
|
||||
def before_request(self, f: ft.BeforeRequestCallable) -> ft.BeforeRequestCallable:
|
||||
"""Register a function to run before each request.
|
||||
|
||||
For example, this can be used to open a database connection, or
|
||||
|
|
@ -556,7 +549,7 @@ class Scaffold:
|
|||
return f
|
||||
|
||||
@setupmethod
|
||||
def after_request(self, f: AfterRequestCallable) -> AfterRequestCallable:
|
||||
def after_request(self, f: ft.AfterRequestCallable) -> ft.AfterRequestCallable:
|
||||
"""Register a function to run after each request to this object.
|
||||
|
||||
The function is called with the response object, and must return
|
||||
|
|
@ -572,7 +565,7 @@ class Scaffold:
|
|||
return f
|
||||
|
||||
@setupmethod
|
||||
def teardown_request(self, f: TeardownCallable) -> TeardownCallable:
|
||||
def teardown_request(self, f: ft.TeardownCallable) -> ft.TeardownCallable:
|
||||
"""Register a function to be run at the end of each request,
|
||||
regardless of whether there was an exception or not. These functions
|
||||
are executed when the request context is popped, even if not an
|
||||
|
|
@ -612,16 +605,16 @@ class Scaffold:
|
|||
|
||||
@setupmethod
|
||||
def context_processor(
|
||||
self, f: TemplateContextProcessorCallable
|
||||
) -> TemplateContextProcessorCallable:
|
||||
self, f: ft.TemplateContextProcessorCallable
|
||||
) -> ft.TemplateContextProcessorCallable:
|
||||
"""Registers a template context processor function."""
|
||||
self.template_context_processors[None].append(f)
|
||||
return f
|
||||
|
||||
@setupmethod
|
||||
def url_value_preprocessor(
|
||||
self, f: URLValuePreprocessorCallable
|
||||
) -> URLValuePreprocessorCallable:
|
||||
self, f: ft.URLValuePreprocessorCallable
|
||||
) -> ft.URLValuePreprocessorCallable:
|
||||
"""Register a URL value preprocessor function for all view
|
||||
functions in the application. These functions will be called before the
|
||||
:meth:`before_request` functions.
|
||||
|
|
@ -638,7 +631,7 @@ class Scaffold:
|
|||
return f
|
||||
|
||||
@setupmethod
|
||||
def url_defaults(self, f: URLDefaultCallable) -> URLDefaultCallable:
|
||||
def url_defaults(self, f: ft.URLDefaultCallable) -> ft.URLDefaultCallable:
|
||||
"""Callback function for URL defaults for all view functions of the
|
||||
application. It's called with the endpoint and values and should
|
||||
update the values passed in place.
|
||||
|
|
@ -649,7 +642,7 @@ class Scaffold:
|
|||
@setupmethod
|
||||
def errorhandler(
|
||||
self, code_or_exception: t.Union[t.Type[Exception], int]
|
||||
) -> t.Callable[["ErrorHandlerCallable"], "ErrorHandlerCallable"]:
|
||||
) -> t.Callable[[ft.ErrorHandlerCallable], ft.ErrorHandlerCallable]:
|
||||
"""Register a function to handle errors by code or exception class.
|
||||
|
||||
A decorator that is used to register a function given an
|
||||
|
|
@ -679,7 +672,7 @@ class Scaffold:
|
|||
an arbitrary exception
|
||||
"""
|
||||
|
||||
def decorator(f: "ErrorHandlerCallable") -> "ErrorHandlerCallable":
|
||||
def decorator(f: ft.ErrorHandlerCallable) -> ft.ErrorHandlerCallable:
|
||||
self.register_error_handler(code_or_exception, f)
|
||||
return f
|
||||
|
||||
|
|
@ -689,7 +682,7 @@ class Scaffold:
|
|||
def register_error_handler(
|
||||
self,
|
||||
code_or_exception: t.Union[t.Type[Exception], int],
|
||||
f: "ErrorHandlerCallable",
|
||||
f: ft.ErrorHandlerCallable,
|
||||
) -> None:
|
||||
"""Alternative error attach function to the :meth:`errorhandler`
|
||||
decorator that is more straightforward to use for non decorator
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import typing as t
|
|||
if t.TYPE_CHECKING:
|
||||
from _typeshed.wsgi import WSGIApplication # noqa: F401
|
||||
from werkzeug.datastructures import Headers # noqa: F401
|
||||
from werkzeug.wrappers.response import Response # noqa: F401
|
||||
from werkzeug.wrappers import Response # noqa: F401
|
||||
|
||||
# The possible types that are directly convertible or are a Response object.
|
||||
ResponseValue = t.Union[
|
||||
|
|
@ -35,8 +35,13 @@ ResponseReturnValue = t.Union[
|
|||
"WSGIApplication",
|
||||
]
|
||||
|
||||
# Allow any subclass of werkzeug.Response, such as the one from Flask,
|
||||
# as a callback argument. Using werkzeug.Response directly makes a
|
||||
# callback annotated with flask.Response fail type checking.
|
||||
ResponseClass = t.TypeVar("ResponseClass", bound="Response")
|
||||
|
||||
AppOrBlueprintKey = t.Optional[str] # The App key is None, whereas blueprints are named
|
||||
AfterRequestCallable = t.Callable[["Response"], "Response"]
|
||||
AfterRequestCallable = t.Callable[[ResponseClass], ResponseClass]
|
||||
BeforeFirstRequestCallable = t.Callable[[], None]
|
||||
BeforeRequestCallable = t.Callable[[], t.Optional[ResponseReturnValue]]
|
||||
TeardownCallable = t.Callable[[t.Optional[BaseException]], None]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import typing as t
|
||||
|
||||
from . import typing as ft
|
||||
from .globals import current_app
|
||||
from .globals import request
|
||||
from .typing import ResponseReturnValue
|
||||
|
||||
|
||||
http_method_funcs = frozenset(
|
||||
|
|
@ -59,7 +59,7 @@ class View:
|
|||
#: .. versionadded:: 0.8
|
||||
decorators: t.List[t.Callable] = []
|
||||
|
||||
def dispatch_request(self) -> ResponseReturnValue:
|
||||
def dispatch_request(self) -> ft.ResponseReturnValue:
|
||||
"""Subclasses have to override this method to implement the
|
||||
actual view function code. This method is called with all
|
||||
the arguments from the URL rule.
|
||||
|
|
@ -79,7 +79,7 @@ class View:
|
|||
constructor of the class.
|
||||
"""
|
||||
|
||||
def view(*args: t.Any, **kwargs: t.Any) -> ResponseReturnValue:
|
||||
def view(*args: t.Any, **kwargs: t.Any) -> ft.ResponseReturnValue:
|
||||
self = view.view_class(*class_args, **class_kwargs) # type: ignore
|
||||
return current_app.ensure_sync(self.dispatch_request)(*args, **kwargs)
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ class MethodView(View, metaclass=MethodViewType):
|
|||
app.add_url_rule('/counter', view_func=CounterAPI.as_view('counter'))
|
||||
"""
|
||||
|
||||
def dispatch_request(self, *args: t.Any, **kwargs: t.Any) -> ResponseReturnValue:
|
||||
def dispatch_request(self, *args: t.Any, **kwargs: t.Any) -> ft.ResponseReturnValue:
|
||||
meth = getattr(self, request.method.lower(), None)
|
||||
|
||||
# If the request method is HEAD and we don't have a handler for it
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue