def read(self, num_bytes=None):
        # Reading past the file size results in a 416 (InvalidRange) error from
        # S3, but accessing the size when not using chunked reading causes an
        # unnecessary HEAD call.
        if self.start_range and self.start_range >= self.size:
            return self._empty_read()

        args = []

        if num_bytes:
            if self.start_range < 0:
                offset = self.size
            else:
                offset = 0
            args = [self.start_range + offset, self.start_range + num_bytes - 1 + offset]
        elif self.start_range:
            args = [self.start_range, '']

        try:
            data, etags, content_range = self._storage._read(self.name, *args)
        except S3Error as e:
            # Catch InvalidRange for 0 length reads. Perhaps we should be
            # catching all kinds of exceptions...
            if '<Code>InvalidRange</Code>' in '%s' % e:
                return self._empty_read()
            raise
        if content_range is not None:
            current_range, size = content_range.split(' ', 1)[1].split('/', 1)
            start_range, end_range = current_range.split('-', 1)
            self._size, self.start_range = int(size), int(end_range) + 1

        self.file = StringIO(data)
        return self.file.getvalue()
dataset/ETHPy150Open kylemacfarlane/django-cb-storage-s3/src/cuddlybuddly/storage/s3/storage.py/S3StorageFile.read/original