'Read at most size bytes from the file
(less if the read hits EOF before obtaining size bytes).
If the size argument is negative or omitted, read all data until EOF
is reached. The bytes are returned as a string object. An empty
string is returned when EOF is encountered immediately.'

def read(self, n=(-1)):

    _complain_ifclosed(self.closed)
    if self.buflist:
        self.buf += ''.join(self.buflist)
        self.buflist = []
    if ((n is None) or (n < 0)):
        newpos = self.len
    else:
        newpos = min((self.pos + n), self.len)
    r = self.buf[self.pos:newpos]
    self.pos = newpos
    return r
