Let json.* work even without app on the stack and added tests
This commit is contained in:
parent
b146d8277a
commit
05c6502cbd
2 changed files with 42 additions and 6 deletions
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,36 @@ class JSONTestCase(FlaskTestCase):
|
|||
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'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue