@@ -94,6 +94,14 @@ def my_completer_function(text, line, begidx, endidx):
9494 as dynamic. Therefore it is up to the developer to validate if the user has typed an acceptable value for these
9595 arguments.
9696
97+ The following functions exist in cases where you may want to manually add choice providing function/methods to
98+ an existing argparse action. For instance, in __init__() of a custom action class.
99+
100+ set_choices_function(action, func)
101+ set_choices_method(action, method)
102+ set_completer_function(action, func)
103+ set_completer_method(action, method)
104+
97105CompletionItem Class:
98106 This class was added to help in cases where uninformative data is being tab completed. For instance,
99107 tab completing ID numbers isn't very helpful to a user without context. Returning a list of CompletionItems
@@ -223,6 +231,9 @@ def __init__(self, value: object, desc: str = '', *args, **kwargs) -> None:
223231 self .description = desc
224232
225233
234+ ############################################################################################################
235+ # Class and functions related to ChoicesCallable
236+ ############################################################################################################
226237class ChoicesCallable :
227238 """
228239 Enables using a callable as the choices provider for an argparse argument.
@@ -241,6 +252,48 @@ def __init__(self, is_method: bool, is_completer: bool, to_call: Callable):
241252 self .to_call = to_call
242253
243254
255+ def _set_choices_callable (action : argparse .Action , choices_callable : ChoicesCallable ) -> None :
256+ """
257+ Set the choices_callable attribute of an argparse Action
258+ :param action: action being edited
259+ :param choices_callable: the ChoicesCallable instance to use
260+ :raises: TypeError if used on incompatible action type
261+ """
262+ # Verify consistent use of parameters
263+ if action .choices is not None :
264+ err_msg = ("None of the following parameters can be used alongside a choices parameter:\n "
265+ "choices_function, choices_method, completer_function, completer_method" )
266+ raise (TypeError (err_msg ))
267+ elif action .nargs == 0 :
268+ err_msg = ("None of the following parameters can be used on an action that takes no arguments:\n "
269+ "choices_function, choices_method, completer_function, completer_method" )
270+ raise (TypeError (err_msg ))
271+
272+ setattr (action , ATTR_CHOICES_CALLABLE , choices_callable )
273+
274+
275+ def set_choices_function (action : argparse .Action , choices_function : Callable [[], Iterable [Any ]]) -> None :
276+ """Set choices_function on an argparse action"""
277+ _set_choices_callable (action , ChoicesCallable (is_method = False , is_completer = False , to_call = choices_function ))
278+
279+
280+ def set_choices_method (action : argparse .Action , choices_method : Callable [[Any ], Iterable [Any ]]) -> None :
281+ """Set choices_method on an argparse action"""
282+ _set_choices_callable (action , ChoicesCallable (is_method = True , is_completer = False , to_call = choices_method ))
283+
284+
285+ def set_completer_function (action : argparse .Action ,
286+ completer_function : Callable [[str , str , int , int ], List [str ]]) -> None :
287+ """Set completer_function on an argparse action"""
288+ _set_choices_callable (action , ChoicesCallable (is_method = False , is_completer = True , to_call = completer_function ))
289+
290+
291+ def set_completer_method (action : argparse .Action ,
292+ completer_method : Callable [[Any , str , str , int , int ], List [str ]]) -> None :
293+ """Set completer_method on an argparse action"""
294+ _set_choices_callable (action , ChoicesCallable (is_method = True , is_completer = True , to_call = completer_method ))
295+
296+
244297############################################################################################################
245298# Patch _ActionsContainer.add_argument with our wrapper to support more arguments
246299############################################################################################################
@@ -291,7 +344,17 @@ def _add_argument_wrapper(self, *args,
291344 See the header of this file for more information
292345
293346 :return: the created argument action
347+ :raises ValueError on incorrect parameter usage
294348 """
349+ # Verify consistent use of arguments
350+ choices_callables = [choices_function , choices_method , completer_function , completer_method ]
351+ num_params_set = len (choices_callables ) - choices_callables .count (None )
352+
353+ if num_params_set > 1 :
354+ err_msg = ("Only one of the following parameters may be used at a time:\n "
355+ "choices_function, choices_method, completer_function, completer_method" )
356+ raise (ValueError (err_msg ))
357+
295358 # Pre-process special ranged nargs
296359 nargs_range = None
297360
@@ -345,34 +408,17 @@ def _add_argument_wrapper(self, *args,
345408 # Create the argument using the original add_argument function
346409 new_arg = orig_actions_container_add_argument (self , * args , ** kwargs )
347410
348- # Verify consistent use of arguments
349- choices_params = [new_arg .choices , choices_function , choices_method , completer_function , completer_method ]
350- num_params_set = len (choices_params ) - choices_params .count (None )
351-
352- if num_params_set > 1 :
353- err_msg = ("Only one of the following parameters may be used at a time:\n "
354- "choices, choices_function, choices_method, completer_function, completer_method" )
355- raise (ValueError (err_msg ))
356- elif num_params_set > 0 and new_arg .nargs == 0 :
357- err_msg = ("None of the following parameters can be used for this type of action:\n "
358- "choices, choices_function, choices_method, completer_function, completer_method" )
359- raise (TypeError (err_msg ))
360-
361411 # Set the custom attributes
362412 setattr (new_arg , ATTR_NARGS_RANGE , nargs_range )
363413
364414 if choices_function :
365- setattr (new_arg , ATTR_CHOICES_CALLABLE ,
366- ChoicesCallable (is_method = False , is_completer = False , to_call = choices_function ))
415+ set_choices_function (new_arg , choices_function )
367416 elif choices_method :
368- setattr (new_arg , ATTR_CHOICES_CALLABLE ,
369- ChoicesCallable (is_method = True , is_completer = False , to_call = choices_method ))
417+ set_choices_method (new_arg , choices_method )
370418 elif completer_function :
371- setattr (new_arg , ATTR_CHOICES_CALLABLE ,
372- ChoicesCallable (is_method = False , is_completer = True , to_call = completer_function ))
419+ set_completer_function (new_arg , completer_function )
373420 elif completer_method :
374- setattr (new_arg , ATTR_CHOICES_CALLABLE ,
375- ChoicesCallable (is_method = True , is_completer = True , to_call = completer_method ))
421+ set_completer_method (new_arg , completer_method )
376422
377423 setattr (new_arg , ATTR_SUPPRESS_TAB_HINT , suppress_tab_hint )
378424 setattr (new_arg , ATTR_DESCRIPTIVE_COMPLETION_HEADER , descriptive_header )
0 commit comments