Skip to content

Commit 714ccef

Browse files
committed
show deprecation warning on json_encoder/decoder access
1 parent 9a1b25f commit 714ccef

File tree

5 files changed

+167
-42
lines changed

5 files changed

+167
-42
lines changed

CHANGES.rst

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ Version 2.2.1
33

44
Unreleased
55

6+
- Setting or accessing ``json_encoder`` or ``json_decoder`` raises a
7+
deprecation warning. :issue:`4732`
8+
69

710
Version 2.2.0
811
-------------
@@ -50,18 +53,18 @@ Released 2022-08-01
5053
provider can be set to use a different JSON library.
5154
``flask.jsonify`` will call ``app.json.response``, other
5255
functions in ``flask.json`` will call corresponding functions in
53-
``app.json``. :pr:`4688`
56+
``app.json``. :pr:`4692`
5457

5558
- JSON configuration is moved to attributes on the default
5659
``app.json`` provider. ``JSON_AS_ASCII``, ``JSON_SORT_KEYS``,
5760
``JSONIFY_MIMETYPE``, and ``JSONIFY_PRETTYPRINT_REGULAR`` are
58-
deprecated. :pr:`4688`
61+
deprecated. :pr:`4692`
5962
- Setting custom ``json_encoder`` and ``json_decoder`` classes on the
6063
app or a blueprint, and the corresponding ``json.JSONEncoder`` and
6164
``JSONDecoder`` classes, are deprecated. JSON behavior can now be
62-
overridden using the ``app.json`` provider interface. :pr:`4688`
65+
overridden using the ``app.json`` provider interface. :pr:`4692`
6366
- ``json.htmlsafe_dumps`` and ``json.htmlsafe_dump`` are deprecated,
64-
the function is built-in to Jinja now. :pr:`4688`
67+
the function is built-in to Jinja now. :pr:`4692`
6568
- Refactor ``register_error_handler`` to consolidate error checking.
6669
Rewrite some error messages to be more consistent. :issue:`4559`
6770
- Use Blueprint decorators and functions intended for setup after

src/flask/app.py

Lines changed: 80 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import functools
22
import inspect
3+
import json
34
import logging
45
import os
56
import sys
@@ -379,25 +380,86 @@ def use_x_sendfile(self, value: bool) -> None:
379380
)
380381
self.config["USE_X_SENDFILE"] = value
381382

382-
#: The JSON encoder class to use. Defaults to
383-
#: :class:`~flask.json.JSONEncoder`.
384-
#:
385-
#: .. deprecated:: 2.2
386-
#: Will be removed in Flask 2.3. Customize
387-
#: :attr:`json_provider_class` instead.
388-
#:
389-
#: .. versionadded:: 0.10
390-
json_encoder: None = None
383+
_json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
384+
_json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
391385

392-
#: The JSON decoder class to use. Defaults to
393-
#: :class:`~flask.json.JSONDecoder`.
394-
#:
395-
#: .. deprecated:: 2.2
396-
#: Will be removed in Flask 2.3. Customize
397-
#: :attr:`json_provider_class` instead.
398-
#:
399-
#: .. versionadded:: 0.10
400-
json_decoder: None = None
386+
@property # type: ignore[override]
387+
def json_encoder(self) -> t.Type[json.JSONEncoder]: # type: ignore[override]
388+
"""The JSON encoder class to use. Defaults to
389+
:class:`~flask.json.JSONEncoder`.
390+
391+
.. deprecated:: 2.2
392+
Will be removed in Flask 2.3. Customize
393+
:attr:`json_provider_class` instead.
394+
395+
.. versionadded:: 0.10
396+
"""
397+
import warnings
398+
399+
warnings.warn(
400+
"'app.json_encoder' is deprecated and will be removed in Flask 2.3."
401+
" Customize 'app.json_provider_class' or 'app.json' instead.",
402+
DeprecationWarning,
403+
stacklevel=2,
404+
)
405+
406+
if self._json_encoder is None:
407+
from . import json
408+
409+
return json.JSONEncoder
410+
411+
return self._json_encoder
412+
413+
@json_encoder.setter
414+
def json_encoder(self, value: t.Type[json.JSONEncoder]) -> None:
415+
import warnings
416+
417+
warnings.warn(
418+
"'app.json_encoder' is deprecated and will be removed in Flask 2.3."
419+
" Customize 'app.json_provider_class' or 'app.json' instead.",
420+
DeprecationWarning,
421+
stacklevel=2,
422+
)
423+
self._json_encoder = value
424+
425+
@property # type: ignore[override]
426+
def json_decoder(self) -> t.Type[json.JSONDecoder]: # type: ignore[override]
427+
"""The JSON decoder class to use. Defaults to
428+
:class:`~flask.json.JSONDecoder`.
429+
430+
.. deprecated:: 2.2
431+
Will be removed in Flask 2.3. Customize
432+
:attr:`json_provider_class` instead.
433+
434+
.. versionadded:: 0.10
435+
"""
436+
import warnings
437+
438+
warnings.warn(
439+
"'app.json_decoder' is deprecated and will be removed in Flask 2.3."
440+
" Customize 'app.json_provider_class' or 'app.json' instead.",
441+
DeprecationWarning,
442+
stacklevel=2,
443+
)
444+
445+
if self._json_decoder is None:
446+
from . import json
447+
448+
return json.JSONDecoder
449+
450+
return self._json_decoder
451+
452+
@json_decoder.setter
453+
def json_decoder(self, value: t.Type[json.JSONDecoder]) -> None:
454+
import warnings
455+
456+
warnings.warn(
457+
"'app.json_decoder' is deprecated and will be removed in Flask 2.3."
458+
" Customize 'app.json_provider_class' or 'app.json' instead.",
459+
DeprecationWarning,
460+
stacklevel=2,
461+
)
462+
self._json_decoder = value
401463

