Merge branch '2.2.x'

This commit is contained in:
David Lord 2022-08-03 17:09:43 -07:00
commit 21aaf0ef9a
No known key found for this signature in database
GPG key ID: 7A1C87E3F5BC42A8
11 changed files with 186 additions and 57 deletions

View file

@ -20,7 +20,7 @@ repos:
hooks: hooks:
- id: black - id: black
- repo: https://github.com/PyCQA/flake8 - repo: https://github.com/PyCQA/flake8
rev: 5.0.2 rev: 5.0.4
hooks: hooks:
- id: flake8 - id: flake8
additional_dependencies: additional_dependencies:

View file

@ -4,6 +4,15 @@ Version 2.3.0
Unreleased Unreleased
Version 2.2.1
-------------
Released 2022-08-03
- Setting or accessing ``json_encoder`` or ``json_decoder`` raises a
deprecation warning. :issue:`4732`
Version 2.2.0 Version 2.2.0
------------- -------------
@ -50,18 +59,18 @@ Released 2022-08-01
provider can be set to use a different JSON library. provider can be set to use a different JSON library.
``flask.jsonify`` will call ``app.json.response``, other ``flask.jsonify`` will call ``app.json.response``, other
functions in ``flask.json`` will call corresponding functions in functions in ``flask.json`` will call corresponding functions in
``app.json``. :pr:`4688` ``app.json``. :pr:`4692`
- JSON configuration is moved to attributes on the default - JSON configuration is moved to attributes on the default
``app.json`` provider. ``JSON_AS_ASCII``, ``JSON_SORT_KEYS``, ``app.json`` provider. ``JSON_AS_ASCII``, ``JSON_SORT_KEYS``,
``JSONIFY_MIMETYPE``, and ``JSONIFY_PRETTYPRINT_REGULAR`` are ``JSONIFY_MIMETYPE``, and ``JSONIFY_PRETTYPRINT_REGULAR`` are
deprecated. :pr:`4688` deprecated. :pr:`4692`
- Setting custom ``json_encoder`` and ``json_decoder`` classes on the - Setting custom ``json_encoder`` and ``json_decoder`` classes on the
app or a blueprint, and the corresponding ``json.JSONEncoder`` and app or a blueprint, and the corresponding ``json.JSONEncoder`` and
``JSONDecoder`` classes, are deprecated. JSON behavior can now be ``JSONDecoder`` classes, are deprecated. JSON behavior can now be
overridden using the ``app.json`` provider interface. :pr:`4688` overridden using the ``app.json`` provider interface. :pr:`4692`
- ``json.htmlsafe_dumps`` and ``json.htmlsafe_dump`` are deprecated, - ``json.htmlsafe_dumps`` and ``json.htmlsafe_dump`` are deprecated,
the function is built-in to Jinja now. :pr:`4688` the function is built-in to Jinja now. :pr:`4692`
- Refactor ``register_error_handler`` to consolidate error checking. - Refactor ``register_error_handler`` to consolidate error checking.
Rewrite some error messages to be more consistent. :issue:`4559` Rewrite some error messages to be more consistent. :issue:`4559`
- Use Blueprint decorators and functions intended for setup after - Use Blueprint decorators and functions intended for setup after

View file

@ -16,7 +16,7 @@ click==8.1.3
# via # via
# pip-compile-multi # pip-compile-multi
# pip-tools # pip-tools
distlib==0.3.4 distlib==0.3.5
# via virtualenv # via virtualenv
filelock==3.7.1 filelock==3.7.1
# via # via
@ -24,13 +24,13 @@ filelock==3.7.1
# virtualenv # virtualenv
greenlet==1.1.2 ; python_version < "3.11" greenlet==1.1.2 ; python_version < "3.11"
# via -r requirements/tests.in # via -r requirements/tests.in
identify==2.5.1 identify==2.5.3
# via pre-commit # via pre-commit
nodeenv==1.7.0 nodeenv==1.7.0
# via pre-commit # via pre-commit
pep517==0.12.0 pep517==0.13.0
# via build # via build
pip-compile-multi==2.4.5 pip-compile-multi==2.4.6
# via -r requirements/dev.in # via -r requirements/dev.in
pip-tools==6.8.0 pip-tools==6.8.0
# via pip-compile-multi # via pip-compile-multi
@ -41,9 +41,7 @@ pre-commit==2.20.0
pyyaml==6.0 pyyaml==6.0
# via pre-commit # via pre-commit
six==1.16.0 six==1.16.0
# via # via tox
# tox
# virtualenv
toml==0.10.2 toml==0.10.2
# via # via
# pre-commit # pre-commit
@ -52,7 +50,7 @@ toposort==1.7
# via pip-compile-multi # via pip-compile-multi
tox==3.25.1 tox==3.25.1
# via -r requirements/dev.in # via -r requirements/dev.in
virtualenv==20.15.1 virtualenv==20.16.2
# via # via
# pre-commit # pre-commit
# tox # tox

View file

@ -68,5 +68,5 @@ sphinxcontrib-qthelp==1.0.3
# via sphinx # via sphinx
sphinxcontrib-serializinghtml==1.1.5 sphinxcontrib-serializinghtml==1.1.5
# via sphinx # via sphinx
urllib3==1.26.10 urllib3==1.26.11
# via requests # via requests

View file

@ -7,9 +7,9 @@
# #
asgiref==3.5.2 asgiref==3.5.2
# via -r requirements/tests.in # via -r requirements/tests.in
attrs==21.4.0 attrs==22.1.0
# via pytest # via pytest
blinker==1.4 blinker==1.5
# via -r requirements/tests.in # via -r requirements/tests.in
greenlet==1.1.2 ; python_version < "3.11" greenlet==1.1.2 ; python_version < "3.11"
# via -r requirements/tests.in # via -r requirements/tests.in

