by Apache XML-RPC implementation for numerics and None.
+======================+=======================================================+
| ``boolean`` | :class:`bool` |
+----------------------+-------------------------------------------------------+
- | ``int`` or ``i4`` | :class:`int` in range from -2147483648 to 2147483647. |
+ | ``int``, ``i1``, | :class:`int` in range from -2147483648 to 2147483647. |
+ | ``i2``, ``i4``, | Values get the ``<int>`` tag. |
+ | ``i8`` or | |
+ | ``biginteger`` | |
+----------------------+-------------------------------------------------------+
- | ``double`` | :class:`float` |
+ | ``double`` or | :class:`float`. Values get the ``<double>`` tag. |
+ | ``float`` | |
+----------------------+-------------------------------------------------------+
| ``string`` | :class:`str` |
+----------------------+-------------------------------------------------------+
| ``nil`` | The ``None`` constant. Passing is allowed only if |
| | *allow_none* is true. |
+----------------------+-------------------------------------------------------+
+ | ``bigdecimal`` | :class:`decimal.Decimal`. Returned type only. |
+ +----------------------+-------------------------------------------------------+
This is the full set of data types supported by XML-RPC. Method calls may also
raise a special :exc:`Fault` instance, used to signal XML-RPC server errors, or
.. versionchanged:: 3.5
Added the *context* argument.
+ .. versionchanged:: 3.6
+ Added support of type tags with prefixes (e.g.``ex:nil``).
+ Added support of unmarsalling additional types used by Apache XML-RPC
+ implementation for numerics: ``i1``, ``i2``, ``i8``, ``biginteger``,
+ ``float`` and ``bigdecimal``.
+ See http://ws.apache.org/xmlrpc/types.html for a description.
+
.. seealso::
<winsound.PlaySound>` (:issue:`27982`).
+xmlrpc.client
+-------------
+
+The module now supports unmarshalling additional data types used by
+Apache XML-RPC implementation for numerics and ``None``.
+(Contributed by Serhiy Storchaka in :issue:`26885`.)
+
+
zipfile
-------
import base64
import datetime
+import decimal
import sys
import time
import unittest
'</struct></value></param></params>')
self.assertRaises(ResponseError, xmlrpclib.loads, data)
+ def check_loads(self, s, value, **kwargs):
+ dump = '<params><param><value>%s</value></param></params>' % s
+ result, m = xmlrpclib.loads(dump, **kwargs)
+ (newvalue,) = result
+ self.assertEqual(newvalue, value)
+ self.assertIs(type(newvalue), type(value))
+ self.assertIsNone(m)
+
+ def test_load_standard_types(self):
+ check = self.check_loads
+ check('string', 'string')
+ check('<string>string</string>', 'string')
+ check('<string>𝔘𝔫𝔦𝔠𝔬𝔡𝔢 string</string>', '𝔘𝔫𝔦𝔠𝔬𝔡𝔢 string')
+ check('<int>2056183947</int>', 2056183947)
+ check('<int>-2056183947</int>', -2056183947)
+ check('<i4>2056183947</i4>', 2056183947)
+ check('<double>46093.78125</double>', 46093.78125)
+ check('<boolean>0</boolean>', False)
+ check('<base64>AGJ5dGUgc3RyaW5n/w==</base64>',
+ xmlrpclib.Binary(b'\x00byte string\xff'))
+ check('<base64>AGJ5dGUgc3RyaW5n/w==</base64>',
+ b'\x00byte string\xff', use_builtin_types=True)
+ check('<dateTime.iso8601>20050210T11:41:23</dateTime.iso8601>',
+ xmlrpclib.DateTime('20050210T11:41:23'))
+ check('<dateTime.iso8601>20050210T11:41:23</dateTime.iso8601>',
+ datetime.datetime(2005, 2, 10, 11, 41, 23),
+ use_builtin_types=True)
+ check('<array><data>'
+ '<value><int>1</int></value><value><int>2</int></value>'
+ '</data></array>', [1, 2])
+ check('<struct>'
+ '<member><name>b</name><value><int>2</int></value></member>'
+ '<member><name>a</name><value><int>1</int></value></member>'
+ '</struct>', {'a': 1, 'b': 2})
+
+ def test_load_extension_types(self):
+ check = self.check_loads
+ check('<nil/>', None)
+ check('<ex:nil/>', None)
+ check('<i1>205</i1>', 205)
+ check('<i2>20561</i2>', 20561)
+ check('<i8>9876543210</i8>', 9876543210)
+ check('<biginteger>98765432100123456789</biginteger>',
+ 98765432100123456789)
+ check('<float>93.78125</float>', 93.78125)
+ check('<bigdecimal>9876543210.0123456789</bigdecimal>',
+ decimal.Decimal('9876543210.0123456789'))
+
def test_get_host_info(self):
# see bug #3613, this raised a TypeError
transp = xmlrpc.client.Transport()
import sys
import time
from datetime import datetime
+from decimal import Decimal
import http.client
import urllib.parse
from xml.parsers import expat
def start(self, tag, attrs):
# prepare to handle this element
+ if ':' in tag:
+ tag = tag.split(':')[-1]
if tag == "array" or tag == "struct":
self._marks.append(len(self._stack))
self._data = []
try:
f = self.dispatch[tag]
except KeyError:
- pass # unknown tag ?
- else:
- return f(self, "".join(self._data))
+ if ':' not in tag:
+ return # unknown tag ?
+ try:
+ f = self.dispatch[tag.split(':')[-1]]
+ except KeyError:
+ return # unknown tag ?
+ return f(self, "".join(self._data))
#
# accelerator support
try:
f = self.dispatch[tag]
except KeyError:
- pass # unknown tag ?
- else:
- return f(self, data)
+ if ':' not in tag:
+ return # unknown tag ?
+ try:
+ f = self.dispatch[tag.split(':')[-1]]
+ except KeyError:
+ return # unknown tag ?
+ return f(self, data)
#
# element decoders
def end_int(self, data):
self.append(int(data))
self._value = 0
+ dispatch["i1"] = end_int
+ dispatch["i2"] = end_int
dispatch["i4"] = end_int
dispatch["i8"] = end_int
dispatch["int"] = end_int
+ dispatch["biginteger"] = end_int
def end_double(self, data):
self.append(float(data))
self._value = 0
dispatch["double"] = end_double
+ dispatch["float"] = end_double
+
+ def end_bigdecimal(self, data):
+ self.append(Decimal(data))
+ self._value = 0
+ dispatch["bigdecimal"] = end_bigdecimal
def end_string(self, data):
if self._encoding:
Library
-------
+- Issue #26885: xmlrpc now supports unmarshalling additional data types used
+ by Apache XML-RPC implementation for numerics and None.
+
- Issue #28070: Fixed parsing inline verbose flag in regular expressions.
- Issue #19500: Add client-side SSL session resumption to the ssl module.