Skip to content

Commit c218633

Browse files
committed
Addresses comments on #362
1 parent ff66a95 commit c218633

6 files changed

Lines changed: 156 additions & 148 deletions

File tree

Lines changed: 127 additions & 102 deletions
Large diffs are not rendered by default.

cmd2/rl_utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@
2222
pass
2323

2424

25-
# Check what implementation of readline we are using
2625
class RlType(Enum):
26+
"""Readline library types we recognize"""
2727
GNU = 1
2828
PYREADLINE = 2
2929
NONE = 3
3030

3131

32+
# Check what implementation of readline we are using
33+
3234
rl_type = RlType.NONE
3335

3436
# The order of this check matters since importing pyreadline will also show readline in the modules list

examples/tab_autocompletion.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from typing import List
88

99
import cmd2
10-
from cmd2 import with_argparser, with_category, AutoCompleter
10+
from cmd2 import with_argparser, with_category, argparse_completer
1111

1212

1313
class TabCompleteExample(cmd2.Cmd):
@@ -91,7 +91,7 @@ def __init__(self):
9191
# - The help output for arguments with multiple flags or with append=True is more concise
9292
# - ACArgumentParser adds the ability to specify ranges of argument counts in 'nargs'
9393

94-
suggest_parser = AutoCompleter.ACArgumentParser()
94+
suggest_parser = argparse_completer.ACArgumentParser()
9595

