def replace_part(url, **kwargs):
    """
    Replace a part of the URL with a new value.

    Keyword arguments can be any properties of urllib.parse.ParseResult.
    """

    netloc_parts = ('username', 'password', 'hostname', 'port')

    for part, value in kwargs.items():
        if part in netloc_parts:
            # Reassemble netloc
            netloc = {
                p: getattr(url, p)
                for p in netloc_parts
            }

            netloc[part] = value

            netloc_str = netloc['hostname']

            if netloc['port']:
                netloc_str += ':' + str(netloc['port'])
            if netloc['username'] or netloc['password']:
                userinfo = netloc['username'] or ''
                if netloc['password']:
                    userinfo += ':' + netloc['password']
                netloc_str = userinfo + '@' + netloc_str

            kwargs = {'netloc': netloc_str}
        else:
            kwargs = {part: value}

        # pylint:disable=protected-access
        url = url._replace(**kwargs)

    return url