def METHOD_NAME(address):  # noqa C901
    # if it looks to be an IPv6 address, make sure it is surrounded by square brackets
    if address.count(":") > 2 and re.match(r"^[a-f0-9\:]+$", address):
        address = "[{}]".format(address)
    # ensure that there's a scheme on the address
    if "://" not in address:
        address = "http://" + address
    # parse out the URL into its components. On python >= 3.11, this
    # will throw a ValueError on invalid IP addresses.
    try:
        parsed = urlparse(address)
    except ValueError as e:
        raise_from(errors.InvalidHostname(address), e)
    p_scheme = parsed.scheme
    p_hostname = parsed.hostname
    p_path = parsed.path.rstrip("/") + "/"
    # defaults to None
    if p_hostname is None:
        raise errors.InvalidHostname(p_hostname)
    try:
        p_port = parsed.port
        if not p_port:
            # since urlparse silently excludes some types of bad ports, check and throw ourselves
            split_by_colon = parsed.netloc.split("]")[-1].rsplit(":")
            if len(split_by_colon) > 1:
                extracted_port = split_by_colon[-1]
                raise errors.InvalidPort(extracted_port)
    except ValueError:
        raise errors.InvalidPort(parsed.netloc.rsplit(":")[-1])
    # perform basic validation on the URL components
    if p_scheme not in ("http", "https"):
        raise errors.InvalidScheme(p_scheme)
    if is_valid_ipv6_address(p_hostname):
        p_hostname = "[{}]".format(p_hostname)
    elif not (is_valid_hostname(p_hostname) or is_valid_ipv4_address(p_hostname)):
        raise errors.InvalidHostname(p_hostname)
    return p_scheme, p_hostname, p_port, p_path