diff --git a/README.markdown b/README.markdown index 9b3952f..19138a4 100644 --- a/README.markdown +++ b/README.markdown @@ -233,12 +233,19 @@ Author Version ======= -* Version: 1.6.1 +* Version: 1.6.2 * Release Date: 2015-03-05 Revision History ================ +Version 1.6.2 +------------- + +* Release Date: 2015-03-05 +* Changes: + * Fixed [issue #35](https://github.com/quandyfactory/dicttoxml/issues/35), dicttoxml fails to identify a `decimal.Decimal` as a number. This is done by replacing `type(val).__name__ in ('int', 'long')` with the more generic `isinstance(val, number.Number)`. Thanks to [jmagnusson](https://github.com/jmagnusson) for finding and fixing the error. + Version 1.6.1 ------------- diff --git a/dicttoxml.py b/dicttoxml.py index b05b40d..c34a97b 100755 --- a/dicttoxml.py +++ b/dicttoxml.py @@ -2,20 +2,22 @@ # coding: utf-8 """ -Converts a native Python dictionary into an XML string. Supports int, float, str, unicode, list, dict and arbitrary nesting. +Converts a native Python dictionary into an XML string. Supports numbers, strings, lists, dictionaries and arbitrary nesting. """ from __future__ import unicode_literals -__version__ = '1.6.1' +__version__ = '1.6.2' version = __version__ from random import randint import collections +import numbers import logging import sys from xml.dom.minidom import parseString + LOG = logging.getLogger("dicttoxml") # python 3 doesn't have a unicode type @@ -64,6 +66,10 @@ def get_xml_type(val): return 'str' if type(val).__name__ in ('int', 'long'): return 'int' + if type(val).__name__ == 'float': + return 'float' + if isinstance(val, numbers.Number): + return 'number' if type(val).__name__ == 'NoneType': return 'null' if isinstance(val, dict): @@ -116,7 +122,7 @@ def make_valid_xml_name(key, attr): def convert(obj, ids, attr_type, parent='root'): """Routes the elements of an object to the right function to convert them based on their data type""" LOG.info('Inside convert(). obj type is: "%s", obj="%s"' % (type(obj).__name__, obj)) - if type(obj) in (int, float, long, str, unicode): + if isinstance(obj, numbers.Number) or type(obj) in (str, unicode): return convert_kv('item', obj, attr_type) if hasattr(obj, 'isoformat'): return convert_kv('item', obj.isoformat(), attr_type) @@ -126,7 +132,7 @@ def convert(obj, ids, attr_type, parent='root'): return convert_none('item', '', attr_type) if isinstance(obj, dict): return convert_dict(obj, ids, parent, attr_type) - if type(obj) in (list, set, tuple) or isinstance(obj, collections.Iterable): + if isinstance(obj, collections.Iterable): return convert_list(obj, ids, parent, attr_type) raise TypeError('Unsupported data type: %s (%s)' % (obj, type(obj).__name__)) @@ -142,7 +148,7 @@ def convert_dict(obj, ids, parent, attr_type): key, attr = make_valid_xml_name(key, attr) - if type(val) in (int, float, long, str, unicode): + if isinstance(val, numbers.Number) or type(val) in (str, unicode): addline(convert_kv(key, val, attr_type, attr)) elif hasattr(val, 'isoformat'): # datetime @@ -181,7 +187,7 @@ def convert_list(items, ids, parent, attr_type): for i, item in enumerate(items): LOG.info('Looping inside convert_list(): item="%s", type="%s"' % (item, type(item).__name__)) attr = {} if not ids else { 'id': '%s_%s' % (this_id, i+1) } - if type(item) in (int, float, long, str, unicode): + if isinstance(item, numbers.Number) or type(item) in (str, unicode): addline(convert_kv('item', item, attr_type, attr)) elif hasattr(item, 'isoformat'): # datetime addline(convert_kv('item', item.isoformat(), attr_type, attr)) @@ -204,7 +210,7 @@ def convert_list(items, ids, parent, attr_type): return ''.join(output) def convert_kv(key, val, attr_type, attr={}): - """Converts an int, float or string into an XML element""" + """Converts a number or string into an XML element""" LOG.info('Inside convert_kv(): key="%s", val="%s", type(val) is: "%s"' % (key, val, type(val).__name__)) key, attr = make_valid_xml_name(key, attr) diff --git a/dist/dicttoxml-1.6.2.tar.gz b/dist/dicttoxml-1.6.2.tar.gz new file mode 100644 index 0000000..d222902 Binary files /dev/null and b/dist/dicttoxml-1.6.2.tar.gz differ diff --git a/setup.py b/setup.py index d825512..9ab4d49 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from distutils.core import setup -version = '1.6.1' +version = '1.6.2' with open('README.markdown') as readme: long_description = readme.read()