remove previously deprecated code
This commit is contained in:
parent
604de4b1dc
commit
6650764e97
16 changed files with 81 additions and 946 deletions
18
CHANGES.rst
18
CHANGES.rst
|
|
@ -3,6 +3,24 @@ Version 2.3.0
|
||||||
|
|
||||||
Unreleased
|
Unreleased
|
||||||
|
|
||||||
|
- Remove previously deprecated code. :pr:`4995`
|
||||||
|
|
||||||
|
- The ``push`` and ``pop`` methods of the deprecated ``_app_ctx_stack`` and
|
||||||
|
``_request_ctx_stack`` objects are removed. ``top`` still exists to give
|
||||||
|
extensions more time to update, but it will be removed.
|
||||||
|
- The ``FLASK_ENV`` environment variable, ``ENV`` config key, and ``app.env``
|
||||||
|
property are removed.
|
||||||
|
- The ``session_cookie_name``, ``send_file_max_age_default``, ``use_x_sendfile``,
|
||||||
|
``propagate_exceptions``, and ``templates_auto_reload`` properties on ``app``
|
||||||
|
are removed.
|
||||||
|
- The ``JSON_AS_ASCII``, ``JSON_SORT_KEYS``, ``JSONIFY_MIMETYPE``, and
|
||||||
|
``JSONIFY_PRETTYPRINT_REGULAR`` config keys are removed.
|
||||||
|
- The ``app.before_first_request`` and ``bp.before_app_first_request`` decorators
|
||||||
|
are removed.
|
||||||
|
- ``json_encoder`` and ``json_decoder`` attributes on app and blueprint, and the
|
||||||
|
corresponding ``json.JSONEncoder`` and ``JSONDecoder`` classes, are removed.
|
||||||
|
- The ``json.htmlsafe_dumps`` and ``htmlsafe_dump`` functions are removed.
|
||||||
|
|
||||||
- Use modern packaging metadata with ``pyproject.toml`` instead of ``setup.cfg``.
|
- Use modern packaging metadata with ``pyproject.toml`` instead of ``setup.cfg``.
|
||||||
:pr:`4947`
|
:pr:`4947`
|
||||||
- Ensure subdomains are applied with nested blueprints. :issue:`4834`
|
- Ensure subdomains are applied with nested blueprints. :issue:`4834`
|
||||||
|
|
|
||||||
|
|
@ -270,12 +270,6 @@ HTML ``<script>`` tags.
|
||||||
:members:
|
:members:
|
||||||
:member-order: bysource
|
:member-order: bysource
|
||||||
|
|
||||||
.. autoclass:: JSONEncoder
|
|
||||||
:members:
|
|
||||||
|
|
||||||
.. autoclass:: JSONDecoder
|
|
||||||
:members:
|
|
||||||
|
|
||||||
.. automodule:: flask.json.tag
|
.. automodule:: flask.json.tag
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,18 +65,6 @@ Builtin Configuration Values
|
||||||
|
|
||||||
The following configuration values are used internally by Flask:
|
The following configuration values are used internally by Flask:
|
||||||
|
|
||||||
.. py:data:: ENV
|
|
||||||
|
|
||||||
What environment the app is running in. The :attr:`~flask.Flask.env` attribute maps
|
|
||||||
to this config key.
|
|
||||||
|
|
||||||
Default: ``'production'``
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Use ``--debug`` instead.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
|
||||||
|
|
||||||
.. py:data:: DEBUG
|
.. py:data:: DEBUG
|
||||||
|
|
||||||
Whether debug mode is enabled. When using ``flask run`` to start the development
|
Whether debug mode is enabled. When using ``flask run`` to start the development
|
||||||
|
|
@ -271,52 +259,6 @@ The following configuration values are used internally by Flask:
|
||||||
|
|
||||||
Default: ``None``
|
Default: ``None``
|
||||||
|
|
||||||
.. py:data:: JSON_AS_ASCII
|
|
||||||
|
|
||||||
Serialize objects to ASCII-encoded JSON. If this is disabled, the
|
|
||||||
JSON returned from ``jsonify`` will contain Unicode characters. This
|
|
||||||
has security implications when rendering the JSON into JavaScript in
|
|
||||||
templates, and should typically remain enabled.
|
|
||||||
|
|
||||||
Default: ``True``
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Set ``app.json.ensure_ascii``
|
|
||||||
instead.
|
|
||||||
|
|
||||||
.. py:data:: JSON_SORT_KEYS
|
|
||||||
|
|
||||||
Sort the keys of JSON objects alphabetically. This is useful for caching
|
|
||||||
because it ensures the data is serialized the same way no matter what
|
|
||||||
Python's hash seed is. While not recommended, you can disable this for a
|
|
||||||
possible performance improvement at the cost of caching.
|
|
||||||
|
|
||||||
Default: ``True``
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Set ``app.json.sort_keys``
|
|
||||||
instead.
|
|
||||||
|
|
||||||
.. py:data:: JSONIFY_PRETTYPRINT_REGULAR
|
|
||||||
|
|
||||||
:func:`~flask.jsonify` responses will be output with newlines,
|
|
||||||
spaces, and indentation for easier reading by humans. Always enabled
|
|
||||||
in debug mode.
|
|
||||||
|
|
||||||
Default: ``False``
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Set ``app.json.compact`` instead.
|
|
||||||
|
|
||||||
.. py:data:: JSONIFY_MIMETYPE
|
|
||||||
|
|
||||||
The mimetype of ``jsonify`` responses.
|
|
||||||
|
|
||||||
Default: ``'application/json'``
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Set ``app.json.mimetype`` instead.
|
|
||||||
|
|
||||||
.. py:data:: TEMPLATES_AUTO_RELOAD
|
.. py:data:: TEMPLATES_AUTO_RELOAD
|
||||||
|
|
||||||
Reload templates when they are changed. If not set, it will be enabled in
|
Reload templates when they are changed. If not set, it will be enabled in
|
||||||
|
|
@ -381,14 +323,13 @@ The following configuration values are used internally by Flask:
|
||||||
.. versionchanged:: 2.2
|
.. versionchanged:: 2.2
|
||||||
Removed ``PRESERVE_CONTEXT_ON_EXCEPTION``.
|
Removed ``PRESERVE_CONTEXT_ON_EXCEPTION``.
|
||||||
|
|
||||||
.. versionchanged:: 2.2
|
.. versionchanged:: 2.3
|
||||||
``JSON_AS_ASCII``, ``JSON_SORT_KEYS``,
|
``JSON_AS_ASCII``, ``JSON_SORT_KEYS``, ``JSONIFY_MIMETYPE``, and
|
||||||
``JSONIFY_MIMETYPE``, and ``JSONIFY_PRETTYPRINT_REGULAR`` will be
|
``JSONIFY_PRETTYPRINT_REGULAR`` were removed. The default ``app.json`` provider has
|
||||||
removed in Flask 2.3. The default ``app.json`` provider has
|
|
||||||
equivalent attributes instead.
|
equivalent attributes instead.
|
||||||
|
|
||||||
.. versionchanged:: 2.2
|
.. versionchanged:: 2.3
|
||||||
``ENV`` will be removed in Flask 2.3. Use ``--debug`` instead.
|
``ENV`` was removed.
|
||||||
|
|
||||||
|
|
||||||
Configuring from Python Files
|
Configuring from Python Files
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ def __getattr__(name):
|
||||||
from .globals import __app_ctx_stack
|
from .globals import __app_ctx_stack
|
||||||
|
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"'_app_ctx_stack' is deprecated and will be removed in Flask 2.3.",
|
"'_app_ctx_stack' is deprecated and will be removed in Flask 2.4.",
|
||||||
DeprecationWarning,
|
DeprecationWarning,
|
||||||
stacklevel=2,
|
stacklevel=2,
|
||||||
)
|
)
|
||||||
|
|
@ -62,7 +62,7 @@ def __getattr__(name):
|
||||||
from .globals import __request_ctx_stack
|
from .globals import __request_ctx_stack
|
||||||
|
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"'_request_ctx_stack' is deprecated and will be removed in Flask 2.3.",
|
"'_request_ctx_stack' is deprecated and will be removed in Flask 2.4.",
|
||||||
DeprecationWarning,
|
DeprecationWarning,
|
||||||
stacklevel=2,
|
stacklevel=2,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
338
src/flask/app.py
338
src/flask/app.py
|
|
@ -1,6 +1,5 @@
|
||||||
import functools
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -75,9 +74,6 @@ if t.TYPE_CHECKING: # pragma: no cover
|
||||||
from .testing import FlaskClient
|
from .testing import FlaskClient
|
||||||
from .testing import FlaskCliRunner
|
from .testing import FlaskCliRunner
|
||||||
|
|
||||||
T_before_first_request = t.TypeVar(
|
|
||||||
"T_before_first_request", bound=ft.BeforeFirstRequestCallable
|
|
||||||
)
|
|
||||||
T_shell_context_processor = t.TypeVar(
|
T_shell_context_processor = t.TypeVar(
|
||||||
"T_shell_context_processor", bound=ft.ShellContextProcessorCallable
|
"T_shell_context_processor", bound=ft.ShellContextProcessorCallable
|
||||||
)
|
)
|
||||||
|
|
@ -274,36 +270,6 @@ class Flask(Scaffold):
|
||||||
#: :data:`SECRET_KEY` configuration key. Defaults to ``None``.
|
#: :data:`SECRET_KEY` configuration key. Defaults to ``None``.
|
||||||
secret_key = ConfigAttribute("SECRET_KEY")
|
secret_key = ConfigAttribute("SECRET_KEY")
|
||||||
|
|
||||||
@property
|
|
||||||
def session_cookie_name(self) -> str:
|
|
||||||
"""The name of the cookie set by the session interface.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Use ``app.config["SESSION_COOKIE_NAME"]``
|
|
||||||
instead.
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'session_cookie_name' is deprecated and will be removed in Flask 2.3. Use"
|
|
||||||
" 'SESSION_COOKIE_NAME' in 'app.config' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return self.config["SESSION_COOKIE_NAME"]
|
|
||||||
|
|
||||||
@session_cookie_name.setter
|
|
||||||
def session_cookie_name(self, value: str) -> None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'session_cookie_name' is deprecated and will be removed in Flask 2.3. Use"
|
|
||||||
" 'SESSION_COOKIE_NAME' in 'app.config' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
self.config["SESSION_COOKIE_NAME"] = value
|
|
||||||
|
|
||||||
#: A :class:`~datetime.timedelta` which is used to set the expiration
|
#: A :class:`~datetime.timedelta` which is used to set the expiration
|
||||||
#: date of a permanent session. The default is 31 days which makes a
|
#: date of a permanent session. The default is 31 days which makes a
|
||||||
#: permanent session survive for roughly one month.
|
#: permanent session survive for roughly one month.
|
||||||
|
|
@ -315,152 +281,6 @@ class Flask(Scaffold):
|
||||||
"PERMANENT_SESSION_LIFETIME", get_converter=_make_timedelta
|
"PERMANENT_SESSION_LIFETIME", get_converter=_make_timedelta
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def send_file_max_age_default(self) -> t.Optional[timedelta]:
|
|
||||||
"""The default value for ``max_age`` for :func:`~flask.send_file`. The default
|
|
||||||
is ``None``, which tells the browser to use conditional requests instead of a
|
|
||||||
timed cache.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Use
|
|
||||||
``app.config["SEND_FILE_MAX_AGE_DEFAULT"]`` instead.
|
|
||||||
|
|
||||||
.. versionchanged:: 2.0
|
|
||||||
Defaults to ``None`` instead of 12 hours.
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'send_file_max_age_default' is deprecated and will be removed in Flask"
|
|
||||||
" 2.3. Use 'SEND_FILE_MAX_AGE_DEFAULT' in 'app.config' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return _make_timedelta(self.config["SEND_FILE_MAX_AGE_DEFAULT"])
|
|
||||||
|
|
||||||
@send_file_max_age_default.setter
|
|
||||||
def send_file_max_age_default(self, value: t.Union[int, timedelta, None]) -> None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'send_file_max_age_default' is deprecated and will be removed in Flask"
|
|
||||||
" 2.3. Use 'SEND_FILE_MAX_AGE_DEFAULT' in 'app.config' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
self.config["SEND_FILE_MAX_AGE_DEFAULT"] = _make_timedelta(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def use_x_sendfile(self) -> bool:
|
|
||||||
"""Enable this to use the ``X-Sendfile`` feature, assuming the server supports
|
|
||||||
it, from :func:`~flask.send_file`.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Use ``app.config["USE_X_SENDFILE"]`` instead.
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'use_x_sendfile' is deprecated and will be removed in Flask 2.3. Use"
|
|
||||||
" 'USE_X_SENDFILE' in 'app.config' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return self.config["USE_X_SENDFILE"]
|
|
||||||
|
|
||||||
@use_x_sendfile.setter
|
|
||||||
def use_x_sendfile(self, value: bool) -> None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'use_x_sendfile' is deprecated and will be removed in Flask 2.3. Use"
|
|
||||||
" 'USE_X_SENDFILE' in 'app.config' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
self.config["USE_X_SENDFILE"] = value
|
|
||||||
|
|
||||||
_json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
|
|
||||||
_json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
|
|
||||||
|
|
||||||
@property # type: ignore[override]
|
|
||||||
def json_encoder(self) -> t.Type[json.JSONEncoder]:
|
|
||||||
"""The JSON encoder class to use. Defaults to
|
|
||||||
:class:`~flask.json.JSONEncoder`.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Customize
|
|
||||||
:attr:`json_provider_class` instead.
|
|
||||||
|
|
||||||
.. versionadded:: 0.10
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'app.json_encoder' is deprecated and will be removed in Flask 2.3."
|
|
||||||
" Customize 'app.json_provider_class' or 'app.json' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
|
|
||||||
if self._json_encoder is None:
|
|
||||||
from . import json
|
|
||||||
|
|
||||||
return json.JSONEncoder
|
|
||||||
|
|
||||||
return self._json_encoder
|
|
||||||
|
|
||||||
@json_encoder.setter
|
|
||||||
def json_encoder(self, value: t.Type[json.JSONEncoder]) -> None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'app.json_encoder' is deprecated and will be removed in Flask 2.3."
|
|
||||||
" Customize 'app.json_provider_class' or 'app.json' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
self._json_encoder = value
|
|
||||||
|
|
||||||
@property # type: ignore[override]
|
|
||||||
def json_decoder(self) -> t.Type[json.JSONDecoder]:
|
|
||||||
"""The JSON decoder class to use. Defaults to
|
|
||||||
:class:`~flask.json.JSONDecoder`.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Customize
|
|
||||||
:attr:`json_provider_class` instead.
|
|
||||||
|
|
||||||
.. versionadded:: 0.10
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'app.json_decoder' is deprecated and will be removed in Flask 2.3."
|
|
||||||
" Customize 'app.json_provider_class' or 'app.json' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
|
|
||||||
if self._json_decoder is None:
|
|
||||||
from . import json
|
|
||||||
|
|
||||||
return json.JSONDecoder
|
|
||||||
|
|
||||||
return self._json_decoder
|
|
||||||
|
|
||||||
@json_decoder.setter
|
|
||||||
def json_decoder(self, value: t.Type[json.JSONDecoder]) -> None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'app.json_decoder' is deprecated and will be removed in Flask 2.3."
|
|
||||||
" Customize 'app.json_provider_class' or 'app.json' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
self._json_decoder = value
|
|
||||||
|
|
||||||
json_provider_class: t.Type[JSONProvider] = DefaultJSONProvider
|
json_provider_class: t.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
|
||||||
|
|
@ -487,7 +307,6 @@ class Flask(Scaffold):
|
||||||
#: Default configuration parameters.
|
#: Default configuration parameters.
|
||||||
default_config = ImmutableDict(
|
default_config = ImmutableDict(
|
||||||
{
|
{
|
||||||
"ENV": None,
|
|
||||||
"DEBUG": None,
|
"DEBUG": None,
|
||||||
"TESTING": False,
|
"TESTING": False,
|
||||||
"PROPAGATE_EXCEPTIONS": None,
|
"PROPAGATE_EXCEPTIONS": None,
|
||||||
|
|
@ -509,10 +328,6 @@ class Flask(Scaffold):
|
||||||
"TRAP_HTTP_EXCEPTIONS": False,
|
"TRAP_HTTP_EXCEPTIONS": False,
|
||||||
"EXPLAIN_TEMPLATE_LOADING": False,
|
"EXPLAIN_TEMPLATE_LOADING": False,
|
||||||
"PREFERRED_URL_SCHEME": "http",
|
"PREFERRED_URL_SCHEME": "http",
|
||||||
"JSON_AS_ASCII": None,
|
|
||||||
"JSON_SORT_KEYS": None,
|
|
||||||
"JSONIFY_PRETTYPRINT_REGULAR": None,
|
|
||||||
"JSONIFY_MIMETYPE": None,
|
|
||||||
"TEMPLATES_AUTO_RELOAD": None,
|
"TEMPLATES_AUTO_RELOAD": None,
|
||||||
"MAX_COOKIE_SIZE": 4093,
|
"MAX_COOKIE_SIZE": 4093,
|
||||||
}
|
}
|
||||||
|
|
@ -625,17 +440,6 @@ class Flask(Scaffold):
|
||||||
t.Callable[[Exception, str, t.Dict[str, t.Any]], str]
|
t.Callable[[Exception, str, t.Dict[str, t.Any]], str]
|
||||||
] = []
|
] = []
|
||||||
|
|
||||||
#: A list of functions that will be called at the beginning of the
|
|
||||||
#: first request to this instance. To register a function, use the
|
|
||||||
#: :meth:`before_first_request` decorator.
|
|
||||||
#:
|
|
||||||
#: .. deprecated:: 2.2
|
|
||||||
#: Will be removed in Flask 2.3. Run setup code when
|
|
||||||
#: creating the application instead.
|
|
||||||
#:
|
|
||||||
#: .. versionadded:: 0.8
|
|
||||||
self.before_first_request_funcs: t.List[ft.BeforeFirstRequestCallable] = []
|
|
||||||
|
|
||||||
#: A list of functions that are called when the application context
|
#: A list of functions that are called when the application context
|
||||||
#: is destroyed. Since the application context is also torn down
|
#: is destroyed. Since the application context is also torn down
|
||||||
#: if the request ends this is the place to store code that disconnects
|
#: if the request ends this is the place to store code that disconnects
|
||||||
|
|
@ -746,28 +550,6 @@ class Flask(Scaffold):
|
||||||
return os.path.splitext(os.path.basename(fn))[0]
|
return os.path.splitext(os.path.basename(fn))[0]
|
||||||
return self.import_name
|
return self.import_name
|
||||||
|
|
||||||
@property
|
|
||||||
def propagate_exceptions(self) -> bool:
|
|
||||||
"""Returns the value of the ``PROPAGATE_EXCEPTIONS`` configuration
|
|
||||||
value in case it's set, otherwise a sensible default is returned.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3.
|
|
||||||
|
|
||||||
.. versionadded:: 0.7
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'propagate_exceptions' is deprecated and will be removed in Flask 2.3.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
rv = self.config["PROPAGATE_EXCEPTIONS"]
|
|
||||||
if rv is not None:
|
|
||||||
return rv
|
|
||||||
return self.testing or self.debug
|
|
||||||
|
|
||||||
@locked_cached_property
|
@locked_cached_property
|
||||||
def logger(self) -> logging.Logger:
|
def logger(self) -> logging.Logger:
|
||||||
"""A standard Python :class:`~logging.Logger` for the app, with
|
"""A standard Python :class:`~logging.Logger` for the app, with
|
||||||
|
|
@ -827,7 +609,6 @@ class Flask(Scaffold):
|
||||||
if instance_relative:
|
if instance_relative:
|
||||||
root_path = self.instance_path
|
root_path = self.instance_path
|
||||||
defaults = dict(self.default_config)
|
defaults = dict(self.default_config)
|
||||||
defaults["ENV"] = os.environ.get("FLASK_ENV") or "production"
|
|
||||||
defaults["DEBUG"] = get_debug_flag()
|
defaults["DEBUG"] = get_debug_flag()
|
||||||
return self.config_class(root_path, defaults)
|
return self.config_class(root_path, defaults)
|
||||||
|
|
||||||
|
|
@ -868,42 +649,6 @@ class Flask(Scaffold):
|
||||||
"""
|
"""
|
||||||
return open(os.path.join(self.instance_path, resource), mode)
|
return open(os.path.join(self.instance_path, resource), mode)
|
||||||
|
|
||||||
@property
|
|
||||||
def templates_auto_reload(self) -> bool:
|
|
||||||
"""Reload templates when they are changed. Used by
|
|
||||||
:meth:`create_jinja_environment`. It is enabled by default in debug mode.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Use ``app.config["TEMPLATES_AUTO_RELOAD"]``
|
|
||||||
instead.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0
|
|
||||||
This property was added but the underlying config and behavior
|
|
||||||
already existed.
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'templates_auto_reload' is deprecated and will be removed in Flask 2.3."
|
|
||||||
" Use 'TEMPLATES_AUTO_RELOAD' in 'app.config' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
rv = self.config["TEMPLATES_AUTO_RELOAD"]
|
|
||||||
return rv if rv is not None else self.debug
|
|
||||||
|
|
||||||
@templates_auto_reload.setter
|
|
||||||
def templates_auto_reload(self, value: bool) -> None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'templates_auto_reload' is deprecated and will be removed in Flask 2.3."
|
|
||||||
" Use 'TEMPLATES_AUTO_RELOAD' in 'app.config' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
self.config["TEMPLATES_AUTO_RELOAD"] = value
|
|
||||||
|
|
||||||
def create_jinja_environment(self) -> Environment:
|
def create_jinja_environment(self) -> Environment:
|
||||||
"""Create the Jinja environment based on :attr:`jinja_options`
|
"""Create the Jinja environment based on :attr:`jinja_options`
|
||||||
and the various Jinja-related methods of the app. Changing
|
and the various Jinja-related methods of the app. Changing
|
||||||
|
|
@ -1010,40 +755,6 @@ class Flask(Scaffold):
|
||||||
rv.update(processor())
|
rv.update(processor())
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
@property
|
|
||||||
def env(self) -> str:
|
|
||||||
"""What environment the app is running in. This maps to the :data:`ENV` config
|
|
||||||
key.
|
|
||||||
|
|
||||||
**Do not enable development when deploying in production.**
|
|
||||||
|
|
||||||
Default: ``'production'``
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3.
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'app.env' is deprecated and will be removed in Flask 2.3."
|
|
||||||
" Use 'app.debug' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return self.config["ENV"]
|
|
||||||
|
|
||||||
@env.setter
|
|
||||||
def env(self, value: str) -> None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'app.env' is deprecated and will be removed in Flask 2.3."
|
|
||||||
" Use 'app.debug' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
self.config["ENV"] = value
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def debug(self) -> bool:
|
def debug(self) -> bool:
|
||||||
"""Whether debug mode is enabled. When using ``flask run`` to start the
|
"""Whether debug mode is enabled. When using ``flask run`` to start the
|
||||||
|
|
@ -1144,16 +855,8 @@ class Flask(Scaffold):
|
||||||
if get_load_dotenv(load_dotenv):
|
if get_load_dotenv(load_dotenv):
|
||||||
cli.load_dotenv()
|
cli.load_dotenv()
|
||||||
|
|
||||||
# if set, let env vars override previous values
|
# if set, env var overrides existing value
|
||||||
if "FLASK_ENV" in os.environ:
|
if "FLASK_DEBUG" in os.environ:
|
||||||
print(
|
|
||||||
"'FLASK_ENV' is deprecated and will not be used in"
|
|
||||||
" Flask 2.3. Use 'FLASK_DEBUG' instead.",
|
|
||||||
file=sys.stderr,
|
|
||||||
)
|
|
||||||
self.config["ENV"] = os.environ.get("FLASK_ENV") or "production"
|
|
||||||
self.debug = get_debug_flag()
|
|
||||||
elif "FLASK_DEBUG" in os.environ:
|
|
||||||
self.debug = get_debug_flag()
|
self.debug = get_debug_flag()
|
||||||
|
|
||||||
# debug passed to method overrides all other sources
|
# debug passed to method overrides all other sources
|
||||||
|
|
@ -1479,32 +1182,6 @@ class Flask(Scaffold):
|
||||||
"""
|
"""
|
||||||
self.jinja_env.globals[name or f.__name__] = f
|
self.jinja_env.globals[name or f.__name__] = f
|
||||||
|
|
||||||
@setupmethod
|
|
||||||
def before_first_request(self, f: T_before_first_request) -> T_before_first_request:
|
|
||||||
"""Registers a function to be run before the first request to this
|
|
||||||
instance of the application.
|
|
||||||
|
|
||||||
The function will be called without any arguments and its return
|
|
||||||
value is ignored.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Run setup code when creating
|
|
||||||
the application instead.
|
|
||||||
|
|
||||||
.. versionadded:: 0.8
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'before_first_request' is deprecated and will be removed"
|
|
||||||
" in Flask 2.3. Run setup code while creating the"
|
|
||||||
" application instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
self.before_first_request_funcs.append(f)
|
|
||||||
return f
|
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def teardown_appcontext(self, f: T_teardown) -> T_teardown:
|
def teardown_appcontext(self, f: T_teardown) -> T_teardown:
|
||||||
"""Registers a function to be called when the application
|
"""Registers a function to be called when the application
|
||||||
|
|
@ -1682,7 +1359,7 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
Always sends the :data:`got_request_exception` signal.
|
Always sends the :data:`got_request_exception` signal.
|
||||||
|
|
||||||
If :attr:`propagate_exceptions` is ``True``, such as in debug
|
If :data:`PROPAGATE_EXCEPTIONS` is ``True``, such as in debug
|
||||||
mode, the error will be re-raised so that the debugger can
|
mode, the error will be re-raised so that the debugger can
|
||||||
display it. Otherwise, the original exception is logged, and
|
display it. Otherwise, the original exception is logged, and
|
||||||
an :exc:`~werkzeug.exceptions.InternalServerError` is returned.
|
an :exc:`~werkzeug.exceptions.InternalServerError` is returned.
|
||||||
|
|
@ -1805,15 +1482,6 @@ class Flask(Scaffold):
|
||||||
|
|
||||||
.. versionadded:: 0.7
|
.. versionadded:: 0.7
|
||||||
"""
|
"""
|
||||||
# Run before_first_request functions if this is the thread's first request.
|
|
||||||
# Inlined to avoid a method call on subsequent requests.
|
|
||||||
# This is deprecated, will be removed in Flask 2.3.
|
|
||||||
if not self._got_first_request:
|
|
||||||
with self._before_request_lock:
|
|
||||||
if not self._got_first_request:
|
|
||||||
for func in self.before_first_request_funcs:
|
|
||||||
self.ensure_sync(func)()
|
|
||||||
|
|
||||||
self._got_first_request = True
|
self._got_first_request = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import typing as t
|
import typing as t
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
@ -15,9 +14,6 @@ if t.TYPE_CHECKING: # pragma: no cover
|
||||||
|
|
||||||
DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable]
|
DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable]
|
||||||
T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable)
|
T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable)
|
||||||
T_before_first_request = t.TypeVar(
|
|
||||||
"T_before_first_request", bound=ft.BeforeFirstRequestCallable
|
|
||||||
)
|
|
||||||
T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable)
|
T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable)
|
||||||
T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable)
|
T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable)
|
||||||
T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable)
|
T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable)
|
||||||
|
|
@ -173,77 +169,6 @@ class Blueprint(Scaffold):
|
||||||
|
|
||||||
_got_registered_once = False
|
_got_registered_once = False
|
||||||
|
|
||||||
_json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
|
|
||||||
_json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def json_encoder(
|
|
||||||
self,
|
|
||||||
) -> t.Union[t.Type[json.JSONEncoder], None]:
|
|
||||||
"""Blueprint-local JSON encoder class to use. Set to ``None`` to use the app's.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Customize
|
|
||||||
:attr:`json_provider_class` instead.
|
|
||||||
|
|
||||||
.. versionadded:: 0.10
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'bp.json_encoder' is deprecated and will be removed in Flask 2.3."
|
|
||||||
" Customize 'app.json_provider_class' or 'app.json' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return self._json_encoder
|
|
||||||
|
|
||||||
@json_encoder.setter
|
|
||||||
def json_encoder(self, value: t.Union[t.Type[json.JSONEncoder], None]) -> None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'bp.json_encoder' is deprecated and will be removed in Flask 2.3."
|
|
||||||
" Customize 'app.json_provider_class' or 'app.json' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
self._json_encoder = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def json_decoder(
|
|
||||||
self,
|
|
||||||
) -> t.Union[t.Type[json.JSONDecoder], None]:
|
|
||||||
"""Blueprint-local JSON decoder class to use. Set to ``None`` to use the app's.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Customize
|
|
||||||
:attr:`json_provider_class` instead.
|
|
||||||
|
|
||||||
.. versionadded:: 0.10
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'bp.json_decoder' is deprecated and will be removed in Flask 2.3."
|
|
||||||
" Customize 'app.json_provider_class' or 'app.json' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return self._json_decoder
|
|
||||||
|
|
||||||
@json_decoder.setter
|
|
||||||
def json_decoder(self, value: t.Union[t.Type[json.JSONDecoder], None]) -> None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'bp.json_decoder' is deprecated and will be removed in Flask 2.3."
|
|
||||||
" Customize 'app.json_provider_class' or 'app.json' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
self._json_decoder = value
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
|
|
@ -361,6 +286,10 @@ class Blueprint(Scaffold):
|
||||||
.. versionchanged:: 2.3
|
.. versionchanged:: 2.3
|
||||||
Nested blueprints now correctly apply subdomains.
|
Nested blueprints now correctly apply subdomains.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.1
|
||||||
|
Registering the same blueprint with the same name multiple
|
||||||
|
times is an error.
|
||||||
|
|
||||||
.. versionchanged:: 2.0.1
|
.. versionchanged:: 2.0.1
|
||||||
Nested blueprints are registered with their dotted name.
|
Nested blueprints are registered with their dotted name.
|
||||||
This allows different blueprints with the same name to be
|
This allows different blueprints with the same name to be
|
||||||
|
|
@ -371,10 +300,6 @@ class Blueprint(Scaffold):
|
||||||
name the blueprint is registered with. This allows the same
|
name the blueprint is registered with. This allows the same
|
||||||
blueprint to be registered multiple times with unique names
|
blueprint to be registered multiple times with unique names
|
||||||
for ``url_for``.
|
for ``url_for``.
|
||||||
|
|
||||||
.. versionchanged:: 2.0.1
|
|
||||||
Registering the same blueprint with the same name multiple
|
|
||||||
times is deprecated and will become an error in Flask 2.1.
|
|
||||||
"""
|
"""
|
||||||
name_prefix = options.get("name_prefix", "")
|
name_prefix = options.get("name_prefix", "")
|
||||||
self_name = options.get("name", self.name)
|
self_name = options.get("name", self.name)
|
||||||
|
|
@ -634,29 +559,6 @@ class Blueprint(Scaffold):
|
||||||
)
|
)
|
||||||
return f
|
return f
|
||||||
|
|
||||||
@setupmethod
|
|
||||||
def before_app_first_request(
|
|
||||||
self, f: T_before_first_request
|
|
||||||
) -> T_before_first_request:
|
|
||||||
"""Register a function to run before the first request to the application is
|
|
||||||
handled by the worker. Equivalent to :meth:`.Flask.before_first_request`.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Run setup code when creating
|
|
||||||
the application instead.
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'before_app_first_request' is deprecated and will be"
|
|
||||||
" removed in Flask 2.3. Use 'record_once' instead to run"
|
|
||||||
" setup code when registering the blueprint.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
self.record_once(lambda s: s.app.before_first_request_funcs.append(f))
|
|
||||||
return f
|
|
||||||
|
|
||||||
@setupmethod
|
@setupmethod
|
||||||
def after_app_request(self, f: T_after_request) -> T_after_request:
|
def after_app_request(self, f: T_after_request) -> T_after_request:
|
||||||
"""Like :meth:`after_request`, but after every request, not only those handled
|
"""Like :meth:`after_request`, but after every request, not only those handled
|
||||||
|
|
|
||||||
|
|
@ -17,30 +17,17 @@ class _FakeStack:
|
||||||
self.name = name
|
self.name = name
|
||||||
self.cv = cv
|
self.cv = cv
|
||||||
|
|
||||||
def _warn(self):
|
@property
|
||||||
|
def top(self) -> t.Optional[t.Any]:
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
f"'_{self.name}_ctx_stack' is deprecated and will be"
|
f"'_{self.name}_ctx_stack' is deprecated and will be removed in Flask 2.4."
|
||||||
" removed in Flask 2.3. Use 'g' to store data, or"
|
f" Use 'g' to store data, or '{self.name}_ctx' to access the current"
|
||||||
f" '{self.name}_ctx' to access the current context.",
|
" context.",
|
||||||
DeprecationWarning,
|
DeprecationWarning,
|
||||||
stacklevel=3,
|
stacklevel=2,
|
||||||
)
|
)
|
||||||
|
|
||||||
def push(self, obj: t.Any) -> None:
|
|
||||||
self._warn()
|
|
||||||
self.cv.set(obj)
|
|
||||||
|
|
||||||
def pop(self) -> t.Any:
|
|
||||||
self._warn()
|
|
||||||
ctx = self.cv.get(None)
|
|
||||||
self.cv.set(None)
|
|
||||||
return ctx
|
|
||||||
|
|
||||||
@property
|
|
||||||
def top(self) -> t.Optional[t.Any]:
|
|
||||||
self._warn()
|
|
||||||
return self.cv.get(None)
|
return self.cv.get(None)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -88,7 +75,7 @@ def __getattr__(name: str) -> t.Any:
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"'_app_ctx_stack' is deprecated and will be removed in Flask 2.3.",
|
"'_app_ctx_stack' is deprecated and will be removed in Flask 2.4.",
|
||||||
DeprecationWarning,
|
DeprecationWarning,
|
||||||
stacklevel=2,
|
stacklevel=2,
|
||||||
)
|
)
|
||||||
|
|
@ -98,7 +85,7 @@ def __getattr__(name: str) -> t.Any:
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"'_request_ctx_stack' is deprecated and will be removed in Flask 2.3.",
|
"'_request_ctx_stack' is deprecated and will be removed in Flask 2.4.",
|
||||||
DeprecationWarning,
|
DeprecationWarning,
|
||||||
stacklevel=2,
|
stacklevel=2,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -25,45 +25,12 @@ if t.TYPE_CHECKING: # pragma: no cover
|
||||||
import typing_extensions as te
|
import typing_extensions as te
|
||||||
|
|
||||||
|
|
||||||
def get_env() -> str:
|
|
||||||
"""Get the environment the app is running in, indicated by the
|
|
||||||
:envvar:`FLASK_ENV` environment variable. The default is
|
|
||||||
``'production'``.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3.
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'FLASK_ENV' and 'get_env' are deprecated and will be removed"
|
|
||||||
" in Flask 2.3. Use 'FLASK_DEBUG' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return os.environ.get("FLASK_ENV") or "production"
|
|
||||||
|
|
||||||
|
|
||||||
def get_debug_flag() -> bool:
|
def get_debug_flag() -> bool:
|
||||||
"""Get whether debug mode should be enabled for the app, indicated by the
|
"""Get whether debug mode should be enabled for the app, indicated by the
|
||||||
:envvar:`FLASK_DEBUG` environment variable. The default is ``False``.
|
:envvar:`FLASK_DEBUG` environment variable. The default is ``False``.
|
||||||
"""
|
"""
|
||||||
val = os.environ.get("FLASK_DEBUG")
|
val = os.environ.get("FLASK_DEBUG")
|
||||||
|
return bool(val and val.lower() not in {"0", "false", "no"})
|
||||||
if not val:
|
|
||||||
env = os.environ.get("FLASK_ENV")
|
|
||||||
|
|
||||||
if env is not None:
|
|
||||||
print(
|
|
||||||
"'FLASK_ENV' is deprecated and will not be used in"
|
|
||||||
" Flask 2.3. Use 'FLASK_DEBUG' instead.",
|
|
||||||
file=sys.stderr,
|
|
||||||
)
|
|
||||||
return env == "development"
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
return val.lower() not in {"0", "false", "no"}
|
|
||||||
|
|
||||||
|
|
||||||
def get_load_dotenv(default: bool = True) -> bool:
|
def get_load_dotenv(default: bool = True) -> bool:
|
||||||
|
|
|
||||||
|
|
@ -3,85 +3,14 @@ from __future__ import annotations
|
||||||
import json as _json
|
import json as _json
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
||||||
from jinja2.utils import htmlsafe_json_dumps as _jinja_htmlsafe_dumps
|
|
||||||
|
|
||||||
from ..globals import current_app
|
from ..globals import current_app
|
||||||
from .provider import _default
|
from .provider import _default
|
||||||
|
|
||||||
if t.TYPE_CHECKING: # pragma: no cover
|
if t.TYPE_CHECKING: # pragma: no cover
|
||||||
from ..app import Flask
|
|
||||||
from ..wrappers import Response
|
from ..wrappers import Response
|
||||||
|
|
||||||
|
|
||||||
class JSONEncoder(_json.JSONEncoder):
|
def dumps(obj: t.Any, **kwargs: t.Any) -> str:
|
||||||
"""The default JSON encoder. Handles extra types compared to the
|
|
||||||
built-in :class:`json.JSONEncoder`.
|
|
||||||
|
|
||||||
- :class:`datetime.datetime` and :class:`datetime.date` are
|
|
||||||
serialized to :rfc:`822` strings. This is the same as the HTTP
|
|
||||||
date format.
|
|
||||||
- :class:`decimal.Decimal` is serialized to a string.
|
|
||||||
- :class:`uuid.UUID` is serialized to a string.
|
|
||||||
- :class:`dataclasses.dataclass` is passed to
|
|
||||||
:func:`dataclasses.asdict`.
|
|
||||||
- :class:`~markupsafe.Markup` (or any object with a ``__html__``
|
|
||||||
method) will call the ``__html__`` method to get a string.
|
|
||||||
|
|
||||||
Assign a subclass of this to :attr:`flask.Flask.json_encoder` or
|
|
||||||
:attr:`flask.Blueprint.json_encoder` to override the default.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Use ``app.json`` instead.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, **kwargs) -> None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'JSONEncoder' is deprecated and will be removed in"
|
|
||||||
" Flask 2.3. Use 'Flask.json' to provide an alternate"
|
|
||||||
" JSON implementation instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=3,
|
|
||||||
)
|
|
||||||
super().__init__(**kwargs)
|
|
||||||
|
|
||||||
def default(self, o: t.Any) -> t.Any:
|
|
||||||
"""Convert ``o`` to a JSON serializable type. See
|
|
||||||
:meth:`json.JSONEncoder.default`. Python does not support
|
|
||||||
overriding how basic types like ``str`` or ``list`` are
|
|
||||||
serialized, they are handled before this method.
|
|
||||||
"""
|
|
||||||
return _default(o)
|
|
||||||
|
|
||||||
|
|
||||||
class JSONDecoder(_json.JSONDecoder):
|
|
||||||
"""The default JSON decoder.
|
|
||||||
|
|
||||||
This does not change any behavior from the built-in
|
|
||||||
:class:`json.JSONDecoder`.
|
|
||||||
|
|
||||||
Assign a subclass of this to :attr:`flask.Flask.json_decoder` or
|
|
||||||
:attr:`flask.Blueprint.json_decoder` to override the default.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. Use ``app.json`` instead.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, **kwargs) -> None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'JSONDecoder' is deprecated and will be removed in"
|
|
||||||
" Flask 2.3. Use 'Flask.json' to provide an alternate"
|
|
||||||
" JSON implementation instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=3,
|
|
||||||
)
|
|
||||||
super().__init__(**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def dumps(obj: t.Any, *, app: Flask | None = None, **kwargs: t.Any) -> str:
|
|
||||||
"""Serialize data as JSON.
|
"""Serialize data as JSON.
|
||||||
|
|
||||||
If :data:`~flask.current_app` is available, it will use its
|
If :data:`~flask.current_app` is available, it will use its
|
||||||
|
|
@ -91,13 +20,13 @@ def dumps(obj: t.Any, *, app: Flask | None = None, **kwargs: t.Any) -> str:
|
||||||
:param obj: The data to serialize.
|
:param obj: The data to serialize.
|
||||||
:param kwargs: Arguments passed to the ``dumps`` implementation.
|
:param kwargs: Arguments passed to the ``dumps`` implementation.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.3
|
||||||
|
The ``app`` parameter was removed.
|
||||||
|
|
||||||
.. versionchanged:: 2.2
|
.. versionchanged:: 2.2
|
||||||
Calls ``current_app.json.dumps``, allowing an app to override
|
Calls ``current_app.json.dumps``, allowing an app to override
|
||||||
the behavior.
|
the behavior.
|
||||||
|
|
||||||
.. versionchanged:: 2.2
|
|
||||||
The ``app`` parameter will be removed in Flask 2.3.
|
|
||||||
|
|
||||||
.. versionchanged:: 2.0.2
|
.. versionchanged:: 2.0.2
|
||||||
:class:`decimal.Decimal` is supported by converting to a string.
|
:class:`decimal.Decimal` is supported by converting to a string.
|
||||||
|
|
||||||
|
|
@ -108,28 +37,14 @@ def dumps(obj: t.Any, *, app: Flask | None = None, **kwargs: t.Any) -> str:
|
||||||
``app`` can be passed directly, rather than requiring an app
|
``app`` can be passed directly, rather than requiring an app
|
||||||
context for configuration.
|
context for configuration.
|
||||||
"""
|
"""
|
||||||
if app is not None:
|
if current_app:
|
||||||
import warnings
|
return current_app.json.dumps(obj, **kwargs)
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"The 'app' parameter is deprecated and will be removed in"
|
|
||||||
" Flask 2.3. Call 'app.json.dumps' directly instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
app = current_app
|
|
||||||
|
|
||||||
if app:
|
|
||||||
return app.json.dumps(obj, **kwargs)
|
|
||||||
|
|
||||||
kwargs.setdefault("default", _default)
|
kwargs.setdefault("default", _default)
|
||||||
return _json.dumps(obj, **kwargs)
|
return _json.dumps(obj, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def dump(
|
def dump(obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None:
|
||||||
obj: t.Any, fp: t.IO[str], *, app: Flask | None = None, **kwargs: t.Any
|
|
||||||
) -> None:
|
|
||||||
"""Serialize data as JSON and write to a file.
|
"""Serialize data as JSON and write to a file.
|
||||||
|
|
||||||
If :data:`~flask.current_app` is available, it will use its
|
If :data:`~flask.current_app` is available, it will use its
|
||||||
|
|
@ -141,37 +56,25 @@ def dump(
|
||||||
encoding to be valid JSON.
|
encoding to be valid JSON.
|
||||||
:param kwargs: Arguments passed to the ``dump`` implementation.
|
:param kwargs: Arguments passed to the ``dump`` implementation.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.3
|
||||||
|
The ``app`` parameter was removed.
|
||||||
|
|
||||||
.. versionchanged:: 2.2
|
.. versionchanged:: 2.2
|
||||||
Calls ``current_app.json.dump``, allowing an app to override
|
Calls ``current_app.json.dump``, allowing an app to override
|
||||||
the behavior.
|
the behavior.
|
||||||
|
|
||||||
.. versionchanged:: 2.2
|
|
||||||
The ``app`` parameter will be removed in Flask 2.3.
|
|
||||||
|
|
||||||
.. versionchanged:: 2.0
|
.. versionchanged:: 2.0
|
||||||
Writing to a binary file, and the ``encoding`` argument, will be
|
Writing to a binary file, and the ``encoding`` argument, will be
|
||||||
removed in Flask 2.1.
|
removed in Flask 2.1.
|
||||||
"""
|
"""
|
||||||
if app is not None:
|
if current_app:
|
||||||
import warnings
|
current_app.json.dump(obj, fp, **kwargs)
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"The 'app' parameter is deprecated and will be removed in"
|
|
||||||
" Flask 2.3. Call 'app.json.dump' directly instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
app = current_app
|
|
||||||
|
|
||||||
if app:
|
|
||||||
app.json.dump(obj, fp, **kwargs)
|
|
||||||
else:
|
else:
|
||||||
kwargs.setdefault("default", _default)
|
kwargs.setdefault("default", _default)
|
||||||
_json.dump(obj, fp, **kwargs)
|
_json.dump(obj, fp, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def loads(s: str | bytes, *, app: Flask | None = None, **kwargs: t.Any) -> t.Any:
|
def loads(s: str | bytes, **kwargs: t.Any) -> t.Any:
|
||||||
"""Deserialize data as JSON.
|
"""Deserialize data as JSON.
|
||||||
|
|
||||||
If :data:`~flask.current_app` is available, it will use its
|
If :data:`~flask.current_app` is available, it will use its
|
||||||
|
|
@ -181,13 +84,13 @@ def loads(s: str | bytes, *, app: Flask | None = None, **kwargs: t.Any) -> t.Any
|
||||||
:param s: Text or UTF-8 bytes.
|
:param s: Text or UTF-8 bytes.
|
||||||
:param kwargs: Arguments passed to the ``loads`` implementation.
|
:param kwargs: Arguments passed to the ``loads`` implementation.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.3
|
||||||
|
The ``app`` parameter was removed.
|
||||||
|
|
||||||
.. versionchanged:: 2.2
|
.. versionchanged:: 2.2
|
||||||
Calls ``current_app.json.loads``, allowing an app to override
|
Calls ``current_app.json.loads``, allowing an app to override
|
||||||
the behavior.
|
the behavior.
|
||||||
|
|
||||||
.. versionchanged:: 2.2
|
|
||||||
The ``app`` parameter will be removed in Flask 2.3.
|
|
||||||
|
|
||||||
.. versionchanged:: 2.0
|
.. versionchanged:: 2.0
|
||||||
``encoding`` will be removed in Flask 2.1. The data must be a
|
``encoding`` will be removed in Flask 2.1. The data must be a
|
||||||
string or UTF-8 bytes.
|
string or UTF-8 bytes.
|
||||||
|
|
@ -196,25 +99,13 @@ def loads(s: str | bytes, *, app: Flask | None = None, **kwargs: t.Any) -> t.Any
|
||||||
``app`` can be passed directly, rather than requiring an app
|
``app`` can be passed directly, rather than requiring an app
|
||||||
context for configuration.
|
context for configuration.
|
||||||
"""
|
"""
|
||||||
if app is not None:
|
if current_app:
|
||||||
import warnings
|
return current_app.json.loads(s, **kwargs)
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"The 'app' parameter is deprecated and will be removed in"
|
|
||||||
" Flask 2.3. Call 'app.json.loads' directly instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
app = current_app
|
|
||||||
|
|
||||||
if app:
|
|
||||||
return app.json.loads(s, **kwargs)
|
|
||||||
|
|
||||||
return _json.loads(s, **kwargs)
|
return _json.loads(s, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def load(fp: t.IO[t.AnyStr], *, app: Flask | None = None, **kwargs: t.Any) -> t.Any:
|
def load(fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any:
|
||||||
"""Deserialize data as JSON read from a file.
|
"""Deserialize data as JSON read from a file.
|
||||||
|
|
||||||
If :data:`~flask.current_app` is available, it will use its
|
If :data:`~flask.current_app` is available, it will use its
|
||||||
|
|
@ -224,6 +115,9 @@ def load(fp: t.IO[t.AnyStr], *, app: Flask | None = None, **kwargs: t.Any) -> t.
|
||||||
:param fp: A file opened for reading text or UTF-8 bytes.
|
:param fp: A file opened for reading text or UTF-8 bytes.
|
||||||
:param kwargs: Arguments passed to the ``load`` implementation.
|
:param kwargs: Arguments passed to the ``load`` implementation.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.3
|
||||||
|
The ``app`` parameter was removed.
|
||||||
|
|
||||||
.. versionchanged:: 2.2
|
.. versionchanged:: 2.2
|
||||||
Calls ``current_app.json.load``, allowing an app to override
|
Calls ``current_app.json.load``, allowing an app to override
|
||||||
the behavior.
|
the behavior.
|
||||||
|
|
@ -235,78 +129,12 @@ def load(fp: t.IO[t.AnyStr], *, app: Flask | None = None, **kwargs: t.Any) -> t.
|
||||||
``encoding`` will be removed in Flask 2.1. The file must be text
|
``encoding`` will be removed in Flask 2.1. The file must be text
|
||||||
mode, or binary mode with UTF-8 bytes.
|
mode, or binary mode with UTF-8 bytes.
|
||||||
"""
|
"""
|
||||||
if app is not None:
|
if current_app:
|
||||||
import warnings
|
return current_app.json.load(fp, **kwargs)
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"The 'app' parameter is deprecated and will be removed in"
|
|
||||||
" Flask 2.3. Call 'app.json.load' directly instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
app = current_app
|
|
||||||
|
|
||||||
if app:
|
|
||||||
return app.json.load(fp, **kwargs)
|
|
||||||
|
|
||||||
return _json.load(fp, **kwargs)
|
return _json.load(fp, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def htmlsafe_dumps(obj: t.Any, **kwargs: t.Any) -> str:
|
|
||||||
"""Serialize an object to a string of JSON with :func:`dumps`, then
|
|
||||||
replace HTML-unsafe characters with Unicode escapes and mark the
|
|
||||||
result safe with :class:`~markupsafe.Markup`.
|
|
||||||
|
|
||||||
This is available in templates as the ``|tojson`` filter.
|
|
||||||
|
|
||||||
The returned string is safe to render in HTML documents and
|
|
||||||
``<script>`` tags. The exception is in HTML attributes that are
|
|
||||||
double quoted; either use single quotes or the ``|forceescape``
|
|
||||||
filter.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3. This is built-in to Jinja now.
|
|
||||||
|
|
||||||
.. versionchanged:: 2.0
|
|
||||||
Uses :func:`jinja2.utils.htmlsafe_json_dumps`. The returned
|
|
||||||
value is marked safe by wrapping in :class:`~markupsafe.Markup`.
|
|
||||||
|
|
||||||
.. versionchanged:: 0.10
|
|
||||||
Single quotes are escaped, making this safe to use in HTML,
|
|
||||||
``<script>`` tags, and single-quoted attributes without further
|
|
||||||
escaping.
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'htmlsafe_dumps' is deprecated and will be removed in Flask"
|
|
||||||
" 2.3. Use 'jinja2.utils.htmlsafe_json_dumps' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return _jinja_htmlsafe_dumps(obj, dumps=dumps, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def htmlsafe_dump(obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None:
|
|
||||||
"""Serialize an object to JSON written to a file object, replacing
|
|
||||||
HTML-unsafe characters with Unicode escapes. See
|
|
||||||
:func:`htmlsafe_dumps` and :func:`dumps`.
|
|
||||||
|
|
||||||
.. deprecated:: 2.2
|
|
||||||
Will be removed in Flask 2.3.
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"'htmlsafe_dump' is deprecated and will be removed in Flask"
|
|
||||||
" 2.3. Use 'jinja2.utils.htmlsafe_json_dumps' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
fp.write(htmlsafe_dumps(obj, **kwargs))
|
|
||||||
|
|
||||||
|
|
||||||
def jsonify(*args: t.Any, **kwargs: t.Any) -> Response:
|
def jsonify(*args: t.Any, **kwargs: t.Any) -> Response:
|
||||||
"""Serialize the given arguments as JSON, and return a
|
"""Serialize the given arguments as JSON, and return a
|
||||||
:class:`~flask.Response` object with the ``application/json``
|
:class:`~flask.Response` object with the ``application/json``
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@ from datetime import date
|
||||||
|
|
||||||
from werkzeug.http import http_date
|
from werkzeug.http import http_date
|
||||||
|
|
||||||
from ..globals import request
|
|
||||||
|
|
||||||
if t.TYPE_CHECKING: # pragma: no cover
|
if t.TYPE_CHECKING: # pragma: no cover
|
||||||
from ..app import Flask
|
from ..app import Flask
|
||||||
from ..wrappers import Response
|
from ..wrappers import Response
|
||||||
|
|
@ -176,57 +174,9 @@ class DefaultJSONProvider(JSONProvider):
|
||||||
:param obj: The data to serialize.
|
:param obj: The data to serialize.
|
||||||
:param kwargs: Passed to :func:`json.dumps`.
|
:param kwargs: Passed to :func:`json.dumps`.
|
||||||
"""
|
"""
|
||||||
cls = self._app._json_encoder
|
|
||||||
bp = self._app.blueprints.get(request.blueprint) if request else None
|
|
||||||
|
|
||||||
if bp is not None and bp._json_encoder is not None:
|
|
||||||
cls = bp._json_encoder
|
|
||||||
|
|
||||||
if cls is not None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"Setting 'json_encoder' on the app or a blueprint is"
|
|
||||||
" deprecated and will be removed in Flask 2.3."
|
|
||||||
" Customize 'app.json' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
kwargs.setdefault("cls", cls)
|
|
||||||
|
|
||||||
if "default" not in cls.__dict__:
|
|
||||||
kwargs.setdefault("default", self.default)
|
kwargs.setdefault("default", self.default)
|
||||||
else:
|
kwargs.setdefault("ensure_ascii", self.ensure_ascii)
|
||||||
kwargs.setdefault("default", self.default)
|
kwargs.setdefault("sort_keys", self.sort_keys)
|
||||||
|
|
||||||
ensure_ascii = self._app.config["JSON_AS_ASCII"]
|
|
||||||
sort_keys = self._app.config["JSON_SORT_KEYS"]
|
|
||||||
|
|
||||||
if ensure_ascii is not None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"The 'JSON_AS_ASCII' config key is deprecated and will"
|
|
||||||
" be removed in Flask 2.3. Set 'app.json.ensure_ascii'"
|
|
||||||
" instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
ensure_ascii = self.ensure_ascii
|
|
||||||
|
|
||||||
if sort_keys is not None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"The 'JSON_SORT_KEYS' config key is deprecated and will"
|
|
||||||
" be removed in Flask 2.3. Set 'app.json.sort_keys'"
|
|
||||||
" instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
sort_keys = self.sort_keys
|
|
||||||
|
|
||||||
kwargs.setdefault("ensure_ascii", ensure_ascii)
|
|
||||||
kwargs.setdefault("sort_keys", sort_keys)
|
|
||||||
return json.dumps(obj, **kwargs)
|
return json.dumps(obj, **kwargs)
|
||||||
|
|
||||||
def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any:
|
def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any:
|
||||||
|
|
@ -235,23 +185,6 @@ class DefaultJSONProvider(JSONProvider):
|
||||||
:param s: Text or UTF-8 bytes.
|
:param s: Text or UTF-8 bytes.
|
||||||
:param kwargs: Passed to :func:`json.loads`.
|
:param kwargs: Passed to :func:`json.loads`.
|
||||||
"""
|
"""
|
||||||
cls = self._app._json_decoder
|
|
||||||
bp = self._app.blueprints.get(request.blueprint) if request else None
|
|
||||||
|
|
||||||
if bp is not None and bp._json_decoder is not None:
|
|
||||||
cls = bp._json_decoder
|
|
||||||
|
|
||||||
if cls is not None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"Setting 'json_decoder' on the app or a blueprint is"
|
|
||||||
" deprecated and will be removed in Flask 2.3."
|
|
||||||
" Customize 'app.json' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
kwargs.setdefault("cls", cls)
|
|
||||||
|
|
||||||
return json.loads(s, **kwargs)
|
return json.loads(s, **kwargs)
|
||||||
|
|
||||||
def response(self, *args: t.Any, **kwargs: t.Any) -> Response:
|
def response(self, *args: t.Any, **kwargs: t.Any) -> Response:
|
||||||
|
|
@ -272,39 +205,12 @@ class DefaultJSONProvider(JSONProvider):
|
||||||
"""
|
"""
|
||||||
obj = self._prepare_response_obj(args, kwargs)
|
obj = self._prepare_response_obj(args, kwargs)
|
||||||
dump_args: t.Dict[str, t.Any] = {}
|
dump_args: t.Dict[str, t.Any] = {}
|
||||||
pretty = self._app.config["JSONIFY_PRETTYPRINT_REGULAR"]
|
|
||||||
mimetype = self._app.config["JSONIFY_MIMETYPE"]
|
|
||||||
|
|
||||||
if pretty is not None:
|
if (self.compact is None and self._app.debug) or self.compact is False:
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"The 'JSONIFY_PRETTYPRINT_REGULAR' config key is"
|
|
||||||
" deprecated and will be removed in Flask 2.3. Set"
|
|
||||||
" 'app.json.compact' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
compact: bool | None = not pretty
|
|
||||||
else:
|
|
||||||
compact = self.compact
|
|
||||||
|
|
||||||
if (compact is None and self._app.debug) or compact is False:
|
|
||||||
dump_args.setdefault("indent", 2)
|
dump_args.setdefault("indent", 2)
|
||||||
else:
|
else:
|
||||||
dump_args.setdefault("separators", (",", ":"))
|
dump_args.setdefault("separators", (",", ":"))
|
||||||
|
|
||||||
if mimetype is not None:
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
|
||||||
"The 'JSONIFY_MIMETYPE' config key is deprecated and"
|
|
||||||
" will be removed in Flask 2.3. Set 'app.json.mimetype'"
|
|
||||||
" instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
mimetype = self.mimetype
|
|
||||||
|
|
||||||
return self._app.response_class(
|
return self._app.response_class(
|
||||||
f"{self.dumps(obj, **dump_args)}\n", mimetype=mimetype
|
f"{self.dumps(obj, **dump_args)}\n", mimetype=self.mimetype
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import importlib.util
|
import importlib.util
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
import pkgutil
|
import pkgutil
|
||||||
|
|
@ -74,20 +73,6 @@ class Scaffold:
|
||||||
_static_folder: t.Optional[str] = None
|
_static_folder: t.Optional[str] = None
|
||||||
_static_url_path: t.Optional[str] = None
|
_static_url_path: t.Optional[str] = None
|
||||||
|
|
||||||
#: JSON encoder class used by :func:`flask.json.dumps`. If a
|
|
||||||
#: blueprint sets this, it will be used instead of the app's value.
|
|
||||||
#:
|
|
||||||
#: .. deprecated:: 2.2
|
|
||||||
#: Will be removed in Flask 2.3.
|
|
||||||
json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
|
|
||||||
|
|
||||||
#: JSON decoder class used by :func:`flask.json.loads`. If a
|
|
||||||
#: blueprint sets this, it will be used instead of the app's value.
|
|
||||||
#:
|
|
||||||
#: .. deprecated:: 2.2
|
|
||||||
#: Will be removed in Flask 2.3.
|
|
||||||
json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
import_name: str,
|
import_name: str,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ def _standard_os_environ():
|
||||||
out = (
|
out = (
|
||||||
(os.environ, "FLASK_ENV_FILE", monkeypatch.notset),
|
(os.environ, "FLASK_ENV_FILE", monkeypatch.notset),
|
||||||
(os.environ, "FLASK_APP", monkeypatch.notset),
|
(os.environ, "FLASK_APP", monkeypatch.notset),
|
||||||
(os.environ, "FLASK_ENV", monkeypatch.notset),
|
|
||||||
(os.environ, "FLASK_DEBUG", monkeypatch.notset),
|
(os.environ, "FLASK_DEBUG", monkeypatch.notset),
|
||||||
(os.environ, "FLASK_RUN_FROM_CLI", monkeypatch.notset),
|
(os.environ, "FLASK_RUN_FROM_CLI", monkeypatch.notset),
|
||||||
(os.environ, "WERKZEUG_RUN_MAIN", monkeypatch.notset),
|
(os.environ, "WERKZEUG_RUN_MAIN", monkeypatch.notset),
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,6 @@ def test_async_error_handler(path, async_app):
|
||||||
|
|
||||||
|
|
||||||
def test_async_before_after_request():
|
def test_async_before_after_request():
|
||||||
app_first_called = False
|
|
||||||
app_before_called = False
|
app_before_called = False
|
||||||
app_after_called = False
|
app_after_called = False
|
||||||
bp_before_called = False
|
bp_before_called = False
|
||||||
|
|
@ -107,13 +106,6 @@ def test_async_before_after_request():
|
||||||
def index():
|
def index():
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
with pytest.deprecated_call():
|
|
||||||
|
|
||||||
@app.before_first_request
|
|
||||||
async def before_first():
|
|
||||||
nonlocal app_first_called
|
|
||||||
app_first_called = True
|
|
||||||
|
|
||||||
@app.before_request
|
@app.before_request
|
||||||
async def before():
|
async def before():
|
||||||
nonlocal app_before_called
|
nonlocal app_before_called
|
||||||
|
|
@ -146,7 +138,6 @@ def test_async_before_after_request():
|
||||||
|
|
||||||
test_client = app.test_client()
|
test_client = app.test_client()
|
||||||
test_client.get("/")
|
test_client.get("/")
|
||||||
assert app_first_called
|
|
||||||
assert app_before_called
|
assert app_before_called
|
||||||
assert app_after_called
|
assert app_after_called
|
||||||
test_client.get("/bp/")
|
test_client.get("/bp/")
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
import gc
|
import gc
|
||||||
import re
|
import re
|
||||||
import time
|
|
||||||
import uuid
|
import uuid
|
||||||
import warnings
|
import warnings
|
||||||
import weakref
|
import weakref
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from datetime import timezone
|
from datetime import timezone
|
||||||
from platform import python_implementation
|
from platform import python_implementation
|
||||||
from threading import Thread
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import werkzeug.serving
|
import werkzeug.serving
|
||||||
|
|
@ -1667,43 +1665,6 @@ def test_no_setup_after_first_request(app, client):
|
||||||
assert "setup method 'add_url_rule'" in str(exc_info.value)
|
assert "setup method 'add_url_rule'" in str(exc_info.value)
|
||||||
|
|
||||||
|
|
||||||
def test_before_first_request_functions(app, client):
|
|
||||||
got = []
|
|
||||||
|
|
||||||
with pytest.deprecated_call():
|
|
||||||
|
|
||||||
@app.before_first_request
|
|
||||||
def foo():
|
|
||||||
got.append(42)
|
|
||||||
|
|
||||||
client.get("/")
|
|
||||||
assert got == [42]
|
|
||||||
client.get("/")
|
|
||||||
assert got == [42]
|
|
||||||
assert app.got_first_request
|
|
||||||
|
|
||||||
|
|
||||||
def test_before_first_request_functions_concurrent(app, client):
|
|
||||||
got = []
|
|
||||||
|
|
||||||
with pytest.deprecated_call():
|
|
||||||
|
|
||||||
@app.before_first_request
|
|
||||||
def foo():
|
|
||||||
time.sleep(0.2)
|
|
||||||
got.append(42)
|
|
||||||
|
|
||||||
def get_and_assert():
|
|
||||||
client.get("/")
|
|
||||||
assert got == [42]
|
|
||||||
|
|
||||||
t = Thread(target=get_and_assert)
|
|
||||||
t.start()
|
|
||||||
get_and_assert()
|
|
||||||
t.join()
|
|
||||||
assert app.got_first_request
|
|
||||||
|
|
||||||
|
|
||||||
def test_routing_redirect_debugging(monkeypatch, app, client):
|
def test_routing_redirect_debugging(monkeypatch, app, client):
|
||||||
app.config["DEBUG"] = True
|
app.config["DEBUG"] = True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -722,12 +722,6 @@ def test_app_request_processing(app, client):
|
||||||
bp = flask.Blueprint("bp", __name__)
|
bp = flask.Blueprint("bp", __name__)
|
||||||
evts = []
|
evts = []
|
||||||
|
|
||||||
with pytest.deprecated_call():
|
|
||||||
|
|
||||||
@bp.before_app_first_request
|
|
||||||
def before_first_request():
|
|
||||||
evts.append("first")
|
|
||||||
|
|
||||||
@bp.before_app_request
|
@bp.before_app_request
|
||||||
def before_app():
|
def before_app():
|
||||||
evts.append("before")
|
evts.append("before")
|
||||||
|
|
@ -755,12 +749,12 @@ def test_app_request_processing(app, client):
|
||||||
# first request
|
# first request
|
||||||
resp = client.get("/").data
|
resp = client.get("/").data
|
||||||
assert resp == b"request|after"
|
assert resp == b"request|after"
|
||||||
assert evts == ["first", "before", "after", "teardown"]
|
assert evts == ["before", "after", "teardown"]
|
||||||
|
|
||||||
# second request
|
# second request
|
||||||
resp = client.get("/").data
|
resp = client.get("/").data
|
||||||
assert resp == b"request|after"
|
assert resp == b"request|after"
|
||||||
assert evts == ["first"] + ["before", "after", "teardown"] * 2
|
assert evts == ["before", "after", "teardown"] * 2
|
||||||
|
|
||||||
|
|
||||||
def test_app_url_processors(app, client):
|
def test_app_url_processors(app, client):
|
||||||
|
|
|
||||||
|
|
@ -302,24 +302,18 @@ class TestStreaming:
|
||||||
|
|
||||||
class TestHelpers:
|
class TestHelpers:
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"debug, expected_flag, expected_default_flag",
|
("debug", "expect"),
|
||||||
[
|
[
|
||||||
("", False, False),
|
("", False),
|
||||||
("0", False, False),
|
("0", False),
|
||||||
("False", False, False),
|
("False", False),
|
||||||
("No", False, False),
|
("No", False),
|
||||||
("True", True, True),
|
("True", True),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_get_debug_flag(
|
def test_get_debug_flag(self, monkeypatch, debug, expect):
|
||||||
self, monkeypatch, debug, expected_flag, expected_default_flag
|
|
||||||
):
|
|
||||||
monkeypatch.setenv("FLASK_DEBUG", debug)
|
monkeypatch.setenv("FLASK_DEBUG", debug)
|
||||||
if expected_flag is None:
|
assert get_debug_flag() == expect
|
||||||
assert get_debug_flag() is None
|
|
||||||
else:
|
|
||||||
assert get_debug_flag() == expected_flag
|
|
||||||
assert get_debug_flag() == expected_default_flag
|
|
||||||
|
|
||||||
def test_make_response(self):
|
def test_make_response(self):
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue