Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Let json.* work even without app on the stack and added tests

  • Loading branch information...
commit 05c6502cbde016f0475233faa0c6364634cccac9 1 parent b146d82
@mitsuhiko authored
Showing with 42 additions and 6 deletions.
  1. +12 −6 flask/json.py
  2. +30 −0 flask/testsuite/helpers.py
View
18 flask/json.py
@@ -70,30 +70,36 @@ class JSONDecoder(_json.JSONDecoder):
def dumps(obj, **kwargs):
"""Serialize ``obj`` to a JSON formatted ``str`` by using the application's
- configured encoder (:attr:`~flask.Flask.json_encoder`).
+ configured encoder (:attr:`~flask.Flask.json_encoder`) if there is an
+ application on the stack.
"""
- kwargs.setdefault('cls', current_app.json_encoder)
+ if current_app:
+ kwargs.setdefault('cls', current_app.json_encoder)
return _json.dumps(obj, **kwargs)
def dump(obj, fp, **kwargs):
"""Like :func:`dumps` but writes into a file object."""
- kwargs.setdefault('cls', current_app.json_encoder)
+ if current_app:
+ kwargs.setdefault('cls', current_app.json_encoder)
return _json.dump(obj, fp, **kwargs)
def loads(s, **kwargs):
"""Unserialize a JSON object from a string ``s`` by using the application's
- configured decoder (:attr:`~flask.Flask.json_decoder`).
+ configured decoder (:attr:`~flask.Flask.json_decoder`) if there is an
+ application on the stack.
"""
- kwargs.setdefault('cls', current_app.json_decoder)
+ if current_app:
+ kwargs.setdefault('cls', current_app.json_decoder)
return _json.loads(s, **kwargs)
def load(fp, **kwargs):
"""Like :func:`loads` but reads from a file object.
"""
- kwargs.setdefault('cls', current_app.json_decoder)
+ if current_app:
+ kwargs.setdefault('cls', current_app.json_decoder)
return _json.load(fp, **kwargs)
View
30 flask/testsuite/helpers.py
@@ -100,6 +100,36 @@ def test_template_escaping(self):
rv = render('{{ "<!--<script>"|tojson|safe }}')
self.assert_equal(rv, '"<\\u0021--<script>"')
+ def test_json_customization(self):
+ class X(object):
+ def __init__(self, val):
+ self.val = val
+ class MyEncoder(flask.json.JSONEncoder):
+ def default(self, o):
+ if isinstance(o, X):
+ return '<%d>' % o.val
+ return flask.json.JSONEncoder.default(self, o)
+ class MyDecoder(flask.json.JSONDecoder):
+ def __init__(self, *args, **kwargs):
+ kwargs.setdefault('object_hook', self.object_hook)
+ flask.json.JSONDecoder.__init__(self, *args, **kwargs)
+ def object_hook(self, obj):
+ if len(obj) == 1 and '_foo' in obj:
+ return X(obj['_foo'])
+ return obj
+ app = flask.Flask(__name__)
+ app.testing = True
+ app.json_encoder = MyEncoder
+ app.json_decoder = MyDecoder
+ @app.route('/', methods=['POST'])
+ def index():
+ return flask.json.dumps(flask.request.json['x'])
+ c = app.test_client()
+ rv = c.post('/', data=flask.json.dumps({
+ 'x': {'_foo': 42}
+ }), content_type='application/json')
+ self.assertEqual(rv.data, '"<42>"')
+
def test_modified_url_encoding(self):
class ModifiedRequest(flask.Request):
url_charset = 'euc-kr'
Please sign in to comment.
Something went wrong with that request. Please try again.