Skip to content

Commit 30a3b66

Browse files
authored
Merge pull request #189 from python-cmd2/case_bugs
Fixed case-sensitivity bugs
2 parents f517ff8 + b6bf292 commit 30a3b66

File tree

5 files changed

+76
-5
lines changed

5 files changed

+76
-5
lines changed

CHANGES.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ News
77
*Release date: TBD*
88

99
* Bug Fixes
10-
* Fixed some timing bugs when running unit tests in parallel by using monkeypatch
10+
* Case-sensitive command parsing was completely broken and has been fixed
11+
* <Ctrl>+D now properly quits when case-sensitive command parsing is enabled
1112
* Fixed some pyperclip clipboard interaction bugs on Linux
12-
13+
* Fixed some timing bugs when running unit tests in parallel by using monkeypatch
14+
1315
0.7.5
1416
-----
1517

cmd2.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -891,13 +891,13 @@ def pseudo_raw_input(self, prompt):
891891
try:
892892
line = sm.input(safe_prompt)
893893
except EOFError:
894-
line = 'EOF'
894+
line = 'eof'
895895
else:
896896
self.stdout.write(safe_prompt)
897897
self.stdout.flush()
898898
line = self.stdin.readline()
899899
if not len(line):
900-
line = 'EOF'
900+
line = 'eof'
901901
else:
902902
line = line.rstrip('\r\n')
903903

@@ -1846,6 +1846,10 @@ def _build_main_parser(self, redirector, terminators, multilineCommands, legalCh
18461846
if case_insensitive:
18471847
multilineCommand.setParseAction(lambda x: x[0].lower())
18481848
oneline_command.setParseAction(lambda x: x[0].lower())
1849+
else:
1850+
multilineCommand.setParseAction(lambda x: x[0])
1851+
oneline_command.setParseAction(lambda x: x[0])
1852+
18491853
if blankLinesAllowed:
18501854
blankLineTerminationParser = pyparsing.NoMatch
18511855
else:

examples/case_sensitive.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env python
2+
# coding=utf-8
3+
"""A sample application demonstrating when commands are set to be case sensitive.
4+
5+
By default cmd2 parses commands in a case-insensitive manner. But this behavior can be changed.
6+
"""
7+
8+
import cmd2
9+
10+
11+
class CaseSensitiveApp(cmd2.Cmd):
12+
""" Example cmd2 application where commands are case-sensitive."""
13+
14+
def __init__(self):
15+
# Set this before calling the super class __init__()
16+
self.case_insensitive = False
17+
18+
cmd2.Cmd.__init__(self)
19+
20+
self.debug = True
21+
22+
23+
if __name__ == '__main__':
24+
app = CaseSensitiveApp()
25+
app.cmdloop()

tests/test_cmd2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1335,4 +1335,4 @@ def test_empty_stdin_input():
13351335
app.stdin.readline = m
13361336

13371337
line = app.pseudo_raw_input('(cmd2)')
1338-
assert line == 'EOF'
1338+
assert line == 'eof'

tests/test_parsing.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def hist():
2020
h = cmd2.History([HistoryItem('first'), HistoryItem('second'), HistoryItem('third'), HistoryItem('fourth')])
2121
return h
2222

23+
# Case-insensitive parser
2324
@pytest.fixture
2425
def parser():
2526
c = cmd2.Cmd()
@@ -32,6 +33,33 @@ def parser():
3233
preparse=c.preparse, postparse=c.postparse, shortcuts=c.shortcuts)
3334
return c.parser_manager.main_parser
3435

36+
# Case-insensitive ParserManager
37+
@pytest.fixture
38+
def ci_pm():
39+
c = cmd2.Cmd()
40+
c.multilineCommands = ['multiline']
41+
c.case_insensitive = True
42+
c.parser_manager = cmd2.ParserManager(redirector=c.redirector, terminators=c.terminators, multilineCommands=c.multilineCommands,
43+
legalChars=c.legalChars, commentGrammars=c.commentGrammars,
44+
commentInProgress=c.commentInProgress, case_insensitive=c.case_insensitive,
45+
blankLinesAllowed=c.blankLinesAllowed, prefixParser=c.prefixParser,
46+
preparse=c.preparse, postparse=c.postparse, shortcuts=c.shortcuts)
47+
return c.parser_manager
48+
49+
# Case-sensitive ParserManager
50+
@pytest.fixture
51+
def cs_pm():
52+
c = cmd2.Cmd()
53+
c.multilineCommands = ['multiline']
54+
c.case_insensitive = False
55+
c.parser_manager = cmd2.ParserManager(redirector=c.redirector, terminators=c.terminators, multilineCommands=c.multilineCommands,
56+
legalChars=c.legalChars, commentGrammars=c.commentGrammars,
57+
commentInProgress=c.commentInProgress, case_insensitive=c.case_insensitive,
58+
blankLinesAllowed=c.blankLinesAllowed, prefixParser=c.prefixParser,
59+
preparse=c.preparse, postparse=c.postparse, shortcuts=c.shortcuts)
60+
return c.parser_manager
61+
62+
3563
@pytest.fixture
3664
def input_parser():
3765
c = cmd2.Cmd()
@@ -190,6 +218,18 @@ def test_parse_output_redirect_with_dash_in_path(parser):
190218
assert results.output == '>'
191219
assert results.outputTo == 'python-cmd2/afile.txt'
192220

221+
222+
def test_case_insensitive_parsed_single_word(ci_pm):
223+
line = 'HeLp'
224+
statement = ci_pm.parsed(line)
225+
assert statement.parsed.command == line.lower()
226+
227+
def test_case_sensitive_parsed_single_word(cs_pm):
228+
line = 'HeLp'
229+
statement = cs_pm.parsed(line)
230+
assert statement.parsed.command == line
231+
232+
193233
def test_parse_input_redirect(input_parser):
194234
line = '< afile.txt'
195235
results = input_parser.parseString(line)

0 commit comments

Comments
 (0)