Skip to content

Commit 7644204

Browse files
committed
Resolve PR feedback
1 parent 76b2903 commit 7644204

File tree

4 files changed

+40
-44
lines changed

4 files changed

+40
-44
lines changed

CHANGELOG.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@
3333
* Changed `Statement.pipe_to` to a string instead of a list
3434
* `preserve_quotes` is now a keyword-only argument in the argparse decorators
3535
* Refactored so that `cmd2.Cmd.cmdloop()` returns the `exit_code` instead of a call to `sys.exit()`
36-
* It is now applicaiton developer's responsibility to treat the return value from `cmdloop()` accordingly
37-
, and is in a binary format,
38-
not a text format.
36+
It is now application developer's responsibility to treat the return value from `cmdloop()` accordingly
3937
* Only valid commands are persistent in history between invocations of `cmd2` based apps. Previously
4038
all user input was persistent in history. If readline is installed, the history available with the up and
4139
down arrow keys (readline history) may not match that shown in the `history` command, because `history`

cmd2/cmd2.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3409,9 +3409,9 @@ def do_history(self, args: argparse.Namespace) -> None:
34093409
traceback_war=False)
34103410
else:
34113411
for runme in history:
3412-
self.pfeedback(runme.statement.raw)
3412+
self.pfeedback(runme.raw)
34133413
if runme:
3414-
self.onecmd_plus_hooks(runme.statement.raw)
3414+
self.onecmd_plus_hooks(runme.raw)
34153415
elif args.edit:
34163416
import tempfile
34173417
fd, fname = tempfile.mkstemp(suffix='.txt', text=True)
@@ -3420,7 +3420,7 @@ def do_history(self, args: argparse.Namespace) -> None:
34203420
if command.statement.multiline_command:
34213421
fobj.write('{}\n'.format(command.expanded.rstrip()))
34223422
else:
3423-
fobj.write('{}\n'.format(command))
3423+
fobj.write('{}\n'.format(command.raw))
34243424
try:
34253425
self.do_edit(fname)
34263426
self.do_load(fname)
@@ -3433,9 +3433,9 @@ def do_history(self, args: argparse.Namespace) -> None:
34333433
with open(os.path.expanduser(args.output_file), 'w') as fobj:
34343434
for item in history:
34353435
if item.statement.multiline_command:
3436-
fobj.write('{}\n'.format(item.statement.expanded_command_line.rstrip()))
3436+
fobj.write('{}\n'.format(item.expanded.rstrip()))
34373437
else:
3438-
fobj.write('{}\n'.format(item.statement.raw))
3438+
fobj.write('{}\n'.format(item.raw))
34393439
plural = 's' if len(history) > 1 else ''
34403440
self.pfeedback('{} command{} saved to {}'.format(len(history), plural, args.output_file))
34413441
except Exception as e:
@@ -3492,9 +3492,9 @@ def _initialize_history(self, hist_file):
34923492
for item in history:
34933493
# readline only adds a single entry for multiple sequential identical commands
34943494
# so we emulate that behavior here
3495-
if item.statement.raw != last:
3496-
readline.add_history(item.statement.raw)
3497-
last = item.statement.raw
3495+
if item.raw != last:
3496+
readline.add_history(item.raw)
3497+
last = item.raw
34983498

