# Buggy code
def download(self, custom_path=None, out=None, timeout=None):
    """
    Download this file. By default, the file is saved in the current working directory with its
    original filename as reported by Telegram. If a ``custom_path`` is supplied, it will be
    saved to that path instead. If ``out`` is defined, the file contents will be saved to that
    object using the ``out.write`` method. ``custom_path`` and ``out`` are mutually exclusive.

    Args:
        custom_path (Optional[str]): Custom path.
        out (Optional[object]): A file-like object. Must be opened in binary mode, if
            applicable.
        timeout (Optional[int|float]): If this value is specified, use it as the read timeout
            from the server (instead of the one specified during creation of the connection
            pool).

    Raises:
        ValueError: If both ``custom_path`` and ``out`` are passed.

    """

    if custom_path is not None and out is not None:
        raise ValueError("custom_path and out are mutually exclusive")

    url = self.file_path

    if out:
        buf = self.bot.request.retrieve(url)
        out.write(buf)

    else:
        if custom_path:
            filename = custom_path
        else:
            filename = basename(url)

        self.bot.request.download(url, filename, timeout=timeout)


# Traceback (UnicodeEncodeError)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/telegram/file.py", line 106, in download
self.bot.request.download(url, filename, timeout=timeout)
File "/usr/local/lib/python3.6/site-packages/telegram/utils/request.py", line 284, in download
buf = self.retrieve(url, timeout=timeout)
File "/usr/local/lib/python3.6/site-packages/telegram/utils/request.py", line 270, in retrieve
return self._request_wrapper('GET', url, **urlopen_kwargs)
File "/usr/local/lib/python3.6/site-packages/telegram/utils/request.py", line 174, in _request_wrapper
resp = self._con_pool.request(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/telegram/vendor/ptb_urllib3/urllib3/request.py", line 66, in request
**urlopen_kw)
File "/usr/local/lib/python3.6/site-packages/telegram/vendor/ptb_urllib3/urllib3/request.py", line 87, in request_encode_url
return self.urlopen(method, url, **extra_kw)
File "/usr/local/lib/python3.6/site-packages/telegram/vendor/ptb_urllib3/urllib3/poolmanager.py", line 244, in urlopen
response = conn.urlopen(method, u.request_uri, **kw)
File "/usr/local/lib/python3.6/site-packages/telegram/vendor/ptb_urllib3/urllib3/connectionpool.py", line 617, in urlopen
chunked=chunked)
File "/usr/local/lib/python3.6/site-packages/telegram/vendor/ptb_urllib3/urllib3/connectionpool.py", line 390, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1239, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1250, in _send_request
self.putrequest(method, url, **skips)
File "/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1117, in putrequest
self._output(request.encode('ascii'))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 69-75: ordinal not in range(128)
'ascii' codec can't encode characters in position 69-75: ordinal not in range(128)

# Fixed code
def download(self, custom_path=None, out=None, timeout=None):
    """
    Download this file. By default, the file is saved in the current working directory with its
    original filename as reported by Telegram. If a ``custom_path`` is supplied, it will be
    saved to that path instead. If ``out`` is defined, the file contents will be saved to that
    object using the ``out.write`` method. ``custom_path`` and ``out`` are mutually exclusive.

    Args:
        custom_path (Optional[str]): Custom path.
        out (Optional[object]): A file-like object. Must be opened in binary mode, if
            applicable.
        timeout (Optional[int|float]): If this value is specified, use it as the read timeout
            from the server (instead of the one specified during creation of the connection
            pool).

    Raises:
        ValueError: If both ``custom_path`` and ``out`` are passed.

    """

    if custom_path is not None and out is not None:
        raise ValueError("custom_path and out are mutually exclusive")

    # Convert any UTF-8 char into a url encoded ASCII string.
    sres = urllib_parse.urlsplit(self.file_path)
    url = urllib_parse.urlunsplit(
        urllib_parse.SplitResult(
            sres.scheme,
            sres.netloc,
            urllib_parse.quote(sres.path),
            sres.query,
            sres.fragment,
        )
    )

    if out:
        buf = self.bot.request.retrieve(url)
        out.write(buf)

    else:
        if custom_path:
            filename = custom_path
        else:
            filename = basename(self.file_path)

        self.bot.request.download(url, filename, timeout=timeout)