Source code for pySPACE.tools.conversion
""" Type conversion helper functions """
import copy
import string
import warnings
import yaml
[docs]def python2yaml(value):
""" Conversion function to handle yaml specialties"""
# due to ugly incompatibilities in the conversion of
# float (yaml) -> float (python) -> float(yaml) and
# iterable(python) -> iterable(yaml),
# we have to introduce this special treatment
str_representation = yaml.dump([value], default_flow_style=True).strip()
if str_representation.startswith('-'):
return str_representation[2:]
elif str_representation.startswith('['):
return str_representation[1:-1]
else:
warnings.warn("Wrong format for yaml conversion of template (%s)."
% str_representation)
return str(value)
[docs]def replace_parameters_and_convert(node_chain_spec, parameter_setting):
""" Replace parameters of parameter_setting in node_chain_spec
and return the Python object and not the YAML string.
"""
# we have not specified a template file but a complete
# node chain instead, for replacing parameters, it has to be reconverted
# to a string
if type(node_chain_spec) == list:
node_chain_spec = repr(node_chain_spec) #yaml.dump(node_chain_spec)
warnings.warn("Issues with parameter replacement might occur!")
elif isinstance(node_chain_spec, basestring):
pass
else:
warnings.warn("Wrong format of template (%s). Trying to proceed."
% str(node_chain_spec))
node_chain_spec = replace_parameters(node_chain_spec, parameter_setting)
# final loading of the modified YAML file
return yaml.load(node_chain_spec)
[docs]def replace_parameters(node_chain_spec, parameter_setting):
""" Replace parameters in string and return this string """
# Instantiate the template
for key, value in parameter_setting.iteritems():
# Parameters framed by "#" are considered to be escaped
if "#"+key+"#" in node_chain_spec:
node_chain_spec = node_chain_spec.replace("#"+key+"#", "##")
#chek for optimization and normal parameter rule
elif key.startswith("_") or key.startswith("~"):
try:
if type(value) == str:
node_chain_spec = \
node_chain_spec.replace("%s" % str(key), value)
else:
node_chain_spec = node_chain_spec.replace(
"%s" % str(key), repr(value))
except:
node_chain_spec = node_chain_spec.replace(
"%s" % str(key), python2yaml(value))
else:
node_chain_spec = node_chain_spec.replace(
"%s" % str(key), python2yaml(value))
warnings.warn("The parameter %s is no regular parameter." +
"Better use one starting with '_' or '~'. " +
"Replacing despite." % key)
if "##" in node_chain_spec:
node_chain_spec = node_chain_spec.replace("##", key)
return node_chain_spec
[docs]def eval_string(s):
if s.startswith("eval("):
try:
return eval(s[5:-1])
except:
return s
else:
return s
[docs]def replace_in_list(list_, replacements):
new_list = []
for item in list_:
# Base case: item is not a structure
if isinstance(item, str):
item = string.Template(item).safe_substitute(**replacements)
item = eval_string(item)
# The item is itself a list, replace recursively
if isinstance(item, list):
# Check recursively
item = replace_in_list(item, replacements)
# The item is a dict, look for keys and values
elif isinstance(item, dict):
item = replace_in_dict(item, replacements)
new_list.append(item)
return new_list
[docs]def replace_in_dict(dict_, replacements):
new_dict = {}
for key, value in dict_.iteritems():
if isinstance(value, list):
value = replace_in_list(value, replacements)
elif isinstance(value, dict):
value = replace_in_dict(value, replacements)
elif isinstance(value, str):
value = string.Template(value).safe_substitute(**replacements)
value = eval_string(value)
key = string.Template(key).safe_substitute(**replacements)
key = eval_string(key)
new_dict[key] = value
return new_dict
[docs]def replace_parameters2(node_chain_spec, parameter_setting):
return replace_in_list(node_chain_spec, parameter_setting)