-
Notifications
You must be signed in to change notification settings - Fork 130
Func plus hooks #578
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Func plus hooks #578
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
5c6d858
Non-argparse commands called as methods of PyscriptBridge now go thro…
kmvanbrunt b50dfc5
Argparse commands called as methods of PyscriptBridge now go through …
kmvanbrunt d3d75f2
Refactored
kmvanbrunt 058db75
Added bug fixes to change log
kmvanbrunt 7786b66
Moved bug fixes to top
kmvanbrunt be82ee5
Removed venv
kmvanbrunt File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,8 +45,14 @@ def __bool__(self) -> bool: | |
| return not self.stderr | ||
|
|
||
|
|
||
| def _exec_cmd(cmd2_app, func: Callable, echo: bool) -> CommandResult: | ||
| """Helper to encapsulate executing a command and capturing the results""" | ||
| def _exec_cmd(cmd2_app, command: str, echo: bool) -> CommandResult: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These changes seem good |
||
| """ | ||
| Helper to encapsulate executing a command and capturing the results | ||
| :param cmd2_app: cmd2 app that will run the command | ||
| :param command: command line being run | ||
| :param echo: if True, output will be echoed to stdout/stderr while the command runs | ||
| :return: result of the command | ||
| """ | ||
| copy_stdout = StdSim(sys.stdout, echo) | ||
| copy_stderr = StdSim(sys.stderr, echo) | ||
|
|
||
|
|
@@ -58,7 +64,8 @@ def _exec_cmd(cmd2_app, func: Callable, echo: bool) -> CommandResult: | |
| cmd2_app.stdout = copy_cmd_stdout | ||
| with redirect_stdout(copy_stdout): | ||
| with redirect_stderr(copy_stderr): | ||
| func() | ||
| # Include a newline in case it's a multiline command | ||
| cmd2_app.onecmd_plus_hooks(command + '\n') | ||
| finally: | ||
| cmd2_app.stdout = copy_cmd_stdout.inner_stream | ||
|
|
||
|
|
@@ -199,28 +206,29 @@ def _run(self): | |
| self._command_name)) | ||
|
|
||
| # reconstruct the cmd2 command from the python call | ||
| cmd_str = [''] | ||
| command = self._command_name | ||
|
|
||
| def process_argument(action, value): | ||
| nonlocal command | ||
| if isinstance(action, argparse._CountAction): | ||
| if isinstance(value, int): | ||
| for _ in range(value): | ||
| cmd_str[0] += '{} '.format(action.option_strings[0]) | ||
| command += ' {}'.format(action.option_strings[0]) | ||
| return | ||
| else: | ||
| raise TypeError('Expected int for ' + action.dest) | ||
| if isinstance(action, argparse._StoreConstAction) or isinstance(action, argparse._AppendConstAction): | ||
| if value: | ||
| # Nothing else to append to the command string, just the flag is enough. | ||
| cmd_str[0] += '{} '.format(action.option_strings[0]) | ||
| command += ' {}'.format(action.option_strings[0]) | ||
| return | ||
| else: | ||
| # value is not True so we default to false, which means don't include the flag | ||
| return | ||
|
|
||
| # was the argument a flag? | ||
| if action.option_strings: | ||
| cmd_str[0] += '{} '.format(action.option_strings[0]) | ||
| command += ' {}'.format(action.option_strings[0]) | ||
|
|
||
| is_remainder_arg = action.dest == self._remainder_arg | ||
|
|
||
|
|
@@ -231,33 +239,34 @@ def process_argument(action, value): | |
| raise ValueError('{} appears to be a flag and should be supplied as a keyword argument ' | ||
| 'to the function.'.format(item)) | ||
| item = quote_string_if_needed(item) | ||
| cmd_str[0] += '{} '.format(item) | ||
| command += ' {}'.format(item) | ||
|
|
||
| # If this is a flag parameter that can accept a variable number of arguments and we have not | ||
| # reached the max number, add a list completion suffix to tell argparse to move to the next | ||
| # parameter | ||
| if action.option_strings and isinstance(action, _RangeAction) and action.nargs_max is not None and \ | ||
| action.nargs_max > len(value): | ||
| cmd_str[0] += '{0}{0} '.format(self._parser.prefix_chars[0]) | ||
| command += ' {0}{0}'.format(self._parser.prefix_chars[0]) | ||
|
|
||
| else: | ||
| value = str(value).strip() | ||
| if not is_remainder_arg and is_potential_flag(value, self._parser): | ||
| raise ValueError('{} appears to be a flag and should be supplied as a keyword argument ' | ||
| 'to the function.'.format(value)) | ||
| value = quote_string_if_needed(value) | ||
| cmd_str[0] += '{} '.format(value) | ||
| command += ' {}'.format(value) | ||
|
|
||
| # If this is a flag parameter that can accept a variable number of arguments and we have not | ||
| # reached the max number, add a list completion suffix to tell argparse to move to the next | ||
| # parameter | ||
| if action.option_strings and isinstance(action, _RangeAction) and action.nargs_max is not None and \ | ||
| action.nargs_max > 1: | ||
| cmd_str[0] += '{0}{0} '.format(self._parser.prefix_chars[0]) | ||
| command += ' {0}{0}'.format(self._parser.prefix_chars[0]) | ||
|
|
||
| def process_action(action): | ||
| nonlocal command | ||
| if isinstance(action, argparse._SubParsersAction): | ||
| cmd_str[0] += '{} '.format(self._args[action.dest]) | ||
| command += ' {}'.format(self._args[action.dest]) | ||
| traverse_parser(action.choices[self._args[action.dest]]) | ||
| elif isinstance(action, argparse._AppendAction): | ||
| if isinstance(self._args[action.dest], list) or isinstance(self._args[action.dest], tuple): | ||
|
|
@@ -284,8 +293,7 @@ def traverse_parser(parser): | |
| process_action(action) | ||
|
|
||
| traverse_parser(self._parser) | ||
|
|
||
| return _exec_cmd(self._cmd2_app, functools.partial(func, cmd_str[0]), self._echo) | ||
| return _exec_cmd(self._cmd2_app, command, self._echo) | ||
|
|
||
|
|
||
| class PyscriptBridge(object): | ||
|
|
@@ -310,7 +318,10 @@ def __getattr__(self, item: str): | |
| else: | ||
| # Command doesn't use argparse, we will accept parameters in the form of a command string | ||
| def wrap_func(args=''): | ||
| return _exec_cmd(self._cmd2_app, functools.partial(func, args), self.cmd_echo) | ||
| command = item | ||
| if args: | ||
| command += ' ' + args | ||
| return _exec_cmd(self._cmd2_app, command, self.cmd_echo) | ||
|
|
||
| return wrap_func | ||
| else: | ||
|
|
@@ -323,17 +334,15 @@ def __dir__(self): | |
| attributes.insert(0, 'cmd_echo') | ||
| return attributes | ||
|
|
||
| def __call__(self, args: str, echo: Optional[bool]=None) -> CommandResult: | ||
| def __call__(self, command: str, echo: Optional[bool]=None) -> CommandResult: | ||
| """ | ||
| Provide functionality to call application commands by calling PyscriptBridge | ||
| ex: app('help') | ||
| :param args: The string being passed to the command | ||
| :param echo: If True, output will be echoed while the command runs | ||
| This temporarily overrides the value of self.cmd_echo | ||
| :param command: command line being run | ||
| :param echo: if True, output will be echoed to stdout/stderr while the command runs | ||
| this temporarily overrides the value of self.cmd_echo | ||
| """ | ||
| if echo is None: | ||
| echo = self.cmd_echo | ||
|
|
||
| return _exec_cmd(self._cmd2_app, | ||
| functools.partial(self._cmd2_app.onecmd_plus_hooks, args + '\n'), | ||
| echo) | ||
| return _exec_cmd(self._cmd2_app, command, echo) | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good