Parse address and returns host and port

    Args:
        str_addr --- string that contains server ip or hostname and optionaly
        port

    Returns: tuple (host, port)

    Examples:

    >>> parse_server_addr('127.0.0.1:26006')
    ('127.0.0.1', 26006)
    >>> parse_server_addr('[2001:db8:85a3:8d3:1319:8a2e:370:7348]:26006')
    ('2001:db8:85a3:8d3:1319:8a2e:370:7348', 26006)
    >>> parse_server_addr('[2001:db8:85a3:8d3:1319:8a2e:370:7348]')
    ('2001:db8:85a3:8d3:1319:8a2e:370:7348', 26000)
    >>> parse_server_addr('localhost:123')
    ('localhost', 123)
    >>> parse_server_addr('localhost:1d23')
    Traceback (most recent call last):
        ...
    ValueError: Bad address string "localhost:1d23"

def parse_server_addr(str_addr, default_port=26000):
    """Parse address and returns host and port

    Args:
        str_addr --- string that contains server ip or hostname and optionaly
        port

    Returns: tuple (host, port)

    Examples:

    >>> parse_server_addr('127.0.0.1:26006')
    ('127.0.0.1', 26006)
    >>> parse_server_addr('[2001:db8:85a3:8d3:1319:8a2e:370:7348]:26006')
    ('2001:db8:85a3:8d3:1319:8a2e:370:7348', 26006)
    >>> parse_server_addr('[2001:db8:85a3:8d3:1319:8a2e:370:7348]')
    ('2001:db8:85a3:8d3:1319:8a2e:370:7348', 26000)
    >>> parse_server_addr('localhost:123')
    ('localhost', 123)
    >>> parse_server_addr('localhost:1d23')
    Traceback (most recent call last):
        ...
    ValueError: Bad address string "localhost:1d23"
    """
    m = ADDR_STR_RE.match(str_addr)
    if m is None:
        raise ValueError('Bad address string "{0}"'.format(str_addr))

    dct = m.groupdict()
    port = dct.get('port')
    if port is None:
        port = default_port
    else:
        port = int(port)  # Caution: could raise ValueEror or TypeError

    if port == 0:
        raise ValueError("Port can't be zero")

    host = dct['host'] if dct['host'] else dct['host6']
    return host, port