def fetch(url_fetcher, url):
    """Call an url_fetcher, fill in optional data, and clean up."""
    try:
        result = url_fetcher(url)
    except Exception as exception:
        raise URLFetchingError(f'{type(exception).__name__}: {exception}')
    result.setdefault('redirected_url', url)
    result.setdefault('mime_type', None)
    if 'file_obj' in result:
        try:
            yield result
        finally:
            try:
                result['file_obj'].close()
            except Exception:  # pragma: no cover
                # May already be closed or something.
                # This is just cleanup anyway: log but make it non-fatal.
                LOGGER.warning(
                    'Error when closing stream for %s:\n%s',
                    url, traceback.format_exc())
    else:
        yield result
Call an url_fetcher, fill in optional data, and clean up.
weasyprint/urls.py