diff options
author | Eric Lin <anselor@gmail.com> | 2020-08-20 11:34:45 -0400 |
---|---|---|
committer | Eric Lin <anselor@gmail.com> | 2020-08-20 13:35:18 -0400 |
commit | 9a20e7ca66bdab4581409d1eac16c931db08d6b6 (patch) | |
tree | c7b2d92bc45ef662c4829d417180a89167b7890b /cmd2 | |
parent | 30d010f62196ff082bf243a4c460517cb70c70f2 (diff) | |
download | cmd2-git-9a20e7ca66bdab4581409d1eac16c931db08d6b6.tar.gz |
Added validation of subcommand handler attributes
Diffstat (limited to 'cmd2')
-rw-r--r-- | cmd2/cmd2.py | 6 | ||||
-rwxr-xr-x | cmd2/parsing.py | 19 |
2 files changed, 17 insertions, 8 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index adf797bf..f6a5251c 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -637,10 +637,14 @@ class Cmd(cmd.Cmd): # iterate through all matching methods for method_name, method in methods: - subcommand_name = getattr(method, constants.SUBCMD_ATTR_NAME) + subcommand_name = getattr(method, constants.SUBCMD_ATTR_NAME) # type: str full_command_name = getattr(method, constants.SUBCMD_ATTR_COMMAND) # type: str subcmd_parser = getattr(method, constants.CMD_ATTR_ARGPARSER) + subcommand_valid, errmsg = self.statement_parser.is_valid_command(subcommand_name, is_subcommand=True) + if not subcommand_valid: + raise CommandSetRegistrationError('Subcommand {} is not valid: {}'.format(str(subcommand_name), errmsg)) + command_tokens = full_command_name.split() command_name = command_tokens[0] subcommand_names = command_tokens[1:] diff --git a/cmd2/parsing.py b/cmd2/parsing.py index a7ee74a1..657db32c 100755 --- a/cmd2/parsing.py +++ b/cmd2/parsing.py @@ -277,7 +277,7 @@ class StatementParser: expr = r'\A\s*(\S*?)({})'.format(second_group) self._command_pattern = re.compile(expr) - def is_valid_command(self, word: str) -> Tuple[bool, str]: + 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, @@ -285,6 +285,7 @@ class StatementParser: shortcut. :param word: the word to check as a command + :param is_subcommand: Flag whether this command name is a subcommand name :return: a tuple of a boolean and an error string If word is not a valid command, return ``False`` and an error string @@ -297,18 +298,22 @@ class StatementParser: """ valid = False + if not isinstance(word, str): + return False, 'must be a string. Received {} instead'.format(str(type(word))) + if not word: return False, 'cannot be an empty string' if word.startswith(constants.COMMENT_CHAR): return False, 'cannot start with the comment character' - for (shortcut, _) in self.shortcuts: - if word.startswith(shortcut): - # Build an error string with all shortcuts listed - errmsg = 'cannot start with a shortcut: ' - errmsg += ', '.join(shortcut for (shortcut, _) in self.shortcuts) - return False, errmsg + if not is_subcommand: + for (shortcut, _) in self.shortcuts: + if word.startswith(shortcut): + # Build an error string with all shortcuts listed + errmsg = 'cannot start with a shortcut: ' + errmsg += ', '.join(shortcut for (shortcut, _) in self.shortcuts) + return False, errmsg errmsg = 'cannot contain: whitespace, quotes, ' errchars = [] |