Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ Unreleased
it's disabled in config. Previously, only disabling worked. :issue:`5916`
- ``Flask.select_jinja_autoescape`` uses case-insensitive comparison instead
of only lower case file extensions. :pr:`6012`
- Add ``allow_nan`` attribute to ``DefaultJSONProvider`` to control whether
``NaN`` and ``Infinity`` values are allowed when serializing to JSON.
Defaults to ``True`` to preserve existing behavior. :issue:`6114`


Version 3.1.3
Expand Down
13 changes: 12 additions & 1 deletion src/flask/json/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@ class DefaultJSONProvider(JSONProvider):
or ``None`` in debug mode, it will use a non-compact representation.
"""

allow_nan = True
"""Allow ``NaN``, ``Infinity``, and ``-Infinity`` to be serialized as
the bare literals ``NaN``, ``Infinity``, and ``-Infinity``. These are
accepted by Python's :mod:`json` but are not valid JSON per
:rfc:`8259`, so strict parsers such as a browser's ``JSON.parse``
will reject them. Set this to ``False`` to raise a ``ValueError``
instead when such a value is serialized.
"""

mimetype = "application/json"
"""The mimetype set in :meth:`response`."""

Expand All @@ -168,14 +177,16 @@ def dumps(self, obj: t.Any, **kwargs: t.Any) -> str:

Keyword arguments are passed to :func:`json.dumps`. Sets some
parameter defaults from the :attr:`default`,
:attr:`ensure_ascii`, and :attr:`sort_keys` attributes.
:attr:`ensure_ascii`, :attr:`sort_keys`, and :attr:`allow_nan`
attributes.

:param obj: The data to serialize.
:param kwargs: Passed to :func:`json.dumps`.
"""
kwargs.setdefault("default", self.default)
kwargs.setdefault("ensure_ascii", self.ensure_ascii)
kwargs.setdefault("sort_keys", self.sort_keys)
kwargs.setdefault("allow_nan", self.allow_nan)
return json.dumps(obj, **kwargs)

def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any:
Expand Down
10 changes: 10 additions & 0 deletions tests/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ def test_json_as_unicode(test_value, expected, app, app_ctx):
assert rv == expected


def test_json_allow_nan(app, app_ctx):
assert app.json.allow_nan
rv = app.json.dumps(float("nan"))
assert rv == "NaN"

app.json.allow_nan = False
with pytest.raises(ValueError):
app.json.dumps(float("nan"))


def test_json_dump_to_file(app, app_ctx):
test_data = {"name": "Flask"}
out = io.StringIO()
Expand Down
Loading