def readline(self, size=None):
        """
        Read one entire line from the file.  A trailing newline character is
        kept in the string (but may be absent when a file ends with an
        incomplete line).  If the size argument is present and non-negative, it
        is a maximum byte count (including the trailing newline) and an
        incomplete line may be returned.  An empty string is returned only when
        EOF is encountered immediately.

        .. note::
            Unlike stdio's ``fgets``, the returned string contains null
            characters (``'\\0'``) if they occurred in the input.

        :param int size: maximum length of returned string.
        :return:
            next line of the file, or an empty string if the end of the
            file has been reached.

            If the file was opened in binary (``'b'``) mode: bytes are returned
            Else: the encoding of the file is assumed to be UTF-8 and character
            strings (`str`) are returned
        """
        # it's almost silly how complex this function is.
        if self._closed:
            raise IOError('File is closed')
        if not (self._flags & self.FLAG_READ):
            raise IOError('File not open for reading')
        line = self._rbuffer
        while True:
            if self._at_trailing_cr and (self._flags & self.FLAG_UNIVERSAL_NEWLINE) and (len(line) > 0):
                # edge case: the newline may be '\r\n' and we may have read
                # only the first '\r' last time.
                if line[0] == linefeed_byte_value:
                    line = line[1:]
                    self._record_newline(crlf)
                else:
                    self._record_newline(cr_byte)
                self._at_trailing_cr = False
            # check size before looking for a linefeed, in case we already have
            # enough.
            if (size is not None) and (size >= 0):
                if len(line) >= size:
                    # truncate line and return
                    self._rbuffer = line[size:]
                    line = line[:size]
                    self._pos += len(line)
                    return line if self._flags & self.FLAG_BINARY else u(line)
                n = size - len(line)
            else:
                n = self._bufsize
            if (linefeed_byte in line) or ((self._flags & self.FLAG_UNIVERSAL_NEWLINE) and (cr_byte in line)):
                break
            try:
                new_data = self._read(n)
            except EOFError:
                new_data = None
            if (new_data is None) or (len(new_data) == 0):
                self._rbuffer = bytes()
                self._pos += len(line)
                return line if self._flags & self.FLAG_BINARY else u(line)
            line += new_data
            self._realpos += len(new_data)
        # find the newline
        pos = line.find(linefeed_byte)
        if self._flags & self.FLAG_UNIVERSAL_NEWLINE:
            rpos = line.find(cr_byte)
            if (rpos >= 0) and (rpos < pos or pos < 0):
                pos = rpos
        xpos = pos + 1
        if (line[pos] == cr_byte_value) and (xpos < len(line)) and (line[xpos] == linefeed_byte_value):
            xpos += 1
        self._rbuffer = line[xpos:]
        lf = line[pos:xpos]
        line = line[:pos] + linefeed_byte
        if (len(self._rbuffer) == 0) and (lf == cr_byte):
            # we could read the line up to a '\r' and there could still be a
            # '\n' following that we read next time.  note that and eat it.
            self._at_trailing_cr = True
        else:
            self._record_newline(lf)
        self._pos += len(line)
        return line if self._flags & self.FLAG_BINARY else u(line)
def readline ( self , size = None ) : if self . _closed : raise IOError ( 'File is closed' ) if not ( self . _flags & self . FLAG_READ ) : raise IOError ( 'File not open for reading' ) line = self . _rbuffer while True : if self . _at_trailing_cr and ( self . _flags & self . FLAG_UNIVERSAL_NEWLINE ) and ( len ( line ) > 0 ) : if line [ 0 ] == linefeed_byte_value : line = line [ 1 : ] self . _record_newline ( crlf ) else : self . _record_newline ( cr_byte ) self . _at_trailing_cr = False if ( size is not None ) and ( size >= 0 ) : if len ( line ) >= size : self . _rbuffer = line [ size : ] line = line [ : size ] self . _pos += len ( line ) return line if self . _flags & self . FLAG_BINARY else u ( line ) n = size - len ( line ) else : n = self . _bufsize if ( linefeed_byte in line ) or ( ( self . _flags & self . FLAG_UNIVERSAL_NEWLINE ) and ( cr_byte in line ) ) : break try : new_data = self . _read ( n ) except EOFError : new_data = None if ( new_data is None ) or ( len ( new_data ) == 0 ) : self . _rbuffer = bytes ( ) self . _pos += len ( line ) return line if self . _flags & self . FLAG_BINARY else u ( line ) line += new_data self . _realpos += len ( new_data ) pos = line . find ( linefeed_byte ) if self . _flags & self . FLAG_UNIVERSAL_NEWLINE : rpos = line . find ( cr_byte ) if ( rpos >= 0 ) and ( rpos < pos or pos < 0 ) : pos = rpos xpos = pos + 1 if ( line [ pos ] == cr_byte_value ) and ( xpos < len ( line ) ) and ( line [ xpos ] == linefeed_byte_value ) : xpos += 1 self . _rbuffer = line [ xpos : ] lf = line [ pos : xpos ] line = line [ : pos ] + linefeed_byte if ( len ( self . _rbuffer ) == 0 ) and ( lf == cr_byte ) : self . _at_trailing_cr = True else : self . _record_newline ( lf ) self . _pos += len ( line ) return line if self . _flags & self . FLAG_BINARY else u ( line )
Read one entire line from the file.  A trailing newline character is
        kept in the string (but may be absent when a file ends with an
        incomplete line).  If the size argument is present and non-negative, it
        is a maximum byte count (including the trailing newline) and an
        incomplete line may be returned.  An empty string is returned only when
        EOF is encountered immediately.

        .. note::
            Unlike stdio's ``fgets``, the returned string contains null
            characters (``'\\0'``) if they occurred in the input.

        :param int size: maximum length of returned string.
        :return:
            next line of the file, or an empty string if the end of the
            file has been reached.

            If the file was opened in binary (``'b'``) mode: bytes are returned
            Else: the encoding of the file is assumed to be UTF-8 and character
            strings (`str`) are returned