'read([size]) -> read at most size bytes, returned as a bytes string.
If the size argument is negative or omitted, read until EOF is reached.
Notice that when in non-blocking mode, less data than what was
requested may be returned, even if no size parameter was given.'

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

    if self.closed:
        raise ValueError('I/O    operation    on    closed    file')
    if (size < 0):
        return ''.join(self)
    elif (not size):
        chunk = ''
    elif self.buf:
        chunk = self.buf
        self.buf = None
    else:
        try:
            chunk = next(self.iterator)
        except StopIteration:
            return ''
    if (len(chunk) > size):
        self.buf = chunk[size:]
        chunk = chunk[:size]
    return chunk
