Skip to content

Commit d3d75f2

Browse files
committed
Refactored
1 parent b50dfc5 commit d3d75f2

File tree

2 files changed

+30
-26
lines changed

2 files changed

+30
-26
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Enhancements
33
* All platforms now depend on [wcwidth](https://pypi.python.org/pypi/wcwidth) to assist with asynchronous alerts.
44
* Macros now accept extra arguments when called. These will be tacked onto the resolved command.
5+
* All cmd2 commands run via py now go through onecmd_plus_hooks.
56

67
## 0.9.5 (October 11, 2018)
78
* Bug Fixes

cmd2/pyscript_bridge.py

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,14 @@ def __bool__(self) -> bool:
4545
return not self.stderr
4646

4747

48-
def _exec_cmd(cmd2_app, func: Callable, echo: bool) -> CommandResult:
49-
"""Helper to encapsulate executing a command and capturing the results"""
48+
def _exec_cmd(cmd2_app, command: str, echo: bool) -> CommandResult:
49+
"""
50+
Helper to encapsulate executing a command and capturing the results
51+
:param cmd2_app: cmd2 app that will run the command
52+
:param command: command line being run
53+
:param echo: if True, output will be echoed to stdout/stderr while the command runs
54+
:return: result of the command
55+
"""
5056
copy_stdout = StdSim(sys.stdout, echo)
5157
copy_stderr = StdSim(sys.stderr, echo)
5258

@@ -58,7 +64,8 @@ def _exec_cmd(cmd2_app, func: Callable, echo: bool) -> CommandResult:
5864
cmd2_app.stdout = copy_cmd_stdout
5965
with redirect_stdout(copy_stdout):
6066
with redirect_stderr(copy_stderr):
61-
func()
67+
# Include a newline in case it's a multiline command
68+
cmd2_app.onecmd_plus_hooks(command + '\n')
6269
finally:
6370
cmd2_app.stdout = copy_cmd_stdout.inner_stream
6471

@@ -199,29 +206,29 @@ def _run(self):
199206
self._command_name))
200207

201208
# reconstruct the cmd2 command from the python call
202-
command = self._command_name + ' '
209+
command = self._command_name
203210

204211
def process_argument(action, value):
205212
nonlocal command
206213
if isinstance(action, argparse._CountAction):
207214
if isinstance(value, int):
208215
for _ in range(value):
209-
command += '{} '.format(action.option_strings[0])
216+
command += ' {}'.format(action.option_strings[0])
210217
return
211218
else:
212219
raise TypeError('Expected int for ' + action.dest)
213220
if isinstance(action, argparse._StoreConstAction) or isinstance(action, argparse._AppendConstAction):
214221
if value:
215222
# Nothing else to append to the command string, just the flag is enough.
216-
command += '{} '.format(action.option_strings[0])
223+
command += ' {}'.format(action.option_strings[0])
217224
return
218225
else:
219226
# value is not True so we default to false, which means don't include the flag
220227
return
221228

222229
# was the argument a flag?
223230
if action.option_strings:
224-
command += '{} '.format(action.option_strings[0])
231+
command += ' {}'.format(action.option_strings[0])
225232

226233
is_remainder_arg = action.dest == self._remainder_arg
227234

@@ -232,34 +239,34 @@ def process_argument(action, value):
232239
raise ValueError('{} appears to be a flag and should be supplied as a keyword argument '
233240
'to the function.'.format(item))
234241
item = quote_string_if_needed(item)
235-
command += '{} '.format(item)
242+
command += ' {}'.format(item)
236243

237244
# If this is a flag parameter that can accept a variable number of arguments and we have not
238245
# reached the max number, add a list completion suffix to tell argparse to move to the next
239246
# parameter
240247
if action.option_strings and isinstance(action, _RangeAction) and action.nargs_max is not None and \
241248
action.nargs_max > len(value):
242-
command += '{0}{0} '.format(self._parser.prefix_chars[0])
249+
command += ' {0}{0}'.format(self._parser.prefix_chars[0])
243250

244251
else:
245252
value = str(value).strip()
246253
if not is_remainder_arg and is_potential_flag(value, self._parser):
247254
raise ValueError('{} appears to be a flag and should be supplied as a keyword argument '
248255
'to the function.'.format(value))
249256
value = quote_string_if_needed(value)
250-
command += '{} '.format(value)
257+
command += ' {}'.format(value)
251258

252259
# If this is a flag parameter that can accept a variable number of arguments and we have not
253260
# reached the max number, add a list completion suffix to tell argparse to move to the next
254261
# parameter
255262
if action.option_strings and isinstance(action, _RangeAction) and action.nargs_max is not None and \
256263
action.nargs_max > 1:
257-
command += '{0}{0} '.format(self._parser.prefix_chars[0])
264+
command += ' {0}{0}'.format(self._parser.prefix_chars[0])
258265

259266
def process_action(action):
260267
nonlocal command
261268
if isinstance(action, argparse._SubParsersAction):
262-
command += '{} '.format(self._args[action.dest])
269+
command += ' {}'.format(self._args[action.dest])
263270
traverse_parser(action.choices[self._args[action.dest]])
264271
elif isinstance(action, argparse._AppendAction):
265272
if isinstance(self._args[action.dest], list) or isinstance(self._args[action.dest], tuple):
@@ -286,9 +293,7 @@ def traverse_parser(parser):
286293
process_action(action)
287294

288295
traverse_parser(self._parser)
289-
return _exec_cmd(self._cmd2_app,
290-
functools.partial(self._cmd2_app.onecmd_plus_hooks, command.strip() + '\n'),
291-
self._echo)
296+
return _exec_cmd(self._cmd2_app, command, self._echo)
292297

293298

294299
class PyscriptBridge(object):
@@ -313,10 +318,10 @@ def __getattr__(self, item: str):
313318
else:
314319
# Command doesn't use argparse, we will accept parameters in the form of a command string
315320
def wrap_func(args=''):
316-
command = (item + ' ' + args).strip()
317-
return _exec_cmd(self._cmd2_app,
318-
functools.partial(self._cmd2_app.onecmd_plus_hooks, command + '\n'),
319-
self.cmd_echo)
321+
command = item
322+
if args:
323+
command += ' ' + args
324+
return _exec_cmd(self._cmd2_app, command, self.cmd_echo)
320325

321326
return wrap_func
322327
else:
@@ -329,17 +334,15 @@ def __dir__(self):
329334
attributes.insert(0, 'cmd_echo')
330335
return attributes
331336

332-
def __call__(self, args: str, echo: Optional[bool]=None) -> CommandResult:
337+
def __call__(self, command: str, echo: Optional[bool]=None) -> CommandResult:
333338
"""
334339
Provide functionality to call application commands by calling PyscriptBridge
335340
ex: app('help')
336-
:param args: The string being passed to the command
337-
:param echo: If True, output will be echoed while the command runs
338-
This temporarily overrides the value of self.cmd_echo
341+
:param command: command line being run
342+
:param echo: if True, output will be echoed to stdout/stderr while the command runs
343+
this temporarily overrides the value of self.cmd_echo
339344
"""
340345
if echo is None:
341346
echo = self.cmd_echo
342347

343-
return _exec_cmd(self._cmd2_app,
344-
functools.partial(self._cmd2_app.onecmd_plus_hooks, args + '\n'),
345-
echo)
348+
return _exec_cmd(self._cmd2_app, command, echo)

0 commit comments

Comments
 (0)