From ac455dc273e7874ea6ba36816a9e8aea23426fa5 Mon Sep 17 00:00:00 2001 From: Tianhao He Date: Tue, 21 Mar 2017 11:20:41 -0700 Subject: [PATCH] Fixes #519, #448, #420, #421 Fix SoapAdapter serializer to support serializing unicode chars We use string formatter to contruct serialization result. The template used is str(byte) in python2 even though when the val is unicode. This is fine when val only contains ASCII chars since python can encode them to str implicitly using ASCII encoding. But when the val is non-ASCII unicodes, the conversion fails. Fix it by using a unicode template to avoid the conversion. --- pyVmomi/SoapAdapter.py | 2 +- tests/test_serializer.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pyVmomi/SoapAdapter.py b/pyVmomi/SoapAdapter.py index 1fb67cf..6eaeb44 100644 --- a/pyVmomi/SoapAdapter.py +++ b/pyVmomi/SoapAdapter.py @@ -448,7 +448,7 @@ class SoapSerializer: # a bug. val = val.decode(XML_ENCODING) result = XmlEscape(val) - self.writer.write('<{0}{1}>{2}'.format(info.name, attr, result)) + self.writer.write(u'<{0}{1}>{2}'.format(info.name, attr, result)) ## Serialize a a data object (internal) # diff --git a/tests/test_serializer.py b/tests/test_serializer.py index 525e6b5..62dd9da 100644 --- a/tests/test_serializer.py +++ b/tests/test_serializer.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + # VMware vSphere Python SDK # Copyright (c) 2008-2015 VMware, Inc. All Rights Reserved. # @@ -40,6 +42,14 @@ class SerializerTests(tests.VCRTestBase): pc.diskSpaceToAddressSpaceRatio = 1.0 SoapAdapter.Serialize(pc, version='vim.version.version10') + def test_serialize_unicode(self): + self.assertEqual(SoapAdapter.SerializeToUnicode('Ḃ'), + u'\u1e02') + self.assertEqual(SoapAdapter.SerializeToUnicode(u'Ḃ'), + u'\u1e02') + self.assertEqual(SoapAdapter.SerializeToUnicode(u'\u1e02'), + u'\u1e02') + def _base_serialize_test(self, soap_creator, request_matcher): my_vcr = config.VCR( custom_patches=( @@ -99,3 +109,4 @@ class SerializerTests(tests.VCRTestBase): self._base_serialize_test(soap_creator, request_matcher) finally: GetRequestContext().pop("vcSessionCookie") +