14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""Helper class to quickly write a loop over all standard input files. 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTypical use is: 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import fileinput 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for line in fileinput.input(): 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm process(line) 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThis iterates over the lines of all files listed in sys.argv[1:], 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdefaulting to sys.stdin if the list is empty. If a filename is '-' it 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmis also replaced by sys.stdin. To specify an alternative list of 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfilenames, pass it as the argument to input(). A single file name is 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmalso allowed. 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmFunctions filename(), lineno() return the filename and cumulative line 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmnumber of the line that has just been read; filelineno() returns its 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmline number in the current file; isfirstline() returns true iff the 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmline just read is the first line of its file; isstdin() returns true 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmiff the line was read from sys.stdin. Function nextfile() closes the 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcurrent file so that the next iteration will read the first line from 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmthe next file (if any); lines not read from the file will not count 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtowards the cumulative line count; the filename is not changed until 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmafter the first line of the next file has been read. Function close() 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcloses the sequence. 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBefore any lines have been read, filename() returns None and both line 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmnumbers are zero; nextfile() has no effect. After all lines have been 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmread, filename() and the line number functions return the values 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmpertaining to the last line read; nextfile() has no effect. 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmAll files are opened in text mode by default, you can override this by 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmsetting the mode parameter to input() or FileInput.__init__(). 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmIf an I/O error occurs during opening or reading a file, the IOError 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexception is raised. 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmIf sys.stdin is used more than once, the second and further use will 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmreturn no lines, except perhaps for interactive use, or if it has been 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexplicitly reset (e.g. using sys.stdin.seek(0)). 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmEmpty files are opened and immediately closed; the only time their 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmpresence in the list of filenames is noticeable at all is when the 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmlast file opened is empty. 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmIt is possible that the last line of a file doesn't end in a newline 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcharacter; otherwise lines are returned including the trailing 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmnewline. 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmClass FileInput is the implementation; its methods filename(), 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmlineno(), fileline(), isfirstline(), isstdin(), nextfile() and close() 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcorrespond to the functions in the module. In addition it has a 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmreadline() method which returns the next input line, and a 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__getitem__() method which implements the sequence behavior. The 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmsequence must be accessed in strictly sequential order; sequence 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmaccess and readline() cannot be mixed. 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmOptional in-place filtering: if the keyword argument inplace=1 is 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmpassed to input() or to the FileInput constructor, the file is moved 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmto a backup file and standard output is directed to the input file. 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThis makes it possible to write a filter that rewrites its input file 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmin place. If the keyword argument backup=".<some extension>" is also 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmgiven, it specifies the extension for the backup file, and the backup 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfile remains around; by default, the extension is ".bak" and it is 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdeleted when the output file is closed. In-place filtering is 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdisabled when standard input is read. XXX The current implementation 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdoes not work for MS-DOS 8+3 filesystems. 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPerformance: this module is unfortunately one of the slower ways of 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmprocessing large numbers of input lines. Nevertheless, a significant 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmspeed-up has been obtained by using readlines(bufsize) instead of 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmreadline(). A new keyword argument, bufsize=N, is present on the 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylminput() function and the FileInput() class to override the default 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmbuffer size. 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmXXX Possible additions: 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm- optional getopt argument processing 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm- isatty() 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm- read(), read(size), even readlines() 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm""" 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport sys, os 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__all__ = ["input","close","nextfile","filename","lineno","filelineno", 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "isfirstline","isstdin","FileInput"] 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_state = None 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmDEFAULT_BUFSIZE = 8*1024 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef input(files=None, inplace=0, backup="", bufsize=0, 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mode="r", openhook=None): 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """input([files[, inplace[, backup[, mode[, openhook]]]]]) 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Create an instance of the FileInput class. The instance will be used 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm as global state for the functions of this module, and is also returned 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm to use during iteration. The parameters to this function will be passed 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm along to the constructor of the FileInput class. 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm global _state 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if _state and _state._file: 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise RuntimeError, "input() already active" 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _state = FileInput(files, inplace, backup, bufsize, mode, openhook) 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _state 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef close(): 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Close the sequence.""" 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm global _state 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state = _state 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _state = None 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if state: 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state.close() 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef nextfile(): 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Close the current file so that the next iteration will read the first 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line from the next file (if any); lines not read from the file will 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm not count towards the cumulative line count. The filename is not 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm changed until after the first line of the next file has been read. 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Before the first line has been read, this function has no effect; 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm it cannot be used to skip the first file. After the last line of the 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm last file has been read, this function has no effect. 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not _state: 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise RuntimeError, "no active input()" 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _state.nextfile() 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef filename(): 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return the name of the file currently being read. 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Before the first line has been read, returns None. 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not _state: 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise RuntimeError, "no active input()" 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _state.filename() 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef lineno(): 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return the cumulative line number of the line that has just been read. 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Before the first line has been read, returns 0. After the last line 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm of the last file has been read, returns the line number of that line. 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not _state: 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise RuntimeError, "no active input()" 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _state.lineno() 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef filelineno(): 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return the line number in the current file. Before the first line 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm has been read, returns 0. After the last line of the last file has 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm been read, returns the line number of that line within the file. 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not _state: 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise RuntimeError, "no active input()" 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _state.filelineno() 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef fileno(): 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return the file number of the current file. When no file is currently 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm opened, returns -1. 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not _state: 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise RuntimeError, "no active input()" 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _state.fileno() 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef isfirstline(): 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Returns true the line just read is the first line of its file, 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm otherwise returns false. 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not _state: 1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise RuntimeError, "no active input()" 1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _state.isfirstline() 1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef isstdin(): 1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Returns true if the last line was read from sys.stdin, 1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm otherwise returns false. 1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not _state: 1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise RuntimeError, "no active input()" 1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _state.isstdin() 1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass FileInput: 1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """class FileInput([files[, inplace[, backup[, mode[, openhook]]]]]) 1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Class FileInput is the implementation of the module; its methods 1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(), 1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm nextfile() and close() correspond to the functions of the same name 1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm in the module. 1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm In addition it has a readline() method which returns the next 1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm input line, and a __getitem__() method which implements the 1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sequence behavior. The sequence must be accessed in strictly 1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sequential order; random access and readline() cannot be mixed. 1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, files=None, inplace=0, backup="", bufsize=0, 1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mode="r", openhook=None): 1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(files, basestring): 2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm files = (files,) 2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if files is None: 2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm files = sys.argv[1:] 2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not files: 2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm files = ('-',) 2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm files = tuple(files) 2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._files = files 2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._inplace = inplace 2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._backup = backup 2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._bufsize = bufsize or DEFAULT_BUFSIZE 2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._savestdout = None 2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._output = None 2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._filename = None 2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._lineno = 0 2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._filelineno = 0 2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._file = None 2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._isstdin = False 2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._backupfilename = None 2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._buffer = [] 2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._bufindex = 0 2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # restrict mode argument to reading modes 2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if mode not in ('r', 'rU', 'U', 'rb'): 2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("FileInput opening mode must be one of " 2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "'r', 'rU', 'U' and 'rb'") 2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._mode = mode 2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if inplace and openhook: 2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("FileInput cannot use an opening hook in inplace mode") 2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif openhook and not hasattr(openhook, '__call__'): 2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("FileInput openhook must be callable") 2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._openhook = openhook 2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __del__(self): 2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.close() 2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def close(self): 2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.nextfile() 2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._files = () 2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __iter__(self): 2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self 2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def next(self): 2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = self._buffer[self._bufindex] 2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except IndexError: 2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._bufindex += 1 2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._lineno += 1 2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._filelineno += 1 2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return line 2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = self.readline() 2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not line: 2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise StopIteration 2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return line 2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __getitem__(self, i): 2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if i != self._lineno: 2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise RuntimeError, "accessing lines out of order" 2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.next() 2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except StopIteration: 2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise IndexError, "end of input reached" 2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def nextfile(self): 2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm savestdout = self._savestdout 2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._savestdout = 0 2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if savestdout: 2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stdout = savestdout 2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output = self._output 2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._output = 0 2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if output: 2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output.close() 2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file = self._file 2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._file = 0 2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if file and not self._isstdin: 2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file.close() 2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm backupfilename = self._backupfilename 2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._backupfilename = 0 2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if backupfilename and not self._backup: 2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: os.unlink(backupfilename) 2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except OSError: pass 2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._isstdin = False 2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._buffer = [] 2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._bufindex = 0 2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def readline(self): 2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = self._buffer[self._bufindex] 2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except IndexError: 2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._bufindex += 1 2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._lineno += 1 3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._filelineno += 1 3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return line 3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not self._file: 3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not self._files: 3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return "" 3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._filename = self._files[0] 3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._files = self._files[1:] 3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._filelineno = 0 3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._file = None 3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._isstdin = False 3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._backupfilename = 0 3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self._filename == '-': 3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._filename = '<stdin>' 3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._file = sys.stdin 3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._isstdin = True 3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self._inplace: 3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._backupfilename = ( 3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._filename + (self._backup or os.extsep+"bak")) 3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: os.unlink(self._backupfilename) 3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except os.error: pass 3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # The next few lines may raise IOError 3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm os.rename(self._filename, self._backupfilename) 3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._file = open(self._backupfilename, self._mode) 3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm perm = os.fstat(self._file.fileno()).st_mode 3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except OSError: 3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._output = open(self._filename, "w") 3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm fd = os.open(self._filename, 3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm os.O_CREAT | os.O_WRONLY | os.O_TRUNC, 3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm perm) 3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._output = os.fdopen(fd, "w") 3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(os, 'chmod'): 3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm os.chmod(self._filename, perm) 3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except OSError: 3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._savestdout = sys.stdout 3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stdout = self._output 3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This may raise IOError 3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self._openhook: 3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._file = self._openhook(self._filename, self._mode) 3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._file = open(self._filename, self._mode) 3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._buffer = self._file.readlines(self._bufsize) 3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._bufindex = 0 3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not self._buffer: 3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.nextfile() 3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Recursive call 3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.readline() 3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def filename(self): 3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self._filename 3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def lineno(self): 3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self._lineno 3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def filelineno(self): 3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self._filelineno 3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def fileno(self): 3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self._file: 3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self._file.fileno() 3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except ValueError: 3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1 3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1 3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def isfirstline(self): 3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self._filelineno == 1 3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def isstdin(self): 3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self._isstdin 3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef hook_compressed(filename, mode): 3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ext = os.path.splitext(filename)[1] 3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if ext == '.gz': 3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import gzip 3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return gzip.open(filename, mode) 3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif ext == '.bz2': 3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import bz2 3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return bz2.BZ2File(filename, mode) 3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return open(filename, mode) 3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef hook_encoded(encoding): 3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import codecs 3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def openhook(filename, mode): 3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return codecs.open(filename, mode, encoding) 3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return openhook 3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _test(): 3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import getopt 3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm inplace = 0 4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm backup = 0 4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm opts, args = getopt.getopt(sys.argv[1:], "ib:") 4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for o, a in opts: 4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if o == '-i': inplace = 1 4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if o == '-b': backup = a 4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for line in input(args, inplace=inplace, backup=backup): 4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if line[-1:] == '\n': line = line[:-1] 4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if line[-1:] == '\r': line = line[:-1] 4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print "%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(), 4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm isfirstline() and "*" or "", line) 4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print "%d: %s[%d]" % (lineno(), filename(), filelineno()) 4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == '__main__': 4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _test() 414