Skip to content

Commit 6cb1b41

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

File tree

4 files changed

+160
-40
lines changed

4 files changed

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

188243
def __init__(
189244
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

0 commit comments

Comments
 (0)