# HG changeset patch # User Dirkjan Ochtman # Date 1190739934 -7200 # Node ID 8c5ef3b87cb1aa824a6003e688f0140efcafe456 # Parent 24de027551c1b56f07ee1fcb7a1ccd524351a692 Don't try to determine interactivity if ui() called with interactive=False. WSGI applications are not supposed to refer to sys.stdin. In ed6df6b1c29a, hgweb and hgwebdir were fixed to pass interactive=False to their ui()'s, but sys.stdin.isatty() was still called by the ui objects. This change makes sure only the ui.fixconfig() method will call ui.isatty() (by making the ui._readline() method, which is currently only called from ui.prompt(), private). ui.fixconfig() is changed to let config files override the initial interactivity setting, but not check isatty() if interactive=False was specified in the creation of the ui. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -211,9 +211,11 @@ class ui(object): if name is None or name in ('quiet', 'verbose', 'debug'): self.verbosity_constraints() if name is None or name == 'interactive': - self.interactive = self.configbool("ui", "interactive", None) - if self.interactive is None: + interactive = self.configbool("ui", "interactive", None) + if interactive is None and self.interactive: self.interactive = self.isatty() + else: + self.interactive = interactive if name is None or name == 'report_untrusted': self.report_untrusted = ( self.configbool("ui", "report_untrusted", True)) @@ -391,7 +393,7 @@ class ui(object): try: sys.stderr.flush() except: pass - def readline(self, prompt=''): + def _readline(self, prompt=''): if self.isatty(): try: # magically add command line editing support, where @@ -406,7 +408,7 @@ class ui(object): def prompt(self, msg, pat=None, default="y", matchflags=0): if not self.interactive: return default try: - r = self.readline(msg + ' ') + r = self._readline(msg + ' ') if not pat or re.match(pat, r, matchflags): return r else: diff --git a/tests/test-non-interactive-wsgi b/tests/test-non-interactive-wsgi new file mode 100755 --- /dev/null +++ b/tests/test-non-interactive-wsgi @@ -0,0 +1,70 @@ +#!/bin/sh + +mkdir repo +cd repo +hg init +echo foo > bar +hg add bar +hg commit -m "test" -d "0 0" +hg tip + +cat > request.py <> sys.__stdout__, 'FILENO' + return self.real.fileno() + def read(self): + print >> sys.__stdout__, 'READ' + return self.real.read() + def readline(self): + print >> sys.__stdout__, 'READLINE' + return self.real.readline() + def isatty(self): + print >> sys.__stdout__, 'ISATTY' + return False + +sys.stdin = FileLike(sys.stdin) +errors = StringIO() +input = StringIO() +output = StringIO() + +def startrsp(headers, data): + print '---- HEADERS' + print headers + print '---- DATA' + print data + return output.write + +env = { + 'wsgi.version': (1, 0), + 'wsgi.url_scheme': 'http', + 'wsgi.errors': errors, + 'wsgi.input': input, + 'wsgi.multithread': False, + 'wsgi.multiprocess': False, + 'wsgi.run_once': False, + 'REQUEST_METHOD': 'GET', + 'SCRIPT_NAME': '', + 'PATH_INFO': '', + 'QUERY_STRING': '', + 'SERVER_NAME': '127.0.0.1', + 'SERVER_PORT': '20059', + 'SERVER_PROTOCOL': 'HTTP/1.0' +} + +_wsgirequest(hgweb('.'), env, startrsp) +print '---- ERRORS' +print errors.getvalue() +EOF + +python request.py diff --git a/tests/test-non-interactive-wsgi.out b/tests/test-non-interactive-wsgi.out new file mode 100644 --- /dev/null +++ b/tests/test-non-interactive-wsgi.out @@ -0,0 +1,12 @@ +changeset: 0:61c9426e69fe +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: test + +---- HEADERS +200 Script output follows +---- DATA +[('content-type', 'text/html; charset=ascii')] +---- ERRORS +