in scripts/ValidateParameters/netaddr/ip/sets.py [0:0]
def symmetric_difference(self, other):
"""
:param other: an IP set.
:return: the symmetric difference of this IP set and another as a new
IP set (all IP addresses and subnets that are in exactly one
of the sets).
"""
# In contrast to intersection() and difference(), we cannot construct
# the result_cidrs easily. Some cidrs may have to be merged, e.g. for
# IPSet(["10.0.0.0/32"]).symmetric_difference(IPSet(["10.0.0.1/32"])).
result_ranges = []
own_nets = sorted(self._cidrs)
other_nets = sorted(other._cidrs)
own_idx = 0
other_idx = 0
own_len = len(own_nets)
other_len = len(other_nets)
while own_idx < own_len and other_idx < other_len:
own_cur = own_nets[own_idx]
other_cur = other_nets[other_idx]
if own_cur == other_cur:
own_idx += 1
other_idx += 1
elif own_cur in other_cur:
own_idx = _subtract(other_cur, own_nets, own_idx, result_ranges)
other_idx += 1
elif other_cur in own_cur:
other_idx = _subtract(own_cur, other_nets, other_idx, result_ranges)
own_idx += 1
else:
# own_cur and other_cur have nothing in common
if own_cur < other_cur:
result_ranges.append((own_cur._module.version,
own_cur.first, own_cur.last))
own_idx += 1
else:
result_ranges.append((other_cur._module.version,
other_cur.first, other_cur.last))
other_idx += 1
# If the above loop terminated because it processed all cidrs of
# "other", then any remaining cidrs in self must be part of the result.
while own_idx < own_len:
own_cur = own_nets[own_idx]
result_ranges.append((own_cur._module.version,
own_cur.first, own_cur.last))
own_idx += 1
# If the above loop terminated because it processed all cidrs of
# self, then any remaining cidrs in "other" must be part of the result.
while other_idx < other_len:
other_cur = other_nets[other_idx]
result_ranges.append((other_cur._module.version,
other_cur.first, other_cur.last))
other_idx += 1
result = IPSet()
for start, stop in _iter_merged_ranges(result_ranges):
cidrs = iprange_to_cidrs(start, stop)
for cidr in cidrs:
result._cidrs[cidr] = True
return result