blob: 6218c4f4e2fdf7ad7ad89bee02224cb515ed8a24 [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
Inada Naoki333d10c2021-04-14 14:12:58 +09006 for line in fileinput.input(encoding="utf-8"):
Guido van Rossum7d5b99d1997-11-21 17:12:59 +00007 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
Michele Angrisanoaca273e2019-06-02 23:01:49 +020011is also replaced by sys.stdin and the optional arguments mode and
12openhook are ignored. To specify an alternative list of filenames,
13pass it as the argument to input(). A single file name is also allowed.
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000014
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__().
Andrew Svetlovf7a17b42012-12-25 16:47:37 +020033If an I/O error occurs during opening or reading a file, the OSError
Georg Brandlc029f872006-02-19 14:12:34 +000034exception 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.
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000066"""
67
Inada Naoki333d10c2021-04-14 14:12:58 +090068import io
Walter Dörwald294bbf32002-06-06 09:48:13 +000069import sys, os
Ethan Smithe3ec44d2020-04-09 21:47:31 -070070from types import GenericAlias
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000071
Georg Brandlef0a8652009-05-17 12:22:57 +000072__all__ = ["input", "close", "nextfile", "filename", "lineno", "filelineno",
Martin Panter7978e102016-01-16 06:26:54 +000073 "fileno", "isfirstline", "isstdin", "FileInput", "hook_compressed",
74 "hook_encoded"]
Skip Montanaroeccd02a2001-01-20 23:34:12 +000075
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000076_state = None
77
Inada Naoki333d10c2021-04-14 14:12:58 +090078def input(files=None, inplace=False, backup="", *, mode="r", openhook=None,
79 encoding=None, errors=None):
Terry Jan Reedy70d2c712013-06-28 18:59:28 -040080 """Return an instance of the FileInput class, which can be iterated.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +000081
Terry Jan Reedy70d2c712013-06-28 18:59:28 -040082 The parameters are passed to the constructor of the FileInput class.
83 The returned instance, in addition to being an iterator,
84 keeps global state for the functions of this module,.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +000085 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000086 global _state
87 if _state and _state._file:
Collin Winterce36ad82007-08-30 01:19:48 +000088 raise RuntimeError("input() already active")
Inada Naoki333d10c2021-04-14 14:12:58 +090089 _state = FileInput(files, inplace, backup, mode=mode, openhook=openhook,
90 encoding=encoding, errors=errors)
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000091 return _state
92
93def close():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +000094 """Close the sequence."""
Guido van Rossum7d5b99d1997-11-21 17:12:59 +000095 global _state
96 state = _state
97 _state = None
98 if state:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000099 state.close()
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000100
101def nextfile():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000102 """
103 Close the current file so that the next iteration will read the first
104 line from the next file (if any); lines not read from the file will
105 not count towards the cumulative line count. The filename is not
106 changed until after the first line of the next file has been read.
107 Before the first line has been read, this function has no effect;
108 it cannot be used to skip the first file. After the last line of the
Tim Peters8ac14952002-05-23 15:15:30 +0000109 last file has been read, this function has no effect.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000110 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000111 if not _state:
Collin Winterce36ad82007-08-30 01:19:48 +0000112 raise RuntimeError("no active input()")
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000113 return _state.nextfile()
114
115def filename():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000116 """
117 Return the name of the file currently being read.
Tim Peters8ac14952002-05-23 15:15:30 +0000118 Before the first line has been read, returns None.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000119 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000120 if not _state:
Collin Winterce36ad82007-08-30 01:19:48 +0000121 raise RuntimeError("no active input()")
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000122 return _state.filename()
123
124def lineno():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000125 """
126 Return the cumulative line number of the line that has just been read.
127 Before the first line has been read, returns 0. After the last line
Tim Peters8ac14952002-05-23 15:15:30 +0000128 of the last file has been read, returns the line number of that line.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000129 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000130 if not _state:
Collin Winterce36ad82007-08-30 01:19:48 +0000131 raise RuntimeError("no active input()")
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000132 return _state.lineno()
133
134def filelineno():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000135 """
136 Return the line number in the current file. Before the first line
137 has been read, returns 0. After the last line of the last file has
Tim Peters8ac14952002-05-23 15:15:30 +0000138 been read, returns the line number of that line within the file.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000139 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000140 if not _state:
Collin Winterce36ad82007-08-30 01:19:48 +0000141 raise RuntimeError("no active input()")
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000142 return _state.filelineno()
143
Georg Brandl67e9fb92006-02-19 13:56:17 +0000144def fileno():
145 """
146 Return the file number of the current file. When no file is currently
147 opened, returns -1.
148 """
149 if not _state:
Collin Winterce36ad82007-08-30 01:19:48 +0000150 raise RuntimeError("no active input()")
Georg Brandl67e9fb92006-02-19 13:56:17 +0000151 return _state.fileno()
152
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000153def isfirstline():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000154 """
155 Returns true the line just read is the first line of its file,
Tim Peters8ac14952002-05-23 15:15:30 +0000156 otherwise returns false.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000157 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000158 if not _state:
Collin Winterce36ad82007-08-30 01:19:48 +0000159 raise RuntimeError("no active input()")
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000160 return _state.isfirstline()
161
162def isstdin():
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000163 """
164 Returns true if the last line was read from sys.stdin,
Tim Peters8ac14952002-05-23 15:15:30 +0000165 otherwise returns false.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000166 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000167 if not _state:
Collin Winterce36ad82007-08-30 01:19:48 +0000168 raise RuntimeError("no active input()")
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000169 return _state.isstdin()
170
171class FileInput:
Matthias Bussonnier1a3faf92019-05-20 13:44:11 -0700172 """FileInput([files[, inplace[, backup]]], *, mode=None, openhook=None)
Tim Peters8ac14952002-05-23 15:15:30 +0000173
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000174 Class FileInput is the implementation of the module; its methods
Georg Brandl67e9fb92006-02-19 13:56:17 +0000175 filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(),
176 nextfile() and close() correspond to the functions of the same name
177 in the module.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000178 In addition it has a readline() method which returns the next
179 input line, and a __getitem__() method which implements the
180 sequence behavior. The sequence must be accessed in strictly
Tim Peters8ac14952002-05-23 15:15:30 +0000181 sequential order; random access and readline() cannot be mixed.
Raymond Hettingerd1fa3db2002-05-15 02:56:03 +0000182 """
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000183
Matthias Bussonnier1a3faf92019-05-20 13:44:11 -0700184 def __init__(self, files=None, inplace=False, backup="", *,
Inada Naoki333d10c2021-04-14 14:12:58 +0900185 mode="r", openhook=None, encoding=None, errors=None):
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000186 if isinstance(files, str):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000187 files = (files,)
Roy Williams002665a2017-05-22 22:24:17 -0700188 elif isinstance(files, os.PathLike):
189 files = (os.fspath(files), )
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000190 else:
Guido van Rossum2516b392000-04-10 17:16:12 +0000191 if files is None:
192 files = sys.argv[1:]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000193 if not files:
Guido van Rossum2516b392000-04-10 17:16:12 +0000194 files = ('-',)
195 else:
196 files = tuple(files)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000197 self._files = files
198 self._inplace = inplace
199 self._backup = backup
200 self._savestdout = None
201 self._output = None
202 self._filename = None
Serhiy Storchakacc2dbc52016-03-08 18:28:36 +0200203 self._startlineno = 0
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000204 self._filelineno = 0
205 self._file = None
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000206 self._isstdin = False
Guido van Rossum0aec9fb1998-07-20 15:49:28 +0000207 self._backupfilename = None
Inada Naoki333d10c2021-04-14 14:12:58 +0900208 self._encoding = encoding
209 self._errors = errors
210
211 # We can not use io.text_encoding() here because old openhook doesn't
212 # take encoding parameter.
213 if "b" not in mode and encoding is None and sys.flags.warn_default_encoding:
214 import warnings
215 warnings.warn("'encoding' argument not specified.",
216 EncodingWarning, 2)
217
Georg Brandlc029f872006-02-19 14:12:34 +0000218 # restrict mode argument to reading modes
Victor Stinner942f7a22020-03-04 18:50:22 +0100219 if mode not in ('r', 'rU', 'U', 'rb'):
220 raise ValueError("FileInput opening mode must be one of "
221 "'r', 'rU', 'U' and 'rb'")
222 if 'U' in mode:
223 import warnings
224 warnings.warn("'U' mode is deprecated",
225 DeprecationWarning, 2)
Georg Brandlc029f872006-02-19 14:12:34 +0000226 self._mode = mode
Victor Stinner942f7a22020-03-04 18:50:22 +0100227 self._write_mode = mode.replace('r', 'w') if 'U' not in mode else 'w'
Florent Xicluna5d1155c2011-10-28 14:45:05 +0200228 if openhook:
229 if inplace:
230 raise ValueError("FileInput cannot use an opening hook in inplace mode")
231 if not callable(openhook):
232 raise ValueError("FileInput openhook must be callable")
Georg Brandlc98eeed2006-02-19 14:57:47 +0000233 self._openhook = openhook
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000234
235 def __del__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000236 self.close()
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000237
238 def close(self):
Serhiy Storchaka7e7a3db2015-04-10 13:24:41 +0300239 try:
240 self.nextfile()
241 finally:
242 self._files = ()
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000243
Georg Brandl6cb7b652010-07-31 20:08:15 +0000244 def __enter__(self):
245 return self
246
247 def __exit__(self, type, value, traceback):
248 self.close()
249
Neil Schemenauer908632a2002-03-26 20:28:40 +0000250 def __iter__(self):
251 return self
252
Georg Brandla18af4e2007-04-21 15:47:16 +0000253 def __next__(self):
Serhiy Storchaka0554d832016-03-08 23:35:35 +0200254 while True:
255 line = self._readline()
256 if line:
257 self._filelineno += 1
258 return line
259 if not self._file:
260 raise StopIteration
261 self.nextfile()
262 # repeat with next file
Tim Peters863ac442002-04-16 01:38:40 +0000263
Neil Schemenauer908632a2002-03-26 20:28:40 +0000264 def __getitem__(self, i):
Berker Peksag84a13fb2018-08-11 09:05:04 +0300265 import warnings
266 warnings.warn(
267 "Support for indexing FileInput objects is deprecated. "
268 "Use iterator protocol instead.",
269 DeprecationWarning,
270 stacklevel=2
271 )
Serhiy Storchakacc2dbc52016-03-08 18:28:36 +0200272 if i != self.lineno():
Collin Winterce36ad82007-08-30 01:19:48 +0000273 raise RuntimeError("accessing lines out of order")
Neil Schemenauer908632a2002-03-26 20:28:40 +0000274 try:
Georg Brandla18af4e2007-04-21 15:47:16 +0000275 return self.__next__()
Neil Schemenauer908632a2002-03-26 20:28:40 +0000276 except StopIteration:
Collin Winterce36ad82007-08-30 01:19:48 +0000277 raise IndexError("end of input reached")
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000278
279 def nextfile(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000280 savestdout = self._savestdout
Serhiy Storchaka2116b122015-04-10 13:29:28 +0300281 self._savestdout = None
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000282 if savestdout:
283 sys.stdout = savestdout
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000284
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000285 output = self._output
Serhiy Storchaka2116b122015-04-10 13:29:28 +0300286 self._output = None
Serhiy Storchaka7e7a3db2015-04-10 13:24:41 +0300287 try:
288 if output:
289 output.close()
290 finally:
291 file = self._file
Serhiy Storchaka2116b122015-04-10 13:29:28 +0300292 self._file = None
Serhiy Storchaka0554d832016-03-08 23:35:35 +0200293 try:
294 del self._readline # restore FileInput._readline
295 except AttributeError:
296 pass
Serhiy Storchaka7e7a3db2015-04-10 13:24:41 +0300297 try:
298 if file and not self._isstdin:
299 file.close()
300 finally:
301 backupfilename = self._backupfilename
Serhiy Storchaka2116b122015-04-10 13:29:28 +0300302 self._backupfilename = None
Serhiy Storchaka7e7a3db2015-04-10 13:24:41 +0300303 if backupfilename and not self._backup:
304 try: os.unlink(backupfilename)
305 except OSError: pass
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000306
Serhiy Storchaka7e7a3db2015-04-10 13:24:41 +0300307 self._isstdin = False
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000308
309 def readline(self):
Serhiy Storchakacc2dbc52016-03-08 18:28:36 +0200310 while True:
311 line = self._readline()
312 if line:
313 self._filelineno += 1
314 return line
315 if not self._file:
316 return line
317 self.nextfile()
318 # repeat with next file
319
Serhiy Storchaka0554d832016-03-08 23:35:35 +0200320 def _readline(self):
Serhiy Storchakacc2dbc52016-03-08 18:28:36 +0200321 if not self._files:
322 if 'b' in self._mode:
323 return b''
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000324 else:
Serhiy Storchakacc2dbc52016-03-08 18:28:36 +0200325 return ''
326 self._filename = self._files[0]
327 self._files = self._files[1:]
328 self._startlineno = self.lineno()
329 self._filelineno = 0
330 self._file = None
331 self._isstdin = False
332 self._backupfilename = 0
333 if self._filename == '-':
334 self._filename = '<stdin>'
335 if 'b' in self._mode:
336 self._file = getattr(sys.stdin, 'buffer', sys.stdin)
337 else:
338 self._file = sys.stdin
339 self._isstdin = True
340 else:
341 if self._inplace:
342 self._backupfilename = (
Zhiming Wang06de1ae2017-09-05 01:37:24 +0800343 os.fspath(self._filename) + (self._backup or ".bak"))
Serhiy Storchakacc2dbc52016-03-08 18:28:36 +0200344 try:
345 os.unlink(self._backupfilename)
346 except OSError:
347 pass
348 # The next few lines may raise OSError
349 os.rename(self._filename, self._backupfilename)
350 self._file = open(self._backupfilename, self._mode)
351 try:
352 perm = os.fstat(self._file.fileno()).st_mode
353 except OSError:
Berker Peksagbe6dbfb2019-04-29 17:55:39 +0300354 self._output = open(self._filename, self._write_mode)
Serhiy Storchakacc2dbc52016-03-08 18:28:36 +0200355 else:
356 mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC
357 if hasattr(os, 'O_BINARY'):
358 mode |= os.O_BINARY
359
360 fd = os.open(self._filename, mode, perm)
Berker Peksagbe6dbfb2019-04-29 17:55:39 +0300361 self._output = os.fdopen(fd, self._write_mode)
Andrew Svetlovad28c7f2012-12-18 22:02:39 +0200362 try:
Anthony Sottile8377cd42019-02-25 14:32:27 -0800363 os.chmod(self._filename, perm)
Andrew Svetlovad28c7f2012-12-18 22:02:39 +0200364 except OSError:
365 pass
Serhiy Storchakacc2dbc52016-03-08 18:28:36 +0200366 self._savestdout = sys.stdout
367 sys.stdout = self._output
368 else:
369 # This may raise OSError
370 if self._openhook:
Inada Naoki333d10c2021-04-14 14:12:58 +0900371 # Custom hooks made previous to Python 3.10 didn't have
372 # encoding argument
373 if self._encoding is None:
374 self._file = self._openhook(self._filename, self._mode)
375 else:
376 self._file = self._openhook(
377 self._filename, self._mode, encoding=self._encoding, errors=self._errors)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000378 else:
Inada Naoki333d10c2021-04-14 14:12:58 +0900379 # EncodingWarning is emitted in __init__() already
380 if "b" not in self._mode:
381 encoding = self._encoding or "locale"
382 else:
383 encoding = None
384 self._file = open(self._filename, self._mode, encoding=encoding, errors=self._errors)
Serhiy Storchaka0554d832016-03-08 23:35:35 +0200385 self._readline = self._file.readline # hide FileInput._readline
Serhiy Storchakacc2dbc52016-03-08 18:28:36 +0200386 return self._readline()
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000387
388 def filename(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000389 return self._filename
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000390
391 def lineno(self):
Serhiy Storchakacc2dbc52016-03-08 18:28:36 +0200392 return self._startlineno + self._filelineno
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000393
394 def filelineno(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000395 return self._filelineno
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000396
Georg Brandl67e9fb92006-02-19 13:56:17 +0000397 def fileno(self):
398 if self._file:
399 try:
400 return self._file.fileno()
401 except ValueError:
402 return -1
403 else:
404 return -1
405
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000406 def isfirstline(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000407 return self._filelineno == 1
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000408
409 def isstdin(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000410 return self._isstdin
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000411
Ethan Smithe3ec44d2020-04-09 21:47:31 -0700412 __class_getitem__ = classmethod(GenericAlias)
413
Georg Brandlc98eeed2006-02-19 14:57:47 +0000414
Inada Naoki333d10c2021-04-14 14:12:58 +0900415def hook_compressed(filename, mode, *, encoding=None, errors=None):
416 if encoding is None: # EncodingWarning is emitted in FileInput() already.
417 encoding = "locale"
Georg Brandlc98eeed2006-02-19 14:57:47 +0000418 ext = os.path.splitext(filename)[1]
419 if ext == '.gz':
420 import gzip
Inada Naoki333d10c2021-04-14 14:12:58 +0900421 stream = gzip.open(filename, mode)
Georg Brandlc98eeed2006-02-19 14:57:47 +0000422 elif ext == '.bz2':
423 import bz2
Inada Naoki333d10c2021-04-14 14:12:58 +0900424 stream = bz2.BZ2File(filename, mode)
Georg Brandlc98eeed2006-02-19 14:57:47 +0000425 else:
Inada Naoki333d10c2021-04-14 14:12:58 +0900426 return open(filename, mode, encoding=encoding, errors=errors)
427
428 # gzip and bz2 are binary mode by default.
429 if "b" not in mode:
430 stream = io.TextIOWrapper(stream, encoding=encoding, errors=errors)
431 return stream
Georg Brandlc98eeed2006-02-19 14:57:47 +0000432
433
Serhiy Storchakab2752102016-04-27 23:13:46 +0300434def hook_encoded(encoding, errors=None):
Georg Brandlc98eeed2006-02-19 14:57:47 +0000435 def openhook(filename, mode):
Serhiy Storchakab2752102016-04-27 23:13:46 +0300436 return open(filename, mode, encoding=encoding, errors=errors)
Georg Brandlc98eeed2006-02-19 14:57:47 +0000437 return openhook
438
439
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000440def _test():
441 import getopt
Georg Brandlef0a8652009-05-17 12:22:57 +0000442 inplace = False
443 backup = False
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000444 opts, args = getopt.getopt(sys.argv[1:], "ib:")
445 for o, a in opts:
Georg Brandlef0a8652009-05-17 12:22:57 +0000446 if o == '-i': inplace = True
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000447 if o == '-b': backup = a
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000448 for line in input(args, inplace=inplace, backup=backup):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000449 if line[-1:] == '\n': line = line[:-1]
450 if line[-1:] == '\r': line = line[:-1]
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000451 print("%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(),
452 isfirstline() and "*" or "", line))
453 print("%d: %s[%d]" % (lineno(), filename(), filelineno()))
Guido van Rossum7d5b99d1997-11-21 17:12:59 +0000454
455if __name__ == '__main__':
456 _test()