diff options
author | scoder <stefan_ml@behnel.de> | 2016-04-08 13:45:09 +0200 |
---|---|---|
committer | scoder <stefan_ml@behnel.de> | 2016-04-08 13:45:09 +0200 |
commit | 85a5d43e6aee3ac29015c0fbd3af7b6cf7f2010b (patch) | |
tree | 8289cae490a24362ab80075a721b5a5672379a13 /src | |
parent | aedf10b01d281ae79f06c4931778d2f47824f379 (diff) | |
parent | 88c535f0df7f2c5bd8fb9c9d478e1b0fb4f85657 (diff) | |
download | python-lxml-85a5d43e6aee3ac29015c0fbd3af7b6cf7f2010b.tar.gz |
Merge pull request #191 from hjoukl/master
Fix losing float precision for lxml.objectify FloatElement.
Diffstat (limited to 'src')
-rw-r--r-- | src/lxml/lxml.objectify.pyx | 15 | ||||
-rw-r--r-- | src/lxml/tests/test_objectify.py | 44 |
2 files changed, 53 insertions, 6 deletions
diff --git a/src/lxml/lxml.objectify.pyx b/src/lxml/lxml.objectify.pyx index 371eb2c5..d79fcd82 100644 --- a/src/lxml/lxml.objectify.pyx +++ b/src/lxml/lxml.objectify.pyx @@ -896,11 +896,14 @@ cdef class PyType: u"""PyType(self, name, type_check, type_class, stringify=None) User defined type. - Named type that contains a type check function and a type class that - inherits from ObjectifiedDataElement. The type check must take a string - as argument and raise ValueError or TypeError if it cannot handle the - string value. It may be None in which case it is not considered for type - guessing. + Named type that contains a type check function, a type class that + inherits from ObjectifiedDataElement and an optional "stringification" + function. The type check must take a string as argument and raise + ValueError or TypeError if it cannot handle the string value. It may be + None in which case it is not considered for type guessing. For registered + named types, the 'stringify' function (or unicode() if None) is used to + convert a Python object with type name 'name' to the string representation + stored in the XML tree. Example:: @@ -1031,7 +1034,7 @@ cdef _registerPyTypes(): pytype = PyType(u'long', None, IntElement) pytype.register() - pytype = PyType(u'float', float, FloatElement) + pytype = PyType(u'float', float, FloatElement, repr) pytype.xmlSchemaTypes = (u"double", u"float") pytype.register() diff --git a/src/lxml/tests/test_objectify.py b/src/lxml/tests/test_objectify.py index b17e38c2..68b9d7a8 100644 --- a/src/lxml/tests/test_objectify.py +++ b/src/lxml/tests/test_objectify.py @@ -1016,6 +1016,50 @@ class ObjectifyTestCase(HelperTestCase): value = objectify.DataElement(5.5) self.assertEqual(hash(value), hash(5.5)) + def test_type_float_precision(self): + # test not losing precision by shortened float str() value + # repr(2.305064300557): '2.305064300557' + # str(2.305064300557): '2.30506430056' + # "%57.54f" % 2.305064300557: + # ' 2.305064300556999956626214043353684246540069580078125000' + Element = self.Element + root = Element("{objectified}root") + s = "2.305064300557" + root.f = float(s) + self.assertTrue(isinstance(root.f, objectify.FloatElement)) + self.assertEqual(root.f.text, s) + self.assertEqual(root.f.pyval, float(s)) + + def test_type_float_instantiation_precision(self): + # test precision preservation for FloatElement instantiation + s = "2.305064300557" + self.assertEqual(objectify.FloatElement(s), float(s)) + + def test_type_float_precision_consistency(self): + # test consistent FloatElement values for the different instantiation + # possibilities + Element = self.Element + root = Element("{objectified}root") + s = "2.305064300557" + f = float(s) + float_elem = objectify.FloatElement(s) + float_data_elem = objectify.DataElement(f) + root.float_child = float(f) + self.assertTrue(f == float_elem == float_data_elem == root.float_child) + + def test_data_element_float_precision(self): + # test not losing precision by shortened float str() value + f = 2305064300557.0 + value = objectify.DataElement(f) + self.assertTrue(isinstance(value, objectify.FloatElement)) + self.assertEqual(value, f) + + def test_data_element_float_hash_repr(self): + # test not losing precision by shortened float str() value + f = 2305064300557.0 + value = objectify.DataElement(f) + self.assertEqual(hash(value), hash(f)) + def test_data_element_xsitypes(self): for xsi, objclass in xsitype2objclass.items(): # 1 is a valid value for all ObjectifiedDataElement classes |