def _is_valid_ip(self, ip_str):
        # We need to have at least one ':'.
        if ':' not in ip_str:
            return False

        # We can only have one '::' shortener.
        if ip_str.count('::') > 1:
            return False

        # '::' should be encompassed by start, digits or end.
        if ':::' in ip_str:
            return False

        # A single colon can neither start nor end an address.
        if ((ip_str.startswith(':') and not ip_str.startswith('::')) or
                (ip_str.endswith(':') and not ip_str.endswith('::'))):
            return False

        # If we have no concatenation, we need to have 8 fields with 7 ':'.
        if '::' not in ip_str and ip_str.count(':') != 7:
            # We might have an IPv4 mapped address.
            if ip_str.count('.') != 3:
                return False

        ip_str = self._explode_shorthand_ip_string(ip_str)

        # Now that we have that all squared away, let's check that each of the
        # hextets are between 0x0 and 0xFFFF.
        for hextet in ip_str.split(':'):
            if hextet.count('.') == 3:
                # If we have an IPv4 mapped address, the IPv4 portion has to
                # be at the end of the IPv6 portion.
                if not ip_str.split(':')[-1] == hextet:
                    return False
                try:
                    IPv4Network(hextet)
                except AddressValueError:
                    return False
            else:
                try:
                    # a value error here means that we got a bad hextet,
                    # something like 0xzzzz
                    if int(hextet, 16) < 0x0 or int(hextet, 16) > 0xFFFF:
                        return False
                except ValueError:
                    return False
        return True
Ensure we have a valid IPv6 address.
dataset/ETHPy150Open anandology/pyjamas/pyjs/src/pyjs/lib/ipaddr.py/_BaseV6._is_valid_ip