From 33a40003745302eff5e6031d24d26642763fb6d8 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 21 Mar 2014 11:24:40 -0400 Subject: [PATCH] Issue #20627: xmlrpc.client.ServerProxy is now a context manager. Patch by Claudiu Popa. --- Doc/library/xmlrpc.client.rst | 23 ++++++++++++++--------- Doc/whatsnew/3.5.rst | 3 ++- Lib/test/test_xmlrpc.py | 18 ++++++++++++++++++ Lib/xmlrpc/client.py | 6 ++++++ Misc/NEWS | 2 ++ 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index 3cb19d18626..6f14227ea9b 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -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: diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index f11291b2aaa..b18bcd2d79d 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -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 diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index 99b3eda13ee..120c54f16cd 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -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): diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py index c2ae7070f9a..567554da37e 100644 --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -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 diff --git a/Misc/NEWS b/Misc/NEWS index ccc1f57ff5b..3c7ac56bd2d 100644 --- 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.