[Python-checkins] cpython (merge 3.5 -> default): Issue #26147: xmlrpc now works with strings not encodable with used

serhiy.storchaka python-checkins at python.org
Wed Jan 20 04:10:01 EST 2016


https://hg.python.org/cpython/rev/72034327022e
changeset:   99998:72034327022e
parent:      99995:689f881dd5d1
parent:      99997:6c624ba1b61e
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Wed Jan 20 10:41:33 2016 +0200
summary:
  Issue #26147: xmlrpc now works with strings not encodable with used
non-UTF-8 encoding.

files:
  Lib/test/test_xmlrpc.py |  30 +++++++++++++++++++++++-----
  Lib/xmlrpc/client.py    |   4 +--
  Lib/xmlrpc/server.py    |   4 +-
  Misc/NEWS               |   3 ++
  4 files changed, 30 insertions(+), 11 deletions(-)


diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py
--- a/Lib/test/test_xmlrpc.py
+++ b/Lib/test/test_xmlrpc.py
@@ -184,19 +184,26 @@
         self.assertRaises(TypeError, xmlrpclib.dumps, (arg1,))
 
     def test_dump_encoding(self):
-        value = '\u20ac'
+        value = {'key\u20ac\xa4':
+                 '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)
-        strg = strg.encode('iso-8859-15')
+        strg = strg.encode('iso-8859-15', 'xmlcharrefreplace')
         self.assertEqual(xmlrpclib.loads(strg)[0][0], value)
 
         strg = xmlrpclib.dumps((value,), encoding='iso-8859-15',
                                methodresponse=True)
         self.assertEqual(xmlrpclib.loads(strg)[0][0], value)
-        strg = strg.encode('iso-8859-15')
+        strg = strg.encode('iso-8859-15', 'xmlcharrefreplace')
         self.assertEqual(xmlrpclib.loads(strg)[0][0], value)
 
+        methodname = '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)
+
     def test_dump_bytes(self):
         sample = b"my dog has fleas"
         self.assertEqual(sample, xmlrpclib.Binary(sample))
@@ -430,6 +437,7 @@
         serv.register_multicall_functions()
         serv.register_function(pow)
         serv.register_function(lambda x,y: x+y, 'add')
+        serv.register_function(lambda x: x, 'têšt')
         serv.register_function(my_function)
         testInstance = TestInstanceClass()
         serv.register_instance(testInstance, allow_dotted_names=True)
@@ -599,7 +607,7 @@
 
     def test_client_encoding(self):
         start_string = '\u20ac'
-        end_string = '\xa3'
+        end_string = '\xa4'
 
         try:
             p = xmlrpclib.ServerProxy(URL, encoding='iso-8859-15')
@@ -611,6 +619,16 @@
                 # protocol error; provide additional information in test output
                 self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
 
+    def test_nonascii_methodname(self):
+        try:
+            p = xmlrpclib.ServerProxy(URL, encoding='ascii')
+            self.assertEqual(p.têšt(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 http.client, it should return 404 header and
@@ -624,7 +642,7 @@
         self.assertEqual(response.reason, 'Not Found')
 
     def test_introspection1(self):
-        expected_methods = set(['pow', 'div', 'my_function', 'add',
+        expected_methods = set(['pow', 'div', 'my_function', 'add', 'têšt',
                                 'system.listMethods', 'system.methodHelp',
                                 'system.methodSignature', 'system.multicall',
                                 'Fixture'])
@@ -767,7 +785,7 @@
 
     def test_server_encoding(self):
         start_string = '\u20ac'
-        end_string = '\xa3'
+        end_string = '\xa4'
 
         try:
             p = xmlrpclib.ServerProxy(URL)
diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py
--- a/Lib/xmlrpc/client.py
+++ b/Lib/xmlrpc/client.py
@@ -955,8 +955,6 @@
     # standard XML-RPC wrappings
     if methodname:
         # a method call
-        if not isinstance(methodname, str):
-            methodname = methodname.encode(encoding)
         data = (
             xmlheader,
             "<methodCall>\n"
@@ -1422,7 +1420,7 @@
         # call a method on the remote server
 
         request = dumps(params, methodname, encoding=self.__encoding,
-                        allow_none=self.__allow_none).encode(self.__encoding)
+                        allow_none=self.__allow_none).encode(self.__encoding, 'xmlcharrefreplace')
 
         response = self.__transport.request(
             self.__host,
diff --git a/Lib/xmlrpc/server.py b/Lib/xmlrpc/server.py
--- a/Lib/xmlrpc/server.py
+++ b/Lib/xmlrpc/server.py
@@ -269,7 +269,7 @@
                 encoding=self.encoding, allow_none=self.allow_none,
                 )
 
-        return response.encode(self.encoding)
+        return response.encode(self.encoding, 'xmlcharrefreplace')
 
     def system_listMethods(self):
         """system.listMethods() => ['add', 'subtract', 'multiple']
@@ -622,7 +622,7 @@
             response = dumps(
                 Fault(1, "%s:%s" % (exc_type, exc_value)),
                 encoding=self.encoding, allow_none=self.allow_none)
-            response = response.encode(self.encoding)
+            response = response.encode(self.encoding, 'xmlcharrefreplace')
         return response
 
 class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -133,6 +133,9 @@
 Library
 -------
 
+- Issue #26147: xmlrpc now works with strings not encodable with used
+  non-UTF-8 encoding.
+
 - Issue #25935: Garbage collector now breaks reference loops with OrderedDict.
 
 - Issue #16620: Fixed AttributeError in msilib.Directory.glob().

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list