-
Notifications
You must be signed in to change notification settings - Fork 148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make folding for lists optional #64
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ | |
|
||
from __future__ import unicode_literals | ||
|
||
__version__ = '1.7.4' | ||
__version__ = '1.8.0' | ||
version = __version__ | ||
|
||
from random import randint | ||
|
@@ -165,7 +165,7 @@ def default_item_func(parent): | |
return 'item' | ||
|
||
|
||
def convert(obj, ids, attr_type, item_func, cdata, parent='root'): | ||
def convert(obj, ids, attr_type, item_func, cdata, fold_list, parent='root'): | ||
"""Routes the elements of an object to the right function to convert them | ||
based on their data type""" | ||
|
||
|
@@ -186,15 +186,15 @@ def convert(obj, ids, attr_type, item_func, cdata, parent='root'): | |
return convert_none(item_name, '', attr_type, cdata) | ||
|
||
if isinstance(obj, dict): | ||
return convert_dict(obj, ids, parent, attr_type, item_func, cdata) | ||
return convert_dict(obj, ids, parent, attr_type, item_func, cdata, fold_list) | ||
|
||
if isinstance(obj, collections.Iterable): | ||
return convert_list(obj, ids, parent, attr_type, item_func, cdata) | ||
return convert_list(obj, ids, parent, attr_type, item_func, cdata, fold_list) | ||
|
||
raise TypeError('Unsupported data type: %s (%s)' % (obj, type(obj).__name__)) | ||
|
||
|
||
def convert_dict(obj, ids, parent, attr_type, item_func, cdata): | ||
def convert_dict(obj, ids, parent, attr_type, item_func, cdata, fold_list): | ||
"""Converts a dict into an XML string.""" | ||
LOG.info('Inside convert_dict(): obj type is: "%s", obj="%s"' % ( | ||
type(obj).__name__, unicode_me(obj)) | ||
|
@@ -227,21 +227,24 @@ def convert_dict(obj, ids, parent, attr_type, item_func, cdata): | |
attr['type'] = get_xml_type(val) | ||
addline('<%s%s>%s</%s>' % ( | ||
key, make_attrstring(attr), | ||
convert_dict(val, ids, key, attr_type, item_func, cdata), | ||
convert_dict(val, ids, key, attr_type, item_func, cdata, fold_list), | ||
key | ||
) | ||
) | ||
|
||
elif isinstance(val, collections.Iterable): | ||
if attr_type: | ||
attr['type'] = get_xml_type(val) | ||
addline('<%s%s>%s</%s>' % ( | ||
key, | ||
make_attrstring(attr), | ||
convert_list(val, ids, key, attr_type, item_func, cdata), | ||
key | ||
if fold_list: | ||
addline('<%s%s>%s</%s>' % ( | ||
key, | ||
make_attrstring(attr), | ||
convert_list(val, ids, key, attr_type, item_func, cdata, fold_list), | ||
key | ||
) | ||
) | ||
) | ||
else: | ||
addline(convert_list(val, ids, key, attr_type, item_func, cdata, fold_list)) | ||
|
||
elif val is None: | ||
addline(convert_none(key, val, attr_type, attr, cdata)) | ||
|
@@ -254,13 +257,16 @@ def convert_dict(obj, ids, parent, attr_type, item_func, cdata): | |
return ''.join(output) | ||
|
||
|
||
def convert_list(items, ids, parent, attr_type, item_func, cdata): | ||
def convert_list(items, ids, parent, attr_type, item_func, cdata, fold_list): | ||
"""Converts a list into an XML string.""" | ||
LOG.info('Inside convert_list()') | ||
output = [] | ||
addline = output.append | ||
|
||
item_name = item_func(parent) | ||
if fold_list: | ||
item_name = item_func(parent) | ||
else: | ||
item_name = parent | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe you could explicitly fail-fast if |
||
|
||
if ids: | ||
this_id = get_unique_id(parent) | ||
|
@@ -283,30 +289,30 @@ def convert_list(items, ids, parent, attr_type, item_func, cdata): | |
if not attr_type: | ||
addline('<%s>%s</%s>' % ( | ||
item_name, | ||
convert_dict(item, ids, parent, attr_type, item_func, cdata), | ||
convert_dict(item, ids, parent, attr_type, item_func, cdata, fold_list), | ||
item_name, | ||
) | ||
) | ||
else: | ||
addline('<%s type="dict">%s</%s>' % ( | ||
item_name, | ||
convert_dict(item, ids, parent, attr_type, item_func, cdata), | ||
convert_dict(item, ids, parent, attr_type, item_func, cdata, fold_list), | ||
item_name, | ||
) | ||
) | ||
|
||
elif isinstance(item, collections.Iterable): | ||
if not attr_type: | ||
addline('<%s %s>%s</%s>' % ( | ||
addline('<%s%s>%s</%s>' % ( | ||
item_name, make_attrstring(attr), | ||
convert_list(item, ids, item_name, attr_type, item_func, cdata), | ||
convert_list(item, ids, item_name, attr_type, item_func, cdata, fold_list), | ||
item_name, | ||
) | ||
) | ||
else: | ||
addline('<%s type="list"%s>%s</%s>' % ( | ||
item_name, make_attrstring(attr), | ||
convert_list(item, ids, item_name, attr_type, item_func, cdata), | ||
convert_list(item, ids, item_name, attr_type, item_func, cdata, fold_list), | ||
item_name, | ||
) | ||
) | ||
|
@@ -366,7 +372,7 @@ def convert_none(key, val, attr_type, attr={}, cdata=False): | |
|
||
|
||
def dicttoxml(obj, root=True, custom_root='root', ids=False, attr_type=True, | ||
item_func=default_item_func, cdata=False): | ||
item_func=default_item_func, cdata=False, fold_list=True): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An alternative design may be to vary the result of # Using a dict may be a bit lazy here, but it should communicate the idea. You'd have
# to check the return type in places that use the result for backward compat.
def custom_item_func(parent):
if parent == 'Special':
return { 'name': parent, 'should_fold': True }
else:
return { 'name': parent, 'should_fold': False }
dicttoxml(…, item_func = custom_item_func) This would enable you to vary the behavior based on the element or some condition. It may also simplify the number of parameters being passed about in the implementation? As another note: in VS Code that there is no doc comment for the new parameter, it might be worth adding it to help with visibility and documentation 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually need this feature. because in a specification I'm implementing both cases are necessary. |
||
"""Converts a python object into XML. | ||
Arguments: | ||
- root specifies whether the output is wrapped in an XML root element | ||
|
@@ -390,11 +396,11 @@ def dicttoxml(obj, root=True, custom_root='root', ids=False, attr_type=True, | |
addline('<?xml version="1.0" encoding="UTF-8" ?>') | ||
addline('<%s>%s</%s>' % ( | ||
custom_root, | ||
convert(obj, ids, attr_type, item_func, cdata, parent=custom_root), | ||
convert(obj, ids, attr_type, item_func, cdata, fold_list, parent=custom_root), | ||
custom_root, | ||
) | ||
) | ||
else: | ||
addline(convert(obj, ids, attr_type, item_func, cdata, parent='')) | ||
addline(convert(obj, ids, attr_type, item_func, cdata, fold_list, parent='')) | ||
return ''.join(output).encode('utf-8') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might also want to bump this in setup.py so it's recognized by pip :-)