add __future__ annotations
This commit is contained in:
parent
cfa863c357
commit
44ffe6c6d6
19 changed files with 277 additions and 262 deletions
|
|
@ -46,6 +46,7 @@ Unreleased
|
||||||
:issue:`5051`
|
:issue:`5051`
|
||||||
- The ``routes`` command shows each rule's ``subdomain`` or ``host`` when domain
|
- The ``routes`` command shows each rule's ``subdomain`` or ``host`` when domain
|
||||||
matching is in use. :issue:`5004`
|
matching is in use. :issue:`5004`
|
||||||
|
- Use postponed evaluation of annotations. :pr:`5071`
|
||||||
|
|
||||||
|
|
||||||
Version 2.2.4
|
Version 2.2.4
|
||||||
|
|
|
||||||
110
src/flask/app.py
110
src/flask/app.py
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -95,7 +97,7 @@ else:
|
||||||
return inspect.iscoroutinefunction(func)
|
return inspect.iscoroutinefunction(func)
|
||||||
|
|
||||||
|
|
||||||
def _make_timedelta(value: t.Union[timedelta, int, None]) -> t.Optional[timedelta]:
|
def _make_timedelta(value: timedelta | int | None) -> timedelta | None:
|
||||||
if value is None or isinstance(value, timedelta):
|
if value is None or isinstance(value, timedelta):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
@ -280,7 +282,7 @@ class Flask(Scaffold):
|
||||||
"PERMANENT_SESSION_LIFETIME", get_converter=_make_timedelta
|
"PERMANENT_SESSION_LIFETIME", get_converter=_make_timedelta
|
||||||
)
|
)
|
||||||
|
|
||||||
json_provider_class: t.Type[JSONProvider] = DefaultJSONProvider
|
json_provider_class: type[JSONProvider] = DefaultJSONProvider
|
||||||
"""A subclass of :class:`~flask.json.provider.JSONProvider`. An
|
"""A subclass of :class:`~flask.json.provider.JSONProvider`. An
|
||||||
instance is created and assigned to :attr:`app.json` when creating
|
instance is created and assigned to :attr:`app.json` when creating
|
||||||
the app.
|
the app.
|
||||||
|
|
@ -348,7 +350,7 @@ class Flask(Scaffold):
|
||||||
#: client class. Defaults to :class:`~flask.testing.FlaskClient`.
|
#: client class. Defaults to :class:`~flask.testing.FlaskClient`.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 0.7
|
#: .. versionadded:: 0.7
|
||||||
test_client_class: t.Optional[t.Type["FlaskClient"]] = None
|
test_client_class: type[FlaskClient] | None = None
|
||||||
|
|
||||||
#: The :class:`~click.testing.CliRunner` subclass, by default
|
#: The :class:`~click.testing.CliRunner` subclass, by default
|
||||||
#: :class:`~flask.testing.FlaskCliRunner` that is used by
|
#: :class:`~flask.testing.FlaskCliRunner` that is used by
|
||||||
|
|
@ -356,7 +358,7 @@ class Flask(Scaffold):
|
||||||
#: Flask app object as the first argument.
|
#: Flask app object as the first argument.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 1.0
|
#: .. versionadded:: 1.0
|
||||||
test_cli_runner_class: t.Optional[t.Type["FlaskCliRunner"]] = None
|
test_cli_runner_class: type[FlaskCliRunner] | None = None
|
||||||
|
|
||||||
#: the session interface to use. By default an instance of
|
#: the session interface to use. By default an instance of
|
||||||
#: :class:`~flask.sessions.SecureCookieSessionInterface` is used here.
|
#: :class:`~flask.sessions.SecureCookieSessionInterface` is used here.
|
||||||
|
|
@ -367,15 +369,15 @@ class Flask(Scaffold):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
import_name: str,
|
import_name: str,
|
||||||
static_url_path: t.Optional[str] = None,
|
static_url_path: str | None = None,
|
||||||
static_folder: t.Optional[t.Union[str, os.PathLike]] = "static",
|
static_folder: str | os.PathLike | None = "static",
|
||||||
static_host: t.Optional[str] = None,
|
static_host: str | None = None,
|
||||||
host_matching: bool = False,
|
host_matching: bool = False,
|
||||||
subdomain_matching: bool = False,
|
subdomain_matching: bool = False,
|
||||||
template_folder: t.Optional[t.Union[str, os.PathLike]] = "templates",
|
template_folder: str | os.PathLike | None = "templates",
|
||||||
instance_path: t.Optional[str] = None,
|
instance_path: str | None = None,
|
||||||
instance_relative_config: bool = False,
|
instance_relative_config: bool = False,
|
||||||
root_path: t.Optional[str] = None,
|
root_path: str | None = None,
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
import_name=import_name,
|
import_name=import_name,
|
||||||
|
|
@ -435,8 +437,8 @@ class Flask(Scaffold):
|
||||||
#: Otherwise, its return value is returned by ``url_for``.
|
#: Otherwise, its return value is returned by ``url_for``.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 0.9
|
#: .. versionadded:: 0.9
|
||||||
self.url_build_error_handlers: t.List[
|
self.url_build_error_handlers: list[
|
||||||
t.Callable[[Exception, str, t.Dict[str, t.Any]], str]
|
t.Callable[[Exception, str, dict[str, t.Any]], str]
|
||||||
] = []
|
] = []
|
||||||
|
|
||||||
#: A list of functions that are called when the application context
|
#: A list of functions that are called when the application context
|
||||||
|
|
@ -445,13 +447,13 @@ class Flask(Scaffold):
|
||||||
#: from databases.
|
#: from databases.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 0.9
|
#: .. versionadded:: 0.9
|
||||||
self.teardown_appcontext_funcs: t.List[ft.TeardownCallable] = []
|
self.teardown_appcontext_funcs: list[ft.TeardownCallable] = []
|
||||||
|
|
||||||
#: A list of shell context processor functions that should be run
|
#: A list of shell context processor functions that should be run
|
||||||
#: when a shell context is created.
|
#: when a shell context is created.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 0.11
|
#: .. versionadded:: 0.11
|
||||||
self.shell_context_processors: t.List[ft.ShellContextProcessorCallable] = []
|
self.shell_context_processors: list[ft.ShellContextProcessorCallable] = []
|
||||||
|
|
||||||
#: Maps registered blueprint names to blueprint objects. The
|
#: Maps registered blueprint names to blueprint objects. The
|
||||||
#: dict retains the order the blueprints were registered in.
|
#: dict retains the order the blueprints were registered in.
|
||||||
|
|
@ -459,7 +461,7 @@ class Flask(Scaffold):
|
||||||
#: not track how often they were attached.
|
#: not track how often they were attached.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 0.7
|
#: .. versionadded:: 0.7
|
||||||
self.blueprints: t.Dict[str, "Blueprint"] = {}
|
self.blueprints: dict[str, Blueprint] = {}
|
||||||
|
|
||||||
#: a place where extensions can store application specific state. For
|
#: a place where extensions can store application specific state. For
|
||||||
#: example this is where an extension could store database engines and
|
#: example this is where an extension could store database engines and
|
||||||
|
|
@ -734,7 +736,7 @@ class Flask(Scaffold):
|
||||||
:param context: the context as a dictionary that is updated in place
|
:param context: the context as a dictionary that is updated in place
|
||||||
to add extra variables.
|
to add extra variables.
|
||||||
"""
|
"""
|
||||||
names: t.Iterable[t.Optional[str]] = (None,)
|
names: t.Iterable[str | None] = (None,)
|
||||||
|
|
||||||
# A template may be rendered outside a request context.
|
# A template may be rendered outside a request context.
|
||||||
if request:
|
if request:
|
||||||
|
|
@ -785,9 +787,9 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
def run(
|
def run(
|
||||||
self,
|
self,
|
||||||
host: t.Optional[str] = None,
|
host: str | None = None,
|
||||||
port: t.Optional[int] = None,
|
port: int | None = None,
|
||||||
debug: t.Optional[bool] = None,
|
debug: bool | None = None,
|
||||||
load_dotenv: bool = True,
|
load_dotenv: bool = True,
|
||||||
**options: t.Any,
|
**options: t.Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
@ -906,7 +908,7 @@ class Flask(Scaffold):
|
||||||
# without reloader and that stuff from an interactive shell.
|
# without reloader and that stuff from an interactive shell.
|
||||||
self._got_first_request = False
|
self._got_first_request = False
|
||||||
|
|
||||||
def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> "FlaskClient":
|
def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> FlaskClient:
|
||||||
"""Creates a test client for this application. For information
|
"""Creates a test client for this application. For information
|
||||||
about unit testing head over to :doc:`/testing`.
|
about unit testing head over to :doc:`/testing`.
|
||||||
|
|
||||||
|
|
@ -964,7 +966,7 @@ class Flask(Scaffold):
|
||||||
self, self.response_class, use_cookies=use_cookies, **kwargs
|
self, self.response_class, use_cookies=use_cookies, **kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_cli_runner(self, **kwargs: t.Any) -> "FlaskCliRunner":
|
def test_cli_runner(self, **kwargs: t.Any) -> FlaskCliRunner:
|
||||||
"""Create a CLI runner for testing CLI commands.
|
"""Create a CLI runner for testing CLI commands.
|
||||||
See :ref:`testing-cli`.
|
See :ref:`testing-cli`.
|
||||||
|
|
||||||
|
|
@ -982,7 +984,7 @@ class Flask(Scaffold):
|
||||||
return cls(self, **kwargs) # type: ignore
|
return cls(self, **kwargs) # type: ignore
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def register_blueprint(self, blueprint: "Blueprint", **options: t.Any) -> None:
|
def register_blueprint(self, blueprint: Blueprint, **options: t.Any) -> None:
|
||||||
"""Register a :class:`~flask.Blueprint` on the application. Keyword
|
"""Register a :class:`~flask.Blueprint` on the application. Keyword
|
||||||
arguments passed to this method will override the defaults set on the
|
arguments passed to this method will override the defaults set on the
|
||||||
blueprint.
|
blueprint.
|
||||||
|
|
@ -1009,7 +1011,7 @@ class Flask(Scaffold):
|
||||||
"""
|
"""
|
||||||
blueprint.register(self, options)
|
blueprint.register(self, options)
|
||||||
|
|
||||||
def iter_blueprints(self) -> t.ValuesView["Blueprint"]:
|
def iter_blueprints(self) -> t.ValuesView[Blueprint]:
|
||||||
"""Iterates over all blueprints by the order they were registered.
|
"""Iterates over all blueprints by the order they were registered.
|
||||||
|
|
||||||
.. versionadded:: 0.11
|
.. versionadded:: 0.11
|
||||||
|
|
@ -1020,9 +1022,9 @@ class Flask(Scaffold):
|
||||||
def add_url_rule(
|
def add_url_rule(
|
||||||
self,
|
self,
|
||||||
rule: str,
|
rule: str,
|
||||||
endpoint: t.Optional[str] = None,
|
endpoint: str | None = None,
|
||||||
view_func: t.Optional[ft.RouteCallable] = None,
|
view_func: ft.RouteCallable | None = None,
|
||||||
provide_automatic_options: t.Optional[bool] = None,
|
provide_automatic_options: bool | None = None,
|
||||||
**options: t.Any,
|
**options: t.Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
if endpoint is None:
|
if endpoint is None:
|
||||||
|
|
@ -1077,7 +1079,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def template_filter(
|
def template_filter(
|
||||||
self, name: t.Optional[str] = None
|
self, name: str | None = None
|
||||||
) -> t.Callable[[T_template_filter], T_template_filter]:
|
) -> t.Callable[[T_template_filter], T_template_filter]:
|
||||||
"""A decorator that is used to register custom template filter.
|
"""A decorator that is used to register custom template filter.
|
||||||
You can specify a name for the filter, otherwise the function
|
You can specify a name for the filter, otherwise the function
|
||||||
|
|
@ -1099,7 +1101,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def add_template_filter(
|
def add_template_filter(
|
||||||
self, f: ft.TemplateFilterCallable, name: t.Optional[str] = None
|
self, f: ft.TemplateFilterCallable, name: str | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register a custom template filter. Works exactly like the
|
"""Register a custom template filter. Works exactly like the
|
||||||
:meth:`template_filter` decorator.
|
:meth:`template_filter` decorator.
|
||||||
|
|
@ -1111,7 +1113,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def template_test(
|
def template_test(
|
||||||
self, name: t.Optional[str] = None
|
self, name: str | None = None
|
||||||
) -> t.Callable[[T_template_test], T_template_test]:
|
) -> t.Callable[[T_template_test], T_template_test]:
|
||||||
"""A decorator that is used to register custom template test.
|
"""A decorator that is used to register custom template test.
|
||||||
You can specify a name for the test, otherwise the function
|
You can specify a name for the test, otherwise the function
|
||||||
|
|
@ -1140,7 +1142,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def add_template_test(
|
def add_template_test(
|
||||||
self, f: ft.TemplateTestCallable, name: t.Optional[str] = None
|
self, f: ft.TemplateTestCallable, name: str | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register a custom template test. Works exactly like the
|
"""Register a custom template test. Works exactly like the
|
||||||
:meth:`template_test` decorator.
|
:meth:`template_test` decorator.
|
||||||
|
|
@ -1154,7 +1156,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def template_global(
|
def template_global(
|
||||||
self, name: t.Optional[str] = None
|
self, name: str | None = None
|
||||||
) -> t.Callable[[T_template_global], T_template_global]:
|
) -> t.Callable[[T_template_global], T_template_global]:
|
||||||
"""A decorator that is used to register a custom template global function.
|
"""A decorator that is used to register a custom template global function.
|
||||||
You can specify a name for the global function, otherwise the function
|
You can specify a name for the global function, otherwise the function
|
||||||
|
|
@ -1178,7 +1180,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def add_template_global(
|
def add_template_global(
|
||||||
self, f: ft.TemplateGlobalCallable, name: t.Optional[str] = None
|
self, f: ft.TemplateGlobalCallable, name: str | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register a custom template global function. Works exactly like the
|
"""Register a custom template global function. Works exactly like the
|
||||||
:meth:`template_global` decorator.
|
:meth:`template_global` decorator.
|
||||||
|
|
@ -1235,7 +1237,7 @@ class Flask(Scaffold):
|
||||||
self.shell_context_processors.append(f)
|
self.shell_context_processors.append(f)
|
||||||
return f
|
return f
|
||||||
|
|
||||||
def _find_error_handler(self, e: Exception) -> t.Optional[ft.ErrorHandlerCallable]:
|
def _find_error_handler(self, e: Exception) -> ft.ErrorHandlerCallable | None:
|
||||||
"""Return a registered error handler for an exception in this order:
|
"""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 a specific code, app handler for a specific code,
|
||||||
blueprint handler for an exception class, app handler for an exception
|
blueprint handler for an exception class, app handler for an exception
|
||||||
|
|
@ -1260,7 +1262,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
def handle_http_exception(
|
def handle_http_exception(
|
||||||
self, e: HTTPException
|
self, e: HTTPException
|
||||||
) -> t.Union[HTTPException, ft.ResponseReturnValue]:
|
) -> HTTPException | ft.ResponseReturnValue:
|
||||||
"""Handles an HTTP exception. By default this will invoke the
|
"""Handles an HTTP exception. By default this will invoke the
|
||||||
registered error handlers and fall back to returning the
|
registered error handlers and fall back to returning the
|
||||||
exception as response.
|
exception as response.
|
||||||
|
|
@ -1330,7 +1332,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
def handle_user_exception(
|
def handle_user_exception(
|
||||||
self, e: Exception
|
self, e: Exception
|
||||||
) -> t.Union[HTTPException, ft.ResponseReturnValue]:
|
) -> HTTPException | ft.ResponseReturnValue:
|
||||||
"""This method is called whenever an exception occurs that
|
"""This method is called whenever an exception occurs that
|
||||||
should be handled. A special case is :class:`~werkzeug
|
should be handled. A special case is :class:`~werkzeug
|
||||||
.exceptions.HTTPException` which is forwarded to the
|
.exceptions.HTTPException` which is forwarded to the
|
||||||
|
|
@ -1404,7 +1406,7 @@ class Flask(Scaffold):
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
self.log_exception(exc_info)
|
self.log_exception(exc_info)
|
||||||
server_error: t.Union[InternalServerError, ft.ResponseReturnValue]
|
server_error: InternalServerError | ft.ResponseReturnValue
|
||||||
server_error = InternalServerError(original_exception=e)
|
server_error = InternalServerError(original_exception=e)
|
||||||
handler = self._find_error_handler(server_error)
|
handler = self._find_error_handler(server_error)
|
||||||
|
|
||||||
|
|
@ -1415,9 +1417,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
def log_exception(
|
def log_exception(
|
||||||
self,
|
self,
|
||||||
exc_info: t.Union[
|
exc_info: (tuple[type, BaseException, TracebackType] | tuple[None, None, None]),
|
||||||
t.Tuple[type, BaseException, TracebackType], t.Tuple[None, None, None]
|
|
||||||
],
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Logs an exception. This is called by :meth:`handle_exception`
|
"""Logs an exception. This is called by :meth:`handle_exception`
|
||||||
if debugging is disabled and right before the handler is called.
|
if debugging is disabled and right before the handler is called.
|
||||||
|
|
@ -1430,7 +1430,7 @@ class Flask(Scaffold):
|
||||||
f"Exception on {request.path} [{request.method}]", exc_info=exc_info
|
f"Exception on {request.path} [{request.method}]", exc_info=exc_info
|
||||||
)
|
)
|
||||||
|
|
||||||
def raise_routing_exception(self, request: Request) -> "te.NoReturn":
|
def raise_routing_exception(self, request: Request) -> te.NoReturn:
|
||||||
"""Intercept routing exceptions and possibly do something else.
|
"""Intercept routing exceptions and possibly do something else.
|
||||||
|
|
||||||
In debug mode, intercept a routing redirect and replace it with
|
In debug mode, intercept a routing redirect and replace it with
|
||||||
|
|
@ -1480,7 +1480,7 @@ class Flask(Scaffold):
|
||||||
):
|
):
|
||||||
return self.make_default_options_response()
|
return self.make_default_options_response()
|
||||||
# otherwise dispatch to the handler for that endpoint
|
# otherwise dispatch to the handler for that endpoint
|
||||||
view_args: t.Dict[str, t.Any] = req.view_args # type: ignore[assignment]
|
view_args: dict[str, t.Any] = req.view_args # type: ignore[assignment]
|
||||||
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
|
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
|
||||||
|
|
||||||
def full_dispatch_request(self) -> Response:
|
def full_dispatch_request(self) -> Response:
|
||||||
|
|
@ -1503,7 +1503,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
def finalize_request(
|
def finalize_request(
|
||||||
self,
|
self,
|
||||||
rv: t.Union[ft.ResponseReturnValue, HTTPException],
|
rv: ft.ResponseReturnValue | HTTPException,
|
||||||
from_error_handler: bool = False,
|
from_error_handler: bool = False,
|
||||||
) -> Response:
|
) -> Response:
|
||||||
"""Given the return value from a view function this finalizes
|
"""Given the return value from a view function this finalizes
|
||||||
|
|
@ -1545,7 +1545,7 @@ class Flask(Scaffold):
|
||||||
rv.allow.update(methods)
|
rv.allow.update(methods)
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
def should_ignore_error(self, error: t.Optional[BaseException]) -> bool:
|
def should_ignore_error(self, error: BaseException | None) -> bool:
|
||||||
"""This is called to figure out if an error should be ignored
|
"""This is called to figure out if an error should be ignored
|
||||||
or not as far as the teardown system is concerned. If this
|
or not as far as the teardown system is concerned. If this
|
||||||
function returns ``True`` then the teardown handlers will not be
|
function returns ``True`` then the teardown handlers will not be
|
||||||
|
|
@ -1596,10 +1596,10 @@ class Flask(Scaffold):
|
||||||
self,
|
self,
|
||||||
endpoint: str,
|
endpoint: str,
|
||||||
*,
|
*,
|
||||||
_anchor: t.Optional[str] = None,
|
_anchor: str | None = None,
|
||||||
_method: t.Optional[str] = None,
|
_method: str | None = None,
|
||||||
_scheme: t.Optional[str] = None,
|
_scheme: str | None = None,
|
||||||
_external: t.Optional[bool] = None,
|
_external: bool | None = None,
|
||||||
**values: t.Any,
|
**values: t.Any,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Generate a URL to the given endpoint with the given values.
|
"""Generate a URL to the given endpoint with the given values.
|
||||||
|
|
@ -1871,9 +1871,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
def create_url_adapter(
|
def create_url_adapter(self, request: Request | None) -> MapAdapter | None:
|
||||||
self, request: t.Optional[Request]
|
|
||||||
) -> t.Optional[MapAdapter]:
|
|
||||||
"""Creates a URL adapter for the given request. The URL adapter
|
"""Creates a URL adapter for the given request. The URL adapter
|
||||||
is created at a point where the request context is not yet set
|
is created at a point where the request context is not yet set
|
||||||
up so the request is passed explicitly.
|
up so the request is passed explicitly.
|
||||||
|
|
@ -1920,7 +1918,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
.. versionadded:: 0.7
|
.. versionadded:: 0.7
|
||||||
"""
|
"""
|
||||||
names: t.Iterable[t.Optional[str]] = (None,)
|
names: t.Iterable[str | None] = (None,)
|
||||||
|
|
||||||
# url_for may be called outside a request context, parse the
|
# url_for may be called outside a request context, parse the
|
||||||
# passed endpoint instead of using request.blueprints.
|
# passed endpoint instead of using request.blueprints.
|
||||||
|
|
@ -1935,7 +1933,7 @@ class Flask(Scaffold):
|
||||||
func(endpoint, values)
|
func(endpoint, values)
|
||||||
|
|
||||||
def handle_url_build_error(
|
def handle_url_build_error(
|
||||||
self, error: BuildError, endpoint: str, values: t.Dict[str, t.Any]
|
self, error: BuildError, endpoint: str, values: dict[str, t.Any]
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Called by :meth:`.url_for` if a
|
"""Called by :meth:`.url_for` if a
|
||||||
:exc:`~werkzeug.routing.BuildError` was raised. If this returns
|
:exc:`~werkzeug.routing.BuildError` was raised. If this returns
|
||||||
|
|
@ -1968,7 +1966,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
raise error
|
raise error
|
||||||
|
|
||||||
def preprocess_request(self) -> t.Optional[ft.ResponseReturnValue]:
|
def preprocess_request(self) -> ft.ResponseReturnValue | None:
|
||||||
"""Called before the request is dispatched. Calls
|
"""Called before the request is dispatched. Calls
|
||||||
:attr:`url_value_preprocessors` registered with the app and the
|
:attr:`url_value_preprocessors` registered with the app and the
|
||||||
current blueprint (if any). Then calls :attr:`before_request_funcs`
|
current blueprint (if any). Then calls :attr:`before_request_funcs`
|
||||||
|
|
@ -2024,7 +2022,7 @@ class Flask(Scaffold):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def do_teardown_request(
|
def do_teardown_request(
|
||||||
self, exc: t.Optional[BaseException] = _sentinel # type: ignore
|
self, exc: BaseException | None = _sentinel # type: ignore
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Called after the request is dispatched and the response is
|
"""Called after the request is dispatched and the response is
|
||||||
returned, right before the request context is popped.
|
returned, right before the request context is popped.
|
||||||
|
|
@ -2057,7 +2055,7 @@ class Flask(Scaffold):
|
||||||
request_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc)
|
request_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc)
|
||||||
|
|
||||||
def do_teardown_appcontext(
|
def do_teardown_appcontext(
|
||||||
self, exc: t.Optional[BaseException] = _sentinel # type: ignore
|
self, exc: BaseException | None = _sentinel # type: ignore
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Called right before the application context is popped.
|
"""Called right before the application context is popped.
|
||||||
|
|
||||||
|
|
@ -2200,7 +2198,7 @@ class Flask(Scaffold):
|
||||||
start the response.
|
start the response.
|
||||||
"""
|
"""
|
||||||
ctx = self.request_context(environ)
|
ctx = self.request_context(environ)
|
||||||
error: t.Optional[BaseException] = None
|
error: BaseException | None = None
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
ctx.push()
|
ctx.push()
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import typing as t
|
import typing as t
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
@ -38,8 +40,8 @@ class BlueprintSetupState:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
blueprint: "Blueprint",
|
blueprint: Blueprint,
|
||||||
app: "Flask",
|
app: Flask,
|
||||||
options: t.Any,
|
options: t.Any,
|
||||||
first_registration: bool,
|
first_registration: bool,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
@ -85,8 +87,8 @@ class BlueprintSetupState:
|
||||||
def add_url_rule(
|
def add_url_rule(
|
||||||
self,
|
self,
|
||||||
rule: str,
|
rule: str,
|
||||||
endpoint: t.Optional[str] = None,
|
endpoint: str | None = None,
|
||||||
view_func: t.Optional[t.Callable] = None,
|
view_func: t.Callable | None = None,
|
||||||
**options: t.Any,
|
**options: t.Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""A helper method to register a rule (and optionally a view function)
|
"""A helper method to register a rule (and optionally a view function)
|
||||||
|
|
@ -173,14 +175,14 @@ class Blueprint(Scaffold):
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
import_name: str,
|
import_name: str,
|
||||||
static_folder: t.Optional[t.Union[str, os.PathLike]] = None,
|
static_folder: str | os.PathLike | None = None,
|
||||||
static_url_path: t.Optional[str] = None,
|
static_url_path: str | None = None,
|
||||||
template_folder: t.Optional[t.Union[str, os.PathLike]] = None,
|
template_folder: str | os.PathLike | None = None,
|
||||||
url_prefix: t.Optional[str] = None,
|
url_prefix: str | None = None,
|
||||||
subdomain: t.Optional[str] = None,
|
subdomain: str | None = None,
|
||||||
url_defaults: t.Optional[dict] = None,
|
url_defaults: dict | None = None,
|
||||||
root_path: t.Optional[str] = None,
|
root_path: str | None = None,
|
||||||
cli_group: t.Optional[str] = _sentinel, # type: ignore
|
cli_group: str | None = _sentinel, # type: ignore
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
import_name=import_name,
|
import_name=import_name,
|
||||||
|
|
@ -199,14 +201,14 @@ class Blueprint(Scaffold):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.url_prefix = url_prefix
|
self.url_prefix = url_prefix
|
||||||
self.subdomain = subdomain
|
self.subdomain = subdomain
|
||||||
self.deferred_functions: t.List[DeferredSetupFunction] = []
|
self.deferred_functions: list[DeferredSetupFunction] = []
|
||||||
|
|
||||||
if url_defaults is None:
|
if url_defaults is None:
|
||||||
url_defaults = {}
|
url_defaults = {}
|
||||||
|
|
||||||
self.url_values_defaults = url_defaults
|
self.url_values_defaults = url_defaults
|
||||||
self.cli_group = cli_group
|
self.cli_group = cli_group
|
||||||
self._blueprints: t.List[t.Tuple["Blueprint", dict]] = []
|
self._blueprints: list[tuple[Blueprint, dict]] = []
|
||||||
|
|
||||||
def _check_setup_finished(self, f_name: str) -> None:
|
def _check_setup_finished(self, f_name: str) -> None:
|
||||||
if self._got_registered_once:
|
if self._got_registered_once:
|
||||||
|
|
@ -242,7 +244,7 @@ class Blueprint(Scaffold):
|
||||||
self.record(update_wrapper(wrapper, func))
|
self.record(update_wrapper(wrapper, func))
|
||||||
|
|
||||||
def make_setup_state(
|
def make_setup_state(
|
||||||
self, app: "Flask", options: dict, first_registration: bool = False
|
self, app: Flask, options: dict, first_registration: bool = False
|
||||||
) -> BlueprintSetupState:
|
) -> BlueprintSetupState:
|
||||||
"""Creates an instance of :meth:`~flask.blueprints.BlueprintSetupState`
|
"""Creates an instance of :meth:`~flask.blueprints.BlueprintSetupState`
|
||||||
object that is later passed to the register callback functions.
|
object that is later passed to the register callback functions.
|
||||||
|
|
@ -251,7 +253,7 @@ class Blueprint(Scaffold):
|
||||||
return BlueprintSetupState(self, app, options, first_registration)
|
return BlueprintSetupState(self, app, options, first_registration)
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def register_blueprint(self, blueprint: "Blueprint", **options: t.Any) -> None:
|
def register_blueprint(self, blueprint: Blueprint, **options: t.Any) -> None:
|
||||||
"""Register a :class:`~flask.Blueprint` on this blueprint. Keyword
|
"""Register a :class:`~flask.Blueprint` on this blueprint. Keyword
|
||||||
arguments passed to this method will override the defaults set
|
arguments passed to this method will override the defaults set
|
||||||
on the blueprint.
|
on the blueprint.
|
||||||
|
|
@ -268,7 +270,7 @@ class Blueprint(Scaffold):
|
||||||
raise ValueError("Cannot register a blueprint on itself")
|
raise ValueError("Cannot register a blueprint on itself")
|
||||||
self._blueprints.append((blueprint, options))
|
self._blueprints.append((blueprint, options))
|
||||||
|
|
||||||
def register(self, app: "Flask", options: dict) -> None:
|
def register(self, app: Flask, options: dict) -> None:
|
||||||
"""Called by :meth:`Flask.register_blueprint` to register all
|
"""Called by :meth:`Flask.register_blueprint` to register all
|
||||||
views and callbacks registered on the blueprint with the
|
views and callbacks registered on the blueprint with the
|
||||||
application. Creates a :class:`.BlueprintSetupState` and calls
|
application. Creates a :class:`.BlueprintSetupState` and calls
|
||||||
|
|
@ -408,9 +410,9 @@ class Blueprint(Scaffold):
|
||||||
def add_url_rule(
|
def add_url_rule(
|
||||||
self,
|
self,
|
||||||
rule: str,
|
rule: str,
|
||||||
endpoint: t.Optional[str] = None,
|
endpoint: str | None = None,
|
||||||
view_func: t.Optional[ft.RouteCallable] = None,
|
view_func: ft.RouteCallable | None = None,
|
||||||
provide_automatic_options: t.Optional[bool] = None,
|
provide_automatic_options: bool | None = None,
|
||||||
**options: t.Any,
|
**options: t.Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register a URL rule with the blueprint. See :meth:`.Flask.add_url_rule` for
|
"""Register a URL rule with the blueprint. See :meth:`.Flask.add_url_rule` for
|
||||||
|
|
@ -437,7 +439,7 @@ class Blueprint(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def app_template_filter(
|
def app_template_filter(
|
||||||
self, name: t.Optional[str] = None
|
self, name: str | None = None
|
||||||
) -> t.Callable[[T_template_filter], T_template_filter]:
|
) -> t.Callable[[T_template_filter], T_template_filter]:
|
||||||
"""Register a template filter, available in any template rendered by the
|
"""Register a template filter, available in any template rendered by the
|
||||||
application. Equivalent to :meth:`.Flask.template_filter`.
|
application. Equivalent to :meth:`.Flask.template_filter`.
|
||||||
|
|
@ -454,7 +456,7 @@ class Blueprint(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def add_app_template_filter(
|
def add_app_template_filter(
|
||||||
self, f: ft.TemplateFilterCallable, name: t.Optional[str] = None
|
self, f: ft.TemplateFilterCallable, name: str | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register a template filter, available in any template rendered by the
|
"""Register a template filter, available in any template rendered by the
|
||||||
application. Works like the :meth:`app_template_filter` decorator. Equivalent to
|
application. Works like the :meth:`app_template_filter` decorator. Equivalent to
|
||||||
|
|
@ -471,7 +473,7 @@ class Blueprint(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def app_template_test(
|
def app_template_test(
|
||||||
self, name: t.Optional[str] = None
|
self, name: str | None = None
|
||||||
) -> t.Callable[[T_template_test], T_template_test]:
|
) -> t.Callable[[T_template_test], T_template_test]:
|
||||||
"""Register a template test, available in any template rendered by the
|
"""Register a template test, available in any template rendered by the
|
||||||
application. Equivalent to :meth:`.Flask.template_test`.
|
application. Equivalent to :meth:`.Flask.template_test`.
|
||||||
|
|
@ -490,7 +492,7 @@ class Blueprint(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def add_app_template_test(
|
def add_app_template_test(
|
||||||
self, f: ft.TemplateTestCallable, name: t.Optional[str] = None
|
self, f: ft.TemplateTestCallable, name: str | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register a template test, available in any template rendered by the
|
"""Register a template test, available in any template rendered by the
|
||||||
application. Works like the :meth:`app_template_test` decorator. Equivalent to
|
application. Works like the :meth:`app_template_test` decorator. Equivalent to
|
||||||
|
|
@ -509,7 +511,7 @@ class Blueprint(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def app_template_global(
|
def app_template_global(
|
||||||
self, name: t.Optional[str] = None
|
self, name: str | None = None
|
||||||
) -> t.Callable[[T_template_global], T_template_global]:
|
) -> t.Callable[[T_template_global], T_template_global]:
|
||||||
"""Register a template global, available in any template rendered by the
|
"""Register a template global, available in any template rendered by the
|
||||||
application. Equivalent to :meth:`.Flask.template_global`.
|
application. Equivalent to :meth:`.Flask.template_global`.
|
||||||
|
|
@ -528,7 +530,7 @@ class Blueprint(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def add_app_template_global(
|
def add_app_template_global(
|
||||||
self, f: ft.TemplateGlobalCallable, name: t.Optional[str] = None
|
self, f: ft.TemplateGlobalCallable, name: str | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register a template global, available in any template rendered by the
|
"""Register a template global, available in any template rendered by the
|
||||||
application. Works like the :meth:`app_template_global` decorator. Equivalent to
|
application. Works like the :meth:`app_template_global` decorator. Equivalent to
|
||||||
|
|
@ -589,7 +591,7 @@ class Blueprint(Scaffold):
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def app_errorhandler(
|
def app_errorhandler(
|
||||||
self, code: t.Union[t.Type[Exception], int]
|
self, code: type[Exception] | int
|
||||||
) -> t.Callable[[T_error_handler], T_error_handler]:
|
) -> t.Callable[[T_error_handler], T_error_handler]:
|
||||||
"""Like :meth:`errorhandler`, but for every request, not only those handled by
|
"""Like :meth:`errorhandler`, but for every request, not only those handled by
|
||||||
the blueprint. Equivalent to :meth:`.Flask.errorhandler`.
|
the blueprint. Equivalent to :meth:`.Flask.errorhandler`.
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ class ScriptInfo:
|
||||||
self.create_app = create_app
|
self.create_app = create_app
|
||||||
#: A dictionary with arbitrary data that can be associated with
|
#: A dictionary with arbitrary data that can be associated with
|
||||||
#: this script info.
|
#: this script info.
|
||||||
self.data: t.Dict[t.Any, t.Any] = {}
|
self.data: dict[t.Any, t.Any] = {}
|
||||||
self.set_debug_flag = set_debug_flag
|
self.set_debug_flag = set_debug_flag
|
||||||
self._loaded_app: Flask | None = None
|
self._loaded_app: Flask | None = None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import errno
|
import errno
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
@ -10,7 +12,7 @@ from werkzeug.utils import import_string
|
||||||
class ConfigAttribute:
|
class ConfigAttribute:
|
||||||
"""Makes an attribute forward to the config"""
|
"""Makes an attribute forward to the config"""
|
||||||
|
|
||||||
def __init__(self, name: str, get_converter: t.Optional[t.Callable] = None) -> None:
|
def __init__(self, name: str, get_converter: t.Callable | None = None) -> None:
|
||||||
self.__name__ = name
|
self.__name__ = name
|
||||||
self.get_converter = get_converter
|
self.get_converter = get_converter
|
||||||
|
|
||||||
|
|
@ -70,7 +72,7 @@ class Config(dict):
|
||||||
:param defaults: an optional dictionary of default values
|
:param defaults: an optional dictionary of default values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, root_path: str, defaults: t.Optional[dict] = None) -> None:
|
def __init__(self, root_path: str, defaults: dict | None = None) -> None:
|
||||||
super().__init__(defaults or {})
|
super().__init__(defaults or {})
|
||||||
self.root_path = root_path
|
self.root_path = root_path
|
||||||
|
|
||||||
|
|
@ -191,7 +193,7 @@ class Config(dict):
|
||||||
self.from_object(d)
|
self.from_object(d)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def from_object(self, obj: t.Union[object, str]) -> None:
|
def from_object(self, obj: object | str) -> None:
|
||||||
"""Updates the values from the given object. An object can be of one
|
"""Updates the values from the given object. An object can be of one
|
||||||
of the following two types:
|
of the following two types:
|
||||||
|
|
||||||
|
|
@ -278,7 +280,7 @@ class Config(dict):
|
||||||
return self.from_mapping(obj)
|
return self.from_mapping(obj)
|
||||||
|
|
||||||
def from_mapping(
|
def from_mapping(
|
||||||
self, mapping: t.Optional[t.Mapping[str, t.Any]] = None, **kwargs: t.Any
|
self, mapping: t.Mapping[str, t.Any] | None = None, **kwargs: t.Any
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Updates the config like :meth:`update` ignoring items with
|
"""Updates the config like :meth:`update` ignoring items with
|
||||||
non-upper keys.
|
non-upper keys.
|
||||||
|
|
@ -287,7 +289,7 @@ class Config(dict):
|
||||||
|
|
||||||
.. versionadded:: 0.11
|
.. versionadded:: 0.11
|
||||||
"""
|
"""
|
||||||
mappings: t.Dict[str, t.Any] = {}
|
mappings: dict[str, t.Any] = {}
|
||||||
if mapping is not None:
|
if mapping is not None:
|
||||||
mappings.update(mapping)
|
mappings.update(mapping)
|
||||||
mappings.update(kwargs)
|
mappings.update(kwargs)
|
||||||
|
|
@ -298,7 +300,7 @@ class Config(dict):
|
||||||
|
|
||||||
def get_namespace(
|
def get_namespace(
|
||||||
self, namespace: str, lowercase: bool = True, trim_namespace: bool = True
|
self, namespace: str, lowercase: bool = True, trim_namespace: bool = True
|
||||||
) -> t.Dict[str, t.Any]:
|
) -> dict[str, t.Any]:
|
||||||
"""Returns a dictionary containing a subset of configuration options
|
"""Returns a dictionary containing a subset of configuration options
|
||||||
that match the specified namespace/prefix. Example usage::
|
that match the specified namespace/prefix. Example usage::
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import contextvars
|
import contextvars
|
||||||
import sys
|
import sys
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
@ -60,7 +62,7 @@ class _AppCtxGlobals:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise AttributeError(name) from None
|
raise AttributeError(name) from None
|
||||||
|
|
||||||
def get(self, name: str, default: t.Optional[t.Any] = None) -> t.Any:
|
def get(self, name: str, default: t.Any | None = None) -> t.Any:
|
||||||
"""Get an attribute by name, or a default value. Like
|
"""Get an attribute by name, or a default value. Like
|
||||||
:meth:`dict.get`.
|
:meth:`dict.get`.
|
||||||
|
|
||||||
|
|
@ -233,18 +235,18 @@ class AppContext:
|
||||||
running CLI commands.
|
running CLI commands.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, app: "Flask") -> None:
|
def __init__(self, app: Flask) -> None:
|
||||||
self.app = app
|
self.app = app
|
||||||
self.url_adapter = app.create_url_adapter(None)
|
self.url_adapter = app.create_url_adapter(None)
|
||||||
self.g: _AppCtxGlobals = app.app_ctx_globals_class()
|
self.g: _AppCtxGlobals = app.app_ctx_globals_class()
|
||||||
self._cv_tokens: t.List[contextvars.Token] = []
|
self._cv_tokens: list[contextvars.Token] = []
|
||||||
|
|
||||||
def push(self) -> None:
|
def push(self) -> None:
|
||||||
"""Binds the app context to the current context."""
|
"""Binds the app context to the current context."""
|
||||||
self._cv_tokens.append(_cv_app.set(self))
|
self._cv_tokens.append(_cv_app.set(self))
|
||||||
appcontext_pushed.send(self.app, _async_wrapper=self.app.ensure_sync)
|
appcontext_pushed.send(self.app, _async_wrapper=self.app.ensure_sync)
|
||||||
|
|
||||||
def pop(self, exc: t.Optional[BaseException] = _sentinel) -> None: # type: ignore
|
def pop(self, exc: BaseException | None = _sentinel) -> None: # type: ignore
|
||||||
"""Pops the app context."""
|
"""Pops the app context."""
|
||||||
try:
|
try:
|
||||||
if len(self._cv_tokens) == 1:
|
if len(self._cv_tokens) == 1:
|
||||||
|
|
@ -262,15 +264,15 @@ class AppContext:
|
||||||
|
|
||||||
appcontext_popped.send(self.app, _async_wrapper=self.app.ensure_sync)
|
appcontext_popped.send(self.app, _async_wrapper=self.app.ensure_sync)
|
||||||
|
|
||||||
def __enter__(self) -> "AppContext":
|
def __enter__(self) -> AppContext:
|
||||||
self.push()
|
self.push()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __exit__(
|
def __exit__(
|
||||||
self,
|
self,
|
||||||
exc_type: t.Optional[type],
|
exc_type: type | None,
|
||||||
exc_value: t.Optional[BaseException],
|
exc_value: BaseException | None,
|
||||||
tb: t.Optional[TracebackType],
|
tb: TracebackType | None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.pop(exc_value)
|
self.pop(exc_value)
|
||||||
|
|
||||||
|
|
@ -299,10 +301,10 @@ class RequestContext:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
app: "Flask",
|
app: Flask,
|
||||||
environ: dict,
|
environ: dict,
|
||||||
request: t.Optional["Request"] = None,
|
request: Request | None = None,
|
||||||
session: t.Optional["SessionMixin"] = None,
|
session: SessionMixin | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.app = app
|
self.app = app
|
||||||
if request is None:
|
if request is None:
|
||||||
|
|
@ -314,16 +316,16 @@ class RequestContext:
|
||||||
self.url_adapter = app.create_url_adapter(self.request)
|
self.url_adapter = app.create_url_adapter(self.request)
|
||||||
except HTTPException as e:
|
except HTTPException as e:
|
||||||
self.request.routing_exception = e
|
self.request.routing_exception = e
|
||||||
self.flashes: t.Optional[t.List[t.Tuple[str, str]]] = None
|
self.flashes: list[tuple[str, str]] | None = None
|
||||||
self.session: t.Optional["SessionMixin"] = session
|
self.session: SessionMixin | None = session
|
||||||
# Functions that should be executed after the request on the response
|
# Functions that should be executed after the request on the response
|
||||||
# object. These will be called before the regular "after_request"
|
# object. These will be called before the regular "after_request"
|
||||||
# functions.
|
# functions.
|
||||||
self._after_request_functions: t.List[ft.AfterRequestCallable] = []
|
self._after_request_functions: list[ft.AfterRequestCallable] = []
|
||||||
|
|
||||||
self._cv_tokens: t.List[t.Tuple[contextvars.Token, t.Optional[AppContext]]] = []
|
self._cv_tokens: list[tuple[contextvars.Token, AppContext | None]] = []
|
||||||
|
|
||||||
def copy(self) -> "RequestContext":
|
def copy(self) -> RequestContext:
|
||||||
"""Creates a copy of this request context with the same request object.
|
"""Creates a copy of this request context with the same request object.
|
||||||
This can be used to move a request context to a different greenlet.
|
This can be used to move a request context to a different greenlet.
|
||||||
Because the actual request object is the same this cannot be used to
|
Because the actual request object is the same this cannot be used to
|
||||||
|
|
@ -382,7 +384,7 @@ class RequestContext:
|
||||||
if self.url_adapter is not None:
|
if self.url_adapter is not None:
|
||||||
self.match_request()
|
self.match_request()
|
||||||
|
|
||||||
def pop(self, exc: t.Optional[BaseException] = _sentinel) -> None: # type: ignore
|
def pop(self, exc: BaseException | None = _sentinel) -> None: # type: ignore
|
||||||
"""Pops the request context and unbinds it by doing that. This will
|
"""Pops the request context and unbinds it by doing that. This will
|
||||||
also trigger the execution of functions registered by the
|
also trigger the execution of functions registered by the
|
||||||
:meth:`~flask.Flask.teardown_request` decorator.
|
:meth:`~flask.Flask.teardown_request` decorator.
|
||||||
|
|
@ -419,15 +421,15 @@ class RequestContext:
|
||||||
f"Popped wrong request context. ({ctx!r} instead of {self!r})"
|
f"Popped wrong request context. ({ctx!r} instead of {self!r})"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __enter__(self) -> "RequestContext":
|
def __enter__(self) -> RequestContext:
|
||||||
self.push()
|
self.push()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __exit__(
|
def __exit__(
|
||||||
self,
|
self,
|
||||||
exc_type: t.Optional[type],
|
exc_type: type | None,
|
||||||
exc_value: t.Optional[BaseException],
|
exc_value: BaseException | None,
|
||||||
tb: t.Optional[TracebackType],
|
tb: TracebackType | None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.pop(exc_value)
|
self.pop(exc_value)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
||||||
from .app import Flask
|
from .app import Flask
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
from contextvars import ContextVar
|
from contextvars import ContextVar
|
||||||
|
|
||||||
|
|
@ -18,7 +20,7 @@ class _FakeStack:
|
||||||
self.cv = cv
|
self.cv = cv
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def top(self) -> t.Optional[t.Any]:
|
def top(self) -> t.Any | None:
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
|
|
@ -38,15 +40,15 @@ This typically means that you attempted to use functionality that needed
|
||||||
the current application. To solve this, set up an application context
|
the current application. To solve this, set up an application context
|
||||||
with app.app_context(). See the documentation for more information.\
|
with app.app_context(). See the documentation for more information.\
|
||||||
"""
|
"""
|
||||||
_cv_app: ContextVar["AppContext"] = ContextVar("flask.app_ctx")
|
_cv_app: ContextVar[AppContext] = ContextVar("flask.app_ctx")
|
||||||
__app_ctx_stack = _FakeStack("app", _cv_app)
|
__app_ctx_stack = _FakeStack("app", _cv_app)
|
||||||
app_ctx: "AppContext" = LocalProxy( # type: ignore[assignment]
|
app_ctx: AppContext = LocalProxy( # type: ignore[assignment]
|
||||||
_cv_app, unbound_message=_no_app_msg
|
_cv_app, unbound_message=_no_app_msg
|
||||||
)
|
)
|
||||||
current_app: "Flask" = LocalProxy( # type: ignore[assignment]
|
current_app: Flask = LocalProxy( # type: ignore[assignment]
|
||||||
_cv_app, "app", unbound_message=_no_app_msg
|
_cv_app, "app", unbound_message=_no_app_msg
|
||||||
)
|
)
|
||||||
g: "_AppCtxGlobals" = LocalProxy( # type: ignore[assignment]
|
g: _AppCtxGlobals = LocalProxy( # type: ignore[assignment]
|
||||||
_cv_app, "g", unbound_message=_no_app_msg
|
_cv_app, "g", unbound_message=_no_app_msg
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -57,15 +59,15 @@ This typically means that you attempted to use functionality that needed
|
||||||
an active HTTP request. Consult the documentation on testing for
|
an active HTTP request. Consult the documentation on testing for
|
||||||
information about how to avoid this problem.\
|
information about how to avoid this problem.\
|
||||||
"""
|
"""
|
||||||
_cv_request: ContextVar["RequestContext"] = ContextVar("flask.request_ctx")
|
_cv_request: ContextVar[RequestContext] = ContextVar("flask.request_ctx")
|
||||||
__request_ctx_stack = _FakeStack("request", _cv_request)
|
__request_ctx_stack = _FakeStack("request", _cv_request)
|
||||||
request_ctx: "RequestContext" = LocalProxy( # type: ignore[assignment]
|
request_ctx: RequestContext = LocalProxy( # type: ignore[assignment]
|
||||||
_cv_request, unbound_message=_no_req_msg
|
_cv_request, unbound_message=_no_req_msg
|
||||||
)
|
)
|
||||||
request: "Request" = LocalProxy( # type: ignore[assignment]
|
request: Request = LocalProxy( # type: ignore[assignment]
|
||||||
_cv_request, "request", unbound_message=_no_req_msg
|
_cv_request, "request", unbound_message=_no_req_msg
|
||||||
)
|
)
|
||||||
session: "SessionMixin" = LocalProxy( # type: ignore[assignment]
|
session: SessionMixin = LocalProxy( # type: ignore[assignment]
|
||||||
_cv_request, "session", unbound_message=_no_req_msg
|
_cv_request, "session", unbound_message=_no_req_msg
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pkgutil
|
import pkgutil
|
||||||
import socket
|
import socket
|
||||||
|
|
@ -50,9 +52,9 @@ def get_load_dotenv(default: bool = True) -> bool:
|
||||||
|
|
||||||
|
|
||||||
def stream_with_context(
|
def stream_with_context(
|
||||||
generator_or_function: t.Union[
|
generator_or_function: (
|
||||||
t.Iterator[t.AnyStr], t.Callable[..., t.Iterator[t.AnyStr]]
|
t.Iterator[t.AnyStr] | t.Callable[..., t.Iterator[t.AnyStr]]
|
||||||
]
|
)
|
||||||
) -> t.Iterator[t.AnyStr]:
|
) -> t.Iterator[t.AnyStr]:
|
||||||
"""Request contexts disappear when the response is started on the server.
|
"""Request contexts disappear when the response is started on the server.
|
||||||
This is done for efficiency reasons and to make it less likely to encounter
|
This is done for efficiency reasons and to make it less likely to encounter
|
||||||
|
|
@ -128,7 +130,7 @@ def stream_with_context(
|
||||||
return wrapped_g
|
return wrapped_g
|
||||||
|
|
||||||
|
|
||||||
def make_response(*args: t.Any) -> "Response":
|
def make_response(*args: t.Any) -> Response:
|
||||||
"""Sometimes it is necessary to set additional headers in a view. Because
|
"""Sometimes it is necessary to set additional headers in a view. Because
|
||||||
views do not have to return response objects but can return a value that
|
views do not have to return response objects but can return a value that
|
||||||
is converted into a response object by Flask itself, it becomes tricky to
|
is converted into a response object by Flask itself, it becomes tricky to
|
||||||
|
|
@ -180,10 +182,10 @@ def make_response(*args: t.Any) -> "Response":
|
||||||
def url_for(
|
def url_for(
|
||||||
endpoint: str,
|
endpoint: str,
|
||||||
*,
|
*,
|
||||||
_anchor: t.Optional[str] = None,
|
_anchor: str | None = None,
|
||||||
_method: t.Optional[str] = None,
|
_method: str | None = None,
|
||||||
_scheme: t.Optional[str] = None,
|
_scheme: str | None = None,
|
||||||
_external: t.Optional[bool] = None,
|
_external: bool | None = None,
|
||||||
**values: t.Any,
|
**values: t.Any,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Generate a URL to the given endpoint with the given values.
|
"""Generate a URL to the given endpoint with the given values.
|
||||||
|
|
@ -232,8 +234,8 @@ def url_for(
|
||||||
|
|
||||||
|
|
||||||
def redirect(
|
def redirect(
|
||||||
location: str, code: int = 302, Response: t.Optional[t.Type["BaseResponse"]] = None
|
location: str, code: int = 302, Response: type[BaseResponse] | None = None
|
||||||
) -> "BaseResponse":
|
) -> BaseResponse:
|
||||||
"""Create a redirect response object.
|
"""Create a redirect response object.
|
||||||
|
|
||||||
If :data:`~flask.current_app` is available, it will use its
|
If :data:`~flask.current_app` is available, it will use its
|
||||||
|
|
@ -255,9 +257,7 @@ def redirect(
|
||||||
return _wz_redirect(location, code=code, Response=Response)
|
return _wz_redirect(location, code=code, Response=Response)
|
||||||
|
|
||||||
|
|
||||||
def abort(
|
def abort(code: int | BaseResponse, *args: t.Any, **kwargs: t.Any) -> te.NoReturn:
|
||||||
code: t.Union[int, "BaseResponse"], *args: t.Any, **kwargs: t.Any
|
|
||||||
) -> "te.NoReturn":
|
|
||||||
"""Raise an :exc:`~werkzeug.exceptions.HTTPException` for the given
|
"""Raise an :exc:`~werkzeug.exceptions.HTTPException` for the given
|
||||||
status code.
|
status code.
|
||||||
|
|
||||||
|
|
@ -338,7 +338,7 @@ def flash(message: str, category: str = "message") -> None:
|
||||||
|
|
||||||
def get_flashed_messages(
|
def get_flashed_messages(
|
||||||
with_categories: bool = False, category_filter: t.Iterable[str] = ()
|
with_categories: bool = False, category_filter: t.Iterable[str] = ()
|
||||||
) -> t.Union[t.List[str], t.List[t.Tuple[str, str]]]:
|
) -> list[str] | list[tuple[str, str]]:
|
||||||
"""Pulls all flashed messages from the session and returns them.
|
"""Pulls all flashed messages from the session and returns them.
|
||||||
Further calls in the same request to the function will return
|
Further calls in the same request to the function will return
|
||||||
the same messages. By default just the messages are returned,
|
the same messages. By default just the messages are returned,
|
||||||
|
|
@ -378,7 +378,7 @@ def get_flashed_messages(
|
||||||
return flashes
|
return flashes
|
||||||
|
|
||||||
|
|
||||||
def _prepare_send_file_kwargs(**kwargs: t.Any) -> t.Dict[str, t.Any]:
|
def _prepare_send_file_kwargs(**kwargs: t.Any) -> dict[str, t.Any]:
|
||||||
if kwargs.get("max_age") is None:
|
if kwargs.get("max_age") is None:
|
||||||
kwargs["max_age"] = current_app.get_send_file_max_age
|
kwargs["max_age"] = current_app.get_send_file_max_age
|
||||||
|
|
||||||
|
|
@ -392,17 +392,15 @@ def _prepare_send_file_kwargs(**kwargs: t.Any) -> t.Dict[str, t.Any]:
|
||||||
|
|
||||||
|
|
||||||
def send_file(
|
def send_file(
|
||||||
path_or_file: t.Union[os.PathLike, str, t.BinaryIO],
|
path_or_file: os.PathLike | str | t.BinaryIO,
|
||||||
mimetype: t.Optional[str] = None,
|
mimetype: str | None = None,
|
||||||
as_attachment: bool = False,
|
as_attachment: bool = False,
|
||||||
download_name: t.Optional[str] = None,
|
download_name: str | None = None,
|
||||||
conditional: bool = True,
|
conditional: bool = True,
|
||||||
etag: t.Union[bool, str] = True,
|
etag: bool | str = True,
|
||||||
last_modified: t.Optional[t.Union[datetime, int, float]] = None,
|
last_modified: datetime | int | float | None = None,
|
||||||
max_age: t.Optional[
|
max_age: None | (int | t.Callable[[str | None], int | None]) = None,
|
||||||
t.Union[int, t.Callable[[t.Optional[str]], t.Optional[int]]]
|
) -> Response:
|
||||||
] = None,
|
|
||||||
) -> "Response":
|
|
||||||
"""Send the contents of a file to the client.
|
"""Send the contents of a file to the client.
|
||||||
|
|
||||||
The first argument can be a file path or a file-like object. Paths
|
The first argument can be a file path or a file-like object. Paths
|
||||||
|
|
@ -520,10 +518,10 @@ def send_file(
|
||||||
|
|
||||||
|
|
||||||
def send_from_directory(
|
def send_from_directory(
|
||||||
directory: t.Union[os.PathLike, str],
|
directory: os.PathLike | str,
|
||||||
path: t.Union[os.PathLike, str],
|
path: os.PathLike | str,
|
||||||
**kwargs: t.Any,
|
**kwargs: t.Any,
|
||||||
) -> "Response":
|
) -> Response:
|
||||||
"""Send a file from within a directory using :func:`send_file`.
|
"""Send a file from within a directory using :func:`send_file`.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
@ -627,8 +625,8 @@ class locked_cached_property(werkzeug.utils.cached_property):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
fget: t.Callable[[t.Any], t.Any],
|
fget: t.Callable[[t.Any], t.Any],
|
||||||
name: t.Optional[str] = None,
|
name: str | None = None,
|
||||||
doc: t.Optional[str] = None,
|
doc: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
|
@ -687,8 +685,8 @@ def is_ip(value: str) -> bool:
|
||||||
|
|
||||||
|
|
||||||
@lru_cache(maxsize=None)
|
@lru_cache(maxsize=None)
|
||||||
def _split_blueprint_path(name: str) -> t.List[str]:
|
def _split_blueprint_path(name: str) -> list[str]:
|
||||||
out: t.List[str] = [name]
|
out: list[str] = [name]
|
||||||
|
|
||||||
if "." in name:
|
if "." in name:
|
||||||
out.extend(_split_blueprint_path(name.rpartition(".")[0]))
|
out.extend(_split_blueprint_path(name.rpartition(".")[0]))
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ class JSONProvider:
|
||||||
return self.loads(fp.read(), **kwargs)
|
return self.loads(fp.read(), **kwargs)
|
||||||
|
|
||||||
def _prepare_response_obj(
|
def _prepare_response_obj(
|
||||||
self, args: t.Tuple[t.Any, ...], kwargs: t.Dict[str, t.Any]
|
self, args: tuple[t.Any, ...], kwargs: dict[str, t.Any]
|
||||||
) -> t.Any:
|
) -> t.Any:
|
||||||
if args and kwargs:
|
if args and kwargs:
|
||||||
raise TypeError("app.json.response() takes either args or kwargs, not both")
|
raise TypeError("app.json.response() takes either args or kwargs, not both")
|
||||||
|
|
@ -204,7 +204,7 @@ class DefaultJSONProvider(JSONProvider):
|
||||||
:param kwargs: Treat as a dict to serialize.
|
:param kwargs: Treat as a dict to serialize.
|
||||||
"""
|
"""
|
||||||
obj = self._prepare_response_obj(args, kwargs)
|
obj = self._prepare_response_obj(args, kwargs)
|
||||||
dump_args: t.Dict[str, t.Any] = {}
|
dump_args: dict[str, t.Any] = {}
|
||||||
|
|
||||||
if (self.compact is None and self._app.debug) or self.compact is False:
|
if (self.compact is None and self._app.debug) or self.compact is False:
|
||||||
dump_args.setdefault("indent", 2)
|
dump_args.setdefault("indent", 2)
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ be processed before ``dict``.
|
||||||
|
|
||||||
app.session_interface.serializer.register(TagOrderedDict, index=0)
|
app.session_interface.serializer.register(TagOrderedDict, index=0)
|
||||||
"""
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
|
|
@ -61,9 +63,9 @@ class JSONTag:
|
||||||
|
|
||||||
#: The tag to mark the serialized object with. If ``None``, this tag is
|
#: The tag to mark the serialized object with. If ``None``, this tag is
|
||||||
#: only used as an intermediate step during tagging.
|
#: only used as an intermediate step during tagging.
|
||||||
key: t.Optional[str] = None
|
key: str | None = None
|
||||||
|
|
||||||
def __init__(self, serializer: "TaggedJSONSerializer") -> None:
|
def __init__(self, serializer: TaggedJSONSerializer) -> None:
|
||||||
"""Create a tagger for the given serializer."""
|
"""Create a tagger for the given serializer."""
|
||||||
self.serializer = serializer
|
self.serializer = serializer
|
||||||
|
|
||||||
|
|
@ -244,17 +246,17 @@ class TaggedJSONSerializer:
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.tags: t.Dict[str, JSONTag] = {}
|
self.tags: dict[str, JSONTag] = {}
|
||||||
self.order: t.List[JSONTag] = []
|
self.order: list[JSONTag] = []
|
||||||
|
|
||||||
for cls in self.default_tags:
|
for cls in self.default_tags:
|
||||||
self.register(cls)
|
self.register(cls)
|
||||||
|
|
||||||
def register(
|
def register(
|
||||||
self,
|
self,
|
||||||
tag_class: t.Type[JSONTag],
|
tag_class: type[JSONTag],
|
||||||
force: bool = False,
|
force: bool = False,
|
||||||
index: t.Optional[int] = None,
|
index: int | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register a new tag with this serializer.
|
"""Register a new tag with this serializer.
|
||||||
|
|
||||||
|
|
@ -283,7 +285,7 @@ class TaggedJSONSerializer:
|
||||||
else:
|
else:
|
||||||
self.order.insert(index, tag)
|
self.order.insert(index, tag)
|
||||||
|
|
||||||
def tag(self, value: t.Any) -> t.Dict[str, t.Any]:
|
def tag(self, value: t.Any) -> dict[str, t.Any]:
|
||||||
"""Convert a value to a tagged representation if necessary."""
|
"""Convert a value to a tagged representation if necessary."""
|
||||||
for tag in self.order:
|
for tag in self.order:
|
||||||
if tag.check(value):
|
if tag.check(value):
|
||||||
|
|
@ -291,7 +293,7 @@ class TaggedJSONSerializer:
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def untag(self, value: t.Dict[str, t.Any]) -> t.Any:
|
def untag(self, value: dict[str, t.Any]) -> t.Any:
|
||||||
"""Convert a tagged representation back to the original type."""
|
"""Convert a tagged representation back to the original type."""
|
||||||
if len(value) != 1:
|
if len(value) != 1:
|
||||||
return value
|
return value
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
@ -50,7 +52,7 @@ default_handler.setFormatter(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_logger(app: "Flask") -> logging.Logger:
|
def create_logger(app: Flask) -> logging.Logger:
|
||||||
"""Get the Flask app's logger and configure it if needed.
|
"""Get the Flask app's logger and configure it if needed.
|
||||||
|
|
||||||
The logger name will be the same as
|
The logger name will be the same as
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import importlib.util
|
import importlib.util
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
|
|
@ -70,16 +72,16 @@ class Scaffold:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
_static_folder: t.Optional[str] = None
|
_static_folder: str | None = None
|
||||||
_static_url_path: t.Optional[str] = None
|
_static_url_path: str | None = None
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
import_name: str,
|
import_name: str,
|
||||||
static_folder: t.Optional[t.Union[str, os.PathLike]] = None,
|
static_folder: str | os.PathLike | None = None,
|
||||||
static_url_path: t.Optional[str] = None,
|
static_url_path: str | None = None,
|
||||||
template_folder: t.Optional[t.Union[str, os.PathLike]] = None,
|
template_folder: str | os.PathLike | None = None,
|
||||||
root_path: t.Optional[str] = None,
|
root_path: str | None = None,
|
||||||
):
|
):
|
||||||
#: The name of the package or module that this object belongs
|
#: The name of the package or module that this object belongs
|
||||||
#: to. Do not change this once it is set by the constructor.
|
#: to. Do not change this once it is set by the constructor.
|
||||||
|
|
@ -112,7 +114,7 @@ class Scaffold:
|
||||||
#:
|
#:
|
||||||
#: This data structure is internal. It should not be modified
|
#: This data structure is internal. It should not be modified
|
||||||
#: directly and its format may change at any time.
|
#: directly and its format may change at any time.
|
||||||
self.view_functions: t.Dict[str, t.Callable] = {}
|
self.view_functions: dict[str, t.Callable] = {}
|
||||||
|
|
||||||
#: A data structure of registered error handlers, in the format
|
#: A data structure of registered error handlers, in the format
|
||||||
#: ``{scope: {code: {class: handler}}}``. The ``scope`` key is
|
#: ``{scope: {code: {class: handler}}}``. The ``scope`` key is
|
||||||
|
|
@ -127,9 +129,9 @@ class Scaffold:
|
||||||
#:
|
#:
|
||||||
#: This data structure is internal. It should not be modified
|
#: This data structure is internal. It should not be modified
|
||||||
#: directly and its format may change at any time.
|
#: directly and its format may change at any time.
|
||||||
self.error_handler_spec: t.Dict[
|
self.error_handler_spec: dict[
|
||||||
ft.AppOrBlueprintKey,
|
ft.AppOrBlueprintKey,
|
||||||
t.Dict[t.Optional[int], t.Dict[t.Type[Exception], ft.ErrorHandlerCallable]],
|
dict[int | None, dict[type[Exception], ft.ErrorHandlerCallable]],
|
||||||
] = defaultdict(lambda: defaultdict(dict))
|
] = defaultdict(lambda: defaultdict(dict))
|
||||||
|
|
||||||
#: A data structure of functions to call at the beginning of
|
#: A data structure of functions to call at the beginning of
|
||||||
|
|
@ -142,8 +144,8 @@ class Scaffold:
|
||||||
#:
|
#:
|
||||||
#: This data structure is internal. It should not be modified
|
#: This data structure is internal. It should not be modified
|
||||||
#: directly and its format may change at any time.
|
#: directly and its format may change at any time.
|
||||||
self.before_request_funcs: t.Dict[
|
self.before_request_funcs: dict[
|
||||||
ft.AppOrBlueprintKey, t.List[ft.BeforeRequestCallable]
|
ft.AppOrBlueprintKey, list[ft.BeforeRequestCallable]
|
||||||
] = defaultdict(list)
|
] = defaultdict(list)
|
||||||
|
|
||||||
#: A data structure of functions to call at the end of each
|
#: A data structure of functions to call at the end of each
|
||||||
|
|
@ -156,8 +158,8 @@ class Scaffold:
|
||||||
#:
|
#:
|
||||||
#: This data structure is internal. It should not be modified
|
#: This data structure is internal. It should not be modified
|
||||||
#: directly and its format may change at any time.
|
#: directly and its format may change at any time.
|
||||||
self.after_request_funcs: t.Dict[
|
self.after_request_funcs: dict[
|
||||||
ft.AppOrBlueprintKey, t.List[ft.AfterRequestCallable]
|
ft.AppOrBlueprintKey, list[ft.AfterRequestCallable]
|
||||||
] = defaultdict(list)
|
] = defaultdict(list)
|
||||||
|
|
||||||
#: A data structure of functions to call at the end of each
|
#: A data structure of functions to call at the end of each
|
||||||
|
|
@ -171,8 +173,8 @@ class Scaffold:
|
||||||
#:
|
#:
|
||||||
#: This data structure is internal. It should not be modified
|
#: This data structure is internal. It should not be modified
|
||||||
#: directly and its format may change at any time.
|
#: directly and its format may change at any time.
|
||||||
self.teardown_request_funcs: t.Dict[
|
self.teardown_request_funcs: dict[
|
||||||
ft.AppOrBlueprintKey, t.List[ft.TeardownCallable]
|
ft.AppOrBlueprintKey, list[ft.TeardownCallable]
|
||||||
] = defaultdict(list)
|
] = defaultdict(list)
|
||||||
|
|
||||||
#: A data structure of functions to call to pass extra context
|
#: A data structure of functions to call to pass extra context
|
||||||
|
|
@ -186,8 +188,8 @@ class Scaffold:
|
||||||
#:
|
#:
|
||||||
#: This data structure is internal. It should not be modified
|
#: This data structure is internal. It should not be modified
|
||||||
#: directly and its format may change at any time.
|
#: directly and its format may change at any time.
|
||||||
self.template_context_processors: t.Dict[
|
self.template_context_processors: dict[
|
||||||
ft.AppOrBlueprintKey, t.List[ft.TemplateContextProcessorCallable]
|
ft.AppOrBlueprintKey, list[ft.TemplateContextProcessorCallable]
|
||||||
] = defaultdict(list, {None: [_default_template_ctx_processor]})
|
] = defaultdict(list, {None: [_default_template_ctx_processor]})
|
||||||
|
|
||||||
#: A data structure of functions to call to modify the keyword
|
#: A data structure of functions to call to modify the keyword
|
||||||
|
|
@ -201,9 +203,9 @@ class Scaffold:
|
||||||
#:
|
#:
|
||||||
#: This data structure is internal. It should not be modified
|
#: This data structure is internal. It should not be modified
|
||||||
#: directly and its format may change at any time.
|
#: directly and its format may change at any time.
|
||||||
self.url_value_preprocessors: t.Dict[
|
self.url_value_preprocessors: dict[
|
||||||
ft.AppOrBlueprintKey,
|
ft.AppOrBlueprintKey,
|
||||||
t.List[ft.URLValuePreprocessorCallable],
|
list[ft.URLValuePreprocessorCallable],
|
||||||
] = defaultdict(list)
|
] = defaultdict(list)
|
||||||
|
|
||||||
#: A data structure of functions to call to modify the keyword
|
#: A data structure of functions to call to modify the keyword
|
||||||
|
|
@ -217,8 +219,8 @@ class Scaffold:
|
||||||
#:
|
#:
|
||||||
#: This data structure is internal. It should not be modified
|
#: This data structure is internal. It should not be modified
|
||||||
#: directly and its format may change at any time.
|
#: directly and its format may change at any time.
|
||||||
self.url_default_functions: t.Dict[
|
self.url_default_functions: dict[
|
||||||
ft.AppOrBlueprintKey, t.List[ft.URLDefaultCallable]
|
ft.AppOrBlueprintKey, list[ft.URLDefaultCallable]
|
||||||
] = defaultdict(list)
|
] = defaultdict(list)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
|
|
@ -228,7 +230,7 @@ class Scaffold:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def static_folder(self) -> t.Optional[str]:
|
def static_folder(self) -> str | None:
|
||||||
"""The absolute path to the configured static folder. ``None``
|
"""The absolute path to the configured static folder. ``None``
|
||||||
if no static folder is set.
|
if no static folder is set.
|
||||||
"""
|
"""
|
||||||
|
|
@ -238,7 +240,7 @@ class Scaffold:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@static_folder.setter
|
@static_folder.setter
|
||||||
def static_folder(self, value: t.Optional[t.Union[str, os.PathLike]]) -> None:
|
def static_folder(self, value: str | os.PathLike | None) -> None:
|
||||||
if value is not None:
|
if value is not None:
|
||||||
value = os.fspath(value).rstrip(r"\/")
|
value = os.fspath(value).rstrip(r"\/")
|
||||||
|
|
||||||
|
|
@ -253,7 +255,7 @@ class Scaffold:
|
||||||
return self.static_folder is not None
|
return self.static_folder is not None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def static_url_path(self) -> t.Optional[str]:
|
def static_url_path(self) -> str | None:
|
||||||
"""The URL prefix that the static route will be accessible from.
|
"""The URL prefix that the static route will be accessible from.
|
||||||
|
|
||||||
If it was not configured during init, it is derived from
|
If it was not configured during init, it is derived from
|
||||||
|
|
@ -269,13 +271,13 @@ class Scaffold:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@static_url_path.setter
|
@static_url_path.setter
|
||||||
def static_url_path(self, value: t.Optional[str]) -> None:
|
def static_url_path(self, value: str | None) -> None:
|
||||||
if value is not None:
|
if value is not None:
|
||||||
value = value.rstrip("/")
|
value = value.rstrip("/")
|
||||||
|
|
||||||
self._static_url_path = value
|
self._static_url_path = value
|
||||||
|
|
||||||
def get_send_file_max_age(self, filename: t.Optional[str]) -> t.Optional[int]:
|
def get_send_file_max_age(self, filename: str | None) -> int | None:
|
||||||
"""Used by :func:`send_file` to determine the ``max_age`` cache
|
"""Used by :func:`send_file` to determine the ``max_age`` cache
|
||||||
value for a given file path if it wasn't passed.
|
value for a given file path if it wasn't passed.
|
||||||
|
|
||||||
|
|
@ -299,7 +301,7 @@ class Scaffold:
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def send_static_file(self, filename: str) -> "Response":
|
def send_static_file(self, filename: str) -> Response:
|
||||||
"""The view function used to serve files from
|
"""The view function used to serve files from
|
||||||
:attr:`static_folder`. A route is automatically registered for
|
:attr:`static_folder`. A route is automatically registered for
|
||||||
this view at :attr:`static_url_path` if :attr:`static_folder` is
|
this view at :attr:`static_url_path` if :attr:`static_folder` is
|
||||||
|
|
@ -318,7 +320,7 @@ class Scaffold:
|
||||||
)
|
)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def jinja_loader(self) -> t.Optional[FileSystemLoader]:
|
def jinja_loader(self) -> FileSystemLoader | None:
|
||||||
"""The Jinja loader for this object's templates. By default this
|
"""The Jinja loader for this object's templates. By default this
|
||||||
is a class :class:`jinja2.loaders.FileSystemLoader` to
|
is a class :class:`jinja2.loaders.FileSystemLoader` to
|
||||||
:attr:`template_folder` if it is set.
|
:attr:`template_folder` if it is set.
|
||||||
|
|
@ -440,9 +442,9 @@ class Scaffold:
|
||||||
def add_url_rule(
|
def add_url_rule(
|
||||||
self,
|
self,
|
||||||
rule: str,
|
rule: str,
|
||||||
endpoint: t.Optional[str] = None,
|
endpoint: str | None = None,
|
||||||
view_func: t.Optional[ft.RouteCallable] = None,
|
view_func: ft.RouteCallable | None = None,
|
||||||
provide_automatic_options: t.Optional[bool] = None,
|
provide_automatic_options: bool | None = None,
|
||||||
**options: t.Any,
|
**options: t.Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register a rule for routing incoming requests and building
|
"""Register a rule for routing incoming requests and building
|
||||||
|
|
@ -668,7 +670,7 @@ class Scaffold:
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def errorhandler(
|
def errorhandler(
|
||||||
self, code_or_exception: t.Union[t.Type[Exception], int]
|
self, code_or_exception: type[Exception] | int
|
||||||
) -> t.Callable[[T_error_handler], T_error_handler]:
|
) -> t.Callable[[T_error_handler], T_error_handler]:
|
||||||
"""Register a function to handle errors by code or exception class.
|
"""Register a function to handle errors by code or exception class.
|
||||||
|
|
||||||
|
|
@ -713,7 +715,7 @@ class Scaffold:
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def register_error_handler(
|
def register_error_handler(
|
||||||
self,
|
self,
|
||||||
code_or_exception: t.Union[t.Type[Exception], int],
|
code_or_exception: type[Exception] | int,
|
||||||
f: ft.ErrorHandlerCallable,
|
f: ft.ErrorHandlerCallable,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Alternative error attach function to the :meth:`errorhandler`
|
"""Alternative error attach function to the :meth:`errorhandler`
|
||||||
|
|
@ -727,8 +729,8 @@ class Scaffold:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_exc_class_and_code(
|
def _get_exc_class_and_code(
|
||||||
exc_class_or_code: t.Union[t.Type[Exception], int]
|
exc_class_or_code: type[Exception] | int,
|
||||||
) -> t.Tuple[t.Type[Exception], t.Optional[int]]:
|
) -> tuple[type[Exception], int | None]:
|
||||||
"""Get the exception class being handled. For HTTP status codes
|
"""Get the exception class being handled. For HTTP status codes
|
||||||
or ``HTTPException`` subclasses, return both the exception and
|
or ``HTTPException`` subclasses, return both the exception and
|
||||||
status code.
|
status code.
|
||||||
|
|
@ -736,7 +738,7 @@ class Scaffold:
|
||||||
:param exc_class_or_code: Any exception class, or an HTTP status
|
:param exc_class_or_code: Any exception class, or an HTTP status
|
||||||
code as an integer.
|
code as an integer.
|
||||||
"""
|
"""
|
||||||
exc_class: t.Type[Exception]
|
exc_class: type[Exception]
|
||||||
|
|
||||||
if isinstance(exc_class_or_code, int):
|
if isinstance(exc_class_or_code, int):
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import typing as t
|
import typing as t
|
||||||
from collections.abc import MutableMapping
|
from collections.abc import MutableMapping
|
||||||
|
|
@ -92,7 +94,7 @@ class NullSession(SecureCookieSession):
|
||||||
but fail on setting.
|
but fail on setting.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _fail(self, *args: t.Any, **kwargs: t.Any) -> "te.NoReturn":
|
def _fail(self, *args: t.Any, **kwargs: t.Any) -> te.NoReturn:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"The session is unavailable because no secret "
|
"The session is unavailable because no secret "
|
||||||
"key was set. Set the secret_key on the "
|
"key was set. Set the secret_key on the "
|
||||||
|
|
@ -153,7 +155,7 @@ class SessionInterface:
|
||||||
#: .. versionadded:: 0.10
|
#: .. versionadded:: 0.10
|
||||||
pickle_based = False
|
pickle_based = False
|
||||||
|
|
||||||
def make_null_session(self, app: "Flask") -> NullSession:
|
def make_null_session(self, app: Flask) -> NullSession:
|
||||||
"""Creates a null session which acts as a replacement object if the
|
"""Creates a null session which acts as a replacement object if the
|
||||||
real session support could not be loaded due to a configuration
|
real session support could not be loaded due to a configuration
|
||||||
error. This mainly aids the user experience because the job of the
|
error. This mainly aids the user experience because the job of the
|
||||||
|
|
@ -174,11 +176,11 @@ class SessionInterface:
|
||||||
"""
|
"""
|
||||||
return isinstance(obj, self.null_session_class)
|
return isinstance(obj, self.null_session_class)
|
||||||
|
|
||||||
def get_cookie_name(self, app: "Flask") -> str:
|
def get_cookie_name(self, app: Flask) -> str:
|
||||||
"""The name of the session cookie. Uses``app.config["SESSION_COOKIE_NAME"]``."""
|
"""The name of the session cookie. Uses``app.config["SESSION_COOKIE_NAME"]``."""
|
||||||
return app.config["SESSION_COOKIE_NAME"]
|
return app.config["SESSION_COOKIE_NAME"]
|
||||||
|
|
||||||
def get_cookie_domain(self, app: "Flask") -> t.Optional[str]:
|
def get_cookie_domain(self, app: Flask) -> str | None:
|
||||||
"""The value of the ``Domain`` parameter on the session cookie. If not set,
|
"""The value of the ``Domain`` parameter on the session cookie. If not set,
|
||||||
browsers will only send the cookie to the exact domain it was set from.
|
browsers will only send the cookie to the exact domain it was set from.
|
||||||
Otherwise, they will send it to any subdomain of the given value as well.
|
Otherwise, they will send it to any subdomain of the given value as well.
|
||||||
|
|
@ -191,7 +193,7 @@ class SessionInterface:
|
||||||
rv = app.config["SESSION_COOKIE_DOMAIN"]
|
rv = app.config["SESSION_COOKIE_DOMAIN"]
|
||||||
return rv if rv else None
|
return rv if rv else None
|
||||||
|
|
||||||
def get_cookie_path(self, app: "Flask") -> str:
|
def get_cookie_path(self, app: Flask) -> str:
|
||||||
"""Returns the path for which the cookie should be valid. The
|
"""Returns the path for which the cookie should be valid. The
|
||||||
default implementation uses the value from the ``SESSION_COOKIE_PATH``
|
default implementation uses the value from the ``SESSION_COOKIE_PATH``
|
||||||
config var if it's set, and falls back to ``APPLICATION_ROOT`` or
|
config var if it's set, and falls back to ``APPLICATION_ROOT`` or
|
||||||
|
|
@ -199,29 +201,27 @@ class SessionInterface:
|
||||||
"""
|
"""
|
||||||
return app.config["SESSION_COOKIE_PATH"] or app.config["APPLICATION_ROOT"]
|
return app.config["SESSION_COOKIE_PATH"] or app.config["APPLICATION_ROOT"]
|
||||||
|
|
||||||
def get_cookie_httponly(self, app: "Flask") -> bool:
|
def get_cookie_httponly(self, app: Flask) -> bool:
|
||||||
"""Returns True if the session cookie should be httponly. This
|
"""Returns True if the session cookie should be httponly. This
|
||||||
currently just returns the value of the ``SESSION_COOKIE_HTTPONLY``
|
currently just returns the value of the ``SESSION_COOKIE_HTTPONLY``
|
||||||
config var.
|
config var.
|
||||||
"""
|
"""
|
||||||
return app.config["SESSION_COOKIE_HTTPONLY"]
|
return app.config["SESSION_COOKIE_HTTPONLY"]
|
||||||
|
|
||||||
def get_cookie_secure(self, app: "Flask") -> bool:
|
def get_cookie_secure(self, app: Flask) -> bool:
|
||||||
"""Returns True if the cookie should be secure. This currently
|
"""Returns True if the cookie should be secure. This currently
|
||||||
just returns the value of the ``SESSION_COOKIE_SECURE`` setting.
|
just returns the value of the ``SESSION_COOKIE_SECURE`` setting.
|
||||||
"""
|
"""
|
||||||
return app.config["SESSION_COOKIE_SECURE"]
|
return app.config["SESSION_COOKIE_SECURE"]
|
||||||
|
|
||||||
def get_cookie_samesite(self, app: "Flask") -> str:
|
def get_cookie_samesite(self, app: Flask) -> str:
|
||||||
"""Return ``'Strict'`` or ``'Lax'`` if the cookie should use the
|
"""Return ``'Strict'`` or ``'Lax'`` if the cookie should use the
|
||||||
``SameSite`` attribute. This currently just returns the value of
|
``SameSite`` attribute. This currently just returns the value of
|
||||||
the :data:`SESSION_COOKIE_SAMESITE` setting.
|
the :data:`SESSION_COOKIE_SAMESITE` setting.
|
||||||
"""
|
"""
|
||||||
return app.config["SESSION_COOKIE_SAMESITE"]
|
return app.config["SESSION_COOKIE_SAMESITE"]
|
||||||
|
|
||||||
def get_expiration_time(
|
def get_expiration_time(self, app: Flask, session: SessionMixin) -> datetime | None:
|
||||||
self, app: "Flask", session: SessionMixin
|
|
||||||
) -> t.Optional[datetime]:
|
|
||||||
"""A helper method that returns an expiration date for the session
|
"""A helper method that returns an expiration date for the session
|
||||||
or ``None`` if the session is linked to the browser session. The
|
or ``None`` if the session is linked to the browser session. The
|
||||||
default implementation returns now + the permanent session
|
default implementation returns now + the permanent session
|
||||||
|
|
@ -231,7 +231,7 @@ class SessionInterface:
|
||||||
return datetime.now(timezone.utc) + app.permanent_session_lifetime
|
return datetime.now(timezone.utc) + app.permanent_session_lifetime
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def should_set_cookie(self, app: "Flask", session: SessionMixin) -> bool:
|
def should_set_cookie(self, app: Flask, session: SessionMixin) -> bool:
|
||||||
"""Used by session backends to determine if a ``Set-Cookie`` header
|
"""Used by session backends to determine if a ``Set-Cookie`` header
|
||||||
should be set for this session cookie for this response. If the session
|
should be set for this session cookie for this response. If the session
|
||||||
has been modified, the cookie is set. If the session is permanent and
|
has been modified, the cookie is set. If the session is permanent and
|
||||||
|
|
@ -247,9 +247,7 @@ class SessionInterface:
|
||||||
session.permanent and app.config["SESSION_REFRESH_EACH_REQUEST"]
|
session.permanent and app.config["SESSION_REFRESH_EACH_REQUEST"]
|
||||||
)
|
)
|
||||||
|
|
||||||
def open_session(
|
def open_session(self, app: Flask, request: Request) -> SessionMixin | None:
|
||||||
self, app: "Flask", request: "Request"
|
|
||||||
) -> t.Optional[SessionMixin]:
|
|
||||||
"""This is called at the beginning of each request, after
|
"""This is called at the beginning of each request, after
|
||||||
pushing the request context, before matching the URL.
|
pushing the request context, before matching the URL.
|
||||||
|
|
||||||
|
|
@ -264,7 +262,7 @@ class SessionInterface:
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def save_session(
|
def save_session(
|
||||||
self, app: "Flask", session: SessionMixin, response: "Response"
|
self, app: Flask, session: SessionMixin, response: Response
|
||||||
) -> None:
|
) -> None:
|
||||||
"""This is called at the end of each request, after generating
|
"""This is called at the end of each request, after generating
|
||||||
a response, before removing the request context. It is skipped
|
a response, before removing the request context. It is skipped
|
||||||
|
|
@ -295,9 +293,7 @@ class SecureCookieSessionInterface(SessionInterface):
|
||||||
serializer = session_json_serializer
|
serializer = session_json_serializer
|
||||||
session_class = SecureCookieSession
|
session_class = SecureCookieSession
|
||||||
|
|
||||||
def get_signing_serializer(
|
def get_signing_serializer(self, app: Flask) -> URLSafeTimedSerializer | None:
|
||||||
self, app: "Flask"
|
|
||||||
) -> t.Optional[URLSafeTimedSerializer]:
|
|
||||||
if not app.secret_key:
|
if not app.secret_key:
|
||||||
return None
|
return None
|
||||||
signer_kwargs = dict(
|
signer_kwargs = dict(
|
||||||
|
|
@ -310,9 +306,7 @@ class SecureCookieSessionInterface(SessionInterface):
|
||||||
signer_kwargs=signer_kwargs,
|
signer_kwargs=signer_kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
def open_session(
|
def open_session(self, app: Flask, request: Request) -> SecureCookieSession | None:
|
||||||
self, app: "Flask", request: "Request"
|
|
||||||
) -> t.Optional[SecureCookieSession]:
|
|
||||||
s = self.get_signing_serializer(app)
|
s = self.get_signing_serializer(app)
|
||||||
if s is None:
|
if s is None:
|
||||||
return None
|
return None
|
||||||
|
|
@ -327,7 +321,7 @@ class SecureCookieSessionInterface(SessionInterface):
|
||||||
return self.session_class()
|
return self.session_class()
|
||||||
|
|
||||||
def save_session(
|
def save_session(
|
||||||
self, app: "Flask", session: SessionMixin, response: "Response"
|
self, app: Flask, session: SessionMixin, response: Response
|
||||||
) -> None:
|
) -> None:
|
||||||
name = self.get_cookie_name(app)
|
name = self.get_cookie_name(app)
|
||||||
domain = self.get_cookie_domain(app)
|
domain = self.get_cookie_domain(app)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
||||||
from jinja2 import BaseLoader
|
from jinja2 import BaseLoader
|
||||||
|
|
@ -18,13 +20,13 @@ if t.TYPE_CHECKING: # pragma: no cover
|
||||||
from .scaffold import Scaffold
|
from .scaffold import Scaffold
|
||||||
|
|
||||||
|
|
||||||
def _default_template_ctx_processor() -> t.Dict[str, t.Any]:
|
def _default_template_ctx_processor() -> dict[str, t.Any]:
|
||||||
"""Default template context processor. Injects `request`,
|
"""Default template context processor. Injects `request`,
|
||||||
`session` and `g`.
|
`session` and `g`.
|
||||||
"""
|
"""
|
||||||
appctx = _cv_app.get(None)
|
appctx = _cv_app.get(None)
|
||||||
reqctx = _cv_request.get(None)
|
reqctx = _cv_request.get(None)
|
||||||
rv: t.Dict[str, t.Any] = {}
|
rv: dict[str, t.Any] = {}
|
||||||
if appctx is not None:
|
if appctx is not None:
|
||||||
rv["g"] = appctx.g
|
rv["g"] = appctx.g
|
||||||
if reqctx is not None:
|
if reqctx is not None:
|
||||||
|
|
@ -39,7 +41,7 @@ class Environment(BaseEnvironment):
|
||||||
name of the blueprint to referenced templates if necessary.
|
name of the blueprint to referenced templates if necessary.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, app: "Flask", **options: t.Any) -> None:
|
def __init__(self, app: Flask, **options: t.Any) -> None:
|
||||||
if "loader" not in options:
|
if "loader" not in options:
|
||||||
options["loader"] = app.create_global_jinja_loader()
|
options["loader"] = app.create_global_jinja_loader()
|
||||||
BaseEnvironment.__init__(self, **options)
|
BaseEnvironment.__init__(self, **options)
|
||||||
|
|
@ -51,24 +53,22 @@ class DispatchingJinjaLoader(BaseLoader):
|
||||||
the blueprint folders.
|
the blueprint folders.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, app: "Flask") -> None:
|
def __init__(self, app: Flask) -> None:
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
||||||
def get_source( # type: ignore
|
def get_source( # type: ignore
|
||||||
self, environment: Environment, template: str
|
self, environment: Environment, template: str
|
||||||
) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable]]:
|
) -> tuple[str, str | None, t.Callable | None]:
|
||||||
if self.app.config["EXPLAIN_TEMPLATE_LOADING"]:
|
if self.app.config["EXPLAIN_TEMPLATE_LOADING"]:
|
||||||
return self._get_source_explained(environment, template)
|
return self._get_source_explained(environment, template)
|
||||||
return self._get_source_fast(environment, template)
|
return self._get_source_fast(environment, template)
|
||||||
|
|
||||||
def _get_source_explained(
|
def _get_source_explained(
|
||||||
self, environment: Environment, template: str
|
self, environment: Environment, template: str
|
||||||
) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable]]:
|
) -> tuple[str, str | None, t.Callable | None]:
|
||||||
attempts = []
|
attempts = []
|
||||||
rv: t.Optional[t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]]
|
rv: tuple[str, str | None, t.Callable[[], bool] | None] | None
|
||||||
trv: t.Optional[
|
trv: None | (tuple[str, str | None, t.Callable[[], bool] | None]) = None
|
||||||
t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]
|
|
||||||
] = None
|
|
||||||
|
|
||||||
for srcobj, loader in self._iter_loaders(template):
|
for srcobj, loader in self._iter_loaders(template):
|
||||||
try:
|
try:
|
||||||
|
|
@ -89,7 +89,7 @@ class DispatchingJinjaLoader(BaseLoader):
|
||||||
|
|
||||||
def _get_source_fast(
|
def _get_source_fast(
|
||||||
self, environment: Environment, template: str
|
self, environment: Environment, template: str
|
||||||
) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable]]:
|
) -> tuple[str, str | None, t.Callable | None]:
|
||||||
for _srcobj, loader in self._iter_loaders(template):
|
for _srcobj, loader in self._iter_loaders(template):
|
||||||
try:
|
try:
|
||||||
return loader.get_source(environment, template)
|
return loader.get_source(environment, template)
|
||||||
|
|
@ -99,7 +99,7 @@ class DispatchingJinjaLoader(BaseLoader):
|
||||||
|
|
||||||
def _iter_loaders(
|
def _iter_loaders(
|
||||||
self, template: str
|
self, template: str
|
||||||
) -> t.Generator[t.Tuple["Scaffold", BaseLoader], None, None]:
|
) -> t.Generator[tuple[Scaffold, BaseLoader], None, None]:
|
||||||
loader = self.app.jinja_loader
|
loader = self.app.jinja_loader
|
||||||
if loader is not None:
|
if loader is not None:
|
||||||
yield self.app, loader
|
yield self.app, loader
|
||||||
|
|
@ -109,7 +109,7 @@ class DispatchingJinjaLoader(BaseLoader):
|
||||||
if loader is not None:
|
if loader is not None:
|
||||||
yield blueprint, loader
|
yield blueprint, loader
|
||||||
|
|
||||||
def list_templates(self) -> t.List[str]:
|
def list_templates(self) -> list[str]:
|
||||||
result = set()
|
result = set()
|
||||||
loader = self.app.jinja_loader
|
loader = self.app.jinja_loader
|
||||||
if loader is not None:
|
if loader is not None:
|
||||||
|
|
@ -124,7 +124,7 @@ class DispatchingJinjaLoader(BaseLoader):
|
||||||
return list(result)
|
return list(result)
|
||||||
|
|
||||||
|
|
||||||
def _render(app: "Flask", template: Template, context: t.Dict[str, t.Any]) -> str:
|
def _render(app: Flask, template: Template, context: dict[str, t.Any]) -> str:
|
||||||
app.update_template_context(context)
|
app.update_template_context(context)
|
||||||
before_render_template.send(
|
before_render_template.send(
|
||||||
app, _async_wrapper=app.ensure_sync, template=template, context=context
|
app, _async_wrapper=app.ensure_sync, template=template, context=context
|
||||||
|
|
@ -137,7 +137,7 @@ def _render(app: "Flask", template: Template, context: t.Dict[str, t.Any]) -> st
|
||||||
|
|
||||||
|
|
||||||
def render_template(
|
def render_template(
|
||||||
template_name_or_list: t.Union[str, Template, t.List[t.Union[str, Template]]],
|
template_name_or_list: str | Template | list[str | Template],
|
||||||
**context: t.Any,
|
**context: t.Any,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Render a template by name with the given context.
|
"""Render a template by name with the given context.
|
||||||
|
|
@ -164,7 +164,7 @@ def render_template_string(source: str, **context: t.Any) -> str:
|
||||||
|
|
||||||
|
|
||||||
def _stream(
|
def _stream(
|
||||||
app: "Flask", template: Template, context: t.Dict[str, t.Any]
|
app: Flask, template: Template, context: dict[str, t.Any]
|
||||||
) -> t.Iterator[str]:
|
) -> t.Iterator[str]:
|
||||||
app.update_template_context(context)
|
app.update_template_context(context)
|
||||||
before_render_template.send(
|
before_render_template.send(
|
||||||
|
|
@ -187,7 +187,7 @@ def _stream(
|
||||||
|
|
||||||
|
|
||||||
def stream_template(
|
def stream_template(
|
||||||
template_name_or_list: t.Union[str, Template, t.List[t.Union[str, Template]]],
|
template_name_or_list: str | Template | list[str | Template],
|
||||||
**context: t.Any,
|
**context: t.Any,
|
||||||
) -> t.Iterator[str]:
|
) -> t.Iterator[str]:
|
||||||
"""Render a template by name with the given context as a stream.
|
"""Render a template by name with the given context as a stream.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from contextlib import ExitStack
|
from contextlib import ExitStack
|
||||||
|
|
@ -43,11 +45,11 @@ class EnvironBuilder(werkzeug.test.EnvironBuilder):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
app: "Flask",
|
app: Flask,
|
||||||
path: str = "/",
|
path: str = "/",
|
||||||
base_url: t.Optional[str] = None,
|
base_url: str | None = None,
|
||||||
subdomain: t.Optional[str] = None,
|
subdomain: str | None = None,
|
||||||
url_scheme: t.Optional[str] = None,
|
url_scheme: str | None = None,
|
||||||
*args: t.Any,
|
*args: t.Any,
|
||||||
**kwargs: t.Any,
|
**kwargs: t.Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
@ -104,12 +106,12 @@ class FlaskClient(Client):
|
||||||
Basic usage is outlined in the :doc:`/testing` chapter.
|
Basic usage is outlined in the :doc:`/testing` chapter.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
application: "Flask"
|
application: Flask
|
||||||
|
|
||||||
def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
|
def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.preserve_context = False
|
self.preserve_context = False
|
||||||
self._new_contexts: t.List[t.ContextManager[t.Any]] = []
|
self._new_contexts: list[t.ContextManager[t.Any]] = []
|
||||||
self._context_stack = ExitStack()
|
self._context_stack = ExitStack()
|
||||||
self.environ_base = {
|
self.environ_base = {
|
||||||
"REMOTE_ADDR": "127.0.0.1",
|
"REMOTE_ADDR": "127.0.0.1",
|
||||||
|
|
@ -199,7 +201,7 @@ class FlaskClient(Client):
|
||||||
buffered: bool = False,
|
buffered: bool = False,
|
||||||
follow_redirects: bool = False,
|
follow_redirects: bool = False,
|
||||||
**kwargs: t.Any,
|
**kwargs: t.Any,
|
||||||
) -> "TestResponse":
|
) -> TestResponse:
|
||||||
if args and isinstance(
|
if args and isinstance(
|
||||||
args[0], (werkzeug.test.EnvironBuilder, dict, BaseRequest)
|
args[0], (werkzeug.test.EnvironBuilder, dict, BaseRequest)
|
||||||
):
|
):
|
||||||
|
|
@ -238,7 +240,7 @@ class FlaskClient(Client):
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def __enter__(self) -> "FlaskClient":
|
def __enter__(self) -> FlaskClient:
|
||||||
if self.preserve_context:
|
if self.preserve_context:
|
||||||
raise RuntimeError("Cannot nest client invocations")
|
raise RuntimeError("Cannot nest client invocations")
|
||||||
self.preserve_context = True
|
self.preserve_context = True
|
||||||
|
|
@ -246,9 +248,9 @@ class FlaskClient(Client):
|
||||||
|
|
||||||
def __exit__(
|
def __exit__(
|
||||||
self,
|
self,
|
||||||
exc_type: t.Optional[type],
|
exc_type: type | None,
|
||||||
exc_value: t.Optional[BaseException],
|
exc_value: BaseException | None,
|
||||||
tb: t.Optional[TracebackType],
|
tb: TracebackType | None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.preserve_context = False
|
self.preserve_context = False
|
||||||
self._context_stack.close()
|
self._context_stack.close()
|
||||||
|
|
@ -260,7 +262,7 @@ class FlaskCliRunner(CliRunner):
|
||||||
:meth:`~flask.Flask.test_cli_runner`. See :ref:`testing-cli`.
|
:meth:`~flask.Flask.test_cli_runner`. See :ref:`testing-cli`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, app: "Flask", **kwargs: t.Any) -> None:
|
def __init__(self, app: Flask, **kwargs: t.Any) -> None:
|
||||||
self.app = app
|
self.app = app
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
||||||
if t.TYPE_CHECKING: # pragma: no cover
|
if t.TYPE_CHECKING: # pragma: no cover
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
||||||
from . import typing as ft
|
from . import typing as ft
|
||||||
|
|
@ -45,12 +47,12 @@ class View:
|
||||||
#: The methods this view is registered for. Uses the same default
|
#: The methods this view is registered for. Uses the same default
|
||||||
#: (``["GET", "HEAD", "OPTIONS"]``) as ``route`` and
|
#: (``["GET", "HEAD", "OPTIONS"]``) as ``route`` and
|
||||||
#: ``add_url_rule`` by default.
|
#: ``add_url_rule`` by default.
|
||||||
methods: t.ClassVar[t.Optional[t.Collection[str]]] = None
|
methods: t.ClassVar[t.Collection[str] | None] = None
|
||||||
|
|
||||||
#: Control whether the ``OPTIONS`` method is handled automatically.
|
#: Control whether the ``OPTIONS`` method is handled automatically.
|
||||||
#: Uses the same default (``True``) as ``route`` and
|
#: Uses the same default (``True``) as ``route`` and
|
||||||
#: ``add_url_rule`` by default.
|
#: ``add_url_rule`` by default.
|
||||||
provide_automatic_options: t.ClassVar[t.Optional[bool]] = None
|
provide_automatic_options: t.ClassVar[bool | None] = None
|
||||||
|
|
||||||
#: A list of decorators to apply, in order, to the generated view
|
#: A list of decorators to apply, in order, to the generated view
|
||||||
#: function. Remember that ``@decorator`` syntax is applied bottom
|
#: function. Remember that ``@decorator`` syntax is applied bottom
|
||||||
|
|
@ -58,7 +60,7 @@ class View:
|
||||||
#: decorator.
|
#: decorator.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 0.8
|
#: .. versionadded:: 0.8
|
||||||
decorators: t.ClassVar[t.List[t.Callable]] = []
|
decorators: t.ClassVar[list[t.Callable]] = []
|
||||||
|
|
||||||
#: Create a new instance of this view class for every request by
|
#: Create a new instance of this view class for every request by
|
||||||
#: default. If a view subclass sets this to ``False``, the same
|
#: default. If a view subclass sets this to ``False``, the same
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
||||||
from werkzeug.exceptions import BadRequest
|
from werkzeug.exceptions import BadRequest
|
||||||
|
|
@ -37,20 +39,20 @@ class Request(RequestBase):
|
||||||
#: because the request was never internally bound.
|
#: because the request was never internally bound.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 0.6
|
#: .. versionadded:: 0.6
|
||||||
url_rule: t.Optional["Rule"] = None
|
url_rule: Rule | None = None
|
||||||
|
|
||||||
#: A dict of view arguments that matched the request. If an exception
|
#: A dict of view arguments that matched the request. If an exception
|
||||||
#: happened when matching, this will be ``None``.
|
#: happened when matching, this will be ``None``.
|
||||||
view_args: t.Optional[t.Dict[str, t.Any]] = None
|
view_args: dict[str, t.Any] | None = None
|
||||||
|
|
||||||
#: If matching the URL failed, this is the exception that will be
|
#: If matching the URL failed, this is the exception that will be
|
||||||
#: raised / was raised as part of the request handling. This is
|
#: raised / was raised as part of the request handling. This is
|
||||||
#: usually a :exc:`~werkzeug.exceptions.NotFound` exception or
|
#: usually a :exc:`~werkzeug.exceptions.NotFound` exception or
|
||||||
#: something similar.
|
#: something similar.
|
||||||
routing_exception: t.Optional[Exception] = None
|
routing_exception: Exception | None = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def max_content_length(self) -> t.Optional[int]: # type: ignore
|
def max_content_length(self) -> int | None: # type: ignore
|
||||||
"""Read-only view of the ``MAX_CONTENT_LENGTH`` config key."""
|
"""Read-only view of the ``MAX_CONTENT_LENGTH`` config key."""
|
||||||
if current_app:
|
if current_app:
|
||||||
return current_app.config["MAX_CONTENT_LENGTH"]
|
return current_app.config["MAX_CONTENT_LENGTH"]
|
||||||
|
|
@ -58,7 +60,7 @@ class Request(RequestBase):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def endpoint(self) -> t.Optional[str]:
|
def endpoint(self) -> str | None:
|
||||||
"""The endpoint that matched the request URL.
|
"""The endpoint that matched the request URL.
|
||||||
|
|
||||||
This will be ``None`` if matching failed or has not been
|
This will be ``None`` if matching failed or has not been
|
||||||
|
|
@ -73,7 +75,7 @@ class Request(RequestBase):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def blueprint(self) -> t.Optional[str]:
|
def blueprint(self) -> str | None:
|
||||||
"""The registered name of the current blueprint.
|
"""The registered name of the current blueprint.
|
||||||
|
|
||||||
This will be ``None`` if the endpoint is not part of a
|
This will be ``None`` if the endpoint is not part of a
|
||||||
|
|
@ -92,7 +94,7 @@ class Request(RequestBase):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def blueprints(self) -> t.List[str]:
|
def blueprints(self) -> list[str]:
|
||||||
"""The registered names of the current blueprint upwards through
|
"""The registered names of the current blueprint upwards through
|
||||||
parent blueprints.
|
parent blueprints.
|
||||||
|
|
||||||
|
|
@ -123,7 +125,7 @@ class Request(RequestBase):
|
||||||
|
|
||||||
attach_enctype_error_multidict(self)
|
attach_enctype_error_multidict(self)
|
||||||
|
|
||||||
def on_json_loading_failed(self, e: t.Optional[ValueError]) -> t.Any:
|
def on_json_loading_failed(self, e: ValueError | None) -> t.Any:
|
||||||
try:
|
try:
|
||||||
return super().on_json_loading_failed(e)
|
return super().on_json_loading_failed(e)
|
||||||
except BadRequest as e:
|
except BadRequest as e:
|
||||||
|
|
@ -151,7 +153,7 @@ class Response(ResponseBase):
|
||||||
Added :attr:`max_cookie_size`.
|
Added :attr:`max_cookie_size`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
default_mimetype: t.Optional[str] = "text/html"
|
default_mimetype: str | None = "text/html"
|
||||||
|
|
||||||
json_module = json
|
json_module = json
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue