summaryrefslogtreecommitdiff
path: root/src/lxml
diff options
context:
space:
mode:
authorTobias Deiminger <haxtibal@posteo.de>2022-02-13 19:40:39 +0100
committerGitHub <noreply@github.com>2022-02-13 19:40:39 +0100
commitf7bb07b5f68fede97754685dad076cd7b7442bac (patch)
tree09c582d6fb2d2b8d90e378ae164e5189d41b7d13 /src/lxml
parent1e3666018329cadf8e147607824614aebf7e2099 (diff)
downloadpython-lxml-f7bb07b5f68fede97754685dad076cd7b7442bac.tar.gz
Use expected XSD spellings for xsi:double infinity and NaN (GH-338)
W3C specification for xsd:double says > The special values positive and negative infinity and > not-a-number have lexical representations INF, -INF and NaN, > respectively. Thus case matters. The previously used float.__repr__ would generate "inf", "-inf", "nan". Now we prepend special handling to get "INF", "-INF", "NaN" instead (which is still pytype compatible). Includes minor non-functional alignments of related bool to text code, and tests to assert its XML schema conformance as well.
Diffstat (limited to 'src/lxml')
-rw-r--r--src/lxml/objectify.pyx20
-rw-r--r--src/lxml/tests/test_objectify.py9
2 files changed, 25 insertions, 4 deletions
diff --git a/src/lxml/objectify.pyx b/src/lxml/objectify.pyx
index cacbe806..376695a8 100644
--- a/src/lxml/objectify.pyx
+++ b/src/lxml/objectify.pyx
@@ -38,6 +38,9 @@ import_lxml__etree()
__version__ = etree.__version__
+cdef object _float_is_inf, _float_is_nan
+from math import isinf as _float_is_inf, isnan as _float_is_nan
+
cdef object re
import re
@@ -1205,8 +1208,17 @@ cdef dict _PYTYPE_DICT = {}
cdef dict _SCHEMA_TYPE_DICT = {}
cdef list _TYPE_CHECKS = []
-cdef unicode _lower_bool(b):
- return u"true" if b else u"false"
+cdef unicode _xml_bool(value):
+ return u"true" if value else u"false"
+
+cdef unicode _xml_float(value):
+ if _float_is_inf(value):
+ if value > 0:
+ return u"INF"
+ return u"-INF"
+ if _float_is_nan(value):
+ return u"NaN"
+ return unicode(repr(value))
cdef _pytypename(obj):
return u"str" if python._isString(obj) else _typename(obj)
@@ -1230,11 +1242,11 @@ cdef _registerPyTypes():
pytype = PyType(u'long', None, IntElement)
pytype.register()
- pytype = PyType(u'float', _checkFloat, FloatElement, repr) # wraps _parseFloat for Python
+ pytype = PyType(u'float', _checkFloat, FloatElement, _xml_float) # wraps functions for Python
pytype.xmlSchemaTypes = (u"double", u"float")
pytype.register()
- pytype = PyType(u'bool', _checkBool, BoolElement, _lower_bool) # wraps functions for Python
+ pytype = PyType(u'bool', _checkBool, BoolElement, _xml_bool) # wraps functions for Python
pytype.xmlSchemaTypes = (u"boolean",)
pytype.register()
diff --git a/src/lxml/tests/test_objectify.py b/src/lxml/tests/test_objectify.py
index 178ba256..f50a3447 100644
--- a/src/lxml/tests/test_objectify.py
+++ b/src/lxml/tests/test_objectify.py
@@ -873,6 +873,10 @@ class ObjectifyTestCase(HelperTestCase):
self.assertTrue(isinstance(value, objectify.BoolElement))
self.assertEqual(value, False)
+ def test_data_element_bool_text(self):
+ self.assertEqual(objectify.DataElement(False).text, "false")
+ self.assertEqual(objectify.DataElement(True).text, "true")
+
def test_type_str(self):
Element = self.Element
SubElement = self.etree.SubElement
@@ -1115,6 +1119,11 @@ class ObjectifyTestCase(HelperTestCase):
value = objectify.DataElement(f)
self.assertEqual(hash(value), hash(f))
+ def test_data_element_float_special_value_text(self):
+ self.assertEqual(objectify.DataElement(float("inf")).text, "INF")
+ self.assertEqual(objectify.DataElement(float("-inf")).text, "-INF")
+ self.assertEqual(objectify.DataElement(float("nan")).text, "NaN")
+
def test_data_element_xsitypes(self):
for xsi, objclass in xsitype2objclass.items():
# 1 is a valid value for all ObjectifiedDataElement classes