Read `num_bytes` and return them.

        Parameters
        ----------
        num_bytes : int
            Number of bytes to extract from the underlying stream.

        Raises
        ------
        UnderflowDecodeError
            Raised when a read failed to extract enough bytes from the
            underlying stream to extract the bytes.

        Returns
        -------
        bytes
            A bytes object extracted from underlying stream.

def read(self, num_bytes):
        """Read `num_bytes` and return them.

        Parameters
        ----------
        num_bytes : int
            Number of bytes to extract from the underlying stream.

        Raises
        ------
        UnderflowDecodeError
            Raised when a read failed to extract enough bytes from the
            underlying stream to extract the bytes.

        Returns
        -------
        bytes
            A bytes object extracted from underlying stream.
        """
        buf = self.__f.read(num_bytes)
        assert len(buf) <= num_bytes
        if len(buf) < num_bytes:
            raise UnderflowDecodeError()
        self.__num_bytes_consumed += num_bytes

        return buf