def cidr_partition()

in scripts/ValidateParameters/netaddr/ip/__init__.py [0:0]


def cidr_partition(target, exclude):
    """
    Partitions a target IP subnet on an exclude IP address.

    :param target: the target IP address or subnet to be divided up.

    :param exclude: the IP address or subnet to partition on

    :return: list of `IPNetwork` objects before, the partition and after, sorted.

    Adding the three lists returns the equivalent of the original subnet.
    """

    target = IPNetwork(target)
    exclude = IPNetwork(exclude)

    if exclude.last < target.first:
        #   Exclude subnet's upper bound address less than target
        #   subnet's lower bound.
        return [], [], [target.cidr]
    elif target.last < exclude.first:
        #   Exclude subnet's lower bound address greater than target
        #   subnet's upper bound.
        return [target.cidr], [], []

    if target.prefixlen >= exclude.prefixlen:
        # Exclude contains the target
        return [], [target], []

    left = []
    right = []

    new_prefixlen = target.prefixlen + 1
    # Some @properties that are expensive to get and don't change below.
    target_module_width = target._module.width

    target_first = target.first
    version = exclude.version
    i_lower = target_first
    i_upper = target_first + (2 ** (target_module_width - new_prefixlen))

    while exclude.prefixlen >= new_prefixlen:
        if exclude.first >= i_upper:
            left.append(IPNetwork((i_lower, new_prefixlen), version=version))
            matched = i_upper
        else:
            right.append(IPNetwork((i_upper, new_prefixlen), version=version))
            matched = i_lower

        new_prefixlen += 1

        if new_prefixlen > target_module_width:
            break

        i_lower = matched
        i_upper = matched + (2 ** (target_module_width - new_prefixlen))

    return left, [exclude], right[::-1]