[PATCH] Flush password prompts for non-terminal callers
Mads Kiilerich
mads at kiilerich.com
Sat Jan 15 18:44:41 CST 2011
Steven Streeting wrote, On 01/15/2011 04:40 PM:
> # HG changeset patch
> # User Steve Streeting<steve at stevestreeting.com>
> # Date 1295105307 0
> # Node ID 407ab604cbb7b923f8e517e5f4858b0005bc14d0
> # Parent 8f72d2f6c26322c235602280ea0a2b3debf37b06
> Ensure that password prompts are flushed so that any non-terminal waiting for them on stderr can reliably see them. This is required to do interactive login from non-terminal clients, without forcing the user to pre-populate their configuration parameters. Without this feature, hg commands which require authentication which hasn't been pre-configured will simply randomly hang waiting for input without the calling program being any the wiser. Flushing the prompt means it always has a chance to know that hg is waiting for a response.
> This is discussed in more detail in this tracker item: http://mercurial.selenic.com/bts/issue2590
Thanks for the patch.
A meta comment: See
http://mercurial.selenic.com/wiki/ContributingChanges , especially
* Patches should be in the '# HG changeset patch' form output by 'hg export'
* patchbomb extension always works (and makes sure the summary is
included correctly in the patch)
* lowercase summary line, no trailing period
* all lines less than 80 characters
* a blank line after the summary
* add '(issueNNNN)' to summary to refer to a BugTracker issue
> diff --git a/mercurial/ui.py b/mercurial/ui.py
> --- a/mercurial/ui.py
> +++ b/mercurial/ui.py
> @@ -468,7 +468,12 @@
> # windows sometimes raises something other than ImportError
> except Exception:
> pass
> - line = raw_input(prompt)
> + # prompt using read_line instead of raw_input which ensures prompt is flushed
> + self.write_err(prompt)
> + line = sys.stdin.readline()
> + # get rid of \r
> + if line and line[-1] == '\r':
> + line = line[:-1]
We generally like readable code without lots of comments. Comments might
be good for describing _why_ the code does what it does if it isn't
obvious, but they should not be used (or necessary) to describe _what_
the code does.
> # When stdin is in binary mode on Windows, it can cause
> # raw_input() to emit an extra trailing carriage return
> if os.linesep == '\r\n' and line and line[-1] == '\r':
> @@ -508,7 +513,13 @@
> if not self.interactive():
> return default
> try:
> - return getpass.getpass(prompt or _('password: '))
> + # Ensure we flush so that we can read prompt in non-terminal
> + self.write_err('password:')
Don't change the prompt.
> + pwd = sys.stdin.readline()
> + # get rid of \r
> + if pwd and pwd[-1] == '\r':
> + pwd = pwd[:-1]
> + return pwd
> except EOFError:
> raise util.Abort(_('response expected'))
> def status(self, *msg, **opts):
You might have a point that there is an issue with raw_input and getpass
not flushing after showing the prompt, but why dismiss them completely?
Instead I suggest first writing the prompt (with flushing), and then
call the existing functions with '' as prompt.
/Mads
More information about the Mercurial-devel
mailing list