Skip to content

Commit

Permalink
Patch #1212287: fileinput.input() now has a mode parameter for
Browse files Browse the repository at this point in the history
specifying the file mode input files should be opened with.
  • Loading branch information
birkenfeld committed Feb 19, 2006
1 parent 67e9fb9 commit c029f87
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 15 deletions.
18 changes: 14 additions & 4 deletions Doc/lib/libfileinput.tex
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ \section{\module{fileinput} ---
it as the first argument to \function{input()}. A single file name is
also allowed.

All files are opened in text mode. If an I/O error occurs during
opening or reading a file, \exception{IOError} is raised.
All files are opened in text mode by default, but you can override this by
specifying the \var{mode} parameter in the call to \function{input()}
or \class{FileInput()}. If an I/O error occurs during opening or reading
a file, \exception{IOError} is raised.

If \code{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
Expand All @@ -44,12 +46,14 @@ \section{\module{fileinput} ---
The following function is the primary interface of this module:

\begin{funcdesc}{input}{\optional{files\optional{,
inplace\optional{, backup}}}}
inplace\optional{, backup\optional{, mode}}}}}
Create an instance of the \class{FileInput} class. The instance
will be used as global state for the functions of this module, and
is also returned to use during iteration. The parameters to this
function will be passed along to the constructor of the
\class{FileInput} class.

\versionchanged[Added the \var{mode} parameter]{2.5}
\end{funcdesc}


Expand Down Expand Up @@ -111,7 +115,7 @@ \section{\module{fileinput} ---
module is available for subclassing as well:

\begin{classdesc}{FileInput}{\optional{files\optional{,
inplace\optional{, backup}}}}
inplace\optional{, backup\optional{, mode}}}}}
Class \class{FileInput} is the implementation; its methods
\method{filename()}, \method{fileno()}, \method{lineno()},
\method{fileline()}, \method{isfirstline()}, \method{isstdin()},
Expand All @@ -122,6 +126,12 @@ \section{\module{fileinput} ---
which implements the sequence behavior. The sequence must be
accessed in strictly sequential order; random access and
\method{readline()} cannot be mixed.

With \var{mode} you can specify which file mode will be passed to
\function{open()}. It must be one of \code{'r'}, \code{'rU'},
\code{'U'} and \code{'rb'}.

\versionchanged[Added the \var{mode} parameter]{2.5}
\end{classdesc}

\strong{Optional in-place filtering:} if the keyword argument
Expand Down
26 changes: 16 additions & 10 deletions Lib/fileinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -72,7 +74,6 @@
XXX Possible additions:
- optional getopt argument processing
- specify open mode ('r' or 'rb')
- isatty()
- read(), read(size), even readlines()
Expand All @@ -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
Expand All @@ -98,7 +99,7 @@ def input(files=None, inplace=0, backup="", bufsize=0):
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():
Expand Down Expand Up @@ -180,7 +181,7 @@ def isstdin():
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(),
Expand All @@ -192,7 +193,7 @@ class FileInput:
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:
Expand All @@ -216,6 +217,11 @@ def __init__(self, files=None, inplace=0, backup="", bufsize=0):
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()
Expand Down Expand Up @@ -307,7 +313,7 @@ def readline(self):
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:
Expand All @@ -326,7 +332,7 @@ def readline(self):
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:
Expand Down
19 changes: 18 additions & 1 deletion Lib/test/test_fileinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -183,3 +183,20 @@ def writeFiles():
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)
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,9 @@ Extension Modules
Library
-------

- Patch #1212287: fileinput.input() now has a mode parameter for
specifying the file mode input files should be opened with.

- Patch #1215184: fileinput now has a fileno() function for getting the
current file number.

Expand Down

0 comments on commit c029f87

Please sign in to comment.