]> granicus.if.org Git - python/commitdiff
Issue #20627: xmlrpc.client.ServerProxy is now a context manager.
authorBrett Cannon <brett@python.org>
Fri, 21 Mar 2014 15:24:40 +0000 (11:24 -0400)
committerBrett Cannon <brett@python.org>
Fri, 21 Mar 2014 15:24:40 +0000 (11:24 -0400)
Patch by Claudiu Popa.

Doc/library/xmlrpc.client.rst
Doc/whatsnew/3.5.rst
Lib/test/test_xmlrpc.py
Lib/xmlrpc/client.py
Misc/NEWS

index 3cb19d186267b1593f3483b200b24d1f8d945d86..6f14227ea9bc7b119e39dcbde8971411ab40ad88 100644 (file)
@@ -191,6 +191,11 @@ grouped under the reserved :attr:`system` attribute:
    no such string is available, an empty string is returned. The documentation
    string may contain HTML markup.
 
+.. versionchanged:: 3.5
+
+   Instances of :class:`ServerProxy` support the :term:`context manager` protocol
+   for closing the underlying transport.
+
 
 A working example follows. The server code::
 
@@ -208,9 +213,9 @@ The client code for the preceding server::
 
    import xmlrpc.client
 
-   proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
-   print("3 is even: %s" % str(proxy.is_even(3)))
-   print("100 is even: %s" % str(proxy.is_even(100)))
+   with xmlrpc.client.ServerProxy("http://localhost:8000/") as proxy:
+       print("3 is even: %s" % str(proxy.is_even(3)))
+       print("100 is even: %s" % str(proxy.is_even(100)))
 
 .. _datetime-objects:
 
@@ -518,14 +523,14 @@ Example of Client Usage
    from xmlrpc.client import ServerProxy, Error
 
    # server = ServerProxy("http://localhost:8000") # local server
-   server = ServerProxy("http://betty.userland.com")
+   with ServerProxy("http://betty.userland.com") as proxy:
 
-   print(server)
+       print(proxy)
 
-   try:
-       print(server.examples.getStateName(41))
-   except Error as v:
-       print("ERROR", v)
+       try:
+           print(proxy.examples.getStateName(41))
+       except Error as v:
+           print("ERROR", v)
 
 To access an XML-RPC server through a proxy, you need to define  a custom
 transport.  The following example shows how:
index f11291b2aaa7f15f8c385c039d23bdd5bbe84b60..b18bcd2d79ddb9da4fa15131410037166e2e3463 100644 (file)
@@ -134,7 +134,8 @@ New Modules
 Improved Modules
 ================
 
-* None yet.
+* :class:`xmlrpc.client.ServerProxy` is now a :term:`context manager`
+  (contributed by Claudiu Popa in :issue:`20627`).
 
 
 Optimizations
index 99b3eda13ee498c5e02175f4d8ab5feb6feef23e..120c54f16cdbab786411e24d709ab677fd9e4f73 100644 (file)
@@ -713,6 +713,23 @@ class SimpleServerTestCase(BaseServerTestCase):
         conn.request('POST', '/RPC2 HTTP/1.0\r\nContent-Length: 100\r\n\r\nbye')
         conn.close()
 
+    def test_context_manager(self):
+        with xmlrpclib.ServerProxy(URL) as server:
+            server.add(2, 3)
+            self.assertNotEqual(server('transport')._connection,
+                                (None, None))
+        self.assertEqual(server('transport')._connection,
+                         (None, None))
+
+    def test_context_manager_method_error(self):
+        try:
+            with xmlrpclib.ServerProxy(URL) as server:
+                server.add(2, "a")
+        except xmlrpclib.Fault:
+            pass
+        self.assertEqual(server('transport')._connection,
+                         (None, None))
+
 
 class MultiPathServerTestCase(BaseServerTestCase):
     threadFunc = staticmethod(http_multi_server)
@@ -898,6 +915,7 @@ class ServerProxyTestCase(unittest.TestCase):
         p = xmlrpclib.ServerProxy(self.url, transport=t)
         self.assertEqual(p('transport'), t)
 
+
 # This is a contrived way to make a failure occur on the server side
 # in order to test the _send_traceback_header flag on the server
 class FailingMessageClass(http.client.HTTPMessage):
index c2ae7070f9ac03985d6ceb50a36adb8651a481ed..567554da37e8c835f40239c84c4a2f022e60fac4 100644 (file)
@@ -1449,6 +1449,12 @@ class ServerProxy:
             return self.__transport
         raise AttributeError("Attribute %r not found" % (attr,))
 
+    def __enter__(self):
+        return self
+
+    def __exit__(self, *args):
+        self.__close()
+
 # compatibility
 
 Server = ServerProxy
index ccc1f57ff5b8dadd78e9000c0d215eefdd00032e..3c7ac56bd2d6cbba689cd217867c330eb252186e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -23,6 +23,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #20627: xmlrpc.client.ServerProxy is now a context manager.
+
 - Issue #19165: The formatter module now raises DeprecationWarning instead of
   PendingDeprecationWarning.