Python 3: encode unicode response bodies

WebOb disallows in py3K to set webob.Response.body to a unicode object,
we should encode unicode bodies in such case.

Change-Id: Ie0dc57fbe3ed9b19dac2e958de14387bc4c1a260
Blueprint: neutron-python3
This commit is contained in:
Cedric Brandily 2015-07-23 00:28:35 +02:00
parent 504dfcc39f
commit 07d3d69663
6 changed files with 35 additions and 16 deletions

View File

@ -92,7 +92,7 @@ class NetworkMetadataProxyHandler(object):
response = webob.Response()
response.status = resp.status
response.headers['Content-Type'] = resp['content-type']
response.body = content
response.body = wsgi.encode_body(content)
return response
elif resp.status == 400:
return webob.exc.HTTPBadRequest()

View File

@ -418,7 +418,7 @@ class RequestExtensionTest(base.BaseTestCase):
def extend_response_data(req, res):
data = jsonutils.loads(res.body)
data['FOXNSOX:extended_key'] = req.GET.get('extended_key')
res.body = jsonutils.dumps(data)
res.body = jsonutils.dumps(data).encode('utf-8')
return res
app = self._setup_app_with_request_handler(extend_response_data, 'GET')
@ -444,7 +444,7 @@ class RequestExtensionTest(base.BaseTestCase):
def _update_handler(req, res):
data = jsonutils.loads(res.body)
data['uneditable'] = req.params['uneditable']
res.body = jsonutils.dumps(data)
res.body = jsonutils.dumps(data).encode('utf-8')
return res
base_app = webtest.TestApp(setup_base_app(self))

View File

