summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorent Xicluna <florent.xicluna@gmail.com>2011-10-30 19:26:28 (GMT)
committerFlorent Xicluna <florent.xicluna@gmail.com>2011-10-30 19:26:28 (GMT)
commit9783b44bcf0f539b56165d823d2b6eede080c1d8 (patch)
treecce085988b5f8a3ccc62fb4541a3180a399d8e85
parentcd06a14df7195404d04442598c802d6c096bb15d (diff)
parent93dfee1dfc0bf572d4d9579fd455a72c0c81f148 (diff)
downloadcpython-9783b44bcf0f539b56165d823d2b6eede080c1d8.zip
cpython-9783b44bcf0f539b56165d823d2b6eede080c1d8.tar.gz
cpython-9783b44bcf0f539b56165d823d2b6eede080c1d8.tar.bz2
Merge heads
-rw-r--r--Lib/test/test_xmlrpc.py63
-rw-r--r--Lib/xmlrpc/client.py36
-rw-r--r--Lib/xmlrpc/server.py10
-rw-r--r--Misc/NEWS5
4 files changed, 71 insertions, 43 deletions
diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py
index 4ccc6ff..e97420b 100644
--- a/Lib/test/test_xmlrpc.py
+++ b/Lib/test/test_xmlrpc.py
@@ -66,15 +66,6 @@ class XMLRPCTestCase(unittest.TestCase):
(newdt,), m = xmlrpclib.loads(s, use_datetime=0)
self.assertEqual(newdt, xmlrpclib.DateTime('00010210T11:41:23'))
- def test_cmp_datetime_DateTime(self):
- now = datetime.datetime.now()
- dt = xmlrpclib.DateTime(now.timetuple())
- self.assertTrue(dt == now)
- self.assertTrue(now == dt)
- then = now + datetime.timedelta(seconds=4)
- self.assertTrue(then >= dt)
- self.assertTrue(dt < then)
-
def test_bug_1164912 (self):
d = xmlrpclib.DateTime()
((new_d,), dummy) = xmlrpclib.loads(xmlrpclib.dumps((d,),
@@ -149,6 +140,9 @@ class XMLRPCTestCase(unittest.TestCase):
('host.tld',
[('Authorization', 'Basic dXNlcg==')], {}))
+ def test_dump_bytes(self):
+ self.assertRaises(TypeError, xmlrpclib.dumps, (b"my dog has fleas",))
+
def test_ssl_presence(self):
try:
import ssl
@@ -186,7 +180,7 @@ class FaultTestCase(unittest.TestCase):
self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, s)
def test_dotted_attribute(self):
- # this will raise AttirebuteError because code don't want us to use
+ # this will raise AttributeError because code don't want us to use
# private methods
self.assertRaises(AttributeError,
xmlrpc.server.resolve_dotted_attribute, str, '__add')
@@ -233,6 +227,45 @@ class DateTimeTestCase(unittest.TestCase):
t2 = xmlrpclib._datetime(d)
self.assertEqual(t1, tref)
+ def test_comparison(self):
+ now = datetime.datetime.now()
+ dtime = xmlrpclib.DateTime(now.timetuple())
+
+ # datetime vs. DateTime
+ self.assertTrue(dtime == now)
+ self.assertTrue(now == dtime)
+ then = now + datetime.timedelta(seconds=4)
+ self.assertTrue(then >= dtime)
+ self.assertTrue(dtime < then)
+
+ # str vs. DateTime
+ dstr = now.strftime("%Y%m%dT%H:%M:%S")
+ self.assertTrue(dtime == dstr)
+ self.assertTrue(dstr == dtime)
+ dtime_then = xmlrpclib.DateTime(then.timetuple())
+ self.assertTrue(dtime_then >= dstr)
+ self.assertTrue(dstr < dtime_then)
+
+ # some other types
+ dbytes = dstr.encode('ascii')
+ dtuple = now.timetuple()
+ with self.assertRaises(TypeError):
+ dtime == 1970
+ with self.assertRaises(TypeError):
+ dtime != dbytes
+ with self.assertRaises(TypeError):
+ dtime == bytearray(dbytes)
+ with self.assertRaises(TypeError):
+ dtime != dtuple
+ with self.assertRaises(TypeError):
+ dtime < float(1970)
+ with self.assertRaises(TypeError):
+ dtime > dbytes
+ with self.assertRaises(TypeError):
+ dtime <= bytearray(dbytes)
+ with self.assertRaises(TypeError):
+ dtime >= dtuple
+
class BinaryTestCase(unittest.TestCase):
# XXX What should str(Binary(b"\xff")) return? I'm chosing "\xff"
@@ -346,6 +379,10 @@ def http_multi_server(evt, numrequests, requestHandler=None):
class MyRequestHandler(requestHandler):
rpc_paths = []
+ class BrokenDispatcher:
+ def _marshaled_dispatch(self, data, dispatch_method=None, path=None):
+ raise RuntimeError("broken dispatcher")
+
serv = MyXMLRPCServer(("localhost", 0), MyRequestHandler,
logRequests=False, bind_and_activate=False)
serv.socket.settimeout(3)
@@ -366,6 +403,7 @@ def http_multi_server(evt, numrequests, requestHandler=None):
d.register_multicall_functions()
serv.get_dispatcher(paths[0]).register_function(pow)
serv.get_dispatcher(paths[1]).register_function(lambda x,y: x+y, 'add')
+ serv.add_dispatcher("/is/broken", BrokenDispatcher())
evt.set()
# handle up to 'numrequests' requests
@@ -595,11 +633,16 @@ class MultiPathServerTestCase(BaseServerTestCase):
p = xmlrpclib.ServerProxy(URL+"/foo")
self.assertEqual(p.pow(6,8), 6**8)
self.assertRaises(xmlrpclib.Fault, p.add, 6, 8)
+
def test_path2(self):
p = xmlrpclib.ServerProxy(URL+"/foo/bar")
self.assertEqual(p.add(6,8), 6+8)
self.assertRaises(xmlrpclib.Fault, p.pow, 6, 8)
+ def test_path3(self):
+ p = xmlrpclib.ServerProxy(URL+"/is/broken")
+ self.assertRaises(xmlrpclib.Fault, p.add, 6, 8)
+
#A test case that verifies that a server using the HTTP/1.1 keep-alive mechanism
#does indeed serve subsequent requests on the same connection
class BaseKeepaliveServerTestCase(BaseServerTestCase):
diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py
index 19d4d69..97d5aac 100644
--- a/Lib/xmlrpc/client.py
+++ b/Lib/xmlrpc/client.py
@@ -85,11 +85,6 @@
# OF THIS SOFTWARE.
# --------------------------------------------------------------------
-#
-# things to look into some day:
-
-# TODO: sort out True/False/boolean issues for Python 2.3
-
"""
An XML-RPC client interface for Python.
@@ -120,8 +115,7 @@ Exported classes:
Exported constants:
- True
- False
+ (none)
Exported functions:
@@ -133,7 +127,8 @@ Exported functions:
name (None if not present).
"""
-import re, time, operator
+import base64
+import time
import http.client
from xml.parsers import expat
import socket
@@ -230,7 +225,7 @@ class ResponseError(Error):
##
# Indicates an XML-RPC fault response package. This exception is
# raised by the unmarshalling layer, if the XML-RPC response contains
-# a fault string. This exception can also used as a class, to
+# a fault string. This exception can also be used as a class, to
# generate a fault XML-RPC message.
#
# @param faultCode The XML-RPC fault code.
@@ -243,10 +238,7 @@ class Fault(Error):
self.faultCode = faultCode
self.faultString = faultString
def __repr__(self):
- return (
- "<Fault %s: %s>" %
- (self.faultCode, repr(self.faultString))
- )
+ return "<Fault %s: %r>" % (self.faultCode, self.faultString)
# --------------------------------------------------------------------
# Special values
@@ -302,7 +294,7 @@ class DateTime:
elif datetime and isinstance(other, datetime.datetime):
s = self.value
o = other.strftime("%Y%m%dT%H:%M:%S")
- elif isinstance(other, (str, unicode)):
+ elif isinstance(other, str):
s = self.value
o = other
elif hasattr(other, "timetuple"):
@@ -352,7 +344,7 @@ class DateTime:
return self.value
def __repr__(self):
- return "<DateTime %s at %x>" % (repr(self.value), id(self))
+ return "<DateTime %r at %x>" % (self.value, id(self))
def decode(self, data):
self.value = str(data).strip()
@@ -378,9 +370,6 @@ def _datetime_type(data):
#
# @param data An 8-bit string containing arbitrary data.
-import base64
-import io
-
class Binary:
"""Wrapper for binary data."""
@@ -514,9 +503,7 @@ class Marshaller:
f = self.dispatch[type(value)]
except KeyError:
# check if this object can be marshalled as a structure
- try:
- value.__dict__
- except:
+ if not hasattr(value, '__dict__'):
raise TypeError("cannot marshal %s objects" % type(value))
# check if this class is a sub-class of a basic type,
# because we don't know how to marshal these types
@@ -564,12 +551,6 @@ class Marshaller:
write("</double></value>\n")
dispatch[float] = dump_double
- def dump_string(self, value, write, escape=escape):
- write("<value><string>")
- write(escape(value))
- write("</string></value>\n")
- dispatch[bytes] = dump_string
-
def dump_unicode(self, value, write, escape=escape):
write("<value><string>")
write(escape(value))
@@ -1198,7 +1179,6 @@ class Transport:
auth, host = urllib.parse.splituser(host)
if auth:
- import base64
auth = urllib.parse.unquote_to_bytes(auth)
auth = base64.encodebytes(auth).decode("utf-8")
auth = "".join(auth.split()) # get rid of whitespace
diff --git a/Lib/xmlrpc/server.py b/Lib/xmlrpc/server.py
index ac252f1..72f3bfc 100644
--- a/Lib/xmlrpc/server.py
+++ b/Lib/xmlrpc/server.py
@@ -329,7 +329,6 @@ class SimpleXMLRPCDispatcher:
if method is None:
return ""
else:
- import pydoc
return pydoc.getdoc(method)
def system_multicall(self, call_list):
@@ -560,7 +559,7 @@ class SimpleXMLRPCServer(socketserver.TCPServer,
Simple XML-RPC server that allows functions and a single instance
to be installed to handle requests. The default implementation
attempts to dispatch XML-RPC calls to the functions or instance
- installed in the server. Override the _dispatch method inhereted
+ installed in the server. Override the _dispatch method inherited
from SimpleXMLRPCDispatcher to change this behavior.
"""
@@ -602,7 +601,7 @@ class MultiPathXMLRPCServer(SimpleXMLRPCServer):
encoding, bind_and_activate)
self.dispatchers = {}
self.allow_none = allow_none
- self.encoding = encoding
+ self.encoding = encoding or 'utf-8'
def add_dispatcher(self, path, dispatcher):
self.dispatchers[path] = dispatcher
@@ -620,9 +619,10 @@ class MultiPathXMLRPCServer(SimpleXMLRPCServer):
# (each dispatcher should have handled their own
# exceptions)
exc_type, exc_value = sys.exc_info()[:2]
- response = xmlrpclib.dumps(
- xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value)),
+ response = dumps(
+ Fault(1, "%s:%s" % (exc_type, exc_value)),
encoding=self.encoding, allow_none=self.allow_none)
+ response = response.encode(self.encoding)
return response
class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher):
diff --git a/Misc/NEWS b/Misc/NEWS
index f01bb51..50a9a3d 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -66,6 +66,11 @@ Core and Builtins
Library
-------
+- Issue #13293: Better error message when trying to marshal bytes using
+ xmlrpc.client.
+
+- Issue #13291: NameError in xmlrpc package.
+
- Issue #13258: Use callable() built-in in the standard library.
- Issue #13273: fix a bug that prevented HTMLParser to properly detect some