New source_to_object() and args_to_objects()
New functions in func_args.py:
- source_to_object:
Evaluate string value as python source code and return the resulting
object.
If value is NOT a string or can not be interpreted as a python source
object definition, simply return value.
The idea is to convert python object definition source code (e.g. for
lists, dictionaries, tuples, etc.) into an object.
- args_to_objects:
Run source_to_object() on each element in args and return the result.
Change-Id: I8f30d805cebec0f1d3e91cda36094dc3cb9c89bb
Signed-off-by: Michael Walsh <micwalsh@us.ibm.com>
diff --git a/lib/func_args.py b/lib/func_args.py
index 3f0b9c5..1bff858 100644
--- a/lib/func_args.py
+++ b/lib/func_args.py
@@ -5,6 +5,7 @@
"""
import gen_print as gp
+import collections
def pop_arg(default, *args, **kwargs):
@@ -69,3 +70,121 @@
arg_value = default
return arg_value, args, kwargs
+
+
+def source_to_object(value):
+ r"""
+ Evaluate string value as python source code and return the resulting
+ object.
+
+ If value is NOT a string or can not be interpreted as a python source
+ object definition, simply return value.
+
+ The idea is to convert python object definition source code (e.g. for
+ lists, dictionaries, tuples, etc.) into an object.
+
+ Example:
+
+ Note that this first example is a special case in that it is a short-cut
+ for specifying a collections.OrderedDict.
+
+ result = source_to_object("[('one', 1), ('two', 2), ('three', 3)]")
+
+ The result is a collections.OrderedDict object:
+
+ result:
+ [one]: 1
+ [two]: 2
+ [three]: 3
+
+ This is a short-cut for the long form shown here:
+
+ result = source_to_object("collections.OrderedDict([
+ ('one', 1),
+ ('two', 2),
+ ('three', 3)])")
+
+ Also note that support for this special-case short-cut precludes the
+ possibility of interpreting such a string as a list of tuples.
+
+ Example:
+
+ In this example, the result will be a list:
+
+ result = source_to_object("[1, 2, 3]")
+
+ result:
+ result[0]: 1
+ result[1]: 2
+ result[2]: 3
+
+ Example:
+
+ In this example, the value passed to this function is not a string, so it
+ is simply returned.
+
+ result = source_to_object(1)
+
+ More examples:
+ result = source_to_object("dict(one=1, two=2, three=3)")
+ result = source_to_object("{'one':1, 'two':2, 'three':3}")
+ result = source_to_object(True)
+ etc.
+
+ Description of argument(s):
+ value If value is a string, it will be evaluated
+ as a python statement. If the statement
+ is valid, the resulting object will be
+ returned. In all other cases, the value
+ will simply be returned.
+ """
+
+ if type(value) not in gp.get_string_types():
+ return value
+
+ # Strip white space prior to attempting to interpret the string as python
+ # code.
+ value = value.strip()
+
+ # Try special case of collections.OrderedDict:
+ if value.startswith("["):
+ try:
+ return eval("collections.OrderedDict(" + value + ")")
+ except (TypeError, NameError, ValueError):
+ pass
+
+ try:
+ return eval(value)
+ except (NameError, SyntaxError):
+ pass
+
+ return value
+
+
+def args_to_objects(args):
+ r"""
+ Run source_to_object() on each element in args and return the result.
+
+ Description of argument(s):
+ args A type of dictionary, list, set, tuple or
+ simple object whose elements are to be
+ converted via a call to source_to_object().
+ """
+
+ type_of_dict = gp.is_dict(args)
+ if type_of_dict:
+ if type_of_dict == gp.dict_type():
+ return {k: source_to_object(v) for (k, v) in args.items()}
+ elif type_of_dict == gp.ordered_dict_type():
+ return collections.OrderedDict((k, v) for (k, v) in args.items())
+ elif type_of_dict == gp.dot_dict_type():
+ return DotDict((k, v) for (k, v) in args.items())
+ elif type_of_dict == gp.normalized_dict_type():
+ return NormalizedDict((k, v) for (k, v) in args.items())
+ # Assume args is list, tuple or set.
+ if type(args) in (list, set):
+ return [source_to_object(arg) for arg in args]
+ elif type(args) is tuple:
+ return tuple([source_to_object(arg) for arg in args])
+
+ return source_to_object(args)