blob: 3f0b9c50d9eb7284385dcbe232e745110f2c8060 [file] [log] [blame]
Michael Walsh0ff2eed2019-03-12 16:21:47 -05001#!/usr/bin/env python
2
3r"""
4This module provides argument manipulation functions like pop_arg.
5"""
6
7import gen_print as gp
8
9
10def pop_arg(default, *args, **kwargs):
11 r"""
12 Pop a named argument from the args/kwargs and return a tuple consisting of
13 the argument value, the modified args and the modified kwargs.
14
15 The name of the argument is determined automatically by this function by
16 examining the source code which calls it (see examples below). If no
17 suitable argument can be found, the default value passed to this function
18 will be returned as the argument value. This function is useful for
19 wrapper functions that wish to process arguments in some way before
20 calling subordinate function.
21
22 Examples:
23
24 Given this code:
25
26 def func1(*args, **kwargs):
27
28 last_name, args, kwargs = pop_arg('Doe', *args, **kwargs)
29 some_function(last_name.capitalize(), *args, **kwargs)
30
31 Consider this call to func1:
32
33 func1('Johnson', ssn='111-11-1111')
34
35 The pop_arg in func1 would return the following:
36
37 'Johnson', [], {'ssn': "111-11-1111"}
38
39 Notice that the 'args' value returned is an empty list. Since last_name
40 was assumed to be the first positional argument, it was popped from args.
41
42 Now consider this call to func1:
43
44 func1(last_name='Johnson', ssn='111-11-1111')
45
46 The pop_arg in func1 would return the same last_name value as in the
47 previous example. The only difference being that the last_name value was
48 popped from kwargs rather than from args.
49
50 Description of argument(s):
51 default The value to return if the named argument
52 is not present in args/kwargs.
53 args The positional arguments passed to the
54 calling function.
55 kwargs The keyword arguments passed to the
56 calling function.
57 """
58
59 # Retrieve the argument name by examining the source code.
60 arg_name = gp.get_arg_name(None, arg_num=-3, stack_frame_ix=2)
61 if arg_name in kwargs:
62 arg_value = kwargs.pop(arg_name)
63 else:
64 # Convert args from a tuple to a list.
65 args = list(args)
66 if args:
67 arg_value = args.pop(0)
68 else:
69 arg_value = default
70
71 return arg_value, args, kwargs