|
0
|
1 try:
|
|
|
2 import ConfigParser
|
|
|
3 except ImportError:
|
|
|
4 import configparser as ConfigParser
|
|
|
5 import argparse
|
|
|
6 import sys
|
|
|
7
|
|
|
8 is_python3 = (sys.version_info[0] == 3)
|
|
|
9
|
|
|
10
|
|
|
11
|
|
|
12 def parseOption(val):
|
|
|
13 """Given a value read from a config file, returns appropriately formatted
|
|
|
14 python variable.
|
|
|
15
|
|
|
16 -If `val` == 'None', returns None variable
|
|
|
17 -If `val` == 'True', returns True
|
|
|
18 -If `val` == 'False', returns False
|
|
|
19 -If `val` is a float, returns float-casted val
|
|
|
20 -If `val` is an int and not a float, returns an int-casted val
|
|
|
21 -If none of these criteria are met, returns the input value
|
|
|
22
|
|
|
23 Parameters
|
|
|
24 ----------
|
|
|
25 val : str
|
|
|
26 String from dict created by config parser
|
|
|
27
|
|
|
28 Output
|
|
|
29 ------
|
|
|
30 val : multi
|
|
|
31 Parsed config value for use with argparse
|
|
|
32
|
|
|
33
|
|
|
34 """
|
|
|
35 if val == 'None':
|
|
|
36 return None
|
|
|
37 if val == 'True':
|
|
|
38 return True
|
|
|
39 if val == 'False':
|
|
|
40 return False
|
|
|
41 try:
|
|
|
42 a = int(val)
|
|
|
43 b = float(val)
|
|
|
44 if a == b:
|
|
|
45 return int(val)
|
|
|
46 return float(val)
|
|
|
47 except:
|
|
|
48 pass
|
|
|
49 return val
|
|
|
50
|
|
|
51 def getConfigFilename(arglist, flag='--conf'):
|
|
|
52 """Reads argument list to determine if there is a config file provided.
|
|
|
53
|
|
|
54 Used to work with argparse. If `flag` is present in the input array,
|
|
|
55 the next argument is assumed to be the filename for the config file.
|
|
|
56
|
|
|
57 Parameters
|
|
|
58 ----------
|
|
|
59 arglist : list
|
|
|
60 List of all arguments to input function, from either sys.argv or a
|
|
|
61 custom list
|
|
|
62 flag : str (optional) ('--conf')
|
|
|
63 Command-line flag to look for in arglist to signify next element
|
|
|
64 is filename for config options
|
|
|
65
|
|
|
66 Returns
|
|
|
67 -------
|
|
|
68 config_filename : str (None)
|
|
|
69 Name of config file if 'flag' is present in arglist, otherwise
|
|
|
70 defaults to None
|
|
|
71 is_first : bool
|
|
|
72 Will be true if `flag` is first element of arglist. Used for method
|
|
|
73 to allow required args to be passed from config file.
|
|
|
74
|
|
|
75 """
|
|
|
76 config_filename = None
|
|
|
77 is_first = False
|
|
|
78 if flag in arglist:
|
|
|
79 idx = arglist.index(flag)
|
|
|
80 config_filename = arglist[idx+1]
|
|
|
81 if idx == 0:
|
|
|
82 is_first = True
|
|
|
83 return config_filename,is_first
|
|
|
84 return None,is_first
|
|
|
85
|
|
|
86
|
|
|
87 def defaultsDictForFunction(func_name, config_name):
|
|
|
88 """Creates a dict with default values for a given function.
|
|
|
89
|
|
|
90 Given an input config file and a function name, this function will
|
|
|
91 read in all values from the given section of the config file, then
|
|
|
92 remove the variables that are used in the config file to define
|
|
|
93 parameters for multiple functions.
|
|
|
94
|
|
|
95 Parameters
|
|
|
96 ----------
|
|
|
97 func_name : str
|
|
|
98 Name of function section of config file. (May not necessarily
|
|
|
99 be name of function in code)
|
|
|
100 config_name : str
|
|
|
101 Name of config file
|
|
|
102
|
|
|
103 Returns
|
|
|
104 -------
|
|
|
105 d_func : dict
|
|
|
106 Dictionary with all attributes for the given function. Values written
|
|
|
107 as 'None' in config file will not be added, so normal defaults
|
|
|
108 can be used.
|
|
|
109
|
|
|
110
|
|
|
111 """
|
|
|
112 if is_python3:
|
|
|
113 config = ConfigParser.ConfigParser()
|
|
|
114 else:
|
|
|
115 config = ConfigParser.SafeConfigParser()
|
|
|
116 config.read(config_name)
|
|
|
117 d_vars = dict(config.items("DEFAULT"))
|
|
|
118 d_hold = dict(config.items(func_name))
|
|
|
119 d_func = {}
|
|
|
120 for k in d_hold.keys():
|
|
|
121 if k not in d_vars:
|
|
|
122 val = parseOption(d_hold[k])
|
|
|
123 if val is not None:
|
|
|
124 d_func[k] = val
|
|
|
125 return d_func
|
|
|
126
|
|
|
127 def makeRequiredList(argdict, reqlist):
|
|
|
128 """Grabs required args from argument dict created by configparser.
|
|
|
129
|
|
|
130 Generates a list of required parameters that will be passed in lieu of
|
|
|
131 a regular arglist or sys.argv. Must be ordered in the same way they will
|
|
|
132 be input to argparse.
|
|
|
133
|
|
|
134 Parameters
|
|
|
135 ----------
|
|
|
136 argdict : dict
|
|
|
137 Dictionary of arguments returned from defaultsDictForFunction.
|
|
|
138 reqlist : list
|
|
|
139 List of required arguments, in order that they should be passed to
|
|
|
140 argparse.
|
|
|
141
|
|
|
142 Returns
|
|
|
143 -------
|
|
|
144 req_arglist : list
|
|
|
145 List of required argument values for given function, in order for
|
|
|
146 passing to argparse
|
|
|
147
|
|
|
148 Exceptions
|
|
|
149 ----------
|
|
|
150 Argument value in argdict for required arg is None
|
|
|
151
|
|
|
152
|
|
|
153
|
|
|
154 """
|
|
|
155 req_arglist = []
|
|
|
156 for arg in reqlist:
|
|
|
157 argval = argdict[arg]
|
|
|
158 if argval is None:
|
|
|
159 raise Exception("Value for required argument %s cannot be None"
|
|
|
160 % argval)
|
|
|
161 req_arglist.append(argdict[arg])
|
|
|
162 return req_arglist
|
|
|
163
|
|
|
164
|
|
|
165 def checkRequired(required_args, defaults):
|
|
|
166 for req in required_args:
|
|
|
167 if req in defaults and req[defaults] is not None:
|
|
|
168 raise Exception(('Required argument %s has value present '
|
|
|
169 ' in config file (%s) and command line' %
|
|
|
170 (req, defaults[req])))
|
|
|
171
|
|
|
172
|
|
|
173 def getArgsWithConfig(parser, sys_args, required_args, func_name):
|
|
|
174 config_name, req_included = getConfigFilename(sys_args)
|
|
|
175 if config_name is not None:
|
|
|
176 defaults = defaultsDictForFunction(func_name, config_name)
|
|
|
177 if not req_included:
|
|
|
178 checkRequired(required_args, defaults)
|
|
|
179 parser.set_defaults(**defaults)
|
|
|
180 if not req_included:
|
|
|
181 return parser.parse_args(sys_args)
|
|
|
182 else:
|
|
|
183 req_args = makeRequiredList(defaults, required_args)
|
|
|
184 return parser.parse_args(req_args)
|