<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def download(self, url, listener=None, path_or_fd=None, chunk_size_bytes=None, timeout_secs=None):
 """Downloads data from the given URL. By default data is downloaded to a temporary file. :param string url: the url to GET data from :param listener: an optional listener to notify of all download lifecycle events :param path_or_fd: an optional file path or open file descriptor to write data to :param chunk_size_bytes: the chunk size to use for buffering data :param timeout_secs: the maximum time to wait for data to be available :returns: the path to the file data was downloaded to. :raises: Fetcher.Error if there was a problem downloading all data from the given url. """

    @contextmanager
    def download_fp(_path_or_fd):
      if _path_or_fd and not isinstance(_path_or_fd, six.string_types):
        yield _path_or_fd, _path_or_fd.name
      else:
        if not _path_or_fd:
          fd, _path_or_fd = tempfile.mkstemp()
          os.close(fd)
        with safe_open(_path_or_fd, 'wb') as fp:
          yield fp, _path_or_fd

    with download_fp(path_or_fd) as (fp, path):
      listener = self.DownloadListener(fp).wrap(listener)
      self.fetch(url, listener, chunk_size_bytes=chunk_size_bytes, timeout_secs=timeout_secs)
      return path