| #!/usr/bin/env python | 
 |  | 
 | 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) |