Skip to content

Conversation

@kmvanbrunt
Copy link
Member

@kmvanbrunt kmvanbrunt commented Mar 19, 2019

Fixes #613

The root cause of #613 was onecmd_plus_hooks() calling _restore_output() if self.redirecting was True. While pyscript was redirecting its output to a file, the PyscriptBridge would call onecmd_plus_hooks() to handle app('help'). After the help command ended, _restore_output() would be called because self.redirecting was True and therefore the file handle pyscript was using to redirect its output would be closed.

The new code keeps track of redirection for each command. Therefore _restore_output() only restores stuff if the current command set up redirection.

This also enhances our pyscript functionality quite a bit. We can now independently redirect each command running within the script. Therefore the outer pyscript call may be writing its output to a file while commands being run within the script can write anywhere they want, including piping to another process.

  1. app("help > help.txt")
  2. app("!cat file | grep string")

This PR also made a change to the piped process in redirection. We now set its stdout to be self.stdout.

Lastly, I no longer append a \n to commands in PyscriptBridge. This was originally done to assist in running multiline commands in a pyscript file. However, it had the unintended consequence of breaking redirection with non-multiline commands. From now on users are expected to include a terminator in multiline commands being run in a pyscript. This fits the expected syntax anyway since commands passed to app() should be the same as they would be typed on the command line.

@codecov
Copy link

codecov bot commented Mar 19, 2019

Codecov Report

Merging #653 into master will increase coverage by 0.13%.
The diff coverage is 91.04%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #653      +/-   ##
==========================================
+ Coverage   94.34%   94.48%   +0.13%     
==========================================
  Files          11       11              
  Lines        3079     3062      -17     
==========================================
- Hits         2905     2893      -12     
+ Misses        174      169       -5
Impacted Files Coverage Δ
cmd2/parsing.py 100% <100%> (ø) ⬆️
cmd2/pyscript_bridge.py 100% <100%> (ø) ⬆️
cmd2/cmd2.py 94.65% <90.76%> (+0.23%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 57dd827...a4ff5ed. Read the comment docs.

tleonhardt
tleonhardt previously approved these changes Mar 20, 2019
Copy link
Member

@tleonhardt tleonhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be a very nice ruggedization improvement.


# Used to restore state after redirection ends
# redirecting and piping are used to know what needs to be restored
RedirectionSavedState = utils.namedtuple_with_defaults('RedirectionSavedState',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this should be declared in utils and imported from there?

@@ -1879,53 +1871,59 @@ def _complete_statement(self, line: str) -> Statement:
newline = '\n'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A unit test for the case inside this if would be nice

newline = '\n'
self.poutput(newline)
line = '{}\n{}'.format(statement.raw, newline)
except KeyboardInterrupt as ex:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A unit test for anything inside tis except would be great (but maybe not easy)

self._cmdfinalization_hooks.append(func)


class Statekeeper(object):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job finally getting rid of this

except KeyboardInterrupt:
try:
line = self.pseudo_raw_input(self.prompt)
except KeyboardInterrupt as ex:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like how you cleaned up handling this case

@tleonhardt
Copy link
Member

I'm going to merge this in because I want to test it in combination with other changes. We can always modify it later. But so far it seems like a great improvement.

@tleonhardt tleonhardt merged commit e89bd4f into master Mar 20, 2019
@tleonhardt tleonhardt deleted the pyscript_fix branch March 20, 2019 00:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Redirecting pyscript with app() commands closes cmd2

3 participants