(self)
Read and return a single logical line from the current file (or
           from an internal buffer if lines have previously been "unread"
           with 'unreadline()').  If the 'join_lines' option is true, this
           may involve reading multiple physical lines concatenated into a
           single string.  Updates the current line number, so calling
           'warn()' after 'readline()' emits a warning about the physical
           line(s) just read.  Returns None on end-of-file, since the empty
           string can occur if 'rstrip_ws' is true but 'strip_blanks' is
           not.
Read and return a single logical line from the current file (or
           from an internal buffer if lines have previously been "unread"
           with 'unreadline()').  If the 'join_lines' option is true, this
           may involve reading multiple physical lines concatenated into a
           single string.  Updates the current line number, so calling
           'warn()' after 'readline()' emits a warning about the physical
           line(s) just read.  Returns None on end-of-file, since the empty
           string can occur if 'rstrip_ws' is true but 'strip_blanks' is
           not.
Read and return a single logical line from the current file ( or from an internal buffer if lines have previously been unread with unreadline () ) . If the join_lines option is true this may involve reading multiple physical lines concatenated into a single string . Updates the current line number so calling warn () after readline () emits a warning about the physical line ( s ) just read . Returns None on end - of - file since the empty string can occur if rstrip_ws is true but strip_blanks is not .
def readline(self):
        """Read and return a single logical line from the current file (or
           from an internal buffer if lines have previously been "unread"
           with 'unreadline()').  If the 'join_lines' option is true, this
           may involve reading multiple physical lines concatenated into a
           single string.  Updates the current line number, so calling
           'warn()' after 'readline()' emits a warning about the physical
           line(s) just read.  Returns None on end-of-file, since the empty
           string can occur if 'rstrip_ws' is true but 'strip_blanks' is
           not."""
        # If any "unread" lines waiting in 'linebuf', return the top
        # one.  (We don't actually buffer read-ahead data -- lines only
        # get put in 'linebuf' if the client explicitly does an
        # 'unreadline()'.
        if self.linebuf:
            line = self.linebuf[-1]
            del self.linebuf[-1]
            return line

        buildup_line = ''

        while True:
            # read the line, make it None if EOF
            line = self.file.readline()
            if line == '':
                line = None

            if self.strip_comments and line:

                # Look for the first "#" in the line.  If none, never
                # mind.  If we find one and it's the first character, or
                # is not preceded by "\", then it starts a comment --
                # strip the comment, strip whitespace before it, and
                # carry on.  Otherwise, it's just an escaped "#", so
                # unescape it (and any other escaped "#"'s that might be
                # lurking in there) and otherwise leave the line alone.

                pos = line.find("#")
                if pos == -1: # no "#" -- no comments
                    pass

                # It's definitely a comment -- either "#" is the first
                # character, or it's elsewhere and unescaped.
                elif pos == 0 or line[pos-1] != "\\":
                    # Have to preserve the trailing newline, because it's
                    # the job of a later step (rstrip_ws) to remove it --
                    # and if rstrip_ws is false, we'd better preserve it!
                    # (NB. this means that if the final line is all comment
                    # and has no trailing newline, we will think that it's
                    # EOF; I think that's OK.)
                    eol = (line[-1] == '\n') and '\n' or ''
                    line = line[0:pos] + eol

                    # If all that's left is whitespace, then skip line
                    # *now*, before we try to join it to 'buildup_line' --
                    # that way constructs like
                    #   hello \\
                    #   # comment that should be ignored
                    #   there
                    # result in "hello there".
                    if line.strip() == "":
                        continue
                else: # it's an escaped "#"
                    line = line.replace("\\#", "#")

            # did previous line end with a backslash? then accumulate
            if self.join_lines and buildup_line:
                # oops: end of file
                if line is None:
                    self.warn("continuation line immediately precedes "
                              "end-of-file")
                    return buildup_line

                if self.collapse_join:
                    line = line.lstrip()
                line = buildup_line + line

                # careful: pay attention to line number when incrementing it
                if isinstance(self.current_line, list):
                    self.current_line[1] = self.current_line[1] + 1
                else:
                    self.current_line = [self.current_line,
                                         self.current_line + 1]
            # just an ordinary line, read it as usual
            else:
                if line is None: # eof
                    return None

                # still have to be careful about incrementing the line number!
                if isinstance(self.current_line, list):
                    self.current_line = self.current_line[1] + 1
                else:
                    self.current_line = self.current_line + 1

            # strip whitespace however the client wants (leading and
            # trailing, or one or the other, or neither)
            if self.lstrip_ws and self.rstrip_ws:
                line = line.strip()
            elif self.lstrip_ws:
                line = line.lstrip()
            elif self.rstrip_ws:
                line = line.rstrip()

            # blank line (whether we rstrip'ed or not)? skip to next line
            # if appropriate
            if (line == '' or line == '\n') and self.skip_blanks:
                continue

            if self.join_lines:
                if line[-1] == '\\':
                    buildup_line = line[:-1]
                    continue

                if line[-2:] == '\\\n':
                    buildup_line = line[0:-2] + '\n'
                    continue

            # well, I guess there's some actual content there: return it
            return line
