Patch #1212287: fileinput.input() now has a mode parameter for
specifying the file mode input files should be opened with.
diff --git a/Lib/fileinput.py b/Lib/fileinput.py
index 692eeea..004cf09 100644
--- a/Lib/fileinput.py
+++ b/Lib/fileinput.py
@@ -28,8 +28,10 @@
 read, filename() and the line number functions return the values
 pertaining to the last line read; nextfile() has no effect.
 
-All files are opened in text mode.  If an I/O error occurs during
-opening or reading a file, the IOError exception is raised.
+All files are opened in text mode by default, you can override this by
+setting the mode parameter to input() or FileInput.__init__().
+If an I/O error occurs during opening or reading a file, the IOError
+exception is raised.
 
 If sys.stdin is used more than once, the second and further use will
 return no lines, except perhaps for interactive use, or if it has been
@@ -72,7 +74,6 @@
 XXX Possible additions:
 
 - optional getopt argument processing
-- specify open mode ('r' or 'rb')
 - isatty()
 - read(), read(size), even readlines()
 
@@ -87,8 +88,8 @@
 
 DEFAULT_BUFSIZE = 8*1024
 
-def input(files=None, inplace=0, backup="", bufsize=0):
-    """input([files[, inplace[, backup]]])
+def input(files=None, inplace=0, backup="", bufsize=0, mode="r"):
+    """input([files[, inplace[, backup[, mode]]]])
 
     Create an instance of the FileInput class. The instance will be used
     as global state for the functions of this module, and is also returned
@@ -98,7 +99,7 @@
     global _state
     if _state and _state._file:
         raise RuntimeError, "input() already active"
-    _state = FileInput(files, inplace, backup, bufsize)
+    _state = FileInput(files, inplace, backup, bufsize, mode)
     return _state
 
 def close():
@@ -180,7 +181,7 @@
     return _state.isstdin()
 
 class FileInput:
-    """class FileInput([files[, inplace[, backup]]])
+    """class FileInput([files[, inplace[, backup[, mode]]]])
 
     Class FileInput is the implementation of the module; its methods
     filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(),
@@ -192,7 +193,7 @@
     sequential order; random access and readline() cannot be mixed.
     """
 
-    def __init__(self, files=None, inplace=0, backup="", bufsize=0):
+    def __init__(self, files=None, inplace=0, backup="", bufsize=0, mode="r"):
         if isinstance(files, basestring):
             files = (files,)
         else:
@@ -216,6 +217,11 @@
         self._backupfilename = None
         self._buffer = []
         self._bufindex = 0
+        # restrict mode argument to reading modes
+        if mode not in ('r', 'rU', 'U', 'rb'):
+            raise ValueError("FileInput opening mode must be one of "
+                             "'r', 'rU', 'U' and 'rb'")
+        self._mode = mode
 
     def __del__(self):
         self.close()
@@ -307,7 +313,7 @@
                     except os.error: pass
                     # The next few lines may raise IOError
                     os.rename(self._filename, self._backupfilename)
-                    self._file = open(self._backupfilename, "r")
+                    self._file = open(self._backupfilename, self._mode)
                     try:
                         perm = os.fstat(self._file.fileno()).st_mode
                     except OSError:
@@ -326,7 +332,7 @@
                     sys.stdout = self._output
                 else:
                     # This may raise IOError
-                    self._file = open(self._filename, "r")
+                    self._file = open(self._filename, self._mode)
         self._buffer = self._file.readlines(self._bufsize)
         self._bufindex = 0
         if not self._buffer:
diff --git a/Lib/test/test_fileinput.py b/Lib/test/test_fileinput.py
index be4cb8e..4080a25 100644
--- a/Lib/test/test_fileinput.py
+++ b/Lib/test/test_fileinput.py
@@ -3,7 +3,7 @@
 Nick Mathewson
 '''
 
-from test.test_support import verify, verbose, TESTFN
+from test.test_support import verify, verbose, TESTFN, TestFailed
 import sys, os, re
 from StringIO import StringIO
 from fileinput import FileInput
@@ -183,3 +183,20 @@
     verify(fi.fileno() == -1)
 finally:
     remove_tempfiles(t1, t2)
+
+if verbose:
+    print "17. Specify opening mode"
+try:
+    # invalid mode, should raise ValueError
+    fi = FileInput(mode="w")
+    raise TestFailed("FileInput should reject invalid mode argument")
+except ValueError:
+    pass
+try:
+    # try opening in universal newline mode
+    t1 = writeTmp(1, ["A\nB\r\nC\rD"])
+    fi = FileInput(files=t1, mode="U")
+    lines = list(fi)
+    verify(lines == ["A\n", "B\n", "C\n", "D"])
+finally:
+    remove_tempfiles(t1)