402464
json_provider_class: t.Type[JSONProvider] = DefaultJSONProvider
403465
"""A subclass of :class:`~flask.json.provider.JSONProvider`. An

src/flask/blueprints.py

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
import os
23
import typing as t
34
from collections import defaultdict
@@ -172,18 +173,76 @@ class Blueprint(Scaffold):
172173

173174
_got_registered_once = False
174175

175-
#: Blueprint local JSON encoder class to use. Set to ``None`` to use
176-
#: the app's :class:`~flask.Flask.json_encoder`.
177-
#:
178-
#: .. deprecated:: 2.2
179-
#: Will be removed in Flask 2.3.
180-
json_encoder: None = None
181-
#: Blueprint local JSON decoder class to use. Set to ``None`` to use
182-
#: the app's :class:`~flask.Flask.json_decoder`.
183-
#:
184-
#: .. deprecated:: 2.2
185-
#: Will be removed in Flask 2.3.
186-
json_decoder: None = None
176+
_json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
177+
_json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
178+
179+
@property # type: ignore[override]
180+
def json_encoder( # type: ignore[override]
181+
self,
182+
) -> t.Union[t.Type[json.JSONEncoder], None]:
183+
"""Blueprint-local JSON encoder class to use. Set to ``None`` to use the app's.
184+
185+
.. deprecated:: 2.2
186+
Will be removed in Flask 2.3. Customize
187+
:attr:`json_provider_class` instead.
188+
189+
.. versionadded:: 0.10
190+
"""
191+
import warnings
192+
193+
warnings.warn(
194+
"'bp.json_encoder' is deprecated and will be removed in Flask 2.3."
195+
" Customize 'app.json_provider_class' or 'app.json' instead.",
196+
DeprecationWarning,
197+
stacklevel=2,
198+
)
199+
return self._json_encoder
200+
201+
@json_encoder.setter
202+
def json_encoder(self, value: t.Union[t.Type[json.JSONEncoder], None]) -> None:
203+
import warnings
204+
205+
warnings.warn(
206+
"'bp.json_encoder' is deprecated and will be removed in Flask 2.3."
207+
" Customize 'app.json_provider_class' or 'app.json' instead.",
208+
DeprecationWarning,
209+
stacklevel=2,
210+
)
211+
self._json_encoder = value
212+
213+
@property # type: ignore[override]
214+
def json_decoder( # type: ignore[override]
215+
self,
216+
) -> t.Union[t.Type[json.JSONDecoder], None]:
217+
"""Blueprint-local JSON decoder class to use. Set to ``None`` to use the app's.
218+
219+
.. deprecated:: 2.2
220+
Will be removed in Flask 2.3. Customize
221+
:attr:`json_provider_class` instead.
222+
223+
.. versionadded:: 0.10
224+
"""
225+
import warnings
226+
227+
warnings.warn(
228+
"'bp.json_decoder' is deprecated and will be removed in Flask 2.3."
229+
" Customize 'app.json_provider_class' or 'app.json' instead.",
230+
DeprecationWarning,
231+
stacklevel=2,
232+
)
233+
return self._json_decoder
234+
235+
@json_decoder.setter
236+
def json_decoder(self, value: t.Union[t.Type[json.JSONDecoder], None]) -> None:
237+
import warnings
238+
239+
warnings.warn(
240+
"'bp.json_decoder' is deprecated and will be removed in Flask 2.3."
241+
" Customize 'app.json_provider_class' or 'app.json' instead.",
242+
DeprecationWarning,
243+
stacklevel=2,
244+
)
245+
self._json_decoder = value
187246

188247
def __init__(
189248
self,

src/flask/json/provider.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,11 @@ def dumps(self, obj: t.Any, **kwargs: t.Any) -> str:
176176
:param obj: The data to serialize.
177177
:param kwargs: Passed to :func:`json.dumps`.
178178
"""
179-
cls = self._app.json_encoder
179+
cls = self._app._json_encoder
180180
bp = self._app.blueprints.get(request.blueprint) if request else None
181181

182-
if bp is not None and bp.json_encoder is not None:
183-
cls = bp.json_encoder
182+
if bp is not None and bp._json_encoder is not None:
183+
cls = bp._json_encoder
184184

185185
if cls is not None:
186186
import warnings
@@ -235,11 +235,11 @@ def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any:
235235
:param s: Text or UTF-8 bytes.
236236
:param kwargs: Passed to :func:`json.loads`.
237237
"""
238-
cls = self._app.json_decoder
238+
cls = self._app._json_decoder
239239
bp = self._app.blueprints.get(request.blueprint) if request else None
240240

241-
if bp is not None and bp.json_decoder is not None:
242-
cls = bp.json_decoder
241+
if bp is not None and bp._json_decoder is not None:
242+
cls = bp._json_decoder
243243

244244
if cls is not None:
245245
import warnings

src/flask/scaffold.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import importlib.util
2+
import json
23
import os
34
import pathlib
45
import pkgutil
@@ -78,14 +79,14 @@ class Scaffold:
7879
#:
7980
#: .. deprecated:: 2.2
8081
#: Will be removed in Flask 2.3.
81-
json_encoder: None = None
82+
json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
8283

8384
#: JSON decoder class used by :func:`flask.json.loads`. If a
8485
#: blueprint sets this, it will be used instead of the app's value.
8586
#:
8687
#: .. deprecated:: 2.2
8788
#: Will be removed in Flask 2.3.
88-
json_decoder: None = None
89+
json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
8990

9091
def __init__(
9192
self,

0 commit comments

Comments
 (0)