9696
suggest_parser.add_argument('-t', '--type', choices=['movie', 'show'], required=True)
9797
suggest_parser.add_argument('-d', '--duration', nargs=(1, 2), action='append',
@@ -113,7 +113,7 @@ def do_suggest(self, args) -> None:
113113

114114
def complete_suggest(self, text: str, line: str, begidx: int, endidx: int) -> List[str]:
115115
""" Adds tab completion to media"""
116-
completer = AutoCompleter.AutoCompleter(TabCompleteExample.suggest_parser, 1)
116+
completer = argparse_completer.AutoCompleter(TabCompleteExample.suggest_parser, 1)
117117

118118
tokens, _ = self.tokens_for_completion(line, begidx, endidx)
119119
results = completer.complete_command(tokens, text, line, begidx, endidx)
@@ -125,7 +125,7 @@ def complete_suggest(self, text: str, line: str, begidx: int, endidx: int) -> Li
125125

126126
suggest_parser_hybrid = argparse.ArgumentParser()
127127
# This registers the custom narg range handling
128-
AutoCompleter.register_custom_actions(suggest_parser_hybrid)
128+
argparse_completer.register_custom_actions(suggest_parser_hybrid)
129129

130130
suggest_parser_hybrid.add_argument('-t', '--type', choices=['movie', 'show'], required=True)
131131
suggest_parser_hybrid.add_argument('-d', '--duration', nargs=(1, 2), action='append',
@@ -141,7 +141,7 @@ def do_hybrid_suggest(self, args):
141141

142142
def complete_hybrid_suggest(self, text, line, begidx, endidx):
143143
""" Adds tab completion to media"""
144-
completer = AutoCompleter.AutoCompleter(TabCompleteExample.suggest_parser_hybrid)
144+
completer = argparse_completer.AutoCompleter(TabCompleteExample.suggest_parser_hybrid)
145145

146146
tokens, _ = self.tokens_for_completion(line, begidx, endidx)
147147
results = completer.complete_command(tokens, text, line, begidx, endidx)
@@ -168,7 +168,7 @@ def do_orig_suggest(self, args) -> None:
168168

169169
def complete_orig_suggest(self, text, line, begidx, endidx) -> List[str]:
170170
""" Adds tab completion to media"""
171-
completer = AutoCompleter.AutoCompleter(TabCompleteExample.suggest_parser_orig)
171+
completer = argparse_completer.AutoCompleter(TabCompleteExample.suggest_parser_orig)
172172

173173
tokens, _ = self.tokens_for_completion(line, begidx, endidx)
174174
results = completer.complete_command(tokens, text, line, begidx, endidx)
@@ -211,7 +211,7 @@ def _do_media_shows(self, args) -> None:
211211
print()
212212

213213

214-
media_parser = AutoCompleter.ACArgumentParser(prog='media')
214+
media_parser = argparse_completer.ACArgumentParser(prog='media')
215215

216216
media_types_subparsers = media_parser.add_subparsers(title='Media Types', dest='type')
217217

@@ -264,7 +264,7 @@ def complete_media(self, text, line, begidx, endidx):
264264
choices = {'actor': self.query_actors, # function
265265
'director': TabCompleteExample.static_list_directors # static list
266266
}
267-
completer = AutoCompleter.AutoCompleter(TabCompleteExample.media_parser, arg_choices=choices)
267+
completer = argparse_completer.AutoCompleter(TabCompleteExample.media_parser, arg_choices=choices)
268268

269269
tokens, _ = self.tokens_for_completion(line, begidx, endidx)
270270
results = completer.complete_command(tokens, text, line, begidx, endidx)
@@ -293,11 +293,11 @@ def _query_movie_database(self):
293293
def _query_movie_user_library(self):
294294
return TabCompleteExample.USER_MOVIE_LIBRARY
295295

296-
def _filter_library(self, text, line, begidx, endidx, full, exclude=[]):
296+
def _filter_library(self, text, line, begidx, endidx, full, exclude=()):
297297
candidates = list(set(full).difference(set(exclude)))
298298
return [entry for entry in candidates if entry.startswith(text)]
299299

300-
library_parser = AutoCompleter.ACArgumentParser(prog='library')
300+
library_parser = argparse_completer.ACArgumentParser(prog='library')
301301

302302
library_subcommands = library_parser.add_subparsers(title='Media Types', dest='type')
303303

@@ -410,8 +410,8 @@ def complete_library(self, text, line, begidx, endidx):
410410
# under the type sub-parser group, there are 2 sub-parsers: 'movie', 'show'
411411
library_subcommand_groups = {'type': library_type_params}
412412

413-
completer = AutoCompleter.AutoCompleter(TabCompleteExample.library_parser,
414-
subcmd_args_lookup=library_subcommand_groups)
413+
completer = argparse_completer.AutoCompleter(TabCompleteExample.library_parser,
414+
subcmd_args_lookup=library_subcommand_groups)
415415

416416
tokens, _ = self.tokens_for_completion(line, begidx, endidx)
417417
results = completer.complete_command(tokens, text, line, begidx, endidx)

tests/test_acargparse.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
"""
2-
Unit/functional testing for readline tab-completion functions in the cmd2.py module.
2+
Unit/functional testing for argparse customizations in cmd2
33
4-
These are primarily tests related to readline completer functions which handle tab-completion of cmd2/cmd commands,
5-
file system paths, and shell commands.
6-
7-
Copyright 2017 Todd Leonhardt <todd.leonhardt@gmail.com>
4+
Copyright 2018 Eric Lin <anselor@gmail.com>
85
Released under MIT license, see LICENSE file
96
"""
107
import pytest
11-
from cmd2.AutoCompleter import ACArgumentParser
8+
from cmd2.argparse_completer import ACArgumentParser
129

1310

1411
def test_acarg_narg_empty_tuple():
@@ -54,5 +51,3 @@ def test_acarg_narg_tuple_zero_base():
5451
def test_acarg_narg_tuple_zero_to_one():
5552
parser = ACArgumentParser(prog='test')
5653
parser.add_argument('tuple', nargs=(0, 1))
57-
58-

tests/test_autocompletion.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
"""
2-
Unit/functional testing for readline tab-completion functions in the cmd2.py module.
2+
Unit/functional testing for argparse completer in cmd2
33
4-
These are primarily tests related to readline completer functions which handle tab-completion of cmd2/cmd commands,
5-
file system paths, and shell commands.
6-
7-
Copyright 2017 Todd Leonhardt <todd.leonhardt@gmail.com>
4+
Copyright 2018 Eric Lin <anselor@gmail.com>
85
Released under MIT license, see LICENSE file
96
"""
107
import pytest
@@ -257,9 +254,3 @@ def test_autcomp_custom_func_list_and_dict_arg(cmd2_app):
257254
first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
258255
assert first_match is not None and \
259256
cmd2_app.completion_matches == ['S01E02', 'S01E03', 'S02E01', 'S02E03']
260-
261-
262-
263-
264-
265-

tests/test_completion.py

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,7 @@ def test_subcommand_tab_completion(sc_app):
863863
# It is at end of line, so extra space is present
864864
assert first_match is not None and sc_app.completion_matches == ['Football ']
865865

866+
866867
def test_subcommand_tab_completion_with_no_completer(sc_app):
867868
# This tests what happens when a subcommand has no completer
868869
# In this case, the foo subcommand has no completer defined
@@ -874,6 +875,7 @@ def test_subcommand_tab_completion_with_no_completer(sc_app):
874875
first_match = complete_tester(text, line, begidx, endidx, sc_app)
875876
assert first_match is None
876877

878+
877879
def test_subcommand_tab_completion_space_in_text(sc_app):
878880
text = 'B'
879881
line = 'base sport "Space {}'.format(text)
@@ -886,10 +888,6 @@ def test_subcommand_tab_completion_space_in_text(sc_app):
886888
sc_app.completion_matches == ['Ball" '] and \
887889
sc_app.display_matches == ['Space Ball']
888890

889-
890-
891-
892-
893891
####################################################
894892

895893

@@ -960,6 +958,7 @@ def do_base(self, args):
960958

961959
@pytest.fixture
962960
def scu_app():
961+
"""Declare test fixture for with_argparser_and_unknown_args"""
963962
app = SubcommandsWithUnknownExample()
964963
return app
965964

@@ -975,6 +974,7 @@ def test_cmd2_subcmd_with_unknown_completion_single_end(scu_app):
975974
# It is at end of line, so extra space is present
976975
assert first_match is not None and scu_app.completion_matches == ['foo ']
977976

977+
978978
def test_cmd2_subcmd_with_unknown_completion_multiple(scu_app):
979979
text = ''
980980
line = 'base {}'.format(text)
@@ -984,6 +984,7 @@ def test_cmd2_subcmd_with_unknown_completion_multiple(scu_app):
984984
first_match = complete_tester(text, line, begidx, endidx, scu_app)
985985
assert first_match is not None and scu_app.completion_matches == ['bar', 'foo', 'sport']
986986

987+
987988
def test_cmd2_subcmd_with_unknown_completion_nomatch(scu_app):
988989
text = 'z'
989990
line = 'base {}'.format(text)
@@ -1001,6 +1002,7 @@ def test_cmd2_help_subcommand_completion_single(scu_app):
10011002
begidx = endidx - len(text)
10021003
assert scu_app.complete_help(text, line, begidx, endidx) == ['base']
10031004

1005+
10041006
def test_cmd2_help_subcommand_completion_multiple(scu_app):
10051007
text = ''
10061008
line = 'help base {}'.format(text)
@@ -1018,6 +1020,7 @@ def test_cmd2_help_subcommand_completion_nomatch(scu_app):
10181020
begidx = endidx - len(text)
10191021
assert scu_app.complete_help(text, line, begidx, endidx) == []
10201022

1023+
10211024
def test_subcommand_tab_completion(scu_app):
10221025
# This makes sure the correct completer for the sport subcommand is called
10231026
text = 'Foot'
@@ -1030,6 +1033,7 @@ def test_subcommand_tab_completion(scu_app):
10301033
# It is at end of line, so extra space is present
10311034
assert first_match is not None and scu_app.completion_matches == ['Football ']
10321035

1036+
10331037
def test_subcommand_tab_completion_with_no_completer(scu_app):
10341038
# This tests what happens when a subcommand has no completer
10351039
# In this case, the foo subcommand has no completer defined
@@ -1041,6 +1045,7 @@ def test_subcommand_tab_completion_with_no_completer(scu_app):
10411045
first_match = complete_tester(text, line, begidx, endidx, scu_app)
10421046
assert first_match is None
10431047

1048+
10441049
def test_subcommand_tab_completion_space_in_text(scu_app):
10451050
text = 'B'
10461051
line = 'base sport "Space {}'.format(text)
@@ -1053,19 +1058,9 @@ def test_subcommand_tab_completion_space_in_text(scu_app):
10531058
scu_app.completion_matches == ['Ball" '] and \
10541059
scu_app.display_matches == ['Space Ball']
10551060

1056-
1057-
10581061
####################################################
10591062

10601063

1061-
1062-
1063-
1064-
1065-
1066-
1067-
1068-
10691064
class SecondLevel(cmd2.Cmd):
10701065
"""To be used as a second level command class. """
10711066

0 commit comments

Comments
 (0)