Example case is running Invoke's own test runner, inv test (which does run('spec', pty=True)) within a Git pre-push hook. Git runs the hook script in some non-pty environment (even if one is running git from a terminal window) and so pexpect's attempt to do things like tty.tcgetattr(self.STDIN_FILENO) explodes with termios.error: (25, 'Inappropriate ioctl for device').
termios.error: (25, 'Inappropriate ioctl for device')
Sure enough, examining that fileno value when running by hand vs hook script shows that os.isatty(self.STDIN_FILENO) is False when things blow up.
I can see two ways to handle this:
While I have some fears about argument bloat, I could see situations where the isatty test isn't foolproof and users might want to force use of a pty when it says False. So I'm also adding a fallback kwarg which overrides the fallback behavior being added. It defaults to True so the fallback is still default behavior for most users (otherwise there'd be little point).
Got the basics for this working, then realized we had way too much junk stuck in Local.run that would eventually need applying to other subclasses. Currently in the middle of a big stinkin' reorg.
Once that is back to full operation I need to:
Implement #219, pty fallback
All done. That was a nice detour...