def readline(self, size=None):
<EOL>if self._closed:<EOL><INDENT>raise IOError('<STR_LIT>')<EOL><DEDENT>if not (self._flags & self.FLAG_READ):<EOL><INDENT>raise IOError('<STR_LIT>')<EOL><DEDENT>line = self._rbuffer<EOL>while True:<EOL><INDENT>if self._at_trailing_cr and (self._flags & self.FLAG_UNIVERSAL_NEWLINE) and (len(line) > <NUM_LIT:0>):<EOL><INDENT>if line[<NUM_LIT:0>] == '<STR_LIT:\n>':<EOL><INDENT>line = line[<NUM_LIT:1>:]<EOL>self._record_newline('<STR_LIT:\r\n>')<EOL><DEDENT>else:<EOL><INDENT>self._record_newline('<STR_LIT:\r>')<EOL><DEDENT>self._at_trailing_cr = False<EOL><DEDENT>if (size is not None) and (size >= <NUM_LIT:0>):<EOL><INDENT>if len(line) >= size:<EOL><INDENT>self._rbuffer = line[size:]<EOL>line = line[:size]<EOL>self._pos += len(line)<EOL>return line<EOL><DEDENT>n = size - len(line)<EOL><DEDENT>else:<EOL><INDENT>n = self._bufsize<EOL><DEDENT>if ('<STR_LIT:\n>' in line) or ((self._flags & self.FLAG_UNIVERSAL_NEWLINE) and ('<STR_LIT:\r>' in line)):<EOL><INDENT>break<EOL><DEDENT>try:<EOL><INDENT>new_data = self._read(n)<EOL><DEDENT>except EOFError:<EOL><INDENT>new_data = None<EOL><DEDENT>if (new_data is None) or (len(new_data) == <NUM_LIT:0>):<EOL><INDENT>self._rbuffer = '<STR_LIT>'<EOL>self._pos += len(line)<EOL>return line<EOL><DEDENT>line += new_data<EOL>self._realpos += len(new_data)<EOL><DEDENT>pos = line.find('<STR_LIT:\n>')<EOL>if self._flags & self.FLAG_UNIVERSAL_NEWLINE:<EOL><INDENT>rpos = line.find('<STR_LIT:\r>')<EOL>if (rpos >= <NUM_LIT:0>) and ((rpos < pos) or (pos < <NUM_LIT:0>)):<EOL><INDENT>pos = rpos<EOL><DEDENT><DEDENT>xpos = pos + <NUM_LIT:1><EOL>if (line[pos] == '<STR_LIT:\r>') and (xpos < len(line)) and (line[xpos] == '<STR_LIT:\n>'):<EOL><INDENT>xpos += <NUM_LIT:1><EOL><DEDENT>self._rbuffer = line[xpos:]<EOL>lf = line[pos:xpos]<EOL>line = line[:pos] + '<STR_LIT:\n>'<EOL>if (len(self._rbuffer) == <NUM_LIT:0>) and (lf == '<STR_LIT:\r>'):<EOL><INDENT>self._at_trailing_cr = True<EOL><DEDENT>else:<EOL><INDENT>self._record_newline(lf)<EOL><DEDENT>self._pos += len(line)<EOL>return line<EOL>
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 C{fgets()}, the returned string contains null
characters (C{'\\0'}) if they occurred in the input.

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