mirror of https://github.com/pallets/flask.git
Merge pull request #3195 from eruvanos/json_support_dataclass
Support dataclass in JSONEncoder (if available)
This commit is contained in:
commit
b0185a6205
|
|
@ -38,6 +38,8 @@ Unreleased
|
|||
dependency to >= 0.15. :issue:`3022`
|
||||
- Support ``static_url_path`` that ends with a forward slash.
|
||||
:issue:`3134`
|
||||
- :meth:`jsonify` supports :class:`dataclasses.dataclass` objects.
|
||||
:pr:`3195`
|
||||
|
||||
.. _#2935: https://github.com/pallets/flask/issues/2935
|
||||
.. _#2957: https://github.com/pallets/flask/issues/2957
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ from jinja2 import Markup
|
|||
# depend anyways.
|
||||
from itsdangerous import json as _json
|
||||
|
||||
try:
|
||||
import dataclasses
|
||||
except ImportError:
|
||||
dataclasses = None
|
||||
|
||||
# Figure out if simplejson escapes slashes. This behavior was changed
|
||||
# from one version to another without reason.
|
||||
|
|
@ -54,11 +58,15 @@ def _wrap_writer_for_text(fp, encoding):
|
|||
|
||||
|
||||
class JSONEncoder(_json.JSONEncoder):
|
||||
"""The default Flask JSON encoder. This one extends the default simplejson
|
||||
encoder by also supporting ``datetime`` objects, ``UUID`` as well as
|
||||
``Markup`` objects which are serialized as RFC 822 datetime strings (same
|
||||
as the HTTP date format). In order to support more data types override the
|
||||
:meth:`default` method.
|
||||
"""The default Flask JSON encoder. This one extends the default
|
||||
encoder by also supporting ``datetime``, ``UUID``, ``dataclasses``,
|
||||
and ``Markup`` objects.
|
||||
|
||||
``datetime`` objects are serialized as RFC 822 datetime strings.
|
||||
This is the same as the HTTP date format.
|
||||
|
||||
In order to support more data types, override the :meth:`default`
|
||||
method.
|
||||
"""
|
||||
|
||||
def default(self, o):
|
||||
|
|
@ -84,6 +92,8 @@ class JSONEncoder(_json.JSONEncoder):
|
|||
return http_date(o.timetuple())
|
||||
if isinstance(o, uuid.UUID):
|
||||
return str(o)
|
||||
if dataclasses and dataclasses.is_dataclass(o):
|
||||
return dataclasses.asdict(o)
|
||||
if hasattr(o, "__html__"):
|
||||
return text_type(o.__html__())
|
||||
return _json.JSONEncoder.default(self, o)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
|
@ -1289,6 +1290,14 @@ def test_jsonify_mimetype(app, req_ctx):
|
|||
assert rv.mimetype == "application/vnd.api+json"
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires Python >= 3.7")
|
||||
def test_json_dump_dataclass(app, req_ctx):
|
||||
from dataclasses import make_dataclass
|
||||
Data = make_dataclass("Data", [("name", str)])
|
||||
value = flask.json.dumps(Data("Flask"), app=app)
|
||||
value = flask.json.loads(value, app=app)
|
||||
assert value == {"name": "Flask"}
|
||||
|
||||
def test_jsonify_args_and_kwargs_check(app, req_ctx):
|
||||
with pytest.raises(TypeError) as e:
|
||||
flask.jsonify("fake args", kwargs="fake")
|
||||
|
|
|
|||
Loading…
Reference in New Issue