mirror of
https://github.com/python/cpython.git
synced 2025-10-13 18:33:34 +00:00
Closes #13297: use bytes type to send and receive binary data through XMLRPC.
This commit is contained in:
parent
1d8f3f451c
commit
6166519d2b
4 changed files with 132 additions and 48 deletions
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
|
|
||||||
.. XXX Not everything is documented yet. It might be good to describe
|
.. XXX Not everything is documented yet. It might be good to describe
|
||||||
Marshaller, Unmarshaller, getparser, dumps, loads, and Transport.
|
Marshaller, Unmarshaller, getparser and Transport.
|
||||||
|
|
||||||
**Source code:** :source:`Lib/xmlrpc/client.py`
|
**Source code:** :source:`Lib/xmlrpc/client.py`
|
||||||
|
|
||||||
|
@ -21,7 +21,12 @@ supports writing XML-RPC client code; it handles all the details of translating
|
||||||
between conformable Python objects and XML on the wire.
|
between conformable Python objects and XML on the wire.
|
||||||
|
|
||||||
|
|
||||||
.. class:: ServerProxy(uri, transport=None, encoding=None, verbose=False, allow_none=False, use_datetime=False)
|
.. class:: ServerProxy(uri, transport=None, encoding=None, verbose=False, \
|
||||||
|
allow_none=False, use_datetime=False, \
|
||||||
|
use_builtin_types=False)
|
||||||
|
|
||||||
|
.. versionchanged:: 3.3
|
||||||
|
The *use_builtin_types* flag was added.
|
||||||
|
|
||||||
A :class:`ServerProxy` instance is an object that manages communication with a
|
A :class:`ServerProxy` instance is an object that manages communication with a
|
||||||
remote XML-RPC server. The required first argument is a URI (Uniform Resource
|
remote XML-RPC server. The required first argument is a URI (Uniform Resource
|
||||||
|
@ -34,9 +39,13 @@ between conformable Python objects and XML on the wire.
|
||||||
XML; the default behaviour is for ``None`` to raise a :exc:`TypeError`. This is
|
XML; the default behaviour is for ``None`` to raise a :exc:`TypeError`. This is
|
||||||
a commonly-used extension to the XML-RPC specification, but isn't supported by
|
a commonly-used extension to the XML-RPC specification, but isn't supported by
|
||||||
all clients and servers; see http://ontosys.com/xml-rpc/extensions.php for a
|
all clients and servers; see http://ontosys.com/xml-rpc/extensions.php for a
|
||||||
description. The *use_datetime* flag can be used to cause date/time values to
|
description. The *use_builtin_types* flag can be used to cause date/time values
|
||||||
be presented as :class:`datetime.datetime` objects; this is false by default.
|
to be presented as :class:`datetime.datetime` objects and binary data to be
|
||||||
:class:`datetime.datetime` objects may be passed to calls.
|
presented as :class:`bytes` objects; this flag is false by default.
|
||||||
|
:class:`datetime.datetime` and :class:`bytes` objects may be passed to calls.
|
||||||
|
|
||||||
|
The obsolete *use_datetime* flag is similar to *use_builtin_types* but it
|
||||||
|
applies only to date/time values.
|
||||||
|
|
||||||
Both the HTTP and HTTPS transports support the URL syntax extension for HTTP
|
Both the HTTP and HTTPS transports support the URL syntax extension for HTTP
|
||||||
Basic Authentication: ``http://user:pass@host:port/path``. The ``user:pass``
|
Basic Authentication: ``http://user:pass@host:port/path``. The ``user:pass``
|
||||||
|
@ -78,12 +87,12 @@ between conformable Python objects and XML on the wire.
|
||||||
| | only their *__dict__* attribute is |
|
| | only their *__dict__* attribute is |
|
||||||
| | transmitted. |
|
| | transmitted. |
|
||||||
+---------------------------------+---------------------------------------------+
|
+---------------------------------+---------------------------------------------+
|
||||||
| :const:`dates` | in seconds since the epoch (pass in an |
|
| :const:`dates` | In seconds since the epoch. Pass in an |
|
||||||
| | instance of the :class:`DateTime` class) or |
|
| | instance of the :class:`DateTime` class or |
|
||||||
| | a :class:`datetime.datetime` instance. |
|
| | a :class:`datetime.datetime` instance. |
|
||||||
+---------------------------------+---------------------------------------------+
|
+---------------------------------+---------------------------------------------+
|
||||||
| :const:`binary data` | pass in an instance of the :class:`Binary` |
|
| :const:`binary data` | Pass in an instance of the :class:`Binary` |
|
||||||
| | wrapper class |
|
| | wrapper class or a :class:`bytes` instance. |
|
||||||
+---------------------------------+---------------------------------------------+
|
+---------------------------------+---------------------------------------------+
|
||||||
|
|
||||||
This is the full set of data types supported by XML-RPC. Method calls may also
|
This is the full set of data types supported by XML-RPC. Method calls may also
|
||||||
|
@ -98,8 +107,9 @@ between conformable Python objects and XML on the wire.
|
||||||
ensure that the string is free of characters that aren't allowed in XML, such as
|
ensure that the string is free of characters that aren't allowed in XML, such as
|
||||||
the control characters with ASCII values between 0 and 31 (except, of course,
|
the control characters with ASCII values between 0 and 31 (except, of course,
|
||||||
tab, newline and carriage return); failing to do this will result in an XML-RPC
|
tab, newline and carriage return); failing to do this will result in an XML-RPC
|
||||||
request that isn't well-formed XML. If you have to pass arbitrary strings via
|
request that isn't well-formed XML. If you have to pass arbitrary bytes
|
||||||
XML-RPC, use the :class:`Binary` wrapper class described below.
|
via XML-RPC, use the :class:`bytes` class or the class:`Binary` wrapper class
|
||||||
|
described below.
|
||||||
|
|
||||||
:class:`Server` is retained as an alias for :class:`ServerProxy` for backwards
|
:class:`Server` is retained as an alias for :class:`ServerProxy` for backwards
|
||||||
compatibility. New code should use :class:`ServerProxy`.
|
compatibility. New code should use :class:`ServerProxy`.
|
||||||
|
@ -249,7 +259,7 @@ The client code for the preceding server::
|
||||||
Binary Objects
|
Binary Objects
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
This class may be initialized from string data (which may include NULs). The
|
This class may be initialized from bytes data (which may include NULs). The
|
||||||
primary access to the content of a :class:`Binary` object is provided by an
|
primary access to the content of a :class:`Binary` object is provided by an
|
||||||
attribute:
|
attribute:
|
||||||
|
|
||||||
|
@ -257,15 +267,15 @@ attribute:
|
||||||
.. attribute:: Binary.data
|
.. attribute:: Binary.data
|
||||||
|
|
||||||
The binary data encapsulated by the :class:`Binary` instance. The data is
|
The binary data encapsulated by the :class:`Binary` instance. The data is
|
||||||
provided as an 8-bit string.
|
provided as a :class:`bytes` object.
|
||||||
|
|
||||||
:class:`Binary` objects have the following methods, supported mainly for
|
:class:`Binary` objects have the following methods, supported mainly for
|
||||||
internal use by the marshalling/unmarshalling code:
|
internal use by the marshalling/unmarshalling code:
|
||||||
|
|
||||||
|
|
||||||
.. method:: Binary.decode(string)
|
.. method:: Binary.decode(bytes)
|
||||||
|
|
||||||
Accept a base64 string and decode it as the instance's new data.
|
Accept a base64 :class:`bytes` object and decode it as the instance's new data.
|
||||||
|
|
||||||
|
|
||||||
.. method:: Binary.encode(out)
|
.. method:: Binary.encode(out)
|
||||||
|
@ -471,14 +481,21 @@ Convenience Functions
|
||||||
it via an extension, provide a true value for *allow_none*.
|
it via an extension, provide a true value for *allow_none*.
|
||||||
|
|
||||||
|
|
||||||
.. function:: loads(data, use_datetime=False)
|
.. function:: loads(data, use_datetime=False, use_builtin_types=False)
|
||||||
|
|
||||||
Convert an XML-RPC request or response into Python objects, a ``(params,
|
Convert an XML-RPC request or response into Python objects, a ``(params,
|
||||||
methodname)``. *params* is a tuple of argument; *methodname* is a string, or
|
methodname)``. *params* is a tuple of argument; *methodname* is a string, or
|
||||||
``None`` if no method name is present in the packet. If the XML-RPC packet
|
``None`` if no method name is present in the packet. If the XML-RPC packet
|
||||||
represents a fault condition, this function will raise a :exc:`Fault` exception.
|
represents a fault condition, this function will raise a :exc:`Fault` exception.
|
||||||
The *use_datetime* flag can be used to cause date/time values to be presented as
|
The *use_builtin_types* flag can be used to cause date/time values to be
|
||||||
:class:`datetime.datetime` objects; this is false by default.
|
presented as :class:`datetime.datetime` objects and binary data to be
|
||||||
|
presented as :class:`bytes` objects; this flag is false by default.
|
||||||
|
|
||||||
|
The obsolete *use_datetime* flag is similar to *use_builtin_types* but it
|
||||||
|
applies only to date/time values.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.3
|
||||||
|
The *use_builtin_types* flag was added.
|
||||||
|
|
||||||
|
|
||||||
.. _xmlrpc-client-example:
|
.. _xmlrpc-client-example:
|
||||||
|
|
|
@ -24,6 +24,8 @@ alist = [{'astring': 'foo@bar.baz.spam',
|
||||||
'ashortlong': 2,
|
'ashortlong': 2,
|
||||||
'anotherlist': ['.zyx.41'],
|
'anotherlist': ['.zyx.41'],
|
||||||
'abase64': xmlrpclib.Binary(b"my dog has fleas"),
|
'abase64': xmlrpclib.Binary(b"my dog has fleas"),
|
||||||
|
'b64bytes': b"my dog has fleas",
|
||||||
|
'b64bytearray': bytearray(b"my dog has fleas"),
|
||||||
'boolean': False,
|
'boolean': False,
|
||||||
'unicode': '\u4000\u6000\u8000',
|
'unicode': '\u4000\u6000\u8000',
|
||||||
'ukey\u4000': 'regular value',
|
'ukey\u4000': 'regular value',
|
||||||
|
@ -44,27 +46,54 @@ class XMLRPCTestCase(unittest.TestCase):
|
||||||
def test_dump_bare_datetime(self):
|
def test_dump_bare_datetime(self):
|
||||||
# This checks that an unwrapped datetime.date object can be handled
|
# This checks that an unwrapped datetime.date object can be handled
|
||||||
# by the marshalling code. This can't be done via test_dump_load()
|
# by the marshalling code. This can't be done via test_dump_load()
|
||||||
# since with use_datetime set to 1 the unmarshaller would create
|
# since with use_builtin_types set to 1 the unmarshaller would create
|
||||||
# datetime objects for the 'datetime[123]' keys as well
|
# datetime objects for the 'datetime[123]' keys as well
|
||||||
dt = datetime.datetime(2005, 2, 10, 11, 41, 23)
|
dt = datetime.datetime(2005, 2, 10, 11, 41, 23)
|
||||||
|
self.assertEqual(dt, xmlrpclib.DateTime('20050210T11:41:23'))
|
||||||
s = xmlrpclib.dumps((dt,))
|
s = xmlrpclib.dumps((dt,))
|
||||||
(newdt,), m = xmlrpclib.loads(s, use_datetime=1)
|
|
||||||
self.assertEqual(newdt, dt)
|
|
||||||
self.assertEqual(m, None)
|
|
||||||
|
|
||||||
(newdt,), m = xmlrpclib.loads(s, use_datetime=0)
|
result, m = xmlrpclib.loads(s, use_builtin_types=True)
|
||||||
self.assertEqual(newdt, xmlrpclib.DateTime('20050210T11:41:23'))
|
(newdt,) = result
|
||||||
|
self.assertEqual(newdt, dt)
|
||||||
|
self.assertIs(type(newdt), datetime.datetime)
|
||||||
|
self.assertIsNone(m)
|
||||||
|
|
||||||
|
result, m = xmlrpclib.loads(s, use_builtin_types=False)
|
||||||
|
(newdt,) = result
|
||||||
|
self.assertEqual(newdt, dt)
|
||||||
|
self.assertIs(type(newdt), xmlrpclib.DateTime)
|
||||||
|
self.assertIsNone(m)
|
||||||
|
|
||||||
|
result, m = xmlrpclib.loads(s, use_datetime=True)
|
||||||
|
(newdt,) = result
|
||||||
|
self.assertEqual(newdt, dt)
|
||||||
|
self.assertIs(type(newdt), datetime.datetime)
|
||||||
|
self.assertIsNone(m)
|
||||||
|
|
||||||
|
result, m = xmlrpclib.loads(s, use_datetime=False)
|
||||||
|
(newdt,) = result
|
||||||
|
self.assertEqual(newdt, dt)
|
||||||
|
self.assertIs(type(newdt), xmlrpclib.DateTime)
|
||||||
|
self.assertIsNone(m)
|
||||||
|
|
||||||
|
|
||||||
def test_datetime_before_1900(self):
|
def test_datetime_before_1900(self):
|
||||||
# same as before but with a date before 1900
|
# same as before but with a date before 1900
|
||||||
dt = datetime.datetime(1, 2, 10, 11, 41, 23)
|
dt = datetime.datetime(1, 2, 10, 11, 41, 23)
|
||||||
|
self.assertEqual(dt, xmlrpclib.DateTime('00010210T11:41:23'))
|
||||||
s = xmlrpclib.dumps((dt,))
|
s = xmlrpclib.dumps((dt,))
|
||||||
(newdt,), m = xmlrpclib.loads(s, use_datetime=1)
|
|
||||||
self.assertEqual(newdt, dt)
|
|
||||||
self.assertEqual(m, None)
|
|
||||||
|
|
||||||
(newdt,), m = xmlrpclib.loads(s, use_datetime=0)
|
result, m = xmlrpclib.loads(s, use_builtin_types=True)
|
||||||
self.assertEqual(newdt, xmlrpclib.DateTime('00010210T11:41:23'))
|
(newdt,) = result
|
||||||
|
self.assertEqual(newdt, dt)
|
||||||
|
self.assertIs(type(newdt), datetime.datetime)
|
||||||
|
self.assertIsNone(m)
|
||||||
|
|
||||||
|
result, m = xmlrpclib.loads(s, use_builtin_types=False)
|
||||||
|
(newdt,) = result
|
||||||
|
self.assertEqual(newdt, dt)
|
||||||
|
self.assertIs(type(newdt), xmlrpclib.DateTime)
|
||||||
|
self.assertIsNone(m)
|
||||||
|
|
||||||
def test_bug_1164912 (self):
|
def test_bug_1164912 (self):
|
||||||
d = xmlrpclib.DateTime()
|
d = xmlrpclib.DateTime()
|
||||||
|
@ -133,6 +162,25 @@ class XMLRPCTestCase(unittest.TestCase):
|
||||||
xmlrpclib.loads(strg)[0][0])
|
xmlrpclib.loads(strg)[0][0])
|
||||||
self.assertRaises(TypeError, xmlrpclib.dumps, (arg1,))
|
self.assertRaises(TypeError, xmlrpclib.dumps, (arg1,))
|
||||||
|
|
||||||
|
def test_dump_bytes(self):
|
||||||
|
sample = b"my dog has fleas"
|
||||||
|
self.assertEqual(sample, xmlrpclib.Binary(sample))
|
||||||
|
for type_ in bytes, bytearray, xmlrpclib.Binary:
|
||||||
|
value = type_(sample)
|
||||||
|
s = xmlrpclib.dumps((value,))
|
||||||
|
|
||||||
|
result, m = xmlrpclib.loads(s, use_builtin_types=True)
|
||||||
|
(newvalue,) = result
|
||||||
|
self.assertEqual(newvalue, sample)
|
||||||
|
self.assertIs(type(newvalue), bytes)
|
||||||
|
self.assertIsNone(m)
|
||||||
|
|
||||||
|
result, m = xmlrpclib.loads(s, use_builtin_types=False)
|
||||||
|
(newvalue,) = result
|
||||||
|
self.assertEqual(newvalue, sample)
|
||||||
|
self.assertIs(type(newvalue), xmlrpclib.Binary)
|
||||||
|
self.assertIsNone(m)
|
||||||
|
|
||||||
def test_get_host_info(self):
|
def test_get_host_info(self):
|
||||||
# see bug #3613, this raised a TypeError
|
# see bug #3613, this raised a TypeError
|
||||||
transp = xmlrpc.client.Transport()
|
transp = xmlrpc.client.Transport()
|
||||||
|
@ -140,9 +188,6 @@ class XMLRPCTestCase(unittest.TestCase):
|
||||||
('host.tld',
|
('host.tld',
|
||||||
[('Authorization', 'Basic dXNlcg==')], {}))
|
[('Authorization', 'Basic dXNlcg==')], {}))
|
||||||
|
|
||||||
def test_dump_bytes(self):
|
|
||||||
self.assertRaises(TypeError, xmlrpclib.dumps, (b"my dog has fleas",))
|
|
||||||
|
|
||||||
def test_ssl_presence(self):
|
def test_ssl_presence(self):
|
||||||
try:
|
try:
|
||||||
import ssl
|
import ssl
|
||||||
|
|
|
@ -386,8 +386,8 @@ class Binary:
|
||||||
if data is None:
|
if data is None:
|
||||||
data = b""
|
data = b""
|
||||||
else:
|
else:
|
||||||
if not isinstance(data, bytes):
|
if not isinstance(data, (bytes, bytearray)):
|
||||||
raise TypeError("expected bytes, not %s" %
|
raise TypeError("expected bytes or bytearray, not %s" %
|
||||||
data.__class__.__name__)
|
data.__class__.__name__)
|
||||||
data = bytes(data) # Make a copy of the bytes!
|
data = bytes(data) # Make a copy of the bytes!
|
||||||
self.data = data
|
self.data = data
|
||||||
|
@ -559,6 +559,14 @@ class Marshaller:
|
||||||
write("</string></value>\n")
|
write("</string></value>\n")
|
||||||
dispatch[str] = dump_unicode
|
dispatch[str] = dump_unicode
|
||||||
|
|
||||||
|
def dump_bytes(self, value, write):
|
||||||
|
write("<value><base64>\n")
|
||||||
|
encoded = base64.encodebytes(value)
|
||||||
|
write(encoded.decode('ascii'))
|
||||||
|
write("</base64></value>\n")
|
||||||
|
dispatch[bytes] = dump_bytes
|
||||||
|
dispatch[bytearray] = dump_bytes
|
||||||
|
|
||||||
def dump_array(self, value, write):
|
def dump_array(self, value, write):
|
||||||
i = id(value)
|
i = id(value)
|
||||||
if i in self.memo:
|
if i in self.memo:
|
||||||
|
@ -629,7 +637,7 @@ class Unmarshaller:
|
||||||
# and again, if you don't understand what's going on in here,
|
# and again, if you don't understand what's going on in here,
|
||||||
# that's perfectly ok.
|
# that's perfectly ok.
|
||||||
|
|
||||||
def __init__(self, use_datetime=False):
|
def __init__(self, use_datetime=False, use_builtin_types=False):
|
||||||
self._type = None
|
self._type = None
|
||||||
self._stack = []
|
self._stack = []
|
||||||
self._marks = []
|
self._marks = []
|
||||||
|
@ -637,7 +645,8 @@ class Unmarshaller:
|
||||||
self._methodname = None
|
self._methodname = None
|
||||||
self._encoding = "utf-8"
|
self._encoding = "utf-8"
|
||||||
self.append = self._stack.append
|
self.append = self._stack.append
|
||||||
self._use_datetime = use_datetime
|
self._use_datetime = use_builtin_types or use_datetime
|
||||||
|
self._use_bytes = use_builtin_types
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
# return response tuple and target method
|
# return response tuple and target method
|
||||||
|
@ -749,6 +758,8 @@ class Unmarshaller:
|
||||||
def end_base64(self, data):
|
def end_base64(self, data):
|
||||||
value = Binary()
|
value = Binary()
|
||||||
value.decode(data.encode("ascii"))
|
value.decode(data.encode("ascii"))
|
||||||
|
if self._use_bytes:
|
||||||
|
value = value.data
|
||||||
self.append(value)
|
self.append(value)
|
||||||
self._value = 0
|
self._value = 0
|
||||||
dispatch["base64"] = end_base64
|
dispatch["base64"] = end_base64
|
||||||
|
@ -860,21 +871,26 @@ FastMarshaller = FastParser = FastUnmarshaller = None
|
||||||
#
|
#
|
||||||
# return A (parser, unmarshaller) tuple.
|
# return A (parser, unmarshaller) tuple.
|
||||||
|
|
||||||
def getparser(use_datetime=False):
|
def getparser(use_datetime=False, use_builtin_types=False):
|
||||||
"""getparser() -> parser, unmarshaller
|
"""getparser() -> parser, unmarshaller
|
||||||
|
|
||||||
Create an instance of the fastest available parser, and attach it
|
Create an instance of the fastest available parser, and attach it
|
||||||
to an unmarshalling object. Return both objects.
|
to an unmarshalling object. Return both objects.
|
||||||
"""
|
"""
|
||||||
if FastParser and FastUnmarshaller:
|
if FastParser and FastUnmarshaller:
|
||||||
if use_datetime:
|
if use_builtin_types:
|
||||||
mkdatetime = _datetime_type
|
mkdatetime = _datetime_type
|
||||||
|
mkbytes = base64.decodebytes
|
||||||
|
elif use_datetime:
|
||||||
|
mkdatetime = _datetime_type
|
||||||
|
mkbytes = _binary
|
||||||
else:
|
else:
|
||||||
mkdatetime = _datetime
|
mkdatetime = _datetime
|
||||||
target = FastUnmarshaller(True, False, _binary, mkdatetime, Fault)
|
mkbytes = _binary
|
||||||
|
target = FastUnmarshaller(True, False, mkbytes, mkdatetime, Fault)
|
||||||
parser = FastParser(target)
|
parser = FastParser(target)
|
||||||
else:
|
else:
|
||||||
target = Unmarshaller(use_datetime=use_datetime)
|
target = Unmarshaller(use_datetime=use_datetime, use_builtin_types=use_builtin_types)
|
||||||
if FastParser:
|
if FastParser:
|
||||||
parser = FastParser(target)
|
parser = FastParser(target)
|
||||||
else:
|
else:
|
||||||
|
@ -912,7 +928,7 @@ def dumps(params, methodname=None, methodresponse=None, encoding=None,
|
||||||
|
|
||||||
encoding: the packet encoding (default is UTF-8)
|
encoding: the packet encoding (default is UTF-8)
|
||||||
|
|
||||||
All 8-bit strings in the data structure are assumed to use the
|
All byte strings in the data structure are assumed to use the
|
||||||
packet encoding. Unicode strings are automatically converted,
|
packet encoding. Unicode strings are automatically converted,
|
||||||
where necessary.
|
where necessary.
|
||||||
"""
|
"""
|
||||||
|
@ -971,7 +987,7 @@ def dumps(params, methodname=None, methodresponse=None, encoding=None,
|
||||||
# (None if not present).
|
# (None if not present).
|
||||||
# @see Fault
|
# @see Fault
|
||||||
|
|
||||||
def loads(data, use_datetime=False):
|
def loads(data, use_datetime=False, use_builtin_types=False):
|
||||||
"""data -> unmarshalled data, method name
|
"""data -> unmarshalled data, method name
|
||||||
|
|
||||||
Convert an XML-RPC packet to unmarshalled data plus a method
|
Convert an XML-RPC packet to unmarshalled data plus a method
|
||||||
|
@ -980,7 +996,7 @@ def loads(data, use_datetime=False):
|
||||||
If the XML-RPC packet represents a fault condition, this function
|
If the XML-RPC packet represents a fault condition, this function
|
||||||
raises a Fault exception.
|
raises a Fault exception.
|
||||||
"""
|
"""
|
||||||
p, u = getparser(use_datetime=use_datetime)
|
p, u = getparser(use_datetime=use_datetime, use_builtin_types=use_builtin_types)
|
||||||
p.feed(data)
|
p.feed(data)
|
||||||
p.close()
|
p.close()
|
||||||
return u.close(), u.getmethodname()
|
return u.close(), u.getmethodname()
|
||||||
|
@ -1092,8 +1108,9 @@ class Transport:
|
||||||
# that they can decode such a request
|
# that they can decode such a request
|
||||||
encode_threshold = None #None = don't encode
|
encode_threshold = None #None = don't encode
|
||||||
|
|
||||||
def __init__(self, use_datetime=False):
|
def __init__(self, use_datetime=False, use_builtin_types=False):
|
||||||
self._use_datetime = use_datetime
|
self._use_datetime = use_datetime
|
||||||
|
self._use_builtin_types = use_builtin_types
|
||||||
self._connection = (None, None)
|
self._connection = (None, None)
|
||||||
self._extra_headers = []
|
self._extra_headers = []
|
||||||
|
|
||||||
|
@ -1154,7 +1171,8 @@ class Transport:
|
||||||
|
|
||||||
def getparser(self):
|
def getparser(self):
|
||||||
# get parser and unmarshaller
|
# get parser and unmarshaller
|
||||||
return getparser(use_datetime=self._use_datetime)
|
return getparser(use_datetime=self._use_datetime,
|
||||||
|
use_builtin_types=self._use_builtin_types)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Get authorization info from host parameter
|
# Get authorization info from host parameter
|
||||||
|
@ -1361,7 +1379,7 @@ class ServerProxy:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, uri, transport=None, encoding=None, verbose=False,
|
def __init__(self, uri, transport=None, encoding=None, verbose=False,
|
||||||
allow_none=False, use_datetime=False):
|
allow_none=False, use_datetime=False, use_builtin_types=False):
|
||||||
# establish a "logical" server connection
|
# establish a "logical" server connection
|
||||||
|
|
||||||
# get the url
|
# get the url
|
||||||
|
@ -1375,9 +1393,11 @@ class ServerProxy:
|
||||||
|
|
||||||
if transport is None:
|
if transport is None:
|
||||||
if type == "https":
|
if type == "https":
|
||||||
transport = SafeTransport(use_datetime=use_datetime)
|
handler = SafeTransport
|
||||||
else:
|
else:
|
||||||
transport = Transport(use_datetime=use_datetime)
|
handler = Transport
|
||||||
|
transport = handler(use_datetime=use_datetime,
|
||||||
|
use_builtin_types=use_builtin_types)
|
||||||
self.__transport = transport
|
self.__transport = transport
|
||||||
|
|
||||||
self.__encoding = encoding or 'utf-8'
|
self.__encoding = encoding or 'utf-8'
|
||||||
|
|
|
@ -374,6 +374,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #13297: Use bytes type to send and receive binary data through XMLRPC.
|
||||||
|
|
||||||
- Issue #6397: Support "/dev/poll" polling objects in select module,
|
- Issue #6397: Support "/dev/poll" polling objects in select module,
|
||||||
under Solaris & derivatives.
|
under Solaris & derivatives.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue