diff --git a/CHANGES.rst b/CHANGES.rst index 638af3a4..44512451 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -15,6 +15,8 @@ Unreleased - Fix registering a blueprint twice with differing names. :issue:`4124` - Fix the type of ``static_folder`` to accept ``pathlib.Path``. :issue:`4150` +- ``jsonify`` handles ``decimal.Decimal`` by encoding to ``str``. + :issue:`4157` Version 2.0.1 diff --git a/src/flask/json/__init__.py b/src/flask/json/__init__.py index 5780e204..10d5123a 100644 --- a/src/flask/json/__init__.py +++ b/src/flask/json/__init__.py @@ -1,3 +1,4 @@ +import decimal import io import json as _json import typing as t @@ -47,7 +48,7 @@ class JSONEncoder(_json.JSONEncoder): """ if isinstance(o, date): return http_date(o) - if isinstance(o, uuid.UUID): + if isinstance(o, (decimal.Decimal, uuid.UUID)): return str(o) if dataclasses and dataclasses.is_dataclass(o): return dataclasses.asdict(o) @@ -117,6 +118,9 @@ def dumps(obj: t.Any, app: t.Optional["Flask"] = None, **kwargs: t.Any) -> str: or defaults. :param kwargs: Extra arguments passed to :func:`json.dumps`. + .. versionchanged:: 2.0.2 + :class:`decimal.Decimal` is supported by converting to a string. + .. versionchanged:: 2.0 ``encoding`` is deprecated and will be removed in Flask 2.1. @@ -324,6 +328,9 @@ def jsonify(*args: t.Any, **kwargs: t.Any) -> "Response": debug mode or if :data:`JSONIFY_PRETTYPRINT_REGULAR` is ``True``, the output will be formatted to be easier to read. + .. versionchanged:: 2.0.2 + :class:`decimal.Decimal` is supported by converting to a string. + .. versionchanged:: 0.11 Added support for serializing top-level arrays. This introduces a security risk in ancient browsers. See :ref:`security-json`. diff --git a/tests/test_json.py b/tests/test_json.py index fb8bdcba..9210275a 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -1,4 +1,5 @@ import datetime +import decimal import io import uuid @@ -187,6 +188,11 @@ def test_jsonify_uuid_types(app, client): assert rv_uuid == test_uuid +def test_json_decimal(): + rv = flask.json.dumps(decimal.Decimal("0.003")) + assert rv == '"0.003"' + + def test_json_attr(app, client): @app.route("/add", methods=["POST"]) def add():