def readline ( self ) : # If any "unread" lines waiting in 'linebuf', return the top # one.  (We don't actually buffer read-ahead data -- lines only # get put in 'linebuf' if the client explicitly does an # 'unreadline()'. if self . linebuf : line = self . linebuf [ - 1 ] del self . linebuf [ - 1 ] return line buildup_line = '' while True : # read the line, make it None if EOF line = self . file . readline ( ) if line == '' : line = None if self . strip_comments and line : # Look for the first "#" in the line.  If none, never # mind.  If we find one and it's the first character, or # is not preceded by "\", then it starts a comment -- # strip the comment, strip whitespace before it, and # carry on.  Otherwise, it's just an escaped "#", so # unescape it (and any other escaped "#"'s that might be # lurking in there) and otherwise leave the line alone. pos = line . find ( "#" ) if pos == - 1 : # no "#" -- no comments pass # It's definitely a comment -- either "#" is the first # character, or it's elsewhere and unescaped. elif pos == 0 or line [ pos - 1 ] != "\\" : # Have to preserve the trailing newline, because it's # the job of a later step (rstrip_ws) to remove it -- # and if rstrip_ws is false, we'd better preserve it! # (NB. this means that if the final line is all comment # and has no trailing newline, we will think that it's # EOF; I think that's OK.) eol = ( line [ - 1 ] == '\n' ) and '\n' or '' line = line [ 0 : pos ] + eol # If all that's left is whitespace, then skip line # *now*, before we try to join it to 'buildup_line' -- # that way constructs like #   hello \\ #   # comment that should be ignored #   there # result in "hello there". if line . strip ( ) == "" : continue else : # it's an escaped "#" line = line . replace ( "\\#" , "#" ) # did previous line end with a backslash? then accumulate if self . join_lines and buildup_line : # oops: end of file if line is None : self . warn ( "continuation line immediately precedes " "end-of-file" ) return buildup_line if self . collapse_join : line = line . lstrip ( ) line = buildup_line + line # careful: pay attention to line number when incrementing it if isinstance ( self . current_line , list ) : self . current_line [ 1 ] = self . current_line [ 1 ] + 1 else : self . current_line = [ self . current_line , self . current_line + 1 ] # just an ordinary line, read it as usual else : if line is None : # eof return None # still have to be careful about incrementing the line number! if isinstance ( self . current_line , list ) : self . current_line = self . current_line [ 1 ] + 1 else : self . current_line = self . current_line + 1 # strip whitespace however the client wants (leading and # trailing, or one or the other, or neither) if self . lstrip_ws and self . rstrip_ws : line = line . strip ( ) elif self . lstrip_ws : line = line . lstrip ( ) elif self . rstrip_ws : line = line . rstrip ( ) # blank line (whether we rstrip'ed or not)? skip to next line # if appropriate if ( line == '' or line == '\n' ) and self . skip_blanks : continue if self . join_lines : if line [ - 1 ] == '\\' : buildup_line = line [ : - 1 ] continue if line [ - 2 : ] == '\\\n' : buildup_line = line [ 0 : - 2 ] + '\n' continue # well, I guess there's some actual content there: return it return line