cpython: af4ae710daf3 (original) (raw)
--- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -214,8 +214,10 @@ def _count_righthand_zero_bits(number, b if number == 0: return bits for i in range(bits):
if (number >> i) % 2:[](#l1.7)
if (number >> i) & 1:[](#l1.8) return i[](#l1.9)
All bits of interest were zero, even if there are more in the number
- return bits
def summarize_address_range(first, last): @@ -263,20 +265,13 @@ def summarize_address_range(first, last) first_int = first._ip last_int = last._ip while first_int <= last_int:
nbits = _count_righthand_zero_bits(first_int, ip_bits)[](#l1.19)
current = None[](#l1.20)
while nbits >= 0:[](#l1.21)
addend = 2**nbits - 1[](#l1.22)
current = first_int + addend[](#l1.23)
nbits -= 1[](#l1.24)
if current <= last_int:[](#l1.25)
break[](#l1.26)
prefix = _get_prefix_length(first_int, current, ip_bits)[](#l1.27)
net = ip('%s/%d' % (first, prefix))[](#l1.28)
nbits = min(_count_righthand_zero_bits(first_int, ip_bits),[](#l1.29)
(last_int - first_int + 1).bit_length() - 1)[](#l1.30)
net = ip('%s/%d' % (first, ip_bits - nbits))[](#l1.31) yield net[](#l1.32)
if current == ip._ALL_ONES:[](#l1.33)
first_int += 1 << nbits[](#l1.34)
if first_int - 1 == ip._ALL_ONES:[](#l1.35) break[](#l1.36)
first_int = current + 1[](#l1.37) first = first.__class__(first_int)[](#l1.38)
@@ -304,26 +299,28 @@ def _collapse_addresses_recursive(addres passed. """
- for cur_addr in addresses:
if not ret_array:[](#l1.53)
ret_array.append(cur_addr)[](#l1.54)
continue[](#l1.55)
if (cur_addr.network_address >= ret_array[-1].network_address and[](#l1.56)
cur_addr.broadcast_address <= ret_array[-1].broadcast_address):[](#l1.57)
optimized = True[](#l1.58)
elif cur_addr == list(ret_array[-1].supernet().subnets())[1]:[](#l1.59)
ret_array.append(ret_array.pop().supernet())[](#l1.60)
optimized = True[](#l1.61)
else:[](#l1.62)
ret_array.append(cur_addr)[](#l1.63)
for cur_addr in addresses:[](#l1.64)
if not ret_array:[](#l1.65)
last_addr = cur_addr[](#l1.66)
ret_array.append(cur_addr)[](#l1.67)
elif (cur_addr.network_address >= last_addr.network_address and[](#l1.68)
cur_addr.broadcast_address <= last_addr.broadcast_address):[](#l1.69)
optimized = True[](#l1.70)
elif cur_addr == list(last_addr.supernet().subnets())[1]:[](#l1.71)
ret_array[-1] = last_addr = last_addr.supernet()[](#l1.72)
optimized = True[](#l1.73)
else:[](#l1.74)
last_addr = cur_addr[](#l1.75)
ret_array.append(cur_addr)[](#l1.76)
addresses = ret_array[](#l1.82)
if not optimized:[](#l1.83)
return addresses[](#l1.84)
def collapse_addresses(addresses): @@ -452,13 +449,7 @@ class _IPAddressBase: An integer, the prefix length. """
while mask:[](#l1.92)
if ip_int & 1 == 1:[](#l1.93)
break[](#l1.94)
ip_int >>= 1[](#l1.95)
mask -= 1[](#l1.96)
return mask[](#l1.98)
return mask - _count_righthand_zero_bits(ip_int, mask)[](#l1.99)
def _ip_string_from_prefix(self, prefixlen=None): """Turn a prefix length into a dotted decimal string. @@ -597,18 +588,16 @@ class _BaseNetwork(_IPAddressBase): or broadcast addresses. """
cur = int(self.network_address) + 1[](#l1.107)
bcast = int(self.broadcast_address) - 1[](#l1.108)
while cur <= bcast:[](#l1.109)
cur += 1[](#l1.110)
yield self._address_class(cur - 1)[](#l1.111)
network = int(self.network_address)[](#l1.112)
broadcast = int(self.broadcast_address)[](#l1.113)
for x in range(network + 1, broadcast):[](#l1.114)
yield self._address_class(x)[](#l1.115)
cur = int(self.network_address)[](#l1.118)
bcast = int(self.broadcast_address)[](#l1.119)
while cur <= bcast:[](#l1.120)
cur += 1[](#l1.121)
yield self._address_class(cur - 1)[](#l1.122)
network = int(self.network_address)[](#l1.123)
broadcast = int(self.broadcast_address)[](#l1.124)
for x in range(network, broadcast + 1):[](#l1.125)
yield self._address_class(x)[](#l1.126)
def getitem(self, n): network = int(self.network_address) @@ -998,7 +987,7 @@ class _BaseV4: _DECIMAL_DIGITS = frozenset('0123456789') # the valid octets for host and netmasks. only useful for IPv4.
def init(self, address): self._version = 4 @@ -1027,13 +1016,10 @@ class _BaseV4: if len(octets) != 4: raise AddressValueError("Expected 4 octets in %r" % ip_str)
packed_ip = 0[](#l1.143)
for oc in octets:[](#l1.144)
try:[](#l1.145)
packed_ip = (packed_ip << 8) | self._parse_octet(oc)[](#l1.146)
except ValueError as exc:[](#l1.147)
raise AddressValueError("%s in %r" % (exc, ip_str)) from None[](#l1.148)
return packed_ip[](#l1.149)
try:[](#l1.150)
return int.from_bytes(map(self._parse_octet, octets), 'big')[](#l1.151)
except ValueError as exc:[](#l1.152)
raise AddressValueError("%s in %r" % (exc, ip_str)) from None[](#l1.153)
def _parse_octet(self, octet_str): """Convert a decimal octet into an integer. @@ -1075,11 +1061,7 @@ class _BaseV4: The IP address as a string in dotted decimal notation. """
octets = [][](#l1.161)
for _ in range(4):[](#l1.162)
octets.insert(0, str(ip_int & 0xFF))[](#l1.163)
ip_int >>= 8[](#l1.164)
return '.'.join(octets)[](#l1.165)
return '.'.join(map(str, ip_int.to_bytes(4, 'big')))[](#l1.166)
def _is_valid_netmask(self, netmask): """Verify that the netmask is valid. @@ -1095,17 +1077,16 @@ class _BaseV4: """ mask = netmask.split('.') if len(mask) == 4:
for x in mask:[](#l1.174)
try:[](#l1.175)
if int(x) in self._valid_mask_octets:[](#l1.176)
continue[](#l1.177)
except ValueError:[](#l1.178)
pass[](#l1.179)
try:[](#l1.180)
for x in mask:[](#l1.181)
if int(x) not in self._valid_mask_octets:[](#l1.182)
return False[](#l1.183)
except ValueError:[](#l1.184) # Found something that isn't an integer or isn't valid[](#l1.185) return False[](#l1.186)
if [y for idx, y in enumerate(mask) if idx > 0 and[](#l1.187)
y > mask[idx - 1]]:[](#l1.188)
return False[](#l1.189)
for idx, y in enumerate(mask):[](#l1.190)
if idx > 0 and y > mask[idx - 1]:[](#l1.191)
return False[](#l1.192) return True[](#l1.193) try:[](#l1.194) netmask = int(netmask)[](#l1.195)
@@ -1125,7 +1106,7 @@ class _BaseV4: """ bits = ip_str.split('.') try:
parts = [int(x) for x in bits if int(x) in self._valid_mask_octets][](#l1.200)
parts = [x for x in map(int, bits) if x in self._valid_mask_octets][](#l1.201) except ValueError:[](#l1.202) return False[](#l1.203) if len(parts) != len(bits):[](#l1.204)
@@ -1526,14 +1507,14 @@ class _BaseV6: # Disregarding the endpoints, find '::' with nothing in between. # This indicates that a run of zeroes has been skipped.
try:[](#l1.209)
skip_index, = ([](#l1.210)
[i for i in range(1, len(parts) - 1) if not parts[i]] or[](#l1.211)
[None])[](#l1.212)
except ValueError:[](#l1.213)
# Can't have more than one '::'[](#l1.214)
msg = "At most one '::' permitted in %r" % ip_str[](#l1.215)
raise AddressValueError(msg) from None[](#l1.216)
skip_index = None[](#l1.217)
for i in range(1, len(parts) - 1):[](#l1.218)
if not parts[i]:[](#l1.219)
if skip_index is not None:[](#l1.220)
# Can't have more than one '::'[](#l1.221)
msg = "At most one '::' permitted in %r" % ip_str[](#l1.222)
raise AddressValueError(msg)[](#l1.223)
skip_index = i[](#l1.224)
# parts_hi is the number of parts to copy from above/before the '::' # parts_lo is the number of parts to copy from below/after the '::' @@ -1680,9 +1661,7 @@ class _BaseV6: raise ValueError('IPv6 address is too large') hex_str = '%032x' % ip_int
hextets = [][](#l1.232)
for x in range(0, 32, 4):[](#l1.233)
hextets.append('%x' % int(hex_str[x:x+4], 16))[](#l1.234)
hextets = ['%x' % int(hex_str[x:x+4], 16) for x in range(0, 32, 4)][](#l1.235)
hextets = self._compress_hextets(hextets) return ':'.join(hextets) @@ -1705,11 +1684,8 @@ class _BaseV6: ip_str = str(self) ip_int = self._ip_int_from_string(ip_str)
parts = [][](#l1.243)
for i in range(self._HEXTET_COUNT):[](#l1.244)
parts.append('%04x' % (ip_int & 0xFFFF))[](#l1.245)
ip_int >>= 16[](#l1.246)
parts.reverse()[](#l1.247)
hex_str = '%032x' % ip_int[](#l1.248)
parts = [hex_str[x:x+4] for x in range(0, 32, 4)][](#l1.249) if isinstance(self, (_BaseNetwork, IPv6Interface)):[](#l1.250) return '%s/%d' % (':'.join(parts), self.prefixlen)[](#l1.251) return ':'.join(parts)[](#l1.252)
@@ -1756,9 +1732,9 @@ class _BaseV6: IPv6Network('FE00::/9')] if isinstance(self, _BaseAddress):
return len([x for x in reserved_networks if self in x]) > 0[](#l1.257)
return len([x for x in reserved_networks if self.network_address in x[](#l1.258)
and self.broadcast_address in x]) > 0[](#l1.259)
return any(self in x for x in reserved_networks)[](#l1.260)
return any(self.network_address in x and self.broadcast_address in x[](#l1.261)
for x in reserved_networks)[](#l1.262)