import ipaddress


def calc_prefix(arg, addresses):
    """Calculates the prefix for the list of addresses.
    
    Creates the prefix from arg if one is supplied, otherwise computes the prefix
    from the addresses.
    """
    
    # This can throw an exception if they supplied an invalid netmask.
    if arg:
        return(ipaddress.ip_network(arg))

    # Should be at least one address present or we return nothing.
    if not addresses:
        return None
    
    v4max = int(ipaddress.IPv4Network('0.0.0.0/0').hostmask)
    v6max = int(ipaddress.IPv6Network('::/0').hostmask)
    v6bitsonly = v4max ^ v6max
    
    # Prefix should be the same for both the ORed and ANDed values.
    ival = int(addresses[0])
    ored = ival
    if ival <= v4max:
        ival |= v6bitsonly
    anded = ival
    for address in addresses[1:]:
        ival = int(address)
        ored |= ival
        if ival <= v4max:
            ival |= v6bitsonly
        anded &= ival
        
    if ored > v4max:
        all_bits = v6max
        n_bits = 128
    else:
        all_bits = v4max
        n_bits = 32
        
    i = 0
    low_bits = 2**i - 1
    mask = low_bits ^ all_bits
    while low_bits <= ored:
        if (anded & mask) == (ored & mask):
            break
        i += 1
        low_bits = 2**i - 1
        mask = low_bits ^ all_bits
    
    return ipaddress.ip_network(((anded & mask), (n_bits - i)))