11# coding=utf-8
22"""
3- This module adds capabilities to argparse by patching a few of its functions. It also defines a parser
4- class called Cmd2ArgumentParser which improves error and help output over normal argparse. All cmd2 code uses
5- this parser and it is recommended that developers of cmd2-based apps either use it or write their own parser
6- that inherits from it. This will give a consistent look-and-feel between the help/error output of built-in
7- cmd2 commands and the app-specific commands. If you wish to override the parser used by cmd2's built-in
8- commands, see override_parser.py example.
3+ This module adds capabilities to argparse by patching a few of its functions.
4+ It also defines a parser class called Cmd2ArgumentParser which improves error
5+ and help output over normal argparse. All cmd2 code uses this parser and it is
6+ recommended that developers of cmd2-based apps either use it or write their own
7+ parser that inherits from it. This will give a consistent look-and-feel between
8+ the help/error output of built-in cmd2 commands and the app-specific commands.
9+ If you wish to override the parser used by cmd2's built-in commands, see
10+ override_parser.py example.
911
10- Since the new capabilities are added by patching at the argparse API level, they are available whether or not
11- Cmd2ArgumentParser is used. However, the help and error output of Cmd2ArgumentParser is customized to notate
12- nargs ranges whereas any other parser class won't be as explicit in their output.
12+ Since the new capabilities are added by patching at the argparse API level,
13+ they are available whether or not Cmd2ArgumentParser is used. However, the help
14+ and error output of Cmd2ArgumentParser is customized to notate nargs ranges
15+ whereas any other parser class won't be as explicit in their output.
1316
14- ############################################################################################################
15- # Added capabilities
16- ############################################################################################################
1717
18- Extends argparse nargs functionality by allowing tuples which specify a range (min, max). To specify a max
19- value with no upper bound, use a 1-item tuple (min,)
20-
21- Example:
22- # -f argument expects at least 3 values
23- parser.add_argument('-f', nargs=(3,))
24-
25- # -f argument expects 3 to 5 values
26- parser.add_argument('-f', nargs=(3, 5))
27-
28- Tab Completion:
29- cmd2 uses its ArgparseCompleter class to enable argparse-based tab completion on all commands that use the
30- @with_argparse wrappers. Out of the box you get tab completion of commands, subcommands, and flag names,
31- as well as instructive hints about the current argument that print when tab is pressed. In addition,
32- you can add tab completion for each argument's values using parameters passed to add_argument().
33-
34- Below are the 5 add_argument() parameters for enabling tab completion of an argument's value. Only one
35- can be used at a time.
36-
37- choices
38- Pass a list of values to the choices parameter.
39- Example:
40- parser.add_argument('-o', '--options', choices=['An Option', 'SomeOtherOption'])
41- parser.add_argument('-o', '--options', choices=my_list)
42-
43- choices_function
44- Pass a function that returns choices. This is good in cases where the choice list is dynamically
45- generated when the user hits tab.
46-
47- Example:
48- def my_choices_function():
49- ...
50- return my_generated_list
51-
52- parser.add_argument('-o', '--options', choices_function=my_choices_function)
53-
54- choices_method
55- This is exactly like choices_function, but the function needs to be an instance method of a cmd2-based class.
56- When ArgparseCompleter calls the method, it will pass the app instance as the self argument. This is good in
57- cases where the list of choices being generated relies on state data of the cmd2-based app
58-
59- Example:
60- def my_choices_method(self):
61- ...
62- return my_generated_list
63-
64- completer_function
65- Pass a tab completion function that does custom completion. Since custom tab completion operations commonly
66- need to modify cmd2's instance variables related to tab completion, it will be rare to need a completer
67- function. completer_method should be used in those cases.
68-
69- Example:
70- def my_completer_function(text, line, begidx, endidx):
71- ...
72- return completions
73- parser.add_argument('-o', '--options', completer_function=my_completer_function)
74-
75- completer_method
76- This is exactly like completer_function, but the function needs to be an instance method of a cmd2-based class.
77- When ArgparseCompleter calls the method, it will pass the app instance as the self argument. cmd2 provides
78- a few completer methods for convenience (e.g., path_complete, delimiter_complete)
79-
80- Example:
81- This adds file-path completion to an argument
82- parser.add_argument('-o', '--options', completer_method=cmd2.Cmd.path_complete)
83-
84-
85- You can use functools.partial() to prepopulate values of the underlying choices and completer functions/methods.
86-
87- Example:
88- This says to call path_complete with a preset value for its path_filter argument.
89- completer_method = functools.partial(path_complete,
90- path_filter=lambda path: os.path.isdir(path))
91- parser.add_argument('-o', '--options', choices_method=completer_method)
92-
93- Of the 5 tab completion parameters, choices is the only one where argparse validates user input against items
94- in the choices list. This is because the other 4 parameters are meant to tab complete data sets that are viewed
95- as dynamic. Therefore it is up to the developer to validate if the user has typed an acceptable value for these
96- arguments.
97-
98- The following functions exist in cases where you may want to manually add a choice-providing function/method to
99- an existing argparse action. For instance, in __init__() of a custom action class.
100-
101- set_choices_function(action, func)
102- set_choices_method(action, method)
103- set_completer_function(action, func)
104- set_completer_method(action, method)
105-
106- There are times when what's being tab completed is determined by a previous argument on the command line.
107- In theses cases, Autocompleter can pass a dictionary that maps the command line tokens up through the one
108- being completed to their argparse argument name. To receive this dictionary, your choices/completer function
109- should have an argument called arg_tokens.
110-
111- Example:
112- def my_choices_method(self, arg_tokens)
113- def my_completer_method(self, text, line, begidx, endidx, arg_tokens)
114-
115- All values of the arg_tokens dictionary are lists, even if a particular argument expects only 1 token. Since
116- ArgparseCompleter is for tab completion, it does not convert the tokens to their actual argument types or validate
117- their values. All tokens are stored in the dictionary as the raw strings provided on the command line. It is up to
118- the developer to determine if the user entered the correct argument type (e.g. int) and validate their values.
119-
120- CompletionItem Class:
121- This class was added to help in cases where uninformative data is being tab completed. For instance,
122- tab completing ID numbers isn't very helpful to a user without context. Returning a list of CompletionItems
123- instead of a regular string for completion results will signal the ArgparseCompleter to output the completion
124- results in a table of completion tokens with descriptions instead of just a table of tokens.
18+ **Added capabilities**
19+
20+ Extends argparse nargs functionality by allowing tuples which specify a range
21+ (min, max). To specify a max value with no upper bound, use a 1-item tuple
22+ (min,)
23+
24+ Example::
25+
26+ # -f argument expects at least 3 values
27+ parser.add_argument('-f', nargs=(3,))
28+
29+ # -f argument expects 3 to 5 values
30+ parser.add_argument('-f', nargs=(3, 5))
31+
32+
33+ **Tab Completion**
34+
35+ cmd2 uses its ArgparseCompleter class to enable argparse-based tab completion
36+ on all commands that use the @with_argparse wrappers. Out of the box you get
37+ tab completion of commands, subcommands, and flag names, as well as instructive
38+ hints about the current argument that print when tab is pressed. In addition,
39+ you can add tab completion for each argument's values using parameters passed
40+ to add_argument().
41+
42+ Below are the 5 add_argument() parameters for enabling tab completion of an
43+ argument's value. Only one can be used at a time.
44+
45+ ``choices`` - pass a list of values to the choices parameter.
46+
47+ Example::
48+
49+ parser.add_argument('-o', '--options', choices=['An Option', 'SomeOtherOption'])
50+ parser.add_argument('-o', '--options', choices=my_list)
51+
52+ ``choices_function`` - pass a function that returns choices. This is good in
53+ cases where the choice list is dynamically generated when the user hits tab.
54+
55+ Example::
56+
57+ def my_choices_function():
58+ ...
59+ return my_generated_list
60+
61+ parser.add_argument('-o', '--options', choices_function=my_choices_function)
62+
63+ ``choices_method`` - this is exactly like choices_function, but the function
64+ needs to be an instance method of a cmd2-based class. When ArgparseCompleter
65+ calls the method, it will pass the app instance as the self argument. This is
66+ good in cases where the list of choices being generated relies on state data of
67+ the cmd2-based app
68+
69+ Example::
70+
71+ def my_choices_method(self):
72+ ...
73+ return my_generated_list
74+
75+ ``completer_function`` - pass a tab completion function that does custom
76+ completion. Since custom tab completion operations commonly need to modify
77+ cmd2's instance variables related to tab completion, it will be rare to need a
78+ completer function. completer_method should be used in those cases.
79+
80+ Example::
81+
82+ def my_completer_function(text, line, begidx, endidx):
83+ ...
84+ return completions
85+ parser.add_argument('-o', '--options', completer_function=my_completer_function)
86+
87+ ``completer_method`` - this is exactly like completer_function, but the
88+ function needs to be an instance method of a cmd2-based class. When
89+ ArgparseCompleter calls the method, it will pass the app instance as the self
90+ argument. cmd2 provides a few completer methods for convenience (e.g.,
91+ path_complete, delimiter_complete)
92+
93+ Example::
94+
95+ # this adds file-path completion to an argument
96+ parser.add_argument('-o', '--options', completer_method=cmd2.Cmd.path_complete)
97+
98+
99+ You can use functools.partial() to prepopulate values of the underlying
100+ choices and completer functions/methods.
101+
102+ Example::
103+
104+ # this says to call path_complete with a preset value for its path_filter argument.
105+ completer_method = functools.partial(path_complete,
106+ path_filter=lambda path: os.path.isdir(path))
107+ parser.add_argument('-o', '--options', choices_method=completer_method)
108+
109+ Of the 5 tab completion parameters, choices is the only one where argparse
110+ validates user input against items in the choices list. This is because the
111+ other 4 parameters are meant to tab complete data sets that are viewed as
112+ dynamic. Therefore it is up to the developer to validate if the user has typed
113+ an acceptable value for these arguments.
114+
115+ The following functions exist in cases where you may want to manually add a
116+ choice-providing function/method to an existing argparse action. For instance,
117+ in __init__() of a custom action class.
118+
119+ - set_choices_function(action, func)
120+ - set_choices_method(action, method)
121+ - set_completer_function(action, func)
122+ - set_completer_method(action, method)
123+
124+ There are times when what's being tab completed is determined by a previous
125+ argument on the command line. In theses cases, Autocompleter can pass a
126+ dictionary that maps the command line tokens up through the one being completed
127+ to their argparse argument name. To receive this dictionary, your
128+ choices/completer function should have an argument called arg_tokens.
129+
130+ Example::
131+
132+ def my_choices_method(self, arg_tokens)
133+ def my_completer_method(self, text, line, begidx, endidx, arg_tokens)
134+
135+ All values of the arg_tokens dictionary are lists, even if a particular
136+ argument expects only 1 token. Since ArgparseCompleter is for tab completion,
137+ it does not convert the tokens to their actual argument types or validate their
138+ values. All tokens are stored in the dictionary as the raw strings provided on
139+ the command line. It is up to the developer to determine if the user entered
140+ the correct argument type (e.g. int) and validate their values.
141+
142+ CompletionItem Class - This class was added to help in cases where
143+ uninformative data is being tab completed. For instance, tab completing ID
144+ numbers isn't very helpful to a user without context. Returning a list of
145+ CompletionItems instead of a regular string for completion results will signal
146+ the ArgparseCompleter to output the completion results in a table of completion
147+ tokens with descriptions instead of just a table of tokens::
125148
126149 Instead of this:
127150 1 2 3
@@ -133,42 +156,50 @@ def my_completer_method(self, text, line, begidx, endidx, arg_tokens)
133156 3 Yet another item
134157
135158
136- The left-most column is the actual value being tab completed and its header is that value's name.
137- The right column header is defined using the descriptive_header parameter of add_argument(). The right
138- column values come from the CompletionItem.description value.
159+ The left-most column is the actual value being tab completed and its header is
160+ that value's name. The right column header is defined using the
161+ descriptive_header parameter of add_argument(). The right column values come
162+ from the CompletionItem.description value.
163+
164+ Example::
139165
140- Example:
141- token = 1
142- token_description = "My Item"
143- completion_item = CompletionItem(token, token_description)
166+ token = 1
167+ token_description = "My Item"
168+ completion_item = CompletionItem(token, token_description)
144169
145- Since descriptive_header and CompletionItem.description are just strings, you can format them in
146- such a way to have multiple columns.
170+ Since descriptive_header and CompletionItem.description are just strings, you
171+ can format them in such a way to have multiple columns::
147172
148173 ITEM_ID Item Name Checked Out Due Date
149174 1 My item True 02/02/2022
150175 2 Another item False
151176 3 Yet another item False
152177
153- To use CompletionItems, just return them from your choices or completer functions.
178+ To use CompletionItems, just return them from your choices or completer
179+ functions.
154180
155- To avoid printing a ton of information to the screen at once when a user presses tab, there is
156- a maximum threshold for the number of CompletionItems that will be shown. Its value is defined
157- in cmd2.Cmd.max_completion_items. It defaults to 50, but can be changed. If the number of completion
158- suggestions exceeds this number, they will be displayed in the typical columnized format and will
159- not include the description value of the CompletionItems.
181+ To avoid printing a ton of information to the screen at once when a user
182+ presses tab, there is a maximum threshold for the number of CompletionItems
183+ that will be shown. Its value is defined in cmd2.Cmd.max_completion_items. It
184+ defaults to 50, but can be changed. If the number of completion suggestions
185+ exceeds this number, they will be displayed in the typical columnized format
186+ and will not include the description value of the CompletionItems.
160187
161- ############################################################################################################
162- # Patched argparse functions:
163- ###########################################################################################################
164- argparse._ActionsContainer.add_argument - adds arguments related to tab completion and enables nargs range parsing
165- See _add_argument_wrapper for more details on these argument
188+
189+ **Patched argparse functions**
190+
191+ argparse._ActionsContainer.add_argument - adds arguments related to tab
192+ completion and enables nargs range
193+ parsing See _add_argument_wrapper for
194+ more details on these argument
166195
167196argparse.ArgumentParser._get_nargs_pattern - adds support to for nargs ranges
168- See _get_nargs_pattern_wrapper for more details
197+ See _get_nargs_pattern_wrapper for
198+ more details
169199
170- argparse.ArgumentParser._match_argument - adds support to for nargs ranges
171- See _match_argument_wrapper for more details
200+ argparse.ArgumentParser._match_argument - adds support to for nargs ranges See
201+ _match_argument_wrapper for more
202+ details
172203"""
173204
174205import argparse
0 commit comments