summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd2/cmd2.py55
-rwxr-xr-xcmd2/parsing.py2
-rw-r--r--docs/api/index.rst2
-rw-r--r--docs/features/argument_processing.rst4
-rw-r--r--docs/features/hooks.rst2
-rwxr-xr-xtests/test_history.py10
-rw-r--r--tests/test_transcript.py27
-rw-r--r--tests_isolated/test_commandset/test_commandset.py2
8 files changed, 46 insertions, 58 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index d2133ca4..7c221e40 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -2655,7 +2655,7 @@ class Cmd(cmd.Cmd):
# Use line buffering
new_stdout = open(utils.strip_quotes(statement.output_to), mode=mode, buffering=1)
except OSError as ex:
- raise RedirectionError('Failed to redirect because - {}'.format(ex))
+ raise RedirectionError(f'Failed to redirect because: {ex}')
redir_saved_state.redirecting = True
sys.stdout = self.stdout = new_stdout
@@ -4288,13 +4288,13 @@ class Cmd(cmd.Cmd):
# -v must be used alone with no other options
if args.verbose:
if args.clear or args.edit or args.output_file or args.run or args.transcript or args.expanded or args.script:
- self.poutput("-v can not be used with any other options")
+ self.poutput("-v cannot be used with any other options")
self.poutput(self.history_parser.format_usage())
return
# -s and -x can only be used if none of these options are present: [-c -r -e -o -t]
if (args.script or args.expanded) and (args.clear or args.edit or args.output_file or args.run or args.transcript):
- self.poutput("-s and -x can not be used with -c, -r, -e, -o, or -t")
+ self.poutput("-s and -x cannot be used with -c, -r, -e, -o, or -t")
self.poutput(self.history_parser.format_usage())
return
@@ -4308,7 +4308,7 @@ class Cmd(cmd.Cmd):
except FileNotFoundError:
pass
except OSError as ex:
- self.pexcept("Error removing history file '{}': {}".format(self.persistent_history_file, ex))
+ self.perror(f"Error removing history file '{self.persistent_history_file}': {ex}")
return
if rl_type != RlType.NONE:
@@ -4331,9 +4331,9 @@ class Cmd(cmd.Cmd):
with os.fdopen(fd, 'w') as fobj:
for command in history.values():
if command.statement.multiline_command:
- fobj.write('{}\n'.format(command.expanded))
+ fobj.write(f'{command.expanded}\n')
else:
- fobj.write('{}\n'.format(command.raw))
+ fobj.write(f'{command.raw}\n')
try:
self._run_editor(fname)
# noinspection PyTypeChecker
@@ -4341,18 +4341,19 @@ class Cmd(cmd.Cmd):
finally:
os.remove(fname)
elif args.output_file:
+ full_path = os.path.abspath(os.path.expanduser(args.output_file))
try:
- with open(os.path.expanduser(args.output_file), 'w') as fobj:
+ with open(full_path, 'w') as fobj:
for item in history.values():
if item.statement.multiline_command:
- fobj.write('{}\n'.format(item.expanded))
+ fobj.write(f"{item.expanded}\n")
else:
- fobj.write('{}\n'.format(item.raw))
+ fobj.write(f"{item.raw}\n")
plural = 's' if len(history) > 1 else ''
- except OSError as e:
- self.pexcept('Error saving {!r} - {}'.format(args.output_file, e))
+ except OSError as ex:
+ self.perror(f"Error saving history file '{full_path}': {ex}")
else:
- self.pfeedback('{} command{} saved to {}'.format(len(history), plural, args.output_file))
+ self.pfeedback(f"{len(history)} command{plural} saved to {full_path}")
elif args.transcript:
self._generate_transcript(list(history.values()), args.transcript)
else:
@@ -4404,11 +4405,10 @@ class Cmd(cmd.Cmd):
hist_file = os.path.abspath(os.path.expanduser(hist_file))
- # on Windows, trying to open a directory throws a permission
+ # On Windows, trying to open a directory throws a permission
# error, not a `IsADirectoryError`. So we'll check it ourselves.
if os.path.isdir(hist_file):
- msg = "Persistent history file '{}' is a directory"
- self.perror(msg.format(hist_file))
+ self.perror(f"Persistent history file '{hist_file}' is a directory")
return
# Create the directory for the history file if it doesn't already exist
@@ -4416,8 +4416,7 @@ class Cmd(cmd.Cmd):
try:
os.makedirs(hist_file_dir, exist_ok=True)
except OSError as ex:
- msg = "Error creating persistent history file directory '{}': {}".format(hist_file_dir, ex)
- self.pexcept(msg)
+ self.perror(f"Error creating persistent history file directory '{hist_file_dir}': {ex}")
return
# first we try and unpickle the history file
@@ -4439,8 +4438,7 @@ class Cmd(cmd.Cmd):
# If any of these errors occur when attempting to unpickle, just use an empty history
pass
except OSError as ex:
- msg = "Can not read persistent history file '{}': {}"
- self.pexcept(msg.format(hist_file, ex))
+ self.perror(f"Cannot read persistent history file '{hist_file}': {ex}")
return
self.history = history
@@ -4476,8 +4474,7 @@ class Cmd(cmd.Cmd):
with open(self.persistent_history_file, 'wb') as fobj:
pickle.dump(self.history, fobj)
except OSError as ex:
- msg = "Can not write persistent history file '{}': {}"
- self.pexcept(msg.format(self.persistent_history_file, ex))
+ self.perror(f"Cannot write persistent history file '{self.persistent_history_file}': {ex}")
def _generate_transcript(self, history: List[Union[HistoryItem, str]], transcript_file: str) -> None:
"""Generate a transcript file from a given history of commands"""
@@ -4485,7 +4482,7 @@ class Cmd(cmd.Cmd):
transcript_path = os.path.abspath(os.path.expanduser(transcript_file))
transcript_dir = os.path.dirname(transcript_path)
if not os.path.isdir(transcript_dir) or not os.access(transcript_dir, os.W_OK):
- self.perror("{!r} is not a directory or you don't have write access".format(transcript_dir))
+ self.perror(f"'{transcript_dir}' is not a directory or you don't have write access")
return
commands_run = 0
@@ -4515,10 +4512,10 @@ class Cmd(cmd.Cmd):
history_item = history_item.raw
for line in history_item.splitlines():
if first:
- command += '{}{}\n'.format(self.prompt, line)
+ command += f"{self.prompt}{line}\n"
first = False
else:
- command += '{}{}\n'.format(self.continuation_prompt, line)
+ command += f"{self.continuation_prompt}{line}\n"
transcript += command
# Use a StdSim object to capture output
@@ -4547,23 +4544,21 @@ class Cmd(cmd.Cmd):
# Check if all commands ran
if commands_run < len(history):
- warning = "Command {} triggered a stop and ended transcript generation early".format(commands_run)
- self.pwarning(warning)
+ self.pwarning(f"Command {commands_run} triggered a stop and ended transcript generation early")
# finally, we can write the transcript out to the file
try:
- with open(transcript_file, 'w') as fout:
+ with open(transcript_path, 'w') as fout:
fout.write(transcript)
except OSError as ex:
- self.pexcept('Failed to save transcript: {}'.format(ex))
+ self.perror(f"Error saving transcript file '{transcript_path}': {ex}")
else:
# and let the user know what we did
if commands_run > 1:
plural = 'commands and their outputs'
else:
plural = 'command and its output'
- msg = '{} {} saved to transcript file {!r}'
- self.pfeedback(msg.format(commands_run, plural, transcript_file))
+ self.pfeedback(f"{commands_run} {plural} saved to transcript file '{transcript_path}'")
edit_description = (
"Run a text editor and optionally open a file with it\n"
diff --git a/cmd2/parsing.py b/cmd2/parsing.py
index 3dff2689..db5dbd92 100755
--- a/cmd2/parsing.py
+++ b/cmd2/parsing.py
@@ -296,7 +296,7 @@ class StatementParser:
def is_valid_command(self, word: str, *, is_subcommand: bool = False) -> Tuple[bool, str]:
"""Determine whether a word is a valid name for a command.
- Commands can not include redirection characters, whitespace,
+ Commands cannot include redirection characters, whitespace,
or termination characters. They also cannot start with a
shortcut.
diff --git a/docs/api/index.rst b/docs/api/index.rst
index 861c3f97..1f5e1625 100644
--- a/docs/api/index.rst
+++ b/docs/api/index.rst
@@ -5,7 +5,7 @@ These pages document the public API for ``cmd2``. If a method, class, function,
attribute, or constant is not documented here, consider it private and subject
to change. There are many classes, methods, functions, and constants in the
source code which do not begin with an underscore but are not documented here.
-When looking at the source code for this library, you can not safely assume
+When looking at the source code for this library, you cannot safely assume
that because something doesn't start with an underscore, it is a public API.
If a release of this library changes any of the items documented here, the
diff --git a/docs/features/argument_processing.rst b/docs/features/argument_processing.rst
index bcc68633..9a78d720 100644
--- a/docs/features/argument_processing.rst
+++ b/docs/features/argument_processing.rst
@@ -170,7 +170,7 @@ To add additional text to the end of the generated help message, use the ``epilo
from cmd2 import with_argparser
argparser = argparse.ArgumentParser(description='create an html tag',
- epilog='This command can not generate tags with no content, like <br/>.')
+ epilog='This command cannot generate tags with no content, like <br/>.')
argparser.add_argument('tag', help='tag')
argparser.add_argument('content', nargs='+', help='content to surround with tag')
@with_argparser(argparser)
@@ -193,7 +193,7 @@ Which yields:
optional arguments:
-h, --help show this help message and exit
- This command can not generate tags with no content, like <br/>
+ This command cannot generate tags with no content, like <br/>
.. warning::
diff --git a/docs/features/hooks.rst b/docs/features/hooks.rst
index acf9dcc4..881b4e7e 100644
--- a/docs/features/hooks.rst
+++ b/docs/features/hooks.rst
@@ -207,7 +207,7 @@ with the :data:`~cmd2.plugin.PostparsingData.stop` attribute set to ``True``:
Precommand Hooks
----------------
-Precommand hooks can modify the user input, but can not request the application
+Precommand hooks can modify the user input, but cannot request the application
terminate. If your hook needs to be able to exit the application, you should
implement it as a postparsing hook.
diff --git a/tests/test_history.py b/tests/test_history.py
index 41ae2a9e..d1285705 100755
--- a/tests/test_history.py
+++ b/tests/test_history.py
@@ -616,7 +616,7 @@ def test_history_verbose_with_other_options(base_app):
for opt in options_to_test:
out, err = run_cmd(base_app, 'history -v ' + opt)
assert len(out) == 4
- assert out[0] == '-v can not be used with any other options'
+ assert out[0] == '-v cannot be used with any other options'
assert out[1].startswith('Usage:')
@@ -635,7 +635,7 @@ def test_history_script_with_invalid_options(base_app):
for opt in options_to_test:
out, err = run_cmd(base_app, 'history -s ' + opt)
assert len(out) == 4
- assert out[0] == '-s and -x can not be used with -c, -r, -e, -o, or -t'
+ assert out[0] == '-s and -x cannot be used with -c, -r, -e, -o, or -t'
assert out[1].startswith('Usage:')
@@ -653,7 +653,7 @@ def test_history_expanded_with_invalid_options(base_app):
for opt in options_to_test:
out, err = run_cmd(base_app, 'history -x ' + opt)
assert len(out) == 4
- assert out[0] == '-s and -x can not be used with -c, -r, -e, -o, or -t'
+ assert out[0] == '-s and -x cannot be used with -c, -r, -e, -o, or -t'
assert out[1].startswith('Usage:')
@@ -761,7 +761,7 @@ def test_history_file_permission_error(mocker, capsys):
cmd2.Cmd(persistent_history_file='/tmp/doesntmatter')
out, err = capsys.readouterr()
assert not out
- assert 'Can not read' in err
+ assert 'Cannot read' in err
def test_history_file_conversion_no_truncate_on_init(hist_file, capsys):
@@ -843,4 +843,4 @@ def test_persist_history_permission_error(hist_file, mocker, capsys):
app._persist_history()
out, err = capsys.readouterr()
assert not out
- assert 'Can not write' in err
+ assert 'Cannot write' in err
diff --git a/tests/test_transcript.py b/tests/test_transcript.py
index ccb28740..22e04239 100644
--- a/tests/test_transcript.py
+++ b/tests/test_transcript.py
@@ -184,31 +184,24 @@ this is a \/multiline\/ command
assert xscript == expected
-def test_history_transcript_bad_filename():
+def test_history_transcript_bad_path(mocker):
app = CmdLineApp()
app.stdout = StdSim(app.stdout)
run_cmd(app, 'orate this is\na /multiline/\ncommand;\n')
run_cmd(app, 'speak /tmp/file.txt is not a regex')
- expected = r"""(Cmd) orate this is
-> a /multiline/
-> command;
-this is a \/multiline\/ command
-(Cmd) speak /tmp/file.txt is not a regex
-\/tmp\/file.txt is not a regex
-"""
-
- # make a tmp file
+ # Bad directory
history_fname = '~/fakedir/this_does_not_exist.txt'
+ out, err = run_cmd(app, 'history -t "{}"'.format(history_fname))
+ assert "is not a directory" in err[0]
- # tell the history command to create a transcript
- run_cmd(app, 'history -t "{}"'.format(history_fname))
+ # Cause os.open to fail and make sure error gets printed
+ mock_remove = mocker.patch('builtins.open')
+ mock_remove.side_effect = OSError
- # read in the transcript created by the history command
- with pytest.raises(FileNotFoundError):
- with open(history_fname) as f:
- transcript = f.read()
- assert transcript == expected
+ history_fname = 'outfile.txt'
+ out, err = run_cmd(app, 'history -t "{}"'.format(history_fname))
+ assert "Error saving transcript file" in err[0]
def test_run_script_record_transcript(base_app, request):
diff --git a/tests_isolated/test_commandset/test_commandset.py b/tests_isolated/test_commandset/test_commandset.py
index 2e7d837f..c3c86458 100644
--- a/tests_isolated/test_commandset/test_commandset.py
+++ b/tests_isolated/test_commandset/test_commandset.py
@@ -157,7 +157,7 @@ def test_custom_construct_commandsets():
cmds_cats, cmds_doc, cmds_undoc, help_topics = app._build_command_info()
assert 'Command Set B' in cmds_cats
- # Verifies that the same CommandSet can not be loaded twice
+ # Verifies that the same CommandSet cannot be loaded twice
command_set_2 = CommandSetB('bar')
with pytest.raises(CommandSetRegistrationError):
assert app.register_command_set(command_set_2)