in libcloud/common/nttcis.py [0:0]
def processor(mapping, name=None):
"""
Closure that keeps the deepcopy of the original dict
converted to XML current.
:param mapping: The converted XML to dict/lists
:type mapping: ``dict``
:param name: (Optional) what becomes the class name if provided
:type: ``str``
:return: Nothing
"""
mapping = mapping
# the map_copy will have keys deleted after the key and value are processed
map_copy = deepcopy(mapping)
def add_items(key, value, name=None):
"""
Add items to the global attr dict, then delete key, value from map copy
:param key: from the process function becomes the attribute name
:type key: ``str``
:param value: The value of the property and may be a dict
:type value: ``str``
:param name: Name of class, often same as key
:type: name" ``str``
"""
if name in attrs:
attrs[name].update({key: value})
elif name is not None:
attrs[name] = value
else:
attrs.update({key: value})
# trim the copy of the mapping
if key in map_copy:
del map_copy[key]
elif key in map_copy[name]:
del map_copy[name][key]
if len(map_copy[name]) == 0:
del map_copy[name]
def handle_map(map, name):
tmp = {}
types = [type(x) for x in map.values()]
if XmlListConfig not in types and XmlDictConfig not in types and dict not in types:
return map
elif XmlListConfig in types:
result = handle_seq(map, name)
return result
else:
for k, v in map.items():
if isinstance(v, str):
tmp.update({k: v})
if isinstance(v, dict):
cls = build_class(k.capitalize(), v)
tmp.update({k: cls})
elif isinstance(v, XmlDictConfig):
cls = build_class(k.capitalize(), v)
return (k, cls)
return tmp
def handle_seq(seq, name):
tmp = {}
if isinstance(seq, list):
tmp = []
for _ in seq:
cls = build_class(name.capitalize(), _)
tmp.append(cls)
return tmp
for k, v in seq.items():
if isinstance(v, MutableSequence):
for _ in v:
if isinstance(_, Mapping):
types = [type(x) for x in _.values()]
if XmlDictConfig in types:
result = handle_map(_, k)
if isinstance(result, tuple):
tmp.update({result[0]: result[1]})
else:
tmp.update({k: result})
else:
tmp_list = [build_class(k.capitalize(), i) for i in v]
tmp[k] = tmp_list
elif isinstance(v, str):
tmp.update({k: v})
return tmp
def build_class(key, value):
klass = class_factory(key.capitalize(), value)
return klass(value)
def process(mapping):
"""
This function is recursive, creating attributes for the class factory
by taking apart the elements in the dictionary. Thus, the calls to
handle_seq or handle_map
:param mapping: the dictionary converted from XML
:return: itself (recursive)
"""
for k1, v1 in mapping.items():
if isinstance(v1, Mapping):
types = [type(v) for v in v1.values()]
if MutableSequence not in types and dict not in types:
result = handle_map(v1, k1)
cls = build_class(k1.capitalize(), result)
add_items(k1, cls)
elif XmlListConfig in types:
result = handle_seq(v1, k1)
cls = build_class(list(v1)[0], result)
add_items(k1, cls)
elif dict in types:
result = handle_map(v1, k1)
cls = build_class(k1.capitalize(), result)
add_items(k1, cls, k1)
elif isinstance(v1, list):
tmp1 = {}
tmp2 = {}
tmp2[k1] = []
for i, j in enumerate(v1):
if isinstance(j, dict):
key = list(j)[0]
result = handle_map(j, key)
tmp1[k1 + str(i)] = build_class(k1, result)
tmp2[k1].append(tmp1[k1 + str(i)])
if tmp2:
add_items(k1, tmp2[k1], k1)
elif isinstance(v1, str):
add_items(k1, v1)
if len(map_copy) == 0:
return 1
return process(mapping)