Read at most `max_bytes` from internal buffer.

        Parameters
        -----------
        max_bytes: int
            Maximum number of bytes to read.

        Raises
        ------
        ValueError
            If read is called after close has been called.

        Returns
        --------
        bytes
            Bytes extracted from internal buffer.  Length may be less
            than `max_bytes`.  On end-of file returns a bytes object
            with zero-length.

def read(self, max_bytes=1):
        """Read at most `max_bytes` from internal buffer.

        Parameters
        -----------
        max_bytes: int
            Maximum number of bytes to read.

        Raises
        ------
        ValueError
            If read is called after close has been called.

        Returns
        --------
        bytes
            Bytes extracted from internal buffer.  Length may be less
            than `max_bytes`.  On end-of file returns a bytes object
            with zero-length.
        """
        if self.__num_bytes_consumed is None:
            raise ValueError('I/O operation on closed file.')

        if self.__num_bytes_consumed + max_bytes >= len(self.__buf):
            max_bytes = len(self.__buf) - self.__num_bytes_consumed

        b = self.__buf[self.__num_bytes_consumed:self.__num_bytes_consumed + max_bytes]
        self.__num_bytes_consumed += max_bytes

        if isinstance(b, bytearray):
            b = bytes(b)

        assert isinstance(b, bytes)
        return b