def split_host_port(host_port):
    """Return a tuple containing (host, port) of a string possibly
    containing both.  If there is no port in host_port, the port
    will be None.

    Supports the following:
    - hostnames
    - ipv4 addresses
    - ipv6 addresses
    with or without ports.  There is no validation of either the
    host or port.

    """
    colon_count = host_port.count(':')
    if colon_count == 0:
        # hostname or ipv4 address without port
        return host_port, None
    elif colon_count == 1:
        # hostname or ipv4 address with port
        return host_port.split(':', 1)
    elif colon_count >= 2:
        # ipv6 address, must be bracketed if it has a port at the end, i.e. [ADDR]:PORT
        if ']:' in host_port:
            host, port = host_port.split(']:', 1)
            if host[0] == '[':
                # for valid addresses, should always be true
                host = host[1:]
            return host, port
        else:
            # no port; may still be bracketed
            host = host_port
            if host[0] == '[':
                host = host[1:]
            if host[-1] == ']':
                host = host[:-1]
            return host, None