|  | #!/usr/bin/env python3 | 
|  |  | 
|  | r""" | 
|  | This module provides argument manipulation functions like pop_arg. | 
|  | """ | 
|  |  | 
|  | import gen_print as gp | 
|  | import collections | 
|  |  | 
|  |  | 
|  | def pop_arg(pop_arg_default=None, *args, **kwargs): | 
|  | r""" | 
|  | Pop a named argument from the args/kwargs and return a tuple consisting of the argument value, the | 
|  | modified args and the modified kwargs. | 
|  |  | 
|  | The name of the argument is determined automatically by this function by examining the source code which | 
|  | calls it (see examples below).  If no suitable argument can be found, the default value passed to this | 
|  | function will be returned as the argument value.  This function is useful for wrapper functions that wish | 
|  | to process arguments in some way before calling subordinate function. | 
|  |  | 
|  | Examples: | 
|  |  | 
|  | Given this code: | 
|  |  | 
|  | def func1(*args, **kwargs): | 
|  |  | 
|  | last_name, args, kwargs = pop_arg('Doe', *args, **kwargs) | 
|  | some_function(last_name.capitalize(), *args, **kwargs) | 
|  |  | 
|  | Consider this call to func1: | 
|  |  | 
|  | func1('Johnson', ssn='111-11-1111') | 
|  |  | 
|  | The pop_arg in func1 would return the following: | 
|  |  | 
|  | 'Johnson', [], {'ssn': "111-11-1111"} | 
|  |  | 
|  | Notice that the 'args' value returned is an empty list. Since last_name was assumed to be the first | 
|  | positional argument, it was popped from args. | 
|  |  | 
|  | Now consider this call to func1: | 
|  |  | 
|  | func1(last_name='Johnson', ssn='111-11-1111') | 
|  |  | 
|  | The pop_arg in func1 would return the same last_name value as in the previous example.  The only | 
|  | difference being that the last_name value was popped from kwargs rather than from args. | 
|  |  | 
|  | Description of argument(s): | 
|  | pop_arg_default                 The value to return if the named argument is not present in args/kwargs. | 
|  | args                            The positional arguments passed to the calling function. | 
|  | kwargs                          The keyword arguments passed to the calling function. | 
|  | """ | 
|  |  | 
|  | # Retrieve the argument name by examining the source code. | 
|  | arg_name = gp.get_arg_name(None, arg_num=-3, stack_frame_ix=2) | 
|  | if arg_name in kwargs: | 
|  | arg_value = kwargs.pop(arg_name) | 
|  | else: | 
|  | # Convert args from a tuple to a list. | 
|  | args = list(args) | 
|  | if args: | 
|  | arg_value = args.pop(0) | 
|  | else: | 
|  | arg_value = pop_arg_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 which accepts a list of tuple pairs. | 
|  | 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) |