Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
fileinput.py443 linesDownload Raw Back to Lib
1"""Helper class to quickly write a loop over all standard input files.2 3Typical use is:4 5    import fileinput6    for line in fileinput.input(encoding="utf-8"):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 '-' it11is also replaced by sys.stdin and the optional arguments mode and12openhook are ignored.  To specify an alternative list of filenames,13pass it as the argument to input().  A single file name is also allowed.14 15Functions filename(), lineno() return the filename and cumulative line16number of the line that has just been read; filelineno() returns its17line number in the current file; isfirstline() returns true iff the18line just read is the first line of its file; isstdin() returns true19iff the line was read from sys.stdin.  Function nextfile() closes the20current file so that the next iteration will read the first line from21the next file (if any); lines not read from the file will not count22towards the cumulative line count; the filename is not changed until23after 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 line27numbers are zero; nextfile() has no effect.  After all lines have been28read, filename() and the line number functions return the values29pertaining to the last line read; nextfile() has no effect.30 31All files are opened in text mode by default, you can override this by32setting the mode parameter to input() or FileInput.__init__().33If an I/O error occurs during opening or reading a file, the OSError34exception is raised.35 36If sys.stdin is used more than once, the second and further use will37return no lines, except perhaps for interactive use, or if it has been38explicitly reset (e.g. using sys.stdin.seek(0)).39 40Empty files are opened and immediately closed; the only time their41presence in the list of filenames is noticeable at all is when the42last file opened is empty.43 44It is possible that the last line of a file doesn't end in a newline45character; otherwise lines are returned including the trailing46newline.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 a51readline() method which returns the next input line, and a52__getitem__() method which implements the sequence behavior.  The53sequence must be accessed in strictly sequential order; sequence54access and readline() cannot be mixed.55 56Optional in-place filtering: if the keyword argument inplace=True is57passed to input() or to the FileInput constructor, the file is moved58to a backup file and standard output is directed to the input file.59This makes it possible to write a filter that rewrites its input file60in place.  If the keyword argument backup=".<some extension>" is also61given, it specifies the extension for the backup file, and the backup62file remains around; by default, the extension is ".bak" and it is63deleted when the output file is closed.  In-place filtering is64disabled when standard input is read.  XXX The current implementation65does not work for MS-DOS 8+3 filesystems.66"""67 68import io69import sys, os70from types import GenericAlias71 72__all__ = ["input", "close", "nextfile", "filename", "lineno", "filelineno",73           "fileno", "isfirstline", "isstdin", "FileInput", "hook_compressed",74           "hook_encoded"]75 76_state = None77 78def input(files=None, inplace=False, backup="", *, mode="r", openhook=None,79          encoding=None, errors=None):80    """Return an instance of the FileInput class, which can be iterated.81 82    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,.85    """86    global _state87    if _state and _state._file:88        raise RuntimeError("input() already active")89    _state = FileInput(files, inplace, backup, mode=mode, openhook=openhook,90                       encoding=encoding, errors=errors)91    return _state92 93def close():94    """Close the sequence."""95    global _state96    state = _state97    _state = None98    if state:99        state.close()100 101def nextfile():102    """103    Close the current file so that the next iteration will read the first104    line from the next file (if any); lines not read from the file will105    not count towards the cumulative line count. The filename is not106    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 the109    last file has been read, this function has no effect.110    """111    if not _state:112        raise RuntimeError("no active input()")113    return _state.nextfile()114 115def filename():116    """117    Return the name of the file currently being read.118    Before the first line has been read, returns None.119    """120    if not _state:121        raise RuntimeError("no active input()")122    return _state.filename()123 124def lineno():125    """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 line128    of the last file has been read, returns the line number of that line.129    """130    if not _state:131        raise RuntimeError("no active input()")132    return _state.lineno()133 134def filelineno():135    """136    Return the line number in the current file. Before the first line137    has been read, returns 0. After the last line of the last file has138    been read, returns the line number of that line within the file.139    """140    if not _state:141        raise RuntimeError("no active input()")142    return _state.filelineno()143 144def fileno():145    """146    Return the file number of the current file. When no file is currently147    opened, returns -1.148    """149    if not _state:150        raise RuntimeError("no active input()")151    return _state.fileno()152 153def isfirstline():154    """155    Returns true the line just read is the first line of its file,156    otherwise returns false.157    """158    if not _state:159        raise RuntimeError("no active input()")160    return _state.isfirstline()161 162def isstdin():163    """164    Returns true if the last line was read from sys.stdin,165    otherwise returns false.166    """167    if not _state:168        raise RuntimeError("no active input()")169    return _state.isstdin()170 171class FileInput:172    """FileInput([files[, inplace[, backup]]], *, mode=None, openhook=None)173 174    Class FileInput is the implementation of the module; its methods175    filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(),176    nextfile() and close() correspond to the functions of the same name177    in the module.178    In addition it has a readline() method which returns the next179    input line, and a __getitem__() method which implements the180    sequence behavior. The sequence must be accessed in strictly181    sequential order; random access and readline() cannot be mixed.182    """183 184    def __init__(self, files=None, inplace=False, backup="", *,185                 mode="r", openhook=None, encoding=None, errors=None):186        if isinstance(files, str):187            files = (files,)188        elif isinstance(files, os.PathLike):189            files = (os.fspath(files), )190        else:191            if files is None:192                files = sys.argv[1:]193            if not files:194                files = ('-',)195            else:196                files = tuple(files)197        self._files = files198        self._inplace = inplace199        self._backup = backup200        self._savestdout = None201        self._output = None202        self._filename = None203        self._startlineno = 0204        self._filelineno = 0205        self._file = None206        self._isstdin = False207        self._backupfilename = None208        self._encoding = encoding209        self._errors = errors210 211        # We can not use io.text_encoding() here because old openhook doesn't212        # take encoding parameter.213        if (sys.flags.warn_default_encoding and214                "b" not in mode and encoding is None and openhook is None):215            import warnings216            warnings.warn("'encoding' argument not specified.",217                          EncodingWarning, 2)218 219        # restrict mode argument to reading modes220        if mode not in ('r', 'rb'):221            raise ValueError("FileInput opening mode must be 'r' or 'rb'")222        self._mode = mode223        self._write_mode = mode.replace('r', 'w')224        if openhook:225            if inplace:226                raise ValueError("FileInput cannot use an opening hook in inplace mode")227            if not callable(openhook):228                raise ValueError("FileInput openhook must be callable")229        self._openhook = openhook230 231    def __del__(self):232        self.close()233 234    def close(self):235        try:236            self.nextfile()237        finally:238            self._files = ()239 240    def __enter__(self):241        return self242 243    def __exit__(self, type, value, traceback):244        self.close()245 246    def __iter__(self):247        return self248 249    def __next__(self):250        while True:251            line = self._readline()252            if line:253                self._filelineno += 1254                return line255            if not self._file:256                raise StopIteration257            self.nextfile()258            # repeat with next file259 260    def nextfile(self):261        savestdout = self._savestdout262        self._savestdout = None263        if savestdout:264            sys.stdout = savestdout265 266        output = self._output267        self._output = None268        try:269            if output:270                output.close()271        finally:272            file = self._file273            self._file = None274            try:275                del self._readline  # restore FileInput._readline276            except AttributeError:277                pass278            try:279                if file and not self._isstdin:280                    file.close()281            finally:282                backupfilename = self._backupfilename283                self._backupfilename = None284                if backupfilename and not self._backup:285                    try: os.unlink(backupfilename)286                    except OSError: pass287 288                self._isstdin = False289 290    def readline(self):291        while True:292            line = self._readline()293            if line:294                self._filelineno += 1295                return line296            if not self._file:297                return line298            self.nextfile()299            # repeat with next file300 301    def _readline(self):302        if not self._files:303            if 'b' in self._mode:304                return b''305            else:306                return ''307        self._filename = self._files[0]308        self._files = self._files[1:]309        self._startlineno = self.lineno()310        self._filelineno = 0311        self._file = None312        self._isstdin = False313        self._backupfilename = 0314 315        # EncodingWarning is emitted in __init__() already316        if "b" not in self._mode:317            encoding = self._encoding or "locale"318        else:319            encoding = None320 321        if self._filename == '-':322            self._filename = '<stdin>'323            if 'b' in self._mode:324                self._file = getattr(sys.stdin, 'buffer', sys.stdin)325            else:326                self._file = sys.stdin327            self._isstdin = True328        else:329            if self._inplace:330                self._backupfilename = (331                    os.fspath(self._filename) + (self._backup or ".bak"))332                try:333                    os.unlink(self._backupfilename)334                except OSError:335                    pass336                # The next few lines may raise OSError337                os.rename(self._filename, self._backupfilename)338                self._file = open(self._backupfilename, self._mode,339                                  encoding=encoding, errors=self._errors)340                try:341                    perm = os.fstat(self._file.fileno()).st_mode342                except OSError:343                    self._output = open(self._filename, self._write_mode,344                                        encoding=encoding, errors=self._errors)345                else:346                    mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC347                    if hasattr(os, 'O_BINARY'):348                        mode |= os.O_BINARY349 350                    fd = os.open(self._filename, mode, perm)351                    self._output = os.fdopen(fd, self._write_mode,352                                             encoding=encoding, errors=self._errors)353                    try:354                        os.chmod(self._filename, perm)355                    except OSError:356                        pass357                self._savestdout = sys.stdout358                sys.stdout = self._output359            else:360                # This may raise OSError361                if self._openhook:362                    # Custom hooks made previous to Python 3.10 didn't have363                    # encoding argument364                    if self._encoding is None:365                        self._file = self._openhook(self._filename, self._mode)366                    else:367                        self._file = self._openhook(368                            self._filename, self._mode, encoding=self._encoding, errors=self._errors)369                else:370                    self._file = open(self._filename, self._mode, encoding=encoding, errors=self._errors)371        self._readline = self._file.readline  # hide FileInput._readline372        return self._readline()373 374    def filename(self):375        return self._filename376 377    def lineno(self):378        return self._startlineno + self._filelineno379 380    def filelineno(self):381        return self._filelineno382 383    def fileno(self):384        if self._file:385            try:386                return self._file.fileno()387            except ValueError:388                return -1389        else:390            return -1391 392    def isfirstline(self):393        return self._filelineno == 1394 395    def isstdin(self):396        return self._isstdin397 398    __class_getitem__ = classmethod(GenericAlias)399 400 401def hook_compressed(filename, mode, *, encoding=None, errors=None):402    if encoding is None and "b" not in mode:  # EncodingWarning is emitted in FileInput() already.403        encoding = "locale"404    ext = os.path.splitext(filename)[1]405    if ext == '.gz':406        import gzip407        stream = gzip.open(filename, mode)408    elif ext == '.bz2':409        import bz2410        stream = bz2.BZ2File(filename, mode)411    else:412        return open(filename, mode, encoding=encoding, errors=errors)413 414    # gzip and bz2 are binary mode by default.415    if "b" not in mode:416        stream = io.TextIOWrapper(stream, encoding=encoding, errors=errors)417    return stream418 419 420def hook_encoded(encoding, errors=None):421    def openhook(filename, mode):422        return open(filename, mode, encoding=encoding, errors=errors)423    return openhook424 425 426def _test():427    import getopt428    inplace = False429    backup = False430    opts, args = getopt.getopt(sys.argv[1:], "ib:")431    for o, a in opts:432        if o == '-i': inplace = True433        if o == '-b': backup = a434    for line in input(args, inplace=inplace, backup=backup):435        if line[-1:] == '\n': line = line[:-1]436        if line[-1:] == '\r': line = line[:-1]437        print("%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(),438                                   isfirstline() and "*" or "", line))439    print("%d: %s[%d]" % (lineno(), filename(), filelineno()))440 441if __name__ == '__main__':442    _test()443 
codekingpro/portable-devtools · Team Ai