@ -77,7 +77,7 @@ class Foxinsocks(object):
# You can use content type header to test for XML.
data = jsonutils.loads(res.body)
data['FOXNSOX:googoose'] = req.GET.get('chewing')
res.body = jsonutils.dumps(data)
res.body = jsonutils.dumps(data).encode('utf-8')
return res
req_ext1 = extensions.RequestExtension('GET', '/dummy_resources/:(id)',
@ -89,7 +89,7 @@ class Foxinsocks(object):
# You can use content type header to test for XML.
data = jsonutils.loads(res.body)
data['FOXNSOX:big_bands'] = 'Pig Bands!'
res.body = jsonutils.dumps(data)
res.body = jsonutils.dumps(data).encode('utf-8')
return res
req_ext2 = extensions.RequestExtension('GET', '/dummy_resources/:(id)',

View File

@ -217,7 +217,7 @@ class SerializerTest(base.BaseTestCase):
serializer = wsgi.Serializer()
result = serializer.serialize(input_data, content_type)
self.assertEqual('{"servers": ["test=pass"]}', result)
self.assertEqual(b'{"servers": ["test=pass"]}', result)
def test_deserialize_raise_bad_request(self):
"""Test serialize verifies that exception is raises."""
@ -308,7 +308,7 @@ class ResponseSerializerTest(testtools.TestCase):
class JSONSerializer(object):
def serialize(self, data, action='default'):
return 'pew_json'
return b'pew_json'
class HeadersSerializer(object):
def serialize(self, response, data, action):
@ -342,7 +342,7 @@ class ResponseSerializerTest(testtools.TestCase):
response = self.serializer.serialize({}, 'application/json')
self.assertEqual('application/json', response.headers['Content-Type'])
self.assertEqual('pew_json', response.body)
self.assertEqual(b'pew_json', response.body)
self.assertEqual(404, response.status_int)
def test_serialize_response_None(self):
@ -350,7 +350,7 @@ class ResponseSerializerTest(testtools.TestCase):
None, 'application/json')
self.assertEqual('application/json', response.headers['Content-Type'])
self.assertEqual('', response.body)
self.assertEqual(b'', response.body)
self.assertEqual(404, response.status_int)
@ -488,28 +488,28 @@ class JSONDictSerializerTest(base.BaseTestCase):
def test_json(self):
input_dict = dict(servers=dict(a=(2, 3)))
expected_json = '{"servers":{"a":[2,3]}}'
expected_json = b'{"servers":{"a":[2,3]}}'
serializer = wsgi.JSONDictSerializer()
result = serializer.serialize(input_dict)
result = result.replace('\n', '').replace(' ', '')
result = result.replace(b'\n', b'').replace(b' ', b'')
self.assertEqual(expected_json, result)
def test_json_with_utf8(self):
input_dict = dict(servers=dict(a=(2, '\xe7\xbd\x91\xe7\xbb\x9c')))
expected_json = '{"servers":{"a":[2,"\\u7f51\\u7edc"]}}'
expected_json = b'{"servers":{"a":[2,"\\u7f51\\u7edc"]}}'
serializer = wsgi.JSONDictSerializer()
result = serializer.serialize(input_dict)
result = result.replace('\n', '').replace(' ', '')
result = result.replace(b'\n', b'').replace(b' ', b'')
self.assertEqual(expected_json, result)
def test_json_with_unicode(self):
input_dict = dict(servers=dict(a=(2, u'\u7f51\u7edc')))
expected_json = '{"servers":{"a":[2,"\\u7f51\\u7edc"]}}'
expected_json = b'{"servers":{"a":[2,"\\u7f51\\u7edc"]}}'
serializer = wsgi.JSONDictSerializer()
result = serializer.serialize(input_dict)
result = result.replace('\n', '').replace(' ', '')
result = result.replace(b'\n', b'').replace(b' ', b'')
self.assertEqual(expected_json, result)

View File

@ -93,6 +93,16 @@ CONF.register_opts(socket_opts)
LOG = logging.getLogger(__name__)
def encode_body(body):
"""Encode unicode body.
WebOb requires to encode unicode body used to update response body.
"""
if isinstance(body, six.text_type):
return body.encode('utf-8')
return body
class WorkerService(common_service.ServiceBase):
"""Wraps a worker to be handled by ProcessLauncher"""
def __init__(self, service, application):
@ -427,7 +437,7 @@ class JSONDictSerializer(DictSerializer):
def default(self, data):
def sanitizer(obj):
return six.text_type(obj)
return jsonutils.dumps(data, default=sanitizer)
return encode_body(jsonutils.dumps(data, default=sanitizer))
class ResponseHeaderSerializer(ActionDispatcher):

View File

@ -116,6 +116,7 @@ commands = python -m testtools.run \
neutron.tests.unit.plugins.ml2.drivers.openvswitch.agent.openflow.ovs_ofctl.test_br_tun \
neutron.tests.unit.plugins.ml2.drivers.openvswitch.agent.test_agent_scheduler \
neutron.tests.unit.plugins.brocade.test_brocade_db \
neutron.tests.unit.plugins.brocade.test_brocade_plugin \
neutron.tests.unit.plugins.brocade.test_brocade_vlan \
neutron.tests.unit.plugins.oneconvergence.test_nvsd_agent \
neutron.tests.unit.plugins.oneconvergence.test_plugin_helper \
@ -153,6 +154,7 @@ commands = python -m testtools.run \
neutron.tests.unit.plugins.cisco.test_network_db \
neutron.tests.unit.scheduler.test_l3_agent_scheduler \
neutron.tests.unit.scheduler.test_dhcp_agent_scheduler \
neutron.tests.unit.db.test_allowedaddresspairs_db \
neutron.tests.unit.db.test_ipam_backend_mixin \
neutron.tests.unit.db.test_l3_dvr_db \
neutron.tests.unit.db.test_l3_hamode_db \
@ -187,6 +189,7 @@ commands = python -m testtools.run \
neutron.tests.unit.agent.l3.test_dvr_fip_ns \
neutron.tests.unit.agent.ovsdb.native.test_helpers \
neutron.tests.unit.agent.common.test_config \
neutron.tests.unit.agent.common.test_ovs_lib \
neutron.tests.unit.agent.common.test_polling \
neutron.tests.unit.agent.common.test_utils \
neutron.tests.unit.agent.linux.test_ip_lib \
@ -214,8 +217,14 @@ commands = python -m testtools.run \
neutron.tests.unit.test_auth \
neutron.tests.unit.test_policy \
neutron.tests.unit.extensions.v2attributes \
neutron.tests.unit.extensions.test_address_scope \
neutron.tests.unit.extensions.test_agent \
neutron.tests.unit.extensions.test_external_net \
neutron.tests.unit.extensions.test_flavors \
neutron.tests.unit.extensions.test_l3_ext_gw_mode \
neutron.tests.unit.extensions.test_extra_dhcp_opt \
neutron.tests.unit.extensions.test_netmtu \
neutron.tests.unit.extensions.test_vlantransparent \
neutron.tests.unit.extensions.extendedattribute \
neutron.tests.unit.extensions.base \
neutron.tests.unit.extensions.foxinsocks \