34993499
# register a function to write history at save
35003500
# if the history file is in plain text format from 0.9.12 or lower
@@ -3549,7 +3549,7 @@ def _generate_transcript(self, history: List[Union[HistoryItem, str]], transcrip
35493549
first = True
35503550
command = ''
35513551
if isinstance(history_item, HistoryItem):
3552-
history_item = history_item.statement.raw
3552+
history_item = history_item.raw
35533553
for line in history_item.splitlines():
35543554
if first:
35553555
command += '{}{}\n'.format(self.prompt, line)

cmd2/history.py

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,31 @@
77

88
from typing import List, Union
99

10+
import attr
11+
1012
from . import utils
1113
from .parsing import Statement
1214

13-
15+
@attr.s(frozen=True)
1416
class HistoryItem():
1517
"""Class used to represent one command in the History list"""
1618
_listformat = ' {:>4} {}\n'
1719
_ex_listformat = ' {:>4}x {}\n'
1820

19-
# def __new__(cls, statement: Statement):
20-
# """Create a new instance of HistoryItem
21+
statement = attr.ib(default=None, validator=attr.validators.instance_of(Statement))
22+
idx = attr.ib(default=None, validator=attr.validators.instance_of(int))
2123

22-
# We must override __new__ because we are subclassing `str` which is
23-
# immutable and takes a different number of arguments as Statement.
24-
# """
25-
# hi = super().__new__(cls, statement.raw)
26-
# hi.statement = statement
27-
# hi.idx = None
28-
# return hi
24+
def __str__(self):
25+
"""A convenient human readable representation of the history item"""
26+
if self.statement:
27+
return self.statement.raw
28+
else:
29+
return ''
2930

30-
def __init__(self, statement: Statement, idx: int):
31-
self.statement = statement
32-
self.idx = idx
31+
@property
32+
def raw(self) -> str:
33+
"""Return the raw input from the user for this item"""
34+
return self.statement.raw
3335

3436
@property
3537
def expanded(self) -> str:
@@ -43,24 +45,23 @@ def pr(self, script=False, expanded=False, verbose=False) -> str:
4345
4446
:return: pretty print string version of a HistoryItem
4547
"""
46-
expanded_command = self.statement.expanded_command_line
4748
if verbose:
48-
ret_str = self._listformat.format(self.idx, self.statement.raw)
49-
if self.statement.raw != expanded_command.rstrip():
50-
ret_str += self._ex_listformat.format(self.idx, expanded_command)
49+
ret_str = self._listformat.format(self.idx, self.raw)
50+
if self.raw != self.expanded.rstrip():
51+
ret_str += self._ex_listformat.format(self.idx, self.expanded)
5152
else:
5253
if script:
5354
# display without entry numbers
5455
if expanded or self.statement.multiline_command:
55-
ret_str = expanded_command.rstrip()
56+
ret_str = self.expanded.rstrip()
5657
else:
57-
ret_str = self.statement.raw
58+
ret_str = self.raw.rstrip()
5859
else:
5960
# display a numbered list
6061
if expanded or self.statement.multiline_command:
61-
ret_str = self._listformat.format(self.idx, expanded_command.rstrip())
62+
ret_str = self._listformat.format(self.idx, self.expanded.rstrip())
6263
else:
63-
ret_str = self._listformat.format(self.idx, self.statement.raw.rstrip())
64+
ret_str = self._listformat.format(self.idx, self.raw.rstrip())
6465
return ret_str
6566

6667

@@ -210,8 +211,8 @@ def str_search(self, search: str) -> List[HistoryItem]:
210211
def isin(history_item):
211212
"""filter function for string search of history"""
212213
sloppy = utils.norm_fold(search)
213-
inraw = sloppy in utils.norm_fold(history_item.statement.raw)
214-
inexpanded = sloppy in utils.norm_fold(history_item.statement.expanded_command_line)
214+
inraw = sloppy in utils.norm_fold(history_item.raw)
215+
inexpanded = sloppy in utils.norm_fold(history_item.expanded)
215216
return inraw or inexpanded
216217
return [item for item in self if isin(item)]
217218

@@ -228,7 +229,7 @@ def regex_search(self, regex: str) -> List[HistoryItem]:
228229

229230
def isin(hi):
230231
"""filter function for doing a regular expression search of history"""
231-
return finder.search(hi.statement.raw) or finder.search(hi.statement.expanded_command_line)
232+
return finder.search(hi.raw) or finder.search(hi.expanded)
232233
return [itm for itm in self if isin(itm)]
233234

234235
def truncate(self, max_length: int) -> None:

tests/test_history.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -459,14 +459,11 @@ def hist_file():
459459
pass
460460

461461
def test_bad_history_file_path(capsys, request):
462-
# Use a directory path as the history file
463-
test_dir = os.path.dirname(request.module.__file__)
464-
465-
# Create a new cmd2 app
466-
cmd2.Cmd(persistent_history_file=test_dir)
467-
_, err = capsys.readouterr()
468-
469-
assert 'is a directory' in err
462+
with tempfile.TemporaryDirectory() as test_dir:
463+
# Create a new cmd2 app
464+
cmd2.Cmd(persistent_history_file=test_dir)
465+
_, err = capsys.readouterr()
466+
assert 'is a directory' in err
470467

471468
def test_history_file_conversion_no_truncate_on_init(hist_file, capsys):
472469
# test the code that converts a plain text history file to a pickle binary

0 commit comments

Comments
 (0)