def read(self, size=None):
        """ Read a specified number of bytes from the file descriptor

        This method emulates the normal file descriptor's ``read()`` method and
        restricts the total number of bytes readable.

        If file descriptor is not present (e.g., ``close()`` method had been
        called), ``ValueError`` is raised.

        If ``size`` is omitted, or ``None``, or any other falsy value, read
        will be done up to the remaining length (constructor's ``length``
        argument minus the bytes that have been read previously).

        This method internally invokes the file descriptor's ``read()`` method,
        and the method must accept a single integer positional argument.
        """
        if not self.fd:
            raise ValueError('I/O on closed file')
        if not size:
            size = self.remaining
        size = min([self.remaining, size])
        if not size:
            return ''
        data = self.fd.read(size)
        self.remaining -= size
        return data
Read a specified number of bytes from the file descriptor

        This method emulates the normal file descriptor's ``read()`` method and
        restricts the total number of bytes readable.

        If file descriptor is not present (e.g., ``close()`` method had been
        called), ``ValueError`` is raised.

        If ``size`` is omitted, or ``None``, or any other falsy value, read
        will be done up to the remaining length (constructor's ``length``
        argument minus the bytes that have been read previously).

        This method internally invokes the file descriptor's ``read()`` method,
        and the method must accept a single integer positional argument.