1*cda5da8dSAndroid Build Coastguard Worker"""Helper class to quickly write a loop over all standard input files. 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard WorkerTypical use is: 4*cda5da8dSAndroid Build Coastguard Worker 5*cda5da8dSAndroid Build Coastguard Worker import fileinput 6*cda5da8dSAndroid Build Coastguard Worker for line in fileinput.input(encoding="utf-8"): 7*cda5da8dSAndroid Build Coastguard Worker process(line) 8*cda5da8dSAndroid Build Coastguard Worker 9*cda5da8dSAndroid Build Coastguard WorkerThis iterates over the lines of all files listed in sys.argv[1:], 10*cda5da8dSAndroid Build Coastguard Workerdefaulting to sys.stdin if the list is empty. If a filename is '-' it 11*cda5da8dSAndroid Build Coastguard Workeris also replaced by sys.stdin and the optional arguments mode and 12*cda5da8dSAndroid Build Coastguard Workeropenhook are ignored. To specify an alternative list of filenames, 13*cda5da8dSAndroid Build Coastguard Workerpass it as the argument to input(). A single file name is also allowed. 14*cda5da8dSAndroid Build Coastguard Worker 15*cda5da8dSAndroid Build Coastguard WorkerFunctions filename(), lineno() return the filename and cumulative line 16*cda5da8dSAndroid Build Coastguard Workernumber of the line that has just been read; filelineno() returns its 17*cda5da8dSAndroid Build Coastguard Workerline number in the current file; isfirstline() returns true iff the 18*cda5da8dSAndroid Build Coastguard Workerline just read is the first line of its file; isstdin() returns true 19*cda5da8dSAndroid Build Coastguard Workeriff the line was read from sys.stdin. Function nextfile() closes the 20*cda5da8dSAndroid Build Coastguard Workercurrent file so that the next iteration will read the first line from 21*cda5da8dSAndroid Build Coastguard Workerthe next file (if any); lines not read from the file will not count 22*cda5da8dSAndroid Build Coastguard Workertowards the cumulative line count; the filename is not changed until 23*cda5da8dSAndroid Build Coastguard Workerafter the first line of the next file has been read. Function close() 24*cda5da8dSAndroid Build Coastguard Workercloses the sequence. 25*cda5da8dSAndroid Build Coastguard Worker 26*cda5da8dSAndroid Build Coastguard WorkerBefore any lines have been read, filename() returns None and both line 27*cda5da8dSAndroid Build Coastguard Workernumbers are zero; nextfile() has no effect. After all lines have been 28*cda5da8dSAndroid Build Coastguard Workerread, filename() and the line number functions return the values 29*cda5da8dSAndroid Build Coastguard Workerpertaining to the last line read; nextfile() has no effect. 30*cda5da8dSAndroid Build Coastguard Worker 31*cda5da8dSAndroid Build Coastguard WorkerAll files are opened in text mode by default, you can override this by 32*cda5da8dSAndroid Build Coastguard Workersetting the mode parameter to input() or FileInput.__init__(). 33*cda5da8dSAndroid Build Coastguard WorkerIf an I/O error occurs during opening or reading a file, the OSError 34*cda5da8dSAndroid Build Coastguard Workerexception is raised. 35*cda5da8dSAndroid Build Coastguard Worker 36*cda5da8dSAndroid Build Coastguard WorkerIf sys.stdin is used more than once, the second and further use will 37*cda5da8dSAndroid Build Coastguard Workerreturn no lines, except perhaps for interactive use, or if it has been 38*cda5da8dSAndroid Build Coastguard Workerexplicitly reset (e.g. using sys.stdin.seek(0)). 39*cda5da8dSAndroid Build Coastguard Worker 40*cda5da8dSAndroid Build Coastguard WorkerEmpty files are opened and immediately closed; the only time their 41*cda5da8dSAndroid Build Coastguard Workerpresence in the list of filenames is noticeable at all is when the 42*cda5da8dSAndroid Build Coastguard Workerlast file opened is empty. 43*cda5da8dSAndroid Build Coastguard Worker 44*cda5da8dSAndroid Build Coastguard WorkerIt is possible that the last line of a file doesn't end in a newline 45*cda5da8dSAndroid Build Coastguard Workercharacter; otherwise lines are returned including the trailing 46*cda5da8dSAndroid Build Coastguard Workernewline. 47*cda5da8dSAndroid Build Coastguard Worker 48*cda5da8dSAndroid Build Coastguard WorkerClass FileInput is the implementation; its methods filename(), 49*cda5da8dSAndroid Build Coastguard Workerlineno(), fileline(), isfirstline(), isstdin(), nextfile() and close() 50*cda5da8dSAndroid Build Coastguard Workercorrespond to the functions in the module. In addition it has a 51*cda5da8dSAndroid Build Coastguard Workerreadline() method which returns the next input line, and a 52*cda5da8dSAndroid Build Coastguard Worker__getitem__() method which implements the sequence behavior. The 53*cda5da8dSAndroid Build Coastguard Workersequence must be accessed in strictly sequential order; sequence 54*cda5da8dSAndroid Build Coastguard Workeraccess and readline() cannot be mixed. 55*cda5da8dSAndroid Build Coastguard Worker 56*cda5da8dSAndroid Build Coastguard WorkerOptional in-place filtering: if the keyword argument inplace=1 is 57*cda5da8dSAndroid Build Coastguard Workerpassed to input() or to the FileInput constructor, the file is moved 58*cda5da8dSAndroid Build Coastguard Workerto a backup file and standard output is directed to the input file. 59*cda5da8dSAndroid Build Coastguard WorkerThis makes it possible to write a filter that rewrites its input file 60*cda5da8dSAndroid Build Coastguard Workerin place. If the keyword argument backup=".<some extension>" is also 61*cda5da8dSAndroid Build Coastguard Workergiven, it specifies the extension for the backup file, and the backup 62*cda5da8dSAndroid Build Coastguard Workerfile remains around; by default, the extension is ".bak" and it is 63*cda5da8dSAndroid Build Coastguard Workerdeleted when the output file is closed. In-place filtering is 64*cda5da8dSAndroid Build Coastguard Workerdisabled when standard input is read. XXX The current implementation 65*cda5da8dSAndroid Build Coastguard Workerdoes not work for MS-DOS 8+3 filesystems. 66*cda5da8dSAndroid Build Coastguard Worker""" 67*cda5da8dSAndroid Build Coastguard Worker 68*cda5da8dSAndroid Build Coastguard Workerimport io 69*cda5da8dSAndroid Build Coastguard Workerimport sys, os 70*cda5da8dSAndroid Build Coastguard Workerfrom types import GenericAlias 71*cda5da8dSAndroid Build Coastguard Worker 72*cda5da8dSAndroid Build Coastguard Worker__all__ = ["input", "close", "nextfile", "filename", "lineno", "filelineno", 73*cda5da8dSAndroid Build Coastguard Worker "fileno", "isfirstline", "isstdin", "FileInput", "hook_compressed", 74*cda5da8dSAndroid Build Coastguard Worker "hook_encoded"] 75*cda5da8dSAndroid Build Coastguard Worker 76*cda5da8dSAndroid Build Coastguard Worker_state = None 77*cda5da8dSAndroid Build Coastguard Worker 78*cda5da8dSAndroid Build Coastguard Workerdef input(files=None, inplace=False, backup="", *, mode="r", openhook=None, 79*cda5da8dSAndroid Build Coastguard Worker encoding=None, errors=None): 80*cda5da8dSAndroid Build Coastguard Worker """Return an instance of the FileInput class, which can be iterated. 81*cda5da8dSAndroid Build Coastguard Worker 82*cda5da8dSAndroid Build Coastguard Worker The parameters are passed to the constructor of the FileInput class. 83*cda5da8dSAndroid Build Coastguard Worker The returned instance, in addition to being an iterator, 84*cda5da8dSAndroid Build Coastguard Worker keeps global state for the functions of this module,. 85*cda5da8dSAndroid Build Coastguard Worker """ 86*cda5da8dSAndroid Build Coastguard Worker global _state 87*cda5da8dSAndroid Build Coastguard Worker if _state and _state._file: 88*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError("input() already active") 89*cda5da8dSAndroid Build Coastguard Worker _state = FileInput(files, inplace, backup, mode=mode, openhook=openhook, 90*cda5da8dSAndroid Build Coastguard Worker encoding=encoding, errors=errors) 91*cda5da8dSAndroid Build Coastguard Worker return _state 92*cda5da8dSAndroid Build Coastguard Worker 93*cda5da8dSAndroid Build Coastguard Workerdef close(): 94*cda5da8dSAndroid Build Coastguard Worker """Close the sequence.""" 95*cda5da8dSAndroid Build Coastguard Worker global _state 96*cda5da8dSAndroid Build Coastguard Worker state = _state 97*cda5da8dSAndroid Build Coastguard Worker _state = None 98*cda5da8dSAndroid Build Coastguard Worker if state: 99*cda5da8dSAndroid Build Coastguard Worker state.close() 100*cda5da8dSAndroid Build Coastguard Worker 101*cda5da8dSAndroid Build Coastguard Workerdef nextfile(): 102*cda5da8dSAndroid Build Coastguard Worker """ 103*cda5da8dSAndroid Build Coastguard Worker Close the current file so that the next iteration will read the first 104*cda5da8dSAndroid Build Coastguard Worker line from the next file (if any); lines not read from the file will 105*cda5da8dSAndroid Build Coastguard Worker not count towards the cumulative line count. The filename is not 106*cda5da8dSAndroid Build Coastguard Worker changed until after the first line of the next file has been read. 107*cda5da8dSAndroid Build Coastguard Worker Before the first line has been read, this function has no effect; 108*cda5da8dSAndroid Build Coastguard Worker it cannot be used to skip the first file. After the last line of the 109*cda5da8dSAndroid Build Coastguard Worker last file has been read, this function has no effect. 110*cda5da8dSAndroid Build Coastguard Worker """ 111*cda5da8dSAndroid Build Coastguard Worker if not _state: 112*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError("no active input()") 113*cda5da8dSAndroid Build Coastguard Worker return _state.nextfile() 114*cda5da8dSAndroid Build Coastguard Worker 115*cda5da8dSAndroid Build Coastguard Workerdef filename(): 116*cda5da8dSAndroid Build Coastguard Worker """ 117*cda5da8dSAndroid Build Coastguard Worker Return the name of the file currently being read. 118*cda5da8dSAndroid Build Coastguard Worker Before the first line has been read, returns None. 119*cda5da8dSAndroid Build Coastguard Worker """ 120*cda5da8dSAndroid Build Coastguard Worker if not _state: 121*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError("no active input()") 122*cda5da8dSAndroid Build Coastguard Worker return _state.filename() 123*cda5da8dSAndroid Build Coastguard Worker 124*cda5da8dSAndroid Build Coastguard Workerdef lineno(): 125*cda5da8dSAndroid Build Coastguard Worker """ 126*cda5da8dSAndroid Build Coastguard Worker Return the cumulative line number of the line that has just been read. 127*cda5da8dSAndroid Build Coastguard Worker Before the first line has been read, returns 0. After the last line 128*cda5da8dSAndroid Build Coastguard Worker of the last file has been read, returns the line number of that line. 129*cda5da8dSAndroid Build Coastguard Worker """ 130*cda5da8dSAndroid Build Coastguard Worker if not _state: 131*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError("no active input()") 132*cda5da8dSAndroid Build Coastguard Worker return _state.lineno() 133*cda5da8dSAndroid Build Coastguard Worker 134*cda5da8dSAndroid Build Coastguard Workerdef filelineno(): 135*cda5da8dSAndroid Build Coastguard Worker """ 136*cda5da8dSAndroid Build Coastguard Worker Return the line number in the current file. Before the first line 137*cda5da8dSAndroid Build Coastguard Worker has been read, returns 0. After the last line of the last file has 138*cda5da8dSAndroid Build Coastguard Worker been read, returns the line number of that line within the file. 139*cda5da8dSAndroid Build Coastguard Worker """ 140*cda5da8dSAndroid Build Coastguard Worker if not _state: 141*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError("no active input()") 142*cda5da8dSAndroid Build Coastguard Worker return _state.filelineno() 143*cda5da8dSAndroid Build Coastguard Worker 144*cda5da8dSAndroid Build Coastguard Workerdef fileno(): 145*cda5da8dSAndroid Build Coastguard Worker """ 146*cda5da8dSAndroid Build Coastguard Worker Return the file number of the current file. When no file is currently 147*cda5da8dSAndroid Build Coastguard Worker opened, returns -1. 148*cda5da8dSAndroid Build Coastguard Worker """ 149*cda5da8dSAndroid Build Coastguard Worker if not _state: 150*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError("no active input()") 151*cda5da8dSAndroid Build Coastguard Worker return _state.fileno() 152*cda5da8dSAndroid Build Coastguard Worker 153*cda5da8dSAndroid Build Coastguard Workerdef isfirstline(): 154*cda5da8dSAndroid Build Coastguard Worker """ 155*cda5da8dSAndroid Build Coastguard Worker Returns true the line just read is the first line of its file, 156*cda5da8dSAndroid Build Coastguard Worker otherwise returns false. 157*cda5da8dSAndroid Build Coastguard Worker """ 158*cda5da8dSAndroid Build Coastguard Worker if not _state: 159*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError("no active input()") 160*cda5da8dSAndroid Build Coastguard Worker return _state.isfirstline() 161*cda5da8dSAndroid Build Coastguard Worker 162*cda5da8dSAndroid Build Coastguard Workerdef isstdin(): 163*cda5da8dSAndroid Build Coastguard Worker """ 164*cda5da8dSAndroid Build Coastguard Worker Returns true if the last line was read from sys.stdin, 165*cda5da8dSAndroid Build Coastguard Worker otherwise returns false. 166*cda5da8dSAndroid Build Coastguard Worker """ 167*cda5da8dSAndroid Build Coastguard Worker if not _state: 168*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError("no active input()") 169*cda5da8dSAndroid Build Coastguard Worker return _state.isstdin() 170*cda5da8dSAndroid Build Coastguard Worker 171*cda5da8dSAndroid Build Coastguard Workerclass FileInput: 172*cda5da8dSAndroid Build Coastguard Worker """FileInput([files[, inplace[, backup]]], *, mode=None, openhook=None) 173*cda5da8dSAndroid Build Coastguard Worker 174*cda5da8dSAndroid Build Coastguard Worker Class FileInput is the implementation of the module; its methods 175*cda5da8dSAndroid Build Coastguard Worker filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(), 176*cda5da8dSAndroid Build Coastguard Worker nextfile() and close() correspond to the functions of the same name 177*cda5da8dSAndroid Build Coastguard Worker in the module. 178*cda5da8dSAndroid Build Coastguard Worker In addition it has a readline() method which returns the next 179*cda5da8dSAndroid Build Coastguard Worker input line, and a __getitem__() method which implements the 180*cda5da8dSAndroid Build Coastguard Worker sequence behavior. The sequence must be accessed in strictly 181*cda5da8dSAndroid Build Coastguard Worker sequential order; random access and readline() cannot be mixed. 182*cda5da8dSAndroid Build Coastguard Worker """ 183*cda5da8dSAndroid Build Coastguard Worker 184*cda5da8dSAndroid Build Coastguard Worker def __init__(self, files=None, inplace=False, backup="", *, 185*cda5da8dSAndroid Build Coastguard Worker mode="r", openhook=None, encoding=None, errors=None): 186*cda5da8dSAndroid Build Coastguard Worker if isinstance(files, str): 187*cda5da8dSAndroid Build Coastguard Worker files = (files,) 188*cda5da8dSAndroid Build Coastguard Worker elif isinstance(files, os.PathLike): 189*cda5da8dSAndroid Build Coastguard Worker files = (os.fspath(files), ) 190*cda5da8dSAndroid Build Coastguard Worker else: 191*cda5da8dSAndroid Build Coastguard Worker if files is None: 192*cda5da8dSAndroid Build Coastguard Worker files = sys.argv[1:] 193*cda5da8dSAndroid Build Coastguard Worker if not files: 194*cda5da8dSAndroid Build Coastguard Worker files = ('-',) 195*cda5da8dSAndroid Build Coastguard Worker else: 196*cda5da8dSAndroid Build Coastguard Worker files = tuple(files) 197*cda5da8dSAndroid Build Coastguard Worker self._files = files 198*cda5da8dSAndroid Build Coastguard Worker self._inplace = inplace 199*cda5da8dSAndroid Build Coastguard Worker self._backup = backup 200*cda5da8dSAndroid Build Coastguard Worker self._savestdout = None 201*cda5da8dSAndroid Build Coastguard Worker self._output = None 202*cda5da8dSAndroid Build Coastguard Worker self._filename = None 203*cda5da8dSAndroid Build Coastguard Worker self._startlineno = 0 204*cda5da8dSAndroid Build Coastguard Worker self._filelineno = 0 205*cda5da8dSAndroid Build Coastguard Worker self._file = None 206*cda5da8dSAndroid Build Coastguard Worker self._isstdin = False 207*cda5da8dSAndroid Build Coastguard Worker self._backupfilename = None 208*cda5da8dSAndroid Build Coastguard Worker self._encoding = encoding 209*cda5da8dSAndroid Build Coastguard Worker self._errors = errors 210*cda5da8dSAndroid Build Coastguard Worker 211*cda5da8dSAndroid Build Coastguard Worker # We can not use io.text_encoding() here because old openhook doesn't 212*cda5da8dSAndroid Build Coastguard Worker # take encoding parameter. 213*cda5da8dSAndroid Build Coastguard Worker if (sys.flags.warn_default_encoding and 214*cda5da8dSAndroid Build Coastguard Worker "b" not in mode and encoding is None and openhook is None): 215*cda5da8dSAndroid Build Coastguard Worker import warnings 216*cda5da8dSAndroid Build Coastguard Worker warnings.warn("'encoding' argument not specified.", 217*cda5da8dSAndroid Build Coastguard Worker EncodingWarning, 2) 218*cda5da8dSAndroid Build Coastguard Worker 219*cda5da8dSAndroid Build Coastguard Worker # restrict mode argument to reading modes 220*cda5da8dSAndroid Build Coastguard Worker if mode not in ('r', 'rb'): 221*cda5da8dSAndroid Build Coastguard Worker raise ValueError("FileInput opening mode must be 'r' or 'rb'") 222*cda5da8dSAndroid Build Coastguard Worker self._mode = mode 223*cda5da8dSAndroid Build Coastguard Worker self._write_mode = mode.replace('r', 'w') 224*cda5da8dSAndroid Build Coastguard Worker if openhook: 225*cda5da8dSAndroid Build Coastguard Worker if inplace: 226*cda5da8dSAndroid Build Coastguard Worker raise ValueError("FileInput cannot use an opening hook in inplace mode") 227*cda5da8dSAndroid Build Coastguard Worker if not callable(openhook): 228*cda5da8dSAndroid Build Coastguard Worker raise ValueError("FileInput openhook must be callable") 229*cda5da8dSAndroid Build Coastguard Worker self._openhook = openhook 230*cda5da8dSAndroid Build Coastguard Worker 231*cda5da8dSAndroid Build Coastguard Worker def __del__(self): 232*cda5da8dSAndroid Build Coastguard Worker self.close() 233*cda5da8dSAndroid Build Coastguard Worker 234*cda5da8dSAndroid Build Coastguard Worker def close(self): 235*cda5da8dSAndroid Build Coastguard Worker try: 236*cda5da8dSAndroid Build Coastguard Worker self.nextfile() 237*cda5da8dSAndroid Build Coastguard Worker finally: 238*cda5da8dSAndroid Build Coastguard Worker self._files = () 239*cda5da8dSAndroid Build Coastguard Worker 240*cda5da8dSAndroid Build Coastguard Worker def __enter__(self): 241*cda5da8dSAndroid Build Coastguard Worker return self 242*cda5da8dSAndroid Build Coastguard Worker 243*cda5da8dSAndroid Build Coastguard Worker def __exit__(self, type, value, traceback): 244*cda5da8dSAndroid Build Coastguard Worker self.close() 245*cda5da8dSAndroid Build Coastguard Worker 246*cda5da8dSAndroid Build Coastguard Worker def __iter__(self): 247*cda5da8dSAndroid Build Coastguard Worker return self 248*cda5da8dSAndroid Build Coastguard Worker 249*cda5da8dSAndroid Build Coastguard Worker def __next__(self): 250*cda5da8dSAndroid Build Coastguard Worker while True: 251*cda5da8dSAndroid Build Coastguard Worker line = self._readline() 252*cda5da8dSAndroid Build Coastguard Worker if line: 253*cda5da8dSAndroid Build Coastguard Worker self._filelineno += 1 254*cda5da8dSAndroid Build Coastguard Worker return line 255*cda5da8dSAndroid Build Coastguard Worker if not self._file: 256*cda5da8dSAndroid Build Coastguard Worker raise StopIteration 257*cda5da8dSAndroid Build Coastguard Worker self.nextfile() 258*cda5da8dSAndroid Build Coastguard Worker # repeat with next file 259*cda5da8dSAndroid Build Coastguard Worker 260*cda5da8dSAndroid Build Coastguard Worker def nextfile(self): 261*cda5da8dSAndroid Build Coastguard Worker savestdout = self._savestdout 262*cda5da8dSAndroid Build Coastguard Worker self._savestdout = None 263*cda5da8dSAndroid Build Coastguard Worker if savestdout: 264*cda5da8dSAndroid Build Coastguard Worker sys.stdout = savestdout 265*cda5da8dSAndroid Build Coastguard Worker 266*cda5da8dSAndroid Build Coastguard Worker output = self._output 267*cda5da8dSAndroid Build Coastguard Worker self._output = None 268*cda5da8dSAndroid Build Coastguard Worker try: 269*cda5da8dSAndroid Build Coastguard Worker if output: 270*cda5da8dSAndroid Build Coastguard Worker output.close() 271*cda5da8dSAndroid Build Coastguard Worker finally: 272*cda5da8dSAndroid Build Coastguard Worker file = self._file 273*cda5da8dSAndroid Build Coastguard Worker self._file = None 274*cda5da8dSAndroid Build Coastguard Worker try: 275*cda5da8dSAndroid Build Coastguard Worker del self._readline # restore FileInput._readline 276*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 277*cda5da8dSAndroid Build Coastguard Worker pass 278*cda5da8dSAndroid Build Coastguard Worker try: 279*cda5da8dSAndroid Build Coastguard Worker if file and not self._isstdin: 280*cda5da8dSAndroid Build Coastguard Worker file.close() 281*cda5da8dSAndroid Build Coastguard Worker finally: 282*cda5da8dSAndroid Build Coastguard Worker backupfilename = self._backupfilename 283*cda5da8dSAndroid Build Coastguard Worker self._backupfilename = None 284*cda5da8dSAndroid Build Coastguard Worker if backupfilename and not self._backup: 285*cda5da8dSAndroid Build Coastguard Worker try: os.unlink(backupfilename) 286*cda5da8dSAndroid Build Coastguard Worker except OSError: pass 287*cda5da8dSAndroid Build Coastguard Worker 288*cda5da8dSAndroid Build Coastguard Worker self._isstdin = False 289*cda5da8dSAndroid Build Coastguard Worker 290*cda5da8dSAndroid Build Coastguard Worker def readline(self): 291*cda5da8dSAndroid Build Coastguard Worker while True: 292*cda5da8dSAndroid Build Coastguard Worker line = self._readline() 293*cda5da8dSAndroid Build Coastguard Worker if line: 294*cda5da8dSAndroid Build Coastguard Worker self._filelineno += 1 295*cda5da8dSAndroid Build Coastguard Worker return line 296*cda5da8dSAndroid Build Coastguard Worker if not self._file: 297*cda5da8dSAndroid Build Coastguard Worker return line 298*cda5da8dSAndroid Build Coastguard Worker self.nextfile() 299*cda5da8dSAndroid Build Coastguard Worker # repeat with next file 300*cda5da8dSAndroid Build Coastguard Worker 301*cda5da8dSAndroid Build Coastguard Worker def _readline(self): 302*cda5da8dSAndroid Build Coastguard Worker if not self._files: 303*cda5da8dSAndroid Build Coastguard Worker if 'b' in self._mode: 304*cda5da8dSAndroid Build Coastguard Worker return b'' 305*cda5da8dSAndroid Build Coastguard Worker else: 306*cda5da8dSAndroid Build Coastguard Worker return '' 307*cda5da8dSAndroid Build Coastguard Worker self._filename = self._files[0] 308*cda5da8dSAndroid Build Coastguard Worker self._files = self._files[1:] 309*cda5da8dSAndroid Build Coastguard Worker self._startlineno = self.lineno() 310*cda5da8dSAndroid Build Coastguard Worker self._filelineno = 0 311*cda5da8dSAndroid Build Coastguard Worker self._file = None 312*cda5da8dSAndroid Build Coastguard Worker self._isstdin = False 313*cda5da8dSAndroid Build Coastguard Worker self._backupfilename = 0 314*cda5da8dSAndroid Build Coastguard Worker 315*cda5da8dSAndroid Build Coastguard Worker # EncodingWarning is emitted in __init__() already 316*cda5da8dSAndroid Build Coastguard Worker if "b" not in self._mode: 317*cda5da8dSAndroid Build Coastguard Worker encoding = self._encoding or "locale" 318*cda5da8dSAndroid Build Coastguard Worker else: 319*cda5da8dSAndroid Build Coastguard Worker encoding = None 320*cda5da8dSAndroid Build Coastguard Worker 321*cda5da8dSAndroid Build Coastguard Worker if self._filename == '-': 322*cda5da8dSAndroid Build Coastguard Worker self._filename = '<stdin>' 323*cda5da8dSAndroid Build Coastguard Worker if 'b' in self._mode: 324*cda5da8dSAndroid Build Coastguard Worker self._file = getattr(sys.stdin, 'buffer', sys.stdin) 325*cda5da8dSAndroid Build Coastguard Worker else: 326*cda5da8dSAndroid Build Coastguard Worker self._file = sys.stdin 327*cda5da8dSAndroid Build Coastguard Worker self._isstdin = True 328*cda5da8dSAndroid Build Coastguard Worker else: 329*cda5da8dSAndroid Build Coastguard Worker if self._inplace: 330*cda5da8dSAndroid Build Coastguard Worker self._backupfilename = ( 331*cda5da8dSAndroid Build Coastguard Worker os.fspath(self._filename) + (self._backup or ".bak")) 332*cda5da8dSAndroid Build Coastguard Worker try: 333*cda5da8dSAndroid Build Coastguard Worker os.unlink(self._backupfilename) 334*cda5da8dSAndroid Build Coastguard Worker except OSError: 335*cda5da8dSAndroid Build Coastguard Worker pass 336*cda5da8dSAndroid Build Coastguard Worker # The next few lines may raise OSError 337*cda5da8dSAndroid Build Coastguard Worker os.rename(self._filename, self._backupfilename) 338*cda5da8dSAndroid Build Coastguard Worker self._file = open(self._backupfilename, self._mode, 339*cda5da8dSAndroid Build Coastguard Worker encoding=encoding, errors=self._errors) 340*cda5da8dSAndroid Build Coastguard Worker try: 341*cda5da8dSAndroid Build Coastguard Worker perm = os.fstat(self._file.fileno()).st_mode 342*cda5da8dSAndroid Build Coastguard Worker except OSError: 343*cda5da8dSAndroid Build Coastguard Worker self._output = open(self._filename, self._write_mode, 344*cda5da8dSAndroid Build Coastguard Worker encoding=encoding, errors=self._errors) 345*cda5da8dSAndroid Build Coastguard Worker else: 346*cda5da8dSAndroid Build Coastguard Worker mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC 347*cda5da8dSAndroid Build Coastguard Worker if hasattr(os, 'O_BINARY'): 348*cda5da8dSAndroid Build Coastguard Worker mode |= os.O_BINARY 349*cda5da8dSAndroid Build Coastguard Worker 350*cda5da8dSAndroid Build Coastguard Worker fd = os.open(self._filename, mode, perm) 351*cda5da8dSAndroid Build Coastguard Worker self._output = os.fdopen(fd, self._write_mode, 352*cda5da8dSAndroid Build Coastguard Worker encoding=encoding, errors=self._errors) 353*cda5da8dSAndroid Build Coastguard Worker try: 354*cda5da8dSAndroid Build Coastguard Worker os.chmod(self._filename, perm) 355*cda5da8dSAndroid Build Coastguard Worker except OSError: 356*cda5da8dSAndroid Build Coastguard Worker pass 357*cda5da8dSAndroid Build Coastguard Worker self._savestdout = sys.stdout 358*cda5da8dSAndroid Build Coastguard Worker sys.stdout = self._output 359*cda5da8dSAndroid Build Coastguard Worker else: 360*cda5da8dSAndroid Build Coastguard Worker # This may raise OSError 361*cda5da8dSAndroid Build Coastguard Worker if self._openhook: 362*cda5da8dSAndroid Build Coastguard Worker # Custom hooks made previous to Python 3.10 didn't have 363*cda5da8dSAndroid Build Coastguard Worker # encoding argument 364*cda5da8dSAndroid Build Coastguard Worker if self._encoding is None: 365*cda5da8dSAndroid Build Coastguard Worker self._file = self._openhook(self._filename, self._mode) 366*cda5da8dSAndroid Build Coastguard Worker else: 367*cda5da8dSAndroid Build Coastguard Worker self._file = self._openhook( 368*cda5da8dSAndroid Build Coastguard Worker self._filename, self._mode, encoding=self._encoding, errors=self._errors) 369*cda5da8dSAndroid Build Coastguard Worker else: 370*cda5da8dSAndroid Build Coastguard Worker self._file = open(self._filename, self._mode, encoding=encoding, errors=self._errors) 371*cda5da8dSAndroid Build Coastguard Worker self._readline = self._file.readline # hide FileInput._readline 372*cda5da8dSAndroid Build Coastguard Worker return self._readline() 373*cda5da8dSAndroid Build Coastguard Worker 374*cda5da8dSAndroid Build Coastguard Worker def filename(self): 375*cda5da8dSAndroid Build Coastguard Worker return self._filename 376*cda5da8dSAndroid Build Coastguard Worker 377*cda5da8dSAndroid Build Coastguard Worker def lineno(self): 378*cda5da8dSAndroid Build Coastguard Worker return self._startlineno + self._filelineno 379*cda5da8dSAndroid Build Coastguard Worker 380*cda5da8dSAndroid Build Coastguard Worker def filelineno(self): 381*cda5da8dSAndroid Build Coastguard Worker return self._filelineno 382*cda5da8dSAndroid Build Coastguard Worker 383*cda5da8dSAndroid Build Coastguard Worker def fileno(self): 384*cda5da8dSAndroid Build Coastguard Worker if self._file: 385*cda5da8dSAndroid Build Coastguard Worker try: 386*cda5da8dSAndroid Build Coastguard Worker return self._file.fileno() 387*cda5da8dSAndroid Build Coastguard Worker except ValueError: 388*cda5da8dSAndroid Build Coastguard Worker return -1 389*cda5da8dSAndroid Build Coastguard Worker else: 390*cda5da8dSAndroid Build Coastguard Worker return -1 391*cda5da8dSAndroid Build Coastguard Worker 392*cda5da8dSAndroid Build Coastguard Worker def isfirstline(self): 393*cda5da8dSAndroid Build Coastguard Worker return self._filelineno == 1 394*cda5da8dSAndroid Build Coastguard Worker 395*cda5da8dSAndroid Build Coastguard Worker def isstdin(self): 396*cda5da8dSAndroid Build Coastguard Worker return self._isstdin 397*cda5da8dSAndroid Build Coastguard Worker 398*cda5da8dSAndroid Build Coastguard Worker __class_getitem__ = classmethod(GenericAlias) 399*cda5da8dSAndroid Build Coastguard Worker 400*cda5da8dSAndroid Build Coastguard Worker 401*cda5da8dSAndroid Build Coastguard Workerdef hook_compressed(filename, mode, *, encoding=None, errors=None): 402*cda5da8dSAndroid Build Coastguard Worker if encoding is None and "b" not in mode: # EncodingWarning is emitted in FileInput() already. 403*cda5da8dSAndroid Build Coastguard Worker encoding = "locale" 404*cda5da8dSAndroid Build Coastguard Worker ext = os.path.splitext(filename)[1] 405*cda5da8dSAndroid Build Coastguard Worker if ext == '.gz': 406*cda5da8dSAndroid Build Coastguard Worker import gzip 407*cda5da8dSAndroid Build Coastguard Worker stream = gzip.open(filename, mode) 408*cda5da8dSAndroid Build Coastguard Worker elif ext == '.bz2': 409*cda5da8dSAndroid Build Coastguard Worker import bz2 410*cda5da8dSAndroid Build Coastguard Worker stream = bz2.BZ2File(filename, mode) 411*cda5da8dSAndroid Build Coastguard Worker else: 412*cda5da8dSAndroid Build Coastguard Worker return open(filename, mode, encoding=encoding, errors=errors) 413*cda5da8dSAndroid Build Coastguard Worker 414*cda5da8dSAndroid Build Coastguard Worker # gzip and bz2 are binary mode by default. 415*cda5da8dSAndroid Build Coastguard Worker if "b" not in mode: 416*cda5da8dSAndroid Build Coastguard Worker stream = io.TextIOWrapper(stream, encoding=encoding, errors=errors) 417*cda5da8dSAndroid Build Coastguard Worker return stream 418*cda5da8dSAndroid Build Coastguard Worker 419*cda5da8dSAndroid Build Coastguard Worker 420*cda5da8dSAndroid Build Coastguard Workerdef hook_encoded(encoding, errors=None): 421*cda5da8dSAndroid Build Coastguard Worker def openhook(filename, mode): 422*cda5da8dSAndroid Build Coastguard Worker return open(filename, mode, encoding=encoding, errors=errors) 423*cda5da8dSAndroid Build Coastguard Worker return openhook 424*cda5da8dSAndroid Build Coastguard Worker 425*cda5da8dSAndroid Build Coastguard Worker 426*cda5da8dSAndroid Build Coastguard Workerdef _test(): 427*cda5da8dSAndroid Build Coastguard Worker import getopt 428*cda5da8dSAndroid Build Coastguard Worker inplace = False 429*cda5da8dSAndroid Build Coastguard Worker backup = False 430*cda5da8dSAndroid Build Coastguard Worker opts, args = getopt.getopt(sys.argv[1:], "ib:") 431*cda5da8dSAndroid Build Coastguard Worker for o, a in opts: 432*cda5da8dSAndroid Build Coastguard Worker if o == '-i': inplace = True 433*cda5da8dSAndroid Build Coastguard Worker if o == '-b': backup = a 434*cda5da8dSAndroid Build Coastguard Worker for line in input(args, inplace=inplace, backup=backup): 435*cda5da8dSAndroid Build Coastguard Worker if line[-1:] == '\n': line = line[:-1] 436*cda5da8dSAndroid Build Coastguard Worker if line[-1:] == '\r': line = line[:-1] 437*cda5da8dSAndroid Build Coastguard Worker print("%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(), 438*cda5da8dSAndroid Build Coastguard Worker isfirstline() and "*" or "", line)) 439*cda5da8dSAndroid Build Coastguard Worker print("%d: %s[%d]" % (lineno(), filename(), filelineno())) 440*cda5da8dSAndroid Build Coastguard Worker 441*cda5da8dSAndroid Build Coastguard Workerif __name__ == '__main__': 442*cda5da8dSAndroid Build Coastguard Worker _test() 443