blob: b2e2f05030ad39b17c1d0ffa57648fd7c369b6ac [file] [log] [blame]
Guido van Rossum7d5b99d1997-11-21 17:12:59 +00001"""Helper class to quickly write a loop over all standard input files.
2
3Typical use is:
4
5 import fileinput
6 for line in fileinput.input():
7 process(line)
8
9This iterates over the lines of all files listed in sys.argv[1:],
10defaulting to sys.stdin if the list is empty. If a filename is '-' it
11is also replaced by sys.stdin. To specify an alternative list of
12filenames, pass it as the argument to input(). A single file name is
13also allowed.
14
15Functions filename(), lineno() return the filename and cumulative line
16number of the line that has just been read; filelineno() returns its
17line number in the current file; isfirstline() returns true iff the
18line just read is the first line of its file; isstdin() returns true
19iff the line was read from sys.stdin. Function nextfile() closes the
20current file so that the next iteration will read the first line from
21the next file (if any); lines not read from the file will not count
22towards the cumulative line count; the filename is not changed until
23after the first line of the next file has been read. Function close()
24closes the sequence.
25
26Before any lines have been read, filename() returns None and both line
27numbers are zero; nextfile() has no effect. After all lines have been
28read, filename() and the line number functions return the values
29pertaining to the last line read; nextfile() has no effect.
30
Georg Brandlc029f872006-02-19 14:12:34 +000031All files are opened in text mode by default, you can override this by
32setting the mode parameter to input() or FileInput.__init__().
33If an I/O error occurs during opening or reading a file, the IOError
34exception is raised.
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000035
36If sys.stdin is used more than once, the second and further use will
37return no lines, except perhaps for interactive use, or if it has been
38explicitly reset (e.g. using sys.stdin.seek(0)).
39
40Empty files are opened and immediately closed; the only time their
41presence in the list of filenames is noticeable at all is when the
42last file opened is empty.
43
44It is possible that the last line of a file doesn't end in a newline
45character; otherwise lines are returned including the trailing
46newline.
47
48Class FileInput is the implementation; its methods filename(),
49lineno(), fileline(), isfirstline(), isstdin(), nextfile() and close()
50correspond to the functions in the module. In addition it has a
51readline() method which returns the next input line, and a
52__getitem__() method which implements the sequence behavior. The
53sequence must be accessed in strictly sequential order; sequence
54access and readline() cannot be mixed.
55
56Optional in-place filtering: if the keyword argument inplace=1 is
57passed to input() or to the FileInput constructor, the file is moved
58to a backup file and standard output is directed to the input file.
59This makes it possible to write a filter that rewrites its input file
60in place. If the keyword argument backup=".<some extension>" is also
61given, it specifies the extension for the backup file, and the backup
62file remains around; by default, the extension is ".bak" and it is
63deleted when the output file is closed. In-place filtering is
64disabled when standard input is read. XXX The current implementation
65does not work for MS-DOS 8+3 filesystems.
66
67XXX Possible additions:
68
69- optional getopt argument processing
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000070- isatty()
71- read(), read(size), even readlines()
72
73"""
74
Walter Dörwald294bbf32002-06-06 09:48:13 +000075import sys, os
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000076
Skip Montanaroeccd02a2001-01-20 23:34:12 +000077__all__ = ["input","close","nextfile","filename","lineno","filelineno",
78 "isfirstline","isstdin","FileInput"]
79
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000080_state = None
81
Serhiy Storchaka69b7f812016-03-08 18:35:45 +020082# No longer used
Guido van Rossum47955242001-01-05 14:44:39 +000083DEFAULT_BUFSIZE = 8*1024
84
Tim Peters200a5802006-02-19 21:26:07 +000085def input(files=None, inplace=0, backup="", bufsize=0,
Georg Brandlc98eeed2006-02-19 14:57:47 +000086 mode="r", openhook=None):
Terry Jan Reedy35115e62013-06-28 18:59:19 -040087 """Return an instance of the FileInput class, which can be iterated.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +000088
Terry Jan Reedy35115e62013-06-28 18:59:19 -040089 The parameters are passed to the constructor of the FileInput class.
90 The returned instance, in addition to being an iterator,
91 keeps global state for the functions of this module,.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +000092 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000093 global _state
94 if _state and _state._file:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000095 raise RuntimeError, "input() already active"
Georg Brandlc98eeed2006-02-19 14:57:47 +000096 _state = FileInput(files, inplace, backup, bufsize, mode, openhook)
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000097 return _state
98
99def close():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000100 """Close the sequence."""
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000101 global _state
102 state = _state
103 _state = None
104 if state:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000105 state.close()
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000106
107def nextfile():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000108 """
109 Close the current file so that the next iteration will read the first
110 line from the next file (if any); lines not read from the file will
111 not count towards the cumulative line count. The filename is not
112 changed until after the first line of the next file has been read.
113 Before the first line has been read, this function has no effect;
114 it cannot be used to skip the first file. After the last line of the
Tim Peters8ac14952002-05-23 15:15:30 +0000115 last file has been read, this function has no effect.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000116 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000117 if not _state:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000118 raise RuntimeError, "no active input()"
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000119 return _state.nextfile()
120
121def filename():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000122 """
123 Return the name of the file currently being read.
Tim Peters8ac14952002-05-23 15:15:30 +0000124 Before the first line has been read, returns None.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000125 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000126 if not _state:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000127 raise RuntimeError, "no active input()"
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000128 return _state.filename()
129
130def lineno():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000131 """
132 Return the cumulative line number of the line that has just been read.
133 Before the first line has been read, returns 0. After the last line
Tim Peters8ac14952002-05-23 15:15:30 +0000134 of the last file has been read, returns the line number of that line.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000135 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000136 if not _state:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000137 raise RuntimeError, "no active input()"
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000138 return _state.lineno()
139
140def filelineno():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000141 """
142 Return the line number in the current file. Before the first line
143 has been read, returns 0. After the last line of the last file has
Tim Peters8ac14952002-05-23 15:15:30 +0000144 been read, returns the line number of that line within the file.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000145 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000146 if not _state:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000147 raise RuntimeError, "no active input()"
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000148 return _state.filelineno()
149
Georg Brandl67e9fb92006-02-19 13:56:17 +0000150def fileno():
151 """
152 Return the file number of the current file. When no file is currently
153 opened, returns -1.
154 """
155 if not _state:
156 raise RuntimeError, "no active input()"
157 return _state.fileno()
158
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000159def isfirstline():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000160 """
161 Returns true the line just read is the first line of its file,
Tim Peters8ac14952002-05-23 15:15:30 +0000162 otherwise returns false.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000163 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000164 if not _state:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000165 raise RuntimeError, "no active input()"
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000166 return _state.isfirstline()
167
168def isstdin():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000169 """
170 Returns true if the last line was read from sys.stdin,
Tim Peters8ac14952002-05-23 15:15:30 +0000171 otherwise returns false.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000172 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000173 if not _state:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000174 raise RuntimeError, "no active input()"
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000175 return _state.isstdin()
176
177class FileInput:
Terry Jan Reedy35115e62013-06-28 18:59:19 -0400178 """FileInput([files[, inplace[, backup[, bufsize[, mode[, openhook]]]]]])
Tim Peters8ac14952002-05-23 15:15:30 +0000179
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000180 Class FileInput is the implementation of the module; its methods
Georg Brandl67e9fb92006-02-19 13:56:17 +0000181 filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(),
182 nextfile() and close() correspond to the functions of the same name
183 in the module.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000184 In addition it has a readline() method which returns the next
185 input line, and a __getitem__() method which implements the
186 sequence behavior. The sequence must be accessed in strictly
Tim Peters8ac14952002-05-23 15:15:30 +0000187 sequential order; random access and readline() cannot be mixed.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000188 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000189
Tim Peters200a5802006-02-19 21:26:07 +0000190 def __init__(self, files=None, inplace=0, backup="", bufsize=0,
Georg Brandlc98eeed2006-02-19 14:57:47 +0000191 mode="r", openhook=None):
Georg Brandle4662172006-02-19 09:51:27 +0000192 if isinstance(files, basestring):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000193 files = (files,)
194 else:
Guido van Rossum2516b392000-04-10 17:16:12 +0000195 if files is None:
196 files = sys.argv[1:]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000197 if not files:
Guido van Rossum2516b392000-04-10 17:16:12 +0000198 files = ('-',)
199 else:
200 files = tuple(files)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000201 self._files = files
202 self._inplace = inplace
203 self._backup = backup
204 self._savestdout = None
205 self._output = None
206 self._filename = None
Serhiy Storchaka69b7f812016-03-08 18:35:45 +0200207 self._startlineno = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000208 self._filelineno = 0
209 self._file = None
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000210 self._isstdin = False
Guido van Rossum0aec9fb1998-07-20 15:49:28 +0000211 self._backupfilename = None
Georg Brandlc029f872006-02-19 14:12:34 +0000212 # restrict mode argument to reading modes
213 if mode not in ('r', 'rU', 'U', 'rb'):
214 raise ValueError("FileInput opening mode must be one of "
215 "'r', 'rU', 'U' and 'rb'")
216 self._mode = mode
Georg Brandlc98eeed2006-02-19 14:57:47 +0000217 if inplace and openhook:
218 raise ValueError("FileInput cannot use an opening hook in inplace mode")
Brett Cannon36bed8a2008-08-03 23:52:32 +0000219 elif openhook and not hasattr(openhook, '__call__'):
Georg Brandlc98eeed2006-02-19 14:57:47 +0000220 raise ValueError("FileInput openhook must be callable")
221 self._openhook = openhook
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000222
223 def __del__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000224 self.close()
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000225
226 def close(self):
Serhiy Storchaka1aa2c0f2015-04-10 13:24:10 +0300227 try:
228 self.nextfile()
229 finally:
230 self._files = ()
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000231
Neil Schemenauer908632a2002-03-26 20:28:40 +0000232 def __iter__(self):
233 return self
234
235 def next(self):
Serhiy Storchaka2c311f92016-03-08 23:34:28 +0200236 while 1:
237 line = self._readline()
238 if line:
239 self._filelineno += 1
240 return line
241 if not self._file:
242 raise StopIteration
243 self.nextfile()
244 # repeat with next file
Tim Peters863ac442002-04-16 01:38:40 +0000245
Neil Schemenauer908632a2002-03-26 20:28:40 +0000246 def __getitem__(self, i):
Serhiy Storchaka69b7f812016-03-08 18:35:45 +0200247 if i != self.lineno():
Neil Schemenauer908632a2002-03-26 20:28:40 +0000248 raise RuntimeError, "accessing lines out of order"
249 try:
250 return self.next()
251 except StopIteration:
252 raise IndexError, "end of input reached"
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000253
254 def nextfile(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000255 savestdout = self._savestdout
256 self._savestdout = 0
257 if savestdout:
258 sys.stdout = savestdout
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000259
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000260 output = self._output
261 self._output = 0
Serhiy Storchaka1aa2c0f2015-04-10 13:24:10 +0300262 try:
263 if output:
264 output.close()
265 finally:
266 file = self._file
Serhiy Storchaka69b7f812016-03-08 18:35:45 +0200267 self._file = None
Serhiy Storchaka2c311f92016-03-08 23:34:28 +0200268 try:
269 del self._readline # restore FileInput._readline
270 except AttributeError:
271 pass
Serhiy Storchaka1aa2c0f2015-04-10 13:24:10 +0300272 try:
273 if file and not self._isstdin:
274 file.close()
275 finally:
276 backupfilename = self._backupfilename
277 self._backupfilename = 0
278 if backupfilename and not self._backup:
279 try: os.unlink(backupfilename)
280 except OSError: pass
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000281
Serhiy Storchaka1aa2c0f2015-04-10 13:24:10 +0300282 self._isstdin = False
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000283
284 def readline(self):
Serhiy Storchaka69b7f812016-03-08 18:35:45 +0200285 while 1:
286 line = self._readline()
287 if line:
288 self._filelineno += 1
289 return line
290 if not self._file:
291 return line
Guido van Rossum47955242001-01-05 14:44:39 +0000292 self.nextfile()
Serhiy Storchaka69b7f812016-03-08 18:35:45 +0200293 # repeat with next file
294
Serhiy Storchaka2c311f92016-03-08 23:34:28 +0200295 def _readline(self):
Serhiy Storchaka69b7f812016-03-08 18:35:45 +0200296 if not self._files:
297 return ""
298 self._filename = self._files[0]
299 self._files = self._files[1:]
300 self._startlineno = self.lineno()
301 self._filelineno = 0
302 self._file = None
303 self._isstdin = False
304 self._backupfilename = 0
305 if self._filename == '-':
306 self._filename = '<stdin>'
307 self._file = sys.stdin
308 self._isstdin = True
309 else:
310 if self._inplace:
311 self._backupfilename = (
312 self._filename + (self._backup or os.extsep+"bak"))
313 try: os.unlink(self._backupfilename)
314 except os.error: pass
315 # The next few lines may raise IOError
316 os.rename(self._filename, self._backupfilename)
317 self._file = open(self._backupfilename, self._mode)
318 try:
319 perm = os.fstat(self._file.fileno()).st_mode
320 except OSError:
321 self._output = open(self._filename, "w")
322 else:
323 fd = os.open(self._filename,
324 os.O_CREAT | os.O_WRONLY | os.O_TRUNC,
325 perm)
326 self._output = os.fdopen(fd, "w")
327 try:
328 if hasattr(os, 'chmod'):
329 os.chmod(self._filename, perm)
330 except OSError:
331 pass
332 self._savestdout = sys.stdout
333 sys.stdout = self._output
334 else:
335 # This may raise IOError
336 if self._openhook:
337 self._file = self._openhook(self._filename, self._mode)
338 else:
339 self._file = open(self._filename, self._mode)
340
Serhiy Storchaka2c311f92016-03-08 23:34:28 +0200341 self._readline = self._file.readline # hide FileInput._readline
Serhiy Storchaka69b7f812016-03-08 18:35:45 +0200342 return self._readline()
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000343
344 def filename(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000345 return self._filename
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000346
347 def lineno(self):
Serhiy Storchaka69b7f812016-03-08 18:35:45 +0200348 return self._startlineno + self._filelineno
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000349
350 def filelineno(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000351 return self._filelineno
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000352
Georg Brandl67e9fb92006-02-19 13:56:17 +0000353 def fileno(self):
354 if self._file:
355 try:
356 return self._file.fileno()
357 except ValueError:
358 return -1
359 else:
360 return -1
361
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000362 def isfirstline(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000363 return self._filelineno == 1
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000364
365 def isstdin(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000366 return self._isstdin
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000367
Georg Brandlc98eeed2006-02-19 14:57:47 +0000368
369def hook_compressed(filename, mode):
370 ext = os.path.splitext(filename)[1]
371 if ext == '.gz':
372 import gzip
373 return gzip.open(filename, mode)
374 elif ext == '.bz2':
375 import bz2
376 return bz2.BZ2File(filename, mode)
377 else:
378 return open(filename, mode)
379
380
381def hook_encoded(encoding):
Serhiy Storchaka68b8a942014-02-26 20:59:08 +0200382 import io
Georg Brandlc98eeed2006-02-19 14:57:47 +0000383 def openhook(filename, mode):
Serhiy Storchaka68b8a942014-02-26 20:59:08 +0200384 mode = mode.replace('U', '').replace('b', '') or 'r'
385 return io.open(filename, mode, encoding=encoding, newline='')
Georg Brandlc98eeed2006-02-19 14:57:47 +0000386 return openhook
387
388
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000389def _test():
390 import getopt
391 inplace = 0
392 backup = 0
393 opts, args = getopt.getopt(sys.argv[1:], "ib:")
394 for o, a in opts:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000395 if o == '-i': inplace = 1
396 if o == '-b': backup = a
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000397 for line in input(args, inplace=inplace, backup=backup):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000398 if line[-1:] == '\n': line = line[:-1]
399 if line[-1:] == '\r': line = line[:-1]
400 print "%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(),
401 isfirstline() and "*" or "", line)
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000402 print "%d: %s[%d]" % (lineno(), filename(), filelineno())
403
404if __name__ == '__main__':
405 _test()