mirror of https://github.com/pallets/flask.git
remove previously deprecated code
This commit is contained in:
parent
604de4b1dc
commit
6650764e97
18
CHANGES.rst
18
CHANGES.rst
|
@ -3,6 +3,24 @@ Version 2.3.0
|
|||
|
||||
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``.
|
||||
:pr:`4947`
|
||||
- Ensure subdomains are applied with nested blueprints. :issue:`4834`
|
||||
|
|
|
@ -270,12 +270,6 @@ HTML ``<script>`` tags.
|
|||
:members:
|
||||
:member-order: bysource
|
||||
|
||||
.. autoclass:: JSONEncoder
|
||||
:members:
|
||||
|
||||
.. autoclass:: JSONDecoder
|
||||
:members:
|
||||
|
||||
.. automodule:: flask.json.tag
|
||||
|
||||
|
||||
|
|
|
@ -65,18 +65,6 @@ Builtin Configuration Values
|
|||
|
||||
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
|
||||
|
||||
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``
|
||||
|
||||
.. 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
|
||||
|
||||
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
|
||||
Removed ``PRESERVE_CONTEXT_ON_EXCEPTION``.
|
||||
|
||||
.. versionchanged:: 2.2
|
||||
``JSON_AS_ASCII``, ``JSON_SORT_KEYS``,
|
||||
``JSONIFY_MIMETYPE``, and ``JSONIFY_PRETTYPRINT_REGULAR`` will be
|
||||
removed in Flask 2.3. The default ``app.json`` provider has
|
||||
.. versionchanged:: 2.3
|
||||
``JSON_AS_ASCII``, ``JSON_SORT_KEYS``, ``JSONIFY_MIMETYPE``, and
|
||||
``JSONIFY_PRETTYPRINT_REGULAR`` were removed. The default ``app.json`` provider has
|
||||
equivalent attributes instead.
|
||||
|
||||
.. versionchanged:: 2.2
|
||||
``ENV`` will be removed in Flask 2.3. Use ``--debug`` instead.
|
||||
.. versionchanged:: 2.3
|
||||
``ENV`` was removed.
|
||||
|
||||
|
||||
Configuring from Python Files
|
||||
|
|
|
@ -51,7 +51,7 @@ def __getattr__(name):
|
|||
from .globals import __app_ctx_stack
|
||||
|
||||
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,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
@ -62,7 +62,7 @@ def __getattr__(name):
|
|||
from .globals import __request_ctx_stack
|
||||
|
||||
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,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
|
340
src/flask/app.py
340
src/flask/app.py
|
@ -1,6 +1,5 @@
|
|||
import functools
|
||||
import inspect
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
@ -75,9 +74,6 @@ if t.TYPE_CHECKING: # pragma: no cover
|
|||
from .testing import FlaskClient
|
||||
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", bound=ft.ShellContextProcessorCallable
|
||||
)
|
||||
|
@ -274,36 +270,6 @@ class Flask(Scaffold):
|
|||
#: :data:`SECRET_KEY` configuration key. Defaults to ``None``.
|
||||
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
|
||||
#: date of a permanent session. The default is 31 days which makes a
|
||||
#: permanent session survive for roughly one month.
|
||||
|
@ -315,152 +281,6 @@ class Flask(Scaffold):
|
|||
"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
|
||||
"""A subclass of :class:`~flask.json.provider.JSONProvider`. An
|
||||
instance is created and assigned to :attr:`app.json` when creating
|
||||
|
@ -487,7 +307,6 @@ class Flask(Scaffold):
|
|||
#: Default configuration parameters.
|
||||
default_config = ImmutableDict(
|
||||
{
|
||||
"ENV": None,
|
||||
"DEBUG": None,
|
||||
"TESTING": False,
|
||||
"PROPAGATE_EXCEPTIONS": None,
|
||||
|
@ -509,10 +328,6 @@ class Flask(Scaffold):
|
|||
"TRAP_HTTP_EXCEPTIONS": False,
|
||||
"EXPLAIN_TEMPLATE_LOADING": False,
|
||||
"PREFERRED_URL_SCHEME": "http",
|
||||
"JSON_AS_ASCII": None,
|
||||
"JSON_SORT_KEYS": None,
|
||||
"JSONIFY_PRETTYPRINT_REGULAR": None,
|
||||
"JSONIFY_MIMETYPE": None,
|
||||
"TEMPLATES_AUTO_RELOAD": None,
|
||||
"MAX_COOKIE_SIZE": 4093,
|
||||
}
|
||||
|
@ -625,17 +440,6 @@ class Flask(Scaffold):
|
|||
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
|
||||
#: is destroyed. Since the application context is also torn down
|
||||
#: 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 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
|
||||
def logger(self) -> logging.Logger:
|
||||
"""A standard Python :class:`~logging.Logger` for the app, with
|
||||
|
@ -827,7 +609,6 @@ class Flask(Scaffold):
|
|||
if instance_relative:
|
||||
root_path = self.instance_path
|
||||
defaults = dict(self.default_config)
|
||||
defaults["ENV"] = os.environ.get("FLASK_ENV") or "production"
|
||||
defaults["DEBUG"] = get_debug_flag()
|
||||
return self.config_class(root_path, defaults)
|
||||
|
||||
|
@ -868,42 +649,6 @@ class Flask(Scaffold):
|
|||
"""
|
||||
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:
|
||||
"""Create the Jinja environment based on :attr:`jinja_options`
|
||||
and the various Jinja-related methods of the app. Changing
|
||||
|
@ -1010,40 +755,6 @@ class Flask(Scaffold):
|
|||
rv.update(processor())
|
||||
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
|
||||
def debug(self) -> bool:
|
||||
"""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):
|
||||
cli.load_dotenv()
|
||||
|
||||
# if set, let env vars override previous values
|
||||
if "FLASK_ENV" 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:
|
||||
# if set, env var overrides existing value
|
||||
if "FLASK_DEBUG" in os.environ:
|
||||
self.debug = get_debug_flag()
|
||||
|
||||
# debug passed to method overrides all other sources
|
||||
|
@ -1479,32 +1182,6 @@ class Flask(Scaffold):
|
|||
"""
|
||||
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
|
||||
def teardown_appcontext(self, f: T_teardown) -> T_teardown:
|
||||
"""Registers a function to be called when the application
|
||||
|
@ -1682,7 +1359,7 @@ class Flask(Scaffold):
|
|||
|
||||
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
|
||||
display it. Otherwise, the original exception is logged, and
|
||||
an :exc:`~werkzeug.exceptions.InternalServerError` is returned.
|
||||
|
@ -1805,16 +1482,7 @@ class Flask(Scaffold):
|
|||
|
||||
.. 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:
|
||||
request_started.send(self)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import json
|
||||
import os
|
||||
import typing as t
|
||||
from collections import defaultdict
|
||||
|
@ -15,9 +14,6 @@ if t.TYPE_CHECKING: # pragma: no cover
|
|||
|
||||
DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable]
|
||||
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_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable)
|
||||
T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable)
|
||||
|
@ -173,77 +169,6 @@ class Blueprint(Scaffold):
|
|||
|
||||
_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__(
|
||||
self,
|
||||
name: str,
|
||||
|
@ -361,6 +286,10 @@ class Blueprint(Scaffold):
|
|||
.. versionchanged:: 2.3
|
||||
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
|
||||
Nested blueprints are registered with their dotted name.
|
||||
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
|
||||
blueprint to be registered multiple times with unique names
|
||||
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", "")
|
||||
self_name = options.get("name", self.name)
|
||||
|
@ -634,29 +559,6 @@ class Blueprint(Scaffold):
|
|||
)
|
||||
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
|
||||
def after_app_request(self, f: T_after_request) -> T_after_request:
|
||||
"""Like :meth:`after_request`, but after every request, not only those handled
|
||||
|
|
|
@ -17,30 +17,17 @@ class _FakeStack:
|
|||
self.name = name
|
||||
self.cv = cv
|
||||
|
||||
def _warn(self):
|
||||
@property
|
||||
def top(self) -> t.Optional[t.Any]:
|
||||
import warnings
|
||||
|
||||
warnings.warn(
|
||||
f"'_{self.name}_ctx_stack' is deprecated and will be"
|
||||
" removed in Flask 2.3. Use 'g' to store data, or"
|
||||
f" '{self.name}_ctx' to access the current context.",
|
||||
f"'_{self.name}_ctx_stack' is deprecated and will be removed in Flask 2.4."
|
||||
f" Use 'g' to store data, or '{self.name}_ctx' to access the current"
|
||||
" context.",
|
||||
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)
|
||||
|
||||
|
||||
|
@ -88,7 +75,7 @@ def __getattr__(name: str) -> t.Any:
|
|||
import warnings
|
||||
|
||||
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,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
@ -98,7 +85,7 @@ def __getattr__(name: str) -> t.Any:
|
|||
import warnings
|
||||
|
||||
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,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
|
|
@ -25,45 +25,12 @@ if t.TYPE_CHECKING: # pragma: no cover
|
|||
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:
|
||||
"""Get whether debug mode should be enabled for the app, indicated by the
|
||||
:envvar:`FLASK_DEBUG` environment variable. The default is ``False``.
|
||||
"""
|
||||
val = os.environ.get("FLASK_DEBUG")
|
||||
|
||||
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"}
|
||||
return bool(val and val.lower() not in {"0", "false", "no"})
|
||||
|
||||
|
||||
def get_load_dotenv(default: bool = True) -> bool:
|
||||
|
|
|
@ -3,85 +3,14 @@ from __future__ import annotations
|
|||
import json as _json
|
||||
import typing as t
|
||||
|
||||
from jinja2.utils import htmlsafe_json_dumps as _jinja_htmlsafe_dumps
|
||||
|
||||
from ..globals import current_app
|
||||
from .provider import _default
|
||||
|
||||
if t.TYPE_CHECKING: # pragma: no cover
|
||||
from ..app import Flask
|
||||
from ..wrappers import Response
|
||||
|
||||
|
||||
class JSONEncoder(_json.JSONEncoder):
|
||||
"""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:
|
||||
def dumps(obj: t.Any, **kwargs: t.Any) -> str:
|
||||
"""Serialize data as JSON.
|
||||
|
||||
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 kwargs: Arguments passed to the ``dumps`` implementation.
|
||||
|
||||
.. versionchanged:: 2.3
|
||||
The ``app`` parameter was removed.
|
||||
|
||||
.. versionchanged:: 2.2
|
||||
Calls ``current_app.json.dumps``, allowing an app to override
|
||||
the behavior.
|
||||
|
||||
.. versionchanged:: 2.2
|
||||
The ``app`` parameter will be removed in Flask 2.3.
|
||||
|
||||
.. versionchanged:: 2.0.2
|
||||
: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
|
||||
context for configuration.
|
||||
"""
|
||||
if app is not None:
|
||||
import warnings
|
||||
|
||||
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)
|
||||
if current_app:
|
||||
return current_app.json.dumps(obj, **kwargs)
|
||||
|
||||
kwargs.setdefault("default", _default)
|
||||
return _json.dumps(obj, **kwargs)
|
||||
|
||||
|
||||
def dump(
|
||||
obj: t.Any, fp: t.IO[str], *, app: Flask | None = None, **kwargs: t.Any
|
||||
) -> None:
|
||||
def dump(obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None:
|
||||
"""Serialize data as JSON and write to a file.
|
||||
|
||||
If :data:`~flask.current_app` is available, it will use its
|
||||
|
@ -141,37 +56,25 @@ def dump(
|
|||
encoding to be valid JSON.
|
||||
:param kwargs: Arguments passed to the ``dump`` implementation.
|
||||
|
||||
.. versionchanged:: 2.3
|
||||
The ``app`` parameter was removed.
|
||||
|
||||
.. versionchanged:: 2.2
|
||||
Calls ``current_app.json.dump``, allowing an app to override
|
||||
the behavior.
|
||||
|
||||
.. versionchanged:: 2.2
|
||||
The ``app`` parameter will be removed in Flask 2.3.
|
||||
|
||||
.. versionchanged:: 2.0
|
||||
Writing to a binary file, and the ``encoding`` argument, will be
|
||||
removed in Flask 2.1.
|
||||
"""
|
||||
if app is not None:
|
||||
import warnings
|
||||
|
||||
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)
|
||||
if current_app:
|
||||
current_app.json.dump(obj, fp, **kwargs)
|
||||
else:
|
||||
kwargs.setdefault("default", _default)
|
||||
_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.
|
||||
|
||||
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 kwargs: Arguments passed to the ``loads`` implementation.
|
||||
|
||||
.. versionchanged:: 2.3
|
||||
The ``app`` parameter was removed.
|
||||
|
||||
.. versionchanged:: 2.2
|
||||
Calls ``current_app.json.loads``, allowing an app to override
|
||||
the behavior.
|
||||
|
||||
.. versionchanged:: 2.2
|
||||
The ``app`` parameter will be removed in Flask 2.3.
|
||||
|
||||
.. versionchanged:: 2.0
|
||||
``encoding`` will be removed in Flask 2.1. The data must be a
|
||||
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
|
||||
context for configuration.
|
||||
"""
|
||||
if app is not None:
|
||||
import warnings
|
||||
|
||||
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)
|
||||
if current_app:
|
||||
return current_app.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.
|
||||
|
||||
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 kwargs: Arguments passed to the ``load`` implementation.
|
||||
|
||||
.. versionchanged:: 2.3
|
||||
The ``app`` parameter was removed.
|
||||
|
||||
.. versionchanged:: 2.2
|
||||
Calls ``current_app.json.load``, allowing an app to override
|
||||
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
|
||||
mode, or binary mode with UTF-8 bytes.
|
||||
"""
|
||||
if app is not None:
|
||||
import warnings
|
||||
|
||||
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)
|
||||
if current_app:
|
||||
return current_app.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:
|
||||
"""Serialize the given arguments as JSON, and return a
|
||||
:class:`~flask.Response` object with the ``application/json``
|
||||
|
|
|
@ -10,8 +10,6 @@ from datetime import date
|
|||
|
||||
from werkzeug.http import http_date
|
||||
|
||||
from ..globals import request
|
||||
|
||||
if t.TYPE_CHECKING: # pragma: no cover
|
||||
from ..app import Flask
|
||||
from ..wrappers import Response
|
||||
|
@ -176,57 +174,9 @@ class DefaultJSONProvider(JSONProvider):
|
|||
:param obj: The data to serialize.
|
||||
: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)
|
||||
else:
|
||||
kwargs.setdefault("default", self.default)
|
||||
|
||||
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)
|
||||
kwargs.setdefault("default", self.default)
|
||||
kwargs.setdefault("ensure_ascii", self.ensure_ascii)
|
||||
kwargs.setdefault("sort_keys", self.sort_keys)
|
||||
return json.dumps(obj, **kwargs)
|
||||
|
||||
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 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)
|
||||
|
||||
def response(self, *args: t.Any, **kwargs: t.Any) -> Response:
|
||||
|
@ -272,39 +205,12 @@ class DefaultJSONProvider(JSONProvider):
|
|||
"""
|
||||
obj = self._prepare_response_obj(args, kwargs)
|
||||
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:
|
||||
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:
|
||||
if (self.compact is None and self._app.debug) or self.compact is False:
|
||||
dump_args.setdefault("indent", 2)
|
||||
else:
|
||||
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(
|
||||
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 json
|
||||
import os
|
||||
import pathlib
|
||||
import pkgutil
|
||||
|
@ -74,20 +73,6 @@ class Scaffold:
|
|||
_static_folder: 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__(
|
||||
self,
|
||||
import_name: str,
|
||||
|
|
|
@ -20,7 +20,6 @@ def _standard_os_environ():
|
|||
out = (
|
||||
(os.environ, "FLASK_ENV_FILE", monkeypatch.notset),
|
||||
(os.environ, "FLASK_APP", monkeypatch.notset),
|
||||
(os.environ, "FLASK_ENV", monkeypatch.notset),
|
||||
(os.environ, "FLASK_DEBUG", monkeypatch.notset),
|
||||
(os.environ, "FLASK_RUN_FROM_CLI", 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():
|
||||
app_first_called = False
|
||||
app_before_called = False
|
||||
app_after_called = False
|
||||
bp_before_called = False
|
||||
|
@ -107,13 +106,6 @@ def test_async_before_after_request():
|
|||
def index():
|
||||
return ""
|
||||
|
||||
with pytest.deprecated_call():
|
||||
|
||||
@app.before_first_request
|
||||
async def before_first():
|
||||
nonlocal app_first_called
|
||||
app_first_called = True
|
||||
|
||||
@app.before_request
|
||||
async def before():
|
||||
nonlocal app_before_called
|
||||
|
@ -146,7 +138,6 @@ def test_async_before_after_request():
|
|||
|
||||
test_client = app.test_client()
|
||||
test_client.get("/")
|
||||
assert app_first_called
|
||||
assert app_before_called
|
||||
assert app_after_called
|
||||
test_client.get("/bp/")
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
import gc
|
||||
import re
|
||||
import time
|
||||
import uuid
|
||||
import warnings
|
||||
import weakref
|
||||
from datetime import datetime
|
||||
from datetime import timezone
|
||||
from platform import python_implementation
|
||||
from threading import Thread
|
||||
|
||||
import pytest
|
||||
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)
|
||||
|
||||
|
||||
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):
|
||||
app.config["DEBUG"] = True
|
||||
|
||||
|
|
|
@ -722,12 +722,6 @@ def test_app_request_processing(app, client):
|
|||
bp = flask.Blueprint("bp", __name__)
|
||||
evts = []
|
||||
|
||||
with pytest.deprecated_call():
|
||||
|
||||
@bp.before_app_first_request
|
||||
def before_first_request():
|
||||
evts.append("first")
|
||||
|
||||
@bp.before_app_request
|
||||
def before_app():
|
||||
evts.append("before")
|
||||
|
@ -755,12 +749,12 @@ def test_app_request_processing(app, client):
|
|||
# first request
|
||||
resp = client.get("/").data
|
||||
assert resp == b"request|after"
|
||||
assert evts == ["first", "before", "after", "teardown"]
|
||||
assert evts == ["before", "after", "teardown"]
|
||||
|
||||
# second request
|
||||
resp = client.get("/").data
|
||||
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):
|
||||
|
|
|
@ -302,24 +302,18 @@ class TestStreaming:
|
|||
|
||||
class TestHelpers:
|
||||
@pytest.mark.parametrize(
|
||||
"debug, expected_flag, expected_default_flag",
|
||||
("debug", "expect"),
|
||||
[
|
||||
("", False, False),
|
||||
("0", False, False),
|
||||
("False", False, False),
|
||||
("No", False, False),
|
||||
("True", True, True),
|
||||
("", False),
|
||||
("0", False),
|
||||
("False", False),
|
||||
("No", False),
|
||||
("True", True),
|
||||
],
|
||||
)
|
||||
def test_get_debug_flag(
|
||||
self, monkeypatch, debug, expected_flag, expected_default_flag
|
||||
):
|
||||
def test_get_debug_flag(self, monkeypatch, debug, expect):
|
||||
monkeypatch.setenv("FLASK_DEBUG", debug)
|
||||
if expected_flag is None:
|
||||
assert get_debug_flag() is None
|
||||
else:
|
||||
assert get_debug_flag() == expected_flag
|
||||
assert get_debug_flag() == expected_default_flag
|
||||
assert get_debug_flag() == expect
|
||||
|
||||
def test_make_response(self):
|
||||
app = flask.Flask(__name__)
|
||||
|
|
Loading…
Reference in New Issue