Kaydet (Commit) 33a40003 authored tarafından Brett Cannon's avatar Brett Cannon

Issue #20627: xmlrpc.client.ServerProxy is now a context manager.

Patch by Claudiu Popa.
üst 051f37d2
...@@ -191,6 +191,11 @@ grouped under the reserved :attr:`system` attribute: ...@@ -191,6 +191,11 @@ grouped under the reserved :attr:`system` attribute:
no such string is available, an empty string is returned. The documentation no such string is available, an empty string is returned. The documentation
string may contain HTML markup. 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:: A working example follows. The server code::
...@@ -208,9 +213,9 @@ The client code for the preceding server:: ...@@ -208,9 +213,9 @@ The client code for the preceding server::
import xmlrpc.client import xmlrpc.client
proxy = xmlrpc.client.ServerProxy("http://localhost:8000/") with xmlrpc.client.ServerProxy("http://localhost:8000/") as proxy:
print("3 is even: %s" % str(proxy.is_even(3))) print("3 is even: %s" % str(proxy.is_even(3)))
print("100 is even: %s" % str(proxy.is_even(100))) print("100 is even: %s" % str(proxy.is_even(100)))
.. _datetime-objects: .. _datetime-objects:
...@@ -518,14 +523,14 @@ Example of Client Usage ...@@ -518,14 +523,14 @@ Example of Client Usage
from xmlrpc.client import ServerProxy, Error from xmlrpc.client import ServerProxy, Error
# server = ServerProxy("http://localhost:8000") # local server # 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: try:
print(server.examples.getStateName(41)) print(proxy.examples.getStateName(41))
except Error as v: except Error as v:
print("ERROR", v) print("ERROR", v)
To access an XML-RPC server through a proxy, you need to define a custom To access an XML-RPC server through a proxy, you need to define a custom
transport. The following example shows how: transport. The following example shows how:
......
...@@ -134,7 +134,8 @@ New Modules ...@@ -134,7 +134,8 @@ New Modules
Improved Modules Improved Modules
================ ================
* None yet. * :class:`xmlrpc.client.ServerProxy` is now a :term:`context manager`
(contributed by Claudiu Popa in :issue:`20627`).
Optimizations Optimizations
......
...@@ -713,6 +713,23 @@ class SimpleServerTestCase(BaseServerTestCase): ...@@ -713,6 +713,23 @@ class SimpleServerTestCase(BaseServerTestCase):
conn.request('POST', '/RPC2 HTTP/1.0\r\nContent-Length: 100\r\n\r\nbye') conn.request('POST', '/RPC2 HTTP/1.0\r\nContent-Length: 100\r\n\r\nbye')
conn.close() 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): class MultiPathServerTestCase(BaseServerTestCase):
threadFunc = staticmethod(http_multi_server) threadFunc = staticmethod(http_multi_server)
...@@ -898,6 +915,7 @@ class ServerProxyTestCase(unittest.TestCase): ...@@ -898,6 +915,7 @@ class ServerProxyTestCase(unittest.TestCase):
p = xmlrpclib.ServerProxy(self.url, transport=t) p = xmlrpclib.ServerProxy(self.url, transport=t)
self.assertEqual(p('transport'), t) self.assertEqual(p('transport'), t)
# This is a contrived way to make a failure occur on the server side # 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 # in order to test the _send_traceback_header flag on the server
class FailingMessageClass(http.client.HTTPMessage): class FailingMessageClass(http.client.HTTPMessage):
......
...@@ -1449,6 +1449,12 @@ class ServerProxy: ...@@ -1449,6 +1449,12 @@ class ServerProxy:
return self.__transport return self.__transport
raise AttributeError("Attribute %r not found" % (attr,)) raise AttributeError("Attribute %r not found" % (attr,))
def __enter__(self):
return self
def __exit__(self, *args):
self.__close()
# compatibility # compatibility
Server = ServerProxy Server = ServerProxy
......
...@@ -23,6 +23,8 @@ Core and Builtins ...@@ -23,6 +23,8 @@ Core and Builtins
Library Library
------- -------
- Issue #20627: xmlrpc.client.ServerProxy is now a context manager.
- Issue #19165: The formatter module now raises DeprecationWarning instead of - Issue #19165: The formatter module now raises DeprecationWarning instead of
PendingDeprecationWarning. PendingDeprecationWarning.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment