From df09c85e8db95622820712f29228dac2dc049935 Mon Sep 17 00:00:00 2001 From: Eric Lin Date: Thu, 19 Apr 2018 12:49:24 -0400 Subject: Identified and marked a few blocks of code that can't be reached during unit tests due to the lack of a real terminal. Some more comments. --- cmd2/argparse_completer.py | 9 +++++++++ cmd2/cmd2.py | 12 ++++++------ cmd2/rl_utils.py | 7 ++++--- examples/tab_autocompletion.py | 6 +++++- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py index 03cc6483..35f9342b 100755 --- a/cmd2/argparse_completer.py +++ b/cmd2/argparse_completer.py @@ -52,6 +52,9 @@ How to supply completion choice lists or functions for sub-commands: The subcommand group dictionary maps subcommand names to tuple(arg_choices, subcmd_args_lookup) For more details of this more complex approach see tab_autocompletion.py in the examples + +Copyright 2018 Eric Lin +Released under MIT license, see LICENSE file """ import argparse @@ -262,6 +265,12 @@ class AutoCompleter(object): current_is_positional = False consumed_arg_values = {} # dict(arg_name -> [values, ...]) + # the following are nested functions that have full access to all variables in the parent + # function including variables declared and updated after this function. Variable values + # are current at the point the nested functions are invoked (as in, they do not receive a + # snapshot of these values, they directly access the current state of variables in the + # parent function) + def consume_flag_argument() -> None: """Consuming token as a flag argument""" # we're consuming flag arguments diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index bc3bc089..871b356b 100755 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -1591,7 +1591,7 @@ class Cmd(cmd.Cmd): return compfunc(text, line, begidx, endidx) @staticmethod - def _pad_matches_to_display(matches_to_display): + def _pad_matches_to_display(matches_to_display): # pragma: no cover """ Adds padding to the matches being displayed as tab completion suggestions. The default padding of readline/pyreadine is small and not visually appealing @@ -1613,7 +1613,7 @@ class Cmd(cmd.Cmd): return [cur_match + padding for cur_match in matches_to_display], len(padding) - def _display_matches_gnu_readline(self, substitution, matches, longest_match_length): + def _display_matches_gnu_readline(self, substitution, matches, longest_match_length): # pragma: no cover """ Prints a match list using GNU readline's rl_display_match_list() This exists to print self.display_matches if it has data. Otherwise matches prints. @@ -1664,7 +1664,7 @@ class Cmd(cmd.Cmd): # Redraw prompt and input line rl_force_redisplay() - def _display_matches_pyreadline(self, matches): + def _display_matches_pyreadline(self, matches): # pragma: no cover """ Prints a match list using pyreadline's _display_completions() This exists to print self.display_matches if it has data. Otherwise matches prints. @@ -3344,7 +3344,7 @@ Script should contain one command per line, just like command would be typed in # self._script_dir list when done. with open(expanded_path, encoding='utf-8') as target: self.cmdqueue = target.read().splitlines() + ['eos'] + self.cmdqueue - except IOError as e: + except IOError as e: # pragma: no cover self.perror('Problem accessing script from {}:\n{}'.format(expanded_path, e)) return @@ -3371,7 +3371,7 @@ Script should contain one command per line, just like command would be typed in # noinspection PyUnusedLocal if sum(1 for line in f) > 0: valid_text_file = True - except IOError: + except IOError: # pragma: no cover pass except UnicodeDecodeError: # The file is not ASCII. Check if it is UTF-8. @@ -3381,7 +3381,7 @@ Script should contain one command per line, just like command would be typed in # noinspection PyUnusedLocal if sum(1 for line in f) > 0: valid_text_file = True - except IOError: + except IOError: # pragma: no cover pass except UnicodeDecodeError: # Not UTF-8 diff --git a/cmd2/rl_utils.py b/cmd2/rl_utils.py index c00a5784..d5bef1ff 100644 --- a/cmd2/rl_utils.py +++ b/cmd2/rl_utils.py @@ -18,7 +18,7 @@ except ImportError: try: # noinspection PyUnresolvedReferences import readline - except ImportError: + except ImportError: # pragma: no cover pass @@ -51,7 +51,8 @@ def rl_force_redisplay() -> None: """ if not sys.stdout.isatty(): return - if rl_type == RlType.GNU: + + if rl_type == RlType.GNU: # pragma: no cover # rl_forced_update_display() is the proper way to redraw the prompt and line, but we # have to use ctypes to do it since Python's readline API does not wrap the function readline_lib.rl_forced_update_display() @@ -60,6 +61,6 @@ def rl_force_redisplay() -> None: display_fixed = ctypes.c_int.in_dll(readline_lib, "rl_display_fixed") display_fixed.value = 1 - elif rl_type == RlType.PYREADLINE: + elif rl_type == RlType.PYREADLINE: # pragma: no cover # noinspection PyProtectedMember readline.rl.mode._print_prompt() diff --git a/examples/tab_autocompletion.py b/examples/tab_autocompletion.py index 448268d0..9741dce2 100755 --- a/examples/tab_autocompletion.py +++ b/examples/tab_autocompletion.py @@ -1,6 +1,10 @@ #!/usr/bin/env python # coding=utf-8 -"""A simple example demonstrating how to use flag and index based tab-completion functions +""" +A example usage of the AutoCompleter + +Copyright 2018 Eric Lin +Released under MIT license, see LICENSE file """ import argparse import itertools -- cgit v1.2.1