|
|
|
@ -8,10 +8,11 @@
|
|
|
|
|
:copyright: (c) 2012 by Armin Ronacher. |
|
|
|
|
:license: BSD, see LICENSE for more details. |
|
|
|
|
""" |
|
|
|
|
import io |
|
|
|
|
import uuid |
|
|
|
|
from datetime import datetime |
|
|
|
|
from .globals import current_app, request |
|
|
|
|
from ._compat import text_type |
|
|
|
|
from ._compat import text_type, PY2 |
|
|
|
|
|
|
|
|
|
from werkzeug.http import http_date |
|
|
|
|
|
|
|
|
@ -33,6 +34,20 @@ __all__ = ['dump', 'dumps', 'load', 'loads', 'htmlsafe_dump',
|
|
|
|
|
'jsonify'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _wrap_reader_for_text(fp, encoding): |
|
|
|
|
if isinstance(fp.read(0), bytes): |
|
|
|
|
fp = io.TextIOWrapper(io.BufferedReader(fp), encoding) |
|
|
|
|
return fp |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _wrap_writer_for_text(fp, encoding): |
|
|
|
|
try: |
|
|
|
|
fp.write('') |
|
|
|
|
except TypeError: |
|
|
|
|
fp = io.TextIOWrapper(fp, encoding) |
|
|
|
|
return fp |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|
@ -100,13 +115,20 @@ def dumps(obj, **kwargs):
|
|
|
|
|
and can be overriden by the simplejson ``ensure_ascii`` parameter. |
|
|
|
|
""" |
|
|
|
|
_dump_arg_defaults(kwargs) |
|
|
|
|
return _json.dumps(obj, **kwargs) |
|
|
|
|
encoding = kwargs.pop('encoding', None) |
|
|
|
|
rv = _json.dumps(obj, **kwargs) |
|
|
|
|
if encoding is not None and isinstance(rv, text_type): |
|
|
|
|
rv = rv.encode(encoding) |
|
|
|
|
return rv |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def dump(obj, fp, **kwargs): |
|
|
|
|
"""Like :func:`dumps` but writes into a file object.""" |
|
|
|
|
_dump_arg_defaults(kwargs) |
|
|
|
|
return _json.dump(obj, fp, **kwargs) |
|
|
|
|
encoding = kwargs.pop('encoding', None) |
|
|
|
|
if encoding is not None: |
|
|
|
|
fp = _wrap_writer_for_text(fp, encoding) |
|
|
|
|
_json.dump(obj, fp, **kwargs) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def loads(s, **kwargs): |
|
|
|
@ -115,6 +137,8 @@ def loads(s, **kwargs):
|
|
|
|
|
application on the stack. |
|
|
|
|
""" |
|
|
|
|
_load_arg_defaults(kwargs) |
|
|
|
|
if isinstance(s, bytes): |
|
|
|
|
s = s.decode(kwargs.pop('encoding', None) or 'utf-8') |
|
|
|
|
return _json.loads(s, **kwargs) |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -122,6 +146,8 @@ def load(fp, **kwargs):
|
|
|
|
|
"""Like :func:`loads` but reads from a file object. |
|
|
|
|
""" |
|
|
|
|
_load_arg_defaults(kwargs) |
|
|
|
|
if not PY2: |
|
|
|
|
fp = _wrap_reader_for_text(fp, kwargs.pop('encoding', None) or 'utf-8') |
|
|
|
|
return _json.load(fp, **kwargs) |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -148,7 +174,7 @@ def jsonify(*args, **kwargs):
|
|
|
|
|
to this function are the same as to the :class:`dict` constructor. |
|
|
|
|
|
|
|
|
|
Example usage:: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from flask import jsonify |
|
|
|
|
|
|
|
|
|
@app.route('/_get_current_user') |
|
|
|
|