changeset: 99997:6c624ba1b61e branch: 3.5 parent: 99994:e1a711808cfe user: Serhiy Storchaka date: Wed Jan 20 10:34:27 2016 +0200 files: Lib/test/test_xmlrpc.py Lib/xmlrpc/client.py Lib/xmlrpc/server.py Misc/NEWS description: Issue #26147: xmlrpc now works with strings not encodable with used non-UTF-8 encoding. diff -r e1a711808cfe -r 6c624ba1b61e Lib/test/test_xmlrpc.py --- a/Lib/test/test_xmlrpc.py Wed Jan 20 08:45:37 2016 +0200 +++ b/Lib/test/test_xmlrpc.py Wed Jan 20 10:34:27 2016 +0200 @@ -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 = "" + 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 -r e1a711808cfe -r 6c624ba1b61e Lib/xmlrpc/client.py --- a/Lib/xmlrpc/client.py Wed Jan 20 08:45:37 2016 +0200 +++ b/Lib/xmlrpc/client.py Wed Jan 20 10:34:27 2016 +0200 @@ -955,8 +955,6 @@ # standard XML-RPC wrappings if methodname: # a method call - if not isinstance(methodname, str): - methodname = methodname.encode(encoding) data = ( xmlheader, "\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 -r e1a711808cfe -r 6c624ba1b61e Lib/xmlrpc/server.py --- a/Lib/xmlrpc/server.py Wed Jan 20 08:45:37 2016 +0200 +++ b/Lib/xmlrpc/server.py Wed Jan 20 10:34:27 2016 +0200 @@ -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 -r e1a711808cfe -r 6c624ba1b61e Misc/NEWS --- a/Misc/NEWS Wed Jan 20 08:45:37 2016 +0200 +++ b/Misc/NEWS Wed Jan 20 10:34:27 2016 +0200 @@ -46,6 +46,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().