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.
--- a/mercurial/ui.py Mon Sep 24 19:14:18 2007 -0300
+++ b/mercurial/ui.py Tue Sep 25 19:05:34 2007 +0200
@@ -211,9 +211,11 @@
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 @@
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 @@
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:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-non-interactive-wsgi Tue Sep 25 19:05:34 2007 +0200
@@ -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 <<EOF
+from mercurial import dispatch
+from mercurial.hgweb.hgweb_mod import hgweb
+from mercurial.hgweb.request import _wsgirequest
+from mercurial.ui import ui
+from mercurial import hg
+from StringIO import StringIO
+import sys
+
+class FileLike(object):
+ def __init__(self, real):
+ self.real = real
+ def fileno(self):
+ print >> 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-non-interactive-wsgi.out Tue Sep 25 19:05:34 2007 +0200
@@ -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
+