From d9f5f2b48927a43a5628bff856f90ad0d8b80c7e Mon Sep 17 00:00:00 2001 From: Kevin Van Brunt Date: Tue, 2 Oct 2018 13:24:18 -0400 Subject: Added echo parameter for calling commands from Pyscript Documented py command's parsing limitations --- cmd2/pyscript_bridge.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'cmd2/pyscript_bridge.py') diff --git a/cmd2/pyscript_bridge.py b/cmd2/pyscript_bridge.py index f03b530f..c8db0960 100644 --- a/cmd2/pyscript_bridge.py +++ b/cmd2/pyscript_bridge.py @@ -10,7 +10,7 @@ Released under MIT license, see LICENSE file import argparse import functools import sys -from typing import List, Callable +from typing import List, Callable, Optional from .argparse_completer import _RangeAction from .utils import namedtuple_with_defaults, StdSim @@ -38,7 +38,7 @@ class CommandResult(namedtuple_with_defaults('CommandResult', ['stdout', 'stderr return not self.stderr and self.data is not None -def _exec_cmd(cmd2_app, func: Callable, echo: bool): +def _exec_cmd(cmd2_app, func: Callable, echo: bool) -> CommandResult: """Helper to encapsulate executing a command and capturing the results""" copy_stdout = StdSim(sys.stdout, echo) copy_stderr = StdSim(sys.stderr, echo) @@ -65,7 +65,7 @@ def _exec_cmd(cmd2_app, func: Callable, echo: bool): class ArgparseFunctor: """ - Encapsulates translating python object traversal + Encapsulates translating Python object traversal """ def __init__(self, echo: bool, cmd2_app, command_name: str, parser: argparse.ArgumentParser): self._echo = echo @@ -250,7 +250,7 @@ class PyscriptBridge(object): self.cmd_echo = False def __getattr__(self, item: str): - """Check if the attribute is a command. If so, return a callable.""" + """If attribute is a command, return a callable. Otherwise return the attribute.""" func = self._cmd2_app.cmd_func(item) if func: @@ -264,7 +264,7 @@ class PyscriptBridge(object): return wrap_func else: - return super().__getattr__(item) + return getattr(self._cmd2_app, item) def __dir__(self): """Return a custom set of attribute names to match the available commands""" @@ -272,6 +272,15 @@ class PyscriptBridge(object): commands.insert(0, 'cmd_echo') return commands - def __call__(self, args: str): + def __call__(self, args: str, echo: Optional[bool]=None) -> CommandResult: + """ + Call a command function (ex: do_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 + """ + if echo is None: + echo = self.cmd_echo + return _exec_cmd(self._cmd2_app, functools.partial(self._cmd2_app.onecmd_plus_hooks, args + '\n'), - self.cmd_echo) + echo) -- cgit v1.2.1 From 1c0616a61740f1407f684a1dbe816fa547873b13 Mon Sep 17 00:00:00 2001 From: Kevin Van Brunt Date: Tue, 2 Oct 2018 15:30:16 -0400 Subject: Changed PyscriptBridge.__getattr__ to raise Attribute error for non-commands --- cmd2/pyscript_bridge.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'cmd2/pyscript_bridge.py') diff --git a/cmd2/pyscript_bridge.py b/cmd2/pyscript_bridge.py index c8db0960..b66fd701 100644 --- a/cmd2/pyscript_bridge.py +++ b/cmd2/pyscript_bridge.py @@ -250,7 +250,10 @@ class PyscriptBridge(object): self.cmd_echo = False def __getattr__(self, item: str): - """If attribute is a command, return a callable. Otherwise return the attribute.""" + """ + Provide a way to call application commands via the PyscriptBridge + ex: app.help() + """ func = self._cmd2_app.cmd_func(item) if func: @@ -264,7 +267,8 @@ class PyscriptBridge(object): return wrap_func else: - return getattr(self._cmd2_app, item) + # item does not refer to a command + raise AttributeError("'{}' object has no attribute '{}'".format(self._cmd2_app.pyscript_name, item)) def __dir__(self): """Return a custom set of attribute names to match the available commands""" -- cgit v1.2.1 From 957137a886e76f5b32f62f667673a72a813f8c0d Mon Sep 17 00:00:00 2001 From: Kevin Van Brunt Date: Tue, 2 Oct 2018 23:14:35 -0400 Subject: Default cmd_echo to True in PyscriptBridge so things like 'py app.help()' will show output --- cmd2/pyscript_bridge.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'cmd2/pyscript_bridge.py') diff --git a/cmd2/pyscript_bridge.py b/cmd2/pyscript_bridge.py index b66fd701..9d865b6b 100644 --- a/cmd2/pyscript_bridge.py +++ b/cmd2/pyscript_bridge.py @@ -247,7 +247,7 @@ class PyscriptBridge(object): def __init__(self, cmd2_app): self._cmd2_app = cmd2_app self._last_result = None - self.cmd_echo = False + self.cmd_echo = True def __getattr__(self, item: str): """ @@ -271,10 +271,10 @@ class PyscriptBridge(object): raise AttributeError("'{}' object has no attribute '{}'".format(self._cmd2_app.pyscript_name, item)) def __dir__(self): - """Return a custom set of attribute names to match the available commands""" - commands = list(self._cmd2_app.get_all_commands()) - commands.insert(0, 'cmd_echo') - return commands + """Return a custom set of attribute names""" + attributes = self._cmd2_app.get_all_commands() + attributes.insert(0, 'cmd_echo') + return attributes def __call__(self, args: str, echo: Optional[bool]=None) -> CommandResult: """ -- cgit v1.2.1 From c347ac8e56899c4662889d6a9f42afbd8d4646fd Mon Sep 17 00:00:00 2001 From: Kevin Van Brunt Date: Tue, 2 Oct 2018 23:26:54 -0400 Subject: Improved documentation --- cmd2/pyscript_bridge.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'cmd2/pyscript_bridge.py') diff --git a/cmd2/pyscript_bridge.py b/cmd2/pyscript_bridge.py index 9d865b6b..4434bb58 100644 --- a/cmd2/pyscript_bridge.py +++ b/cmd2/pyscript_bridge.py @@ -251,7 +251,7 @@ class PyscriptBridge(object): def __getattr__(self, item: str): """ - Provide a way to call application commands via the PyscriptBridge + Provide functionality to call application commands as a method of PyscriptBridge ex: app.help() """ func = self._cmd2_app.cmd_func(item) @@ -278,7 +278,8 @@ class PyscriptBridge(object): def __call__(self, args: str, echo: Optional[bool]=None) -> CommandResult: """ - Call a command function (ex: do_help) + 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 @@ -286,5 +287,6 @@ class PyscriptBridge(object): if echo is None: echo = self.cmd_echo - return _exec_cmd(self._cmd2_app, functools.partial(self._cmd2_app.onecmd_plus_hooks, args + '\n'), + return _exec_cmd(self._cmd2_app, + functools.partial(self._cmd2_app.onecmd_plus_hooks, args + '\n'), echo) -- cgit v1.2.1 From 60bf3aa5385f4c6dde6396c48262ae7d5177fd0c Mon Sep 17 00:00:00 2001 From: Kevin Van Brunt Date: Tue, 2 Oct 2018 23:54:01 -0400 Subject: Returned cmd_echo default to False except when running a Python command at the CLI --- cmd2/pyscript_bridge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmd2/pyscript_bridge.py') diff --git a/cmd2/pyscript_bridge.py b/cmd2/pyscript_bridge.py index 4434bb58..07ce7212 100644 --- a/cmd2/pyscript_bridge.py +++ b/cmd2/pyscript_bridge.py @@ -247,7 +247,7 @@ class PyscriptBridge(object): def __init__(self, cmd2_app): self._cmd2_app = cmd2_app self._last_result = None - self.cmd_echo = True + self.cmd_echo = False def __getattr__(self, item: str): """ -- cgit v1.2.1 From d8c0b0a56d21716f985f3715e3c9e31d2309d7da Mon Sep 17 00:00:00 2001 From: Kevin Van Brunt Date: Wed, 3 Oct 2018 10:38:48 -0400 Subject: Tweaked some error strings --- cmd2/pyscript_bridge.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cmd2/pyscript_bridge.py') diff --git a/cmd2/pyscript_bridge.py b/cmd2/pyscript_bridge.py index 07ce7212..a70a7ae6 100644 --- a/cmd2/pyscript_bridge.py +++ b/cmd2/pyscript_bridge.py @@ -169,7 +169,7 @@ class ArgparseFunctor: # Check if there are any extra arguments we don't know how to handle for kw in kwargs: if kw not in self._args: # consumed_kw: - raise TypeError('{}() got an unexpected keyword argument \'{}\''.format( + raise TypeError("{}() got an unexpected keyword argument '{}'".format( self.__current_subcommand_parser.prog, kw)) if has_subcommand: @@ -181,7 +181,7 @@ class ArgparseFunctor: # look up command function func = self._cmd2_app.cmd_func(self._command_name) if func is None: - raise AttributeError("{!r} object has no command called {!r}".format(self._cmd2_app.__class__.__name__, + raise AttributeError("'{}' object has no command called '{}'".format(self._cmd2_app.__class__.__name__, self._command_name)) # reconstruct the cmd2 command from the python call -- cgit v1.2.1