View file

@ -9,7 +9,7 @@ cffi==1.15.1
# via cryptography # via cryptography
cryptography==37.0.4 cryptography==37.0.4
# via -r requirements/typing.in # via -r requirements/typing.in
mypy==0.961 mypy==0.971
# via -r requirements/typing.in # via -r requirements/typing.in
mypy-extensions==0.4.3 mypy-extensions==0.4.3
# via mypy # via mypy
@ -21,7 +21,7 @@ types-contextvars==2.4.7
# via -r requirements/typing.in # via -r requirements/typing.in
types-dataclasses==0.6.6 types-dataclasses==0.6.6
# via -r requirements/typing.in # via -r requirements/typing.in
types-setuptools==62.6.1 types-setuptools==63.2.3
# via -r requirements/typing.in # via -r requirements/typing.in
typing-extensions==4.3.0 typing-extensions==4.3.0
# via mypy # via mypy

View file

@ -42,7 +42,7 @@ from .templating import render_template_string as render_template_string
from .templating import stream_template as stream_template from .templating import stream_template as stream_template
from .templating import stream_template_string as stream_template_string from .templating import stream_template_string as stream_template_string
__version__ = "2.2.0" __version__ = "2.2.1"
def __getattr__(name): def __getattr__(name):

View file

@ -1,5 +1,6 @@
import functools import functools
import inspect import inspect
import json
import logging import logging
import os import os
import sys import sys
@ -379,25 +380,86 @@ class Flask(Scaffold):
) )
self.config["USE_X_SENDFILE"] = value self.config["USE_X_SENDFILE"] = value
#: The JSON encoder class to use. Defaults to _json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
#: :class:`~flask.json.JSONEncoder`. _json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
#:
#: .. deprecated:: 2.2
#: Will be removed in Flask 2.3. Customize
#: :attr:`json_provider_class` instead.
#:
#: .. versionadded:: 0.10
json_encoder: None = None
#: The JSON decoder class to use. Defaults to @property # type: ignore[override]
#: :class:`~flask.json.JSONDecoder`. def json_encoder(self) -> t.Type[json.JSONEncoder]: # type: ignore[override]
#: """The JSON encoder class to use. Defaults to
#: .. deprecated:: 2.2 :class:`~flask.json.JSONEncoder`.
#: Will be removed in Flask 2.3. Customize
#: :attr:`json_provider_class` instead. .. deprecated:: 2.2
#: Will be removed in Flask 2.3. Customize
#: .. versionadded:: 0.10 :attr:`json_provider_class` instead.
json_decoder: None = None
.. 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]: # type: ignore[override]
"""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

View file

@ -1,3 +1,4 @@
import json
import os import os
import typing as t import typing as t
from collections import defaultdict from collections import defaultdict
@ -172,18 +173,76 @@ class Blueprint(Scaffold):
_got_registered_once = False _got_registered_once = False
#: Blueprint local JSON encoder class to use. Set to ``None`` to use _json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
#: the app's :class:`~flask.Flask.json_encoder`. _json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
#:
#: .. deprecated:: 2.2 @property # type: ignore[override]
#: Will be removed in Flask 2.3. def json_encoder( # type: ignore[override]
json_encoder: None = None self,
#: Blueprint local JSON decoder class to use. Set to ``None`` to use ) -> t.Union[t.Type[json.JSONEncoder], None]:
#: the app's :class:`~flask.Flask.json_decoder`. """Blueprint-local JSON encoder class to use. Set to ``None`` to use the app's.
#:
#: .. deprecated:: 2.2 .. deprecated:: 2.2
#: Will be removed in Flask 2.3. Will be removed in Flask 2.3. Customize
json_decoder: None = None :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 # type: ignore[override]
def json_decoder( # type: ignore[override]
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,

View file

@ -176,11 +176,11 @@ 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 cls = self._app._json_encoder
bp = self._app.blueprints.get(request.blueprint) if request else None bp = self._app.blueprints.get(request.blueprint) if request else None
if bp is not None and bp.json_encoder is not None: if bp is not None and bp._json_encoder is not None:
cls = bp.json_encoder cls = bp._json_encoder
if cls is not None: if cls is not None:
import warnings import warnings
@ -235,11 +235,11 @@ 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 cls = self._app._json_decoder
bp = self._app.blueprints.get(request.blueprint) if request else None bp = self._app.blueprints.get(request.blueprint) if request else None
if bp is not None and bp.json_decoder is not None: if bp is not None and bp._json_decoder is not None:
cls = bp.json_decoder cls = bp._json_decoder
if cls is not None: if cls is not None:
import warnings import warnings

View file

@ -1,4 +1,5 @@
import importlib.util import importlib.util
import json
import os import os
import pathlib import pathlib
import pkgutil import pkgutil
@ -78,14 +79,14 @@ class Scaffold:
#: #:
#: .. deprecated:: 2.2 #: .. deprecated:: 2.2
#: Will be removed in Flask 2.3. #: Will be removed in Flask 2.3.
json_encoder: None = None json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
#: JSON decoder class used by :func:`flask.json.loads`. If a #: JSON decoder class used by :func:`flask.json.loads`. If a
#: blueprint sets this, it will be used instead of the app's value. #: blueprint sets this, it will be used instead of the app's value.
#: #:
#: .. deprecated:: 2.2 #: .. deprecated:: 2.2
#: Will be removed in Flask 2.3. #: Will be removed in Flask 2.3.
json_decoder: None = None json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
def __init__( def __init__(
self, self,