Issue #20627: xmlrpc.client.ServerProxy is now a context manager.
Patch by Claudiu Popa.
This commit is contained in:
parent
051f37d2e7
commit
33a4000374
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue