Add jsonutils.dump_as_bytes() function for py3

The jsonutils.dumps() function returns bytes on Python 2 and Unicode
oon Python 3. In some cases, we always want bytes. For example, a
HTTP body must be bytes. This function avoids an condition call to
.encode() depending on the type or on the Python version.

For example:

    body = jsonutils.dumps(data)
    if isinstance(body, six.text_type):
        body = body.encode('utf-8')

can be replaced with:

    body = jsonutils.dump_as_bytes(data)

Change-Id: Ib9d8f1309982762b54d8a91b1f24f64d0ae6723a
This commit is contained in:
Victor Stinner 2015-09-23 14:20:33 +02:00
parent f49cc0289b
commit 92f2111b26
2 changed files with 25 additions and 0 deletions

View File

@ -179,12 +179,34 @@ def dumps(obj, default=to_primitive, **kwargs):
:param kwargs: extra named parameters, please see documentation \
of `json.dumps <https://docs.python.org/2/library/json.html#basic-usage>`_
:returns: json formatted string
Use dump_as_bytes() to ensure that the result type is ``bytes`` on Python 2
and Python 3.
"""
if is_simplejson:
kwargs['namedtuple_as_object'] = False
return json.dumps(obj, default=default, **kwargs)
def dump_as_bytes(obj, default=to_primitive, encoding='utf-8', **kwargs):
"""Serialize ``obj`` to a JSON formatted ``bytes``.
:param obj: object to be serialized
:param default: function that returns a serializable version of an object
:param encoding: encoding used to encode the serialized JSON output
:param kwargs: extra named parameters, please see documentation \
of `json.dumps <https://docs.python.org/2/library/json.html#basic-usage>`_
:returns: json formatted string
.. versionadded:: 2.0
"""
serialized = dumps(obj, default=default, **kwargs)
if isinstance(serialized, six.text_type):
# On Python 3, json.dumps() returns Unicode
serialized = serialized.encode(encoding)
return serialized
def dump(obj, fp, *args, **kwargs):
"""Serialize ``obj`` as a JSON formatted stream to ``fp``

View File

@ -46,6 +46,9 @@ class JSONUtilsTestMixin(object):
def test_dumps(self):
self.assertEqual('{"a": "b"}', jsonutils.dumps({'a': 'b'}))
def test_dump_as_bytes(self):
self.assertEqual(b'{"a": "b"}', jsonutils.dump_as_bytes({'a': 'b'}))
def test_dumps_namedtuple(self):
n = collections.namedtuple("foo", "bar baz")(1, 2)
self.assertEqual('[1, 2]', jsonutils.dumps(n))