]> granicus.if.org Git - python/commitdiff
Issue #26147: xmlrpclib now works with unicode not encodable with used
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 20 Jan 2016 08:33:51 +0000 (10:33 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Wed, 20 Jan 2016 08:33:51 +0000 (10:33 +0200)
non-UTF-8 encoding.

Lib/test/test_xmlrpc.py
Lib/xmlrpclib.py
Misc/NEWS

index 2c199411a7ab98b256208308eb0375cc1611b7a8..ca8d5d8cc03e1afc3d88eb60fe84bca3c33e1488 100644 (file)
@@ -149,7 +149,8 @@ class XMLRPCTestCase(unittest.TestCase):
 
     @test_support.requires_unicode
     def test_dump_encoding(self):
-        value = unichr(0x20ac)
+        value = {test_support.u(r'key\u20ac\xa4'):
+                 test_support.u(r'value\u20ac\xa4')}
         strg = xmlrpclib.dumps((value,), encoding='iso-8859-15')
         strg = "<?xml version='1.0' encoding='iso-8859-15'?>" + strg
         self.assertEqual(xmlrpclib.loads(strg)[0][0], value)
@@ -158,6 +159,12 @@ class XMLRPCTestCase(unittest.TestCase):
                                methodresponse=True)
         self.assertEqual(xmlrpclib.loads(strg)[0][0], value)
 
+        methodname = test_support.u(r'method\u20ac\xa4')
+        strg = xmlrpclib.dumps((value,), encoding='iso-8859-15',
+                               methodname=methodname)
+        self.assertEqual(xmlrpclib.loads(strg)[0][0], value)
+        self.assertEqual(xmlrpclib.loads(strg)[1], methodname)
+
     @test_support.requires_unicode
     def test_default_encoding_issues(self):
         # SF bug #1115989: wrong decoding in '_stringify'
@@ -332,6 +339,7 @@ def http_server(evt, numrequests, requestHandler=None, encoding=None):
         serv.register_multicall_functions()
         serv.register_function(pow)
         serv.register_function(lambda x,y: x+y, 'add')
+        serv.register_function(lambda x: x, test_support.u(r't\xea\u0161t'))
         serv.register_function(my_function)
         serv.register_instance(TestInstanceClass())
         evt.set()
@@ -496,7 +504,7 @@ class SimpleServerTestCase(BaseServerTestCase):
     @test_support.requires_unicode
     def test_client_encoding(self):
         start_string = unichr(0x20ac)
-        end_string = unichr(0xa3)
+        end_string = unichr(0xa4)
 
         try:
             p = xmlrpclib.ServerProxy(URL, encoding='iso-8859-15')
@@ -508,6 +516,18 @@ class SimpleServerTestCase(BaseServerTestCase):
                 # protocol error; provide additional information in test output
                 self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
 
+    @test_support.requires_unicode
+    def test_nonascii_methodname(self):
+        try:
+            p = xmlrpclib.ServerProxy(URL, encoding='iso-8859-15')
+            m = getattr(p, 't\xea\xa8t')
+            self.assertEqual(m(42), 42)
+        except (xmlrpclib.ProtocolError, socket.error) as e:
+            # ignore failures due to non-blocking socket unavailable errors.
+            if not is_unavailable_exception(e):
+                # protocol error; provide additional information in test output
+                self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
+
     # [ch] The test 404 is causing lots of false alarms.
     def XXXtest_404(self):
         # send POST with httplib, it should return 404 header and
@@ -525,6 +545,7 @@ class SimpleServerTestCase(BaseServerTestCase):
             p = xmlrpclib.ServerProxy(URL)
             meth = p.system.listMethods()
             expected_methods = set(['pow', 'div', 'my_function', 'add',
+                                    test_support.u(r't\xea\u0161t'),
                                     'system.listMethods', 'system.methodHelp',
                                     'system.methodSignature', 'system.multicall'])
             self.assertEqual(set(meth), expected_methods)
@@ -635,7 +656,7 @@ class SimpleServerEncodingTestCase(BaseServerTestCase):
     @test_support.requires_unicode
     def test_server_encoding(self):
         start_string = unichr(0x20ac)
-        end_string = unichr(0xa3)
+        end_string = unichr(0xa4)
 
         try:
             p = xmlrpclib.ServerProxy(URL)
index a1800a18a56b1541f03327e6776e0840f884a4da..e0e399c449addaf83df541e43c6a8caaed4c57e5 100644 (file)
@@ -703,9 +703,8 @@ class Marshaller:
 
     if unicode:
         def dump_unicode(self, value, write, escape=escape):
-            value = value.encode(self.encoding)
             write("<value><string>")
-            write(escape(value))
+            write(escape(value).encode(self.encoding, 'xmlcharrefreplace'))
             write("</string></value>\n")
         dispatch[UnicodeType] = dump_unicode
 
@@ -732,12 +731,13 @@ class Marshaller:
         write("<value><struct>\n")
         for k, v in value.items():
             write("<member>\n")
-            if type(k) is not StringType:
-                if unicode and type(k) is UnicodeType:
-                    k = k.encode(self.encoding)
-                else:
-                    raise TypeError, "dictionary key must be string"
-            write("<name>%s</name>\n" % escape(k))
+            if type(k) is StringType:
+                k = escape(k)
+            elif unicode and type(k) is UnicodeType:
+                k = escape(k).encode(self.encoding, 'xmlcharrefreplace')
+            else:
+                raise TypeError, "dictionary key must be string"
+            write("<name>%s</name>\n" % k)
             dump(v, write)
             write("</member>\n")
         write("</struct></value>\n")
@@ -1099,7 +1099,7 @@ def dumps(params, methodname=None, methodresponse=None, encoding=None,
     if methodname:
         # a method call
         if not isinstance(methodname, StringType):
-            methodname = methodname.encode(encoding)
+            methodname = methodname.encode(encoding, 'xmlcharrefreplace')
         data = (
             xmlheader,
             "<methodCall>\n"
index b658f729ad6632e6300e9c79efdd7b144f43d6ad..0d176456e6d4ef28c69a870e571af6d9d048d50d 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -39,6 +39,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #26147: xmlrpclib now works with unicode not encodable with used
+  non-UTF-8 encoding.
+
 - Issue #16620: Fixed AttributeError in msilib.Directory.glob().
 
 - Issue #21847: Fixed xmlrpclib on Unicode-disabled builds.