From b61728ea7e47e2f2bbbb91e0a825c70275e476da Mon Sep 17 00:00:00 2001 From: Kevin Van Brunt Date: Sat, 16 Mar 2019 23:27:34 -0400 Subject: Added Statement object to argparse Namespace passed to wrapped functions --- cmd2/parsing.py | 90 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 39 deletions(-) (limited to 'cmd2/parsing.py') diff --git a/cmd2/parsing.py b/cmd2/parsing.py index d72ca4ec..cbb220fb 100644 --- a/cmd2/parsing.py +++ b/cmd2/parsing.py @@ -236,34 +236,6 @@ class Statement(str): return rtn -def get_command_arg_list(to_parse: Union[Statement, str], preserve_quotes: bool) -> List[str]: - """ - Called by the argument_list and argparse wrappers to retrieve just the arguments being - passed to their do_* methods as a list. - - :param to_parse: what is being passed to the do_* method. It can be one of two types: - 1. An already parsed Statement - 2. An argument string in cases where a do_* method is explicitly called - e.g.: Calling do_help('alias create') would cause to_parse to be 'alias create' - - :param preserve_quotes: if True, then quotes will not be stripped from the arguments - :return: the arguments in a list - """ - if isinstance(to_parse, Statement): - # In the case of a Statement, we already have what we need - if preserve_quotes: - return to_parse.arg_list - else: - return to_parse.argv[1:] - else: - # We have the arguments in a string. Use shlex to split it. - parsed_arglist = shlex_split(to_parse) - if not preserve_quotes: - parsed_arglist = [utils.strip_quotes(arg) for arg in parsed_arglist] - - return parsed_arglist - - class StatementParser: """Parse raw text into command components. @@ -371,16 +343,21 @@ class StatementParser: errmsg = '' return valid, errmsg - def tokenize(self, line: str) -> List[str]: - """Lex a string into a list of tokens. - - shortcuts and aliases are expanded and comments are removed - - Raises ValueError if there are unclosed quotation marks. + def tokenize(self, line: str, expand: bool = True) -> List[str]: + """ + Lex a string into a list of tokens. Shortcuts and aliases are expanded and comments are removed + + :param line: the command line being lexed + :param expand: if True, then aliases and shortcuts will be expanded + set this to False if the first token does not need to be expanded + because the command name is already known (Defaults to True) + :return: A list of tokens + :raises ValueError if there are unclosed quotation marks. """ # expand shortcuts and aliases - line = self._expand(line) + if expand: + line = self._expand(line) # check if this line is a comment if line.strip().startswith(constants.COMMENT_CHAR): @@ -393,12 +370,18 @@ class StatementParser: tokens = self._split_on_punctuation(tokens) return tokens - def parse(self, line: str) -> Statement: - """Tokenize the input and parse it into a Statement object, stripping + def parse(self, line: str, expand: bool = True) -> Statement: + """ + Tokenize the input and parse it into a Statement object, stripping comments, expanding aliases and shortcuts, and extracting output redirection directives. - Raises ValueError if there are unclosed quotation marks. + :param line: the command line being parsed + :param expand: if True, then aliases and shortcuts will be expanded + set this to False if the first token does not need to be expanded + because the command name is already known (Defaults to True) + :return: A parsed Statement + :raises ValueError if there are unclosed quotation marks """ # handle the special case/hardcoded terminator of a blank line @@ -413,7 +396,7 @@ class StatementParser: arg_list = [] # lex the input into a list of tokens - tokens = self.tokenize(line) + tokens = self.tokenize(line, expand) # of the valid terminators, find the first one to occur in the input terminator_pos = len(tokens) + 1 @@ -594,6 +577,35 @@ class StatementParser: ) return statement + def get_command_arg_list(self, command_name: str, to_parse: Union[Statement, str], + preserve_quotes: bool) -> Tuple[Statement, List[str]]: + """ + Called by the argument_list and argparse wrappers to retrieve just the arguments being + passed to their do_* methods as a list. + + :param command_name: name of the command being run + :param to_parse: what is being passed to the do_* method. It can be one of two types: + 1. An already parsed Statement + 2. An argument string in cases where a do_* method is explicitly called + e.g.: Calling do_help('alias create') would cause to_parse to be 'alias create' + + In this case, the string will be converted to a Statement and returned along + with the argument list. + + :param preserve_quotes: if True, then quotes will not be stripped from the arguments + :return: A tuple containing: + The Statement used to retrieve the arguments + The argument list + """ + # Check if to_parse needs to be converted to a Statement + if not isinstance(to_parse, Statement): + to_parse = self.parse(command_name + ' ' + to_parse, expand=False) + + if preserve_quotes: + return to_parse, to_parse.arg_list + else: + return to_parse, to_parse.argv[1:] + def _expand(self, line: str) -> str: """Expand shortcuts and aliases""" -- cgit v1.2.1 From 28b7ec2ae2531366d41805b19700ca93677502b4 Mon Sep 17 00:00:00 2001 From: Kevin Van Brunt Date: Sat, 16 Mar 2019 23:48:37 -0400 Subject: Updated documentation --- cmd2/parsing.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'cmd2/parsing.py') diff --git a/cmd2/parsing.py b/cmd2/parsing.py index cbb220fb..f2fe7628 100644 --- a/cmd2/parsing.py +++ b/cmd2/parsing.py @@ -348,9 +348,10 @@ class StatementParser: Lex a string into a list of tokens. Shortcuts and aliases are expanded and comments are removed :param line: the command line being lexed - :param expand: if True, then aliases and shortcuts will be expanded - set this to False if the first token does not need to be expanded - because the command name is already known (Defaults to True) + :param expand: If True, then aliases and shortcuts will be expanded. + Set this to False if no expansion should occur because the command name is already known. + Otherwise the command could be expanded if it matched an alias name. This is for cases where + a do_* function was called manually (e.g do_help('alias'). :return: A list of tokens :raises ValueError if there are unclosed quotation marks. """ @@ -377,9 +378,10 @@ class StatementParser: redirection directives. :param line: the command line being parsed - :param expand: if True, then aliases and shortcuts will be expanded - set this to False if the first token does not need to be expanded - because the command name is already known (Defaults to True) + :param expand: If True, then aliases and shortcuts will be expanded. + Set this to False if no expansion should occur because the command name is already known. + Otherwise the command could be expanded if it matched an alias name. This is for cases where + a do_* function was called manually (e.g do_help('alias'). :return: A parsed Statement :raises ValueError if there are unclosed quotation marks """ -- cgit v1.2.1 From 40f75f7453c3df83d8e74a281ec1311d53b23eec Mon Sep 17 00:00:00 2001 From: Kevin Van Brunt Date: Sun, 17 Mar 2019 00:52:34 -0400 Subject: Updated docs and example --- cmd2/parsing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cmd2/parsing.py') diff --git a/cmd2/parsing.py b/cmd2/parsing.py index f2fe7628..514f5faf 100644 --- a/cmd2/parsing.py +++ b/cmd2/parsing.py @@ -351,7 +351,7 @@ class StatementParser: :param expand: If True, then aliases and shortcuts will be expanded. Set this to False if no expansion should occur because the command name is already known. Otherwise the command could be expanded if it matched an alias name. This is for cases where - a do_* function was called manually (e.g do_help('alias'). + a do_* method was called manually (e.g do_help('alias'). :return: A list of tokens :raises ValueError if there are unclosed quotation marks. """ @@ -381,7 +381,7 @@ class StatementParser: :param expand: If True, then aliases and shortcuts will be expanded. Set this to False if no expansion should occur because the command name is already known. Otherwise the command could be expanded if it matched an alias name. This is for cases where - a do_* function was called manually (e.g do_help('alias'). + a do_* method was called manually (e.g do_help('alias'). :return: A parsed Statement :raises ValueError if there are unclosed quotation marks """ -- cgit v1.2.1