@@ -160,25 +160,6 @@ def get_option(name: str, options: list[Options]) -> Options | None:
160
160
return None
161
161
162
162
163
- def parse_value (option : Options | Required , val : str | None ) -> Any :
164
- if val is None and option .nargs == 1 :
165
- Log ().error (f"{ option .names [0 ]} needs argument." )
166
-
167
- try :
168
- value = option .type (val )
169
- except CoerceError as e :
170
- Log ().error (e )
171
-
172
- if option .choices is not None and value not in option .choices :
173
- choices = ", " .join (option .choices )
174
-
175
- Log ().error (
176
- f"{ value } is not a choice for { option .names [0 ]} \n choices are:\n { choices } "
177
- )
178
-
179
- return value
180
-
181
-
182
163
class ArgumentParser :
183
164
def __init__ (self , program_name : str | None ):
184
165
self .program_name = program_name
@@ -201,6 +182,7 @@ def parse_args(
201
182
self ,
202
183
ns_obj : type [T ],
203
184
sys_args : list [str ],
185
+ log_ : Log | None = None ,
204
186
macros : list [tuple [set [str ], list [str ]]] | None = None ,
205
187
) -> T :
206
188
if not sys_args and self .program_name is not None :
@@ -219,9 +201,26 @@ def parse_args(
219
201
del _macros
220
202
del macros
221
203
204
+ log = Log () if log_ is None else log_
222
205
ns = ns_obj ()
223
206
option_names : list [str ] = []
224
207
208
+ def parse_value (option : Options | Required , val : str | None ) -> Any :
209
+ if val is None and option .nargs == 1 :
210
+ log .error (f"{ option .names [0 ]} needs argument." )
211
+
212
+ try :
213
+ value = option .type (val )
214
+ except CoerceError as e :
215
+ log .error (e )
216
+
217
+ if option .choices is not None and value not in option .choices :
218
+ log .error (
219
+ f"{ value } is not a choice for { option .names [0 ]} \n "
220
+ f"choices are:\n { ', ' .join (option .choices )} "
221
+ )
222
+ return value
223
+
225
224
program_name = self .program_name
226
225
requireds = self .requireds
227
226
options = self .options
@@ -256,7 +255,7 @@ def parse_args(
256
255
val = oplist_coerce (arg )
257
256
ns .__setattr__ (oplist_name , getattr (ns , oplist_name ) + [val ])
258
257
except (CoerceError , ValueError ) as e :
259
- Log () .error (e )
258
+ log .error (e )
260
259
elif requireds and not arg .startswith ("--" ):
261
260
if requireds [0 ].nargs == 1 :
262
261
ns .__setattr__ (req_list_name , parse_value (requireds [0 ], arg ))
@@ -268,19 +267,19 @@ def parse_args(
268
267
269
268
# 'Did you mean' message might appear that options need a comma.
270
269
if arg .replace ("," , "" ) in option_names :
271
- Log () .error (f"Option '{ arg } ' has an unnecessary comma." )
270
+ log .error (f"Option '{ arg } ' has an unnecessary comma." )
272
271
273
272
close_matches = difflib .get_close_matches (arg , option_names )
274
273
if close_matches :
275
- Log () .error (
274
+ log .error (
276
275
f"Unknown { label } : { arg } \n \n Did you mean:\n "
277
276
+ ", " .join (close_matches )
278
277
)
279
- Log () .error (f"Unknown { label } : { arg } " )
278
+ log .error (f"Unknown { label } : { arg } " )
280
279
else :
281
280
if option .nargs != "*" :
282
281
if option in used_options :
283
- Log () .error (
282
+ log .error (
284
283
f"Option { option .names [0 ]} may not be used more than once."
285
284
)
286
285
used_options .append (option )
0 commit comments