summaryrefslogtreecommitdiffstats
path: root/Lib/ipaddress.py
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2014-05-15 18:21:48 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2014-05-15 18:21:48 (GMT)
commit824db30b3eecc07062925a697e39485158a429a8 (patch)
tree7b38893b2bf9546955a4d77b6da213c5ba2002d3 /Lib/ipaddress.py
parent45aba189c6293deda04a1776aa95207435f959c6 (diff)
downloadcpython-824db30b3eecc07062925a697e39485158a429a8.zip
cpython-824db30b3eecc07062925a697e39485158a429a8.tar.gz
cpython-824db30b3eecc07062925a697e39485158a429a8.tar.bz2
Issue #21487: Optimize ipaddress.summarize_address_range() and ipaddress.{IPv4Network,IPv6Network}.subnets().
Diffstat (limited to 'Lib/ipaddress.py')
-rw-r--r--Lib/ipaddress.py28
1 files changed, 7 insertions, 21 deletions
diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py
index 426ca53..b54e136 100644
--- a/Lib/ipaddress.py
+++ b/Lib/ipaddress.py
@@ -195,11 +195,7 @@ def _count_righthand_zero_bits(number, bits):
"""
if number == 0:
return bits
- for i in range(bits):
- if (number >> i) & 1:
- return i
- # All bits of interest were zero, even if there are more in the number
- return bits
+ return min(bits, (~number & (number-1)).bit_length())
def summarize_address_range(first, last):
@@ -250,12 +246,11 @@ def summarize_address_range(first, last):
while first_int <= last_int:
nbits = min(_count_righthand_zero_bits(first_int, ip_bits),
(last_int - first_int + 1).bit_length() - 1)
- net = ip('%s/%d' % (first, ip_bits - nbits))
+ net = ip((first_int, ip_bits - nbits))
yield net
first_int += 1 << nbits
if first_int - 1 == ip._ALL_ONES:
break
- first = first.__class__(first_int)
def _collapse_addresses_recursive(addresses):
@@ -949,20 +944,11 @@ class _BaseNetwork(_IPAddressBase):
'prefix length diff %d is invalid for netblock %s' % (
new_prefixlen, self))
- first = self.__class__('%s/%s' %
- (self.network_address,
- self._prefixlen + prefixlen_diff))
-
- yield first
- current = first
- while True:
- broadcast = current.broadcast_address
- if broadcast == self.broadcast_address:
- return
- new_addr = self._address_class(int(broadcast) + 1)
- current = self.__class__('%s/%s' % (new_addr,
- new_prefixlen))
-
+ start = int(self.network_address)
+ end = int(self.broadcast_address)
+ step = (int(self.hostmask) + 1) >> prefixlen_diff
+ for new_addr in range(start, end, step):
+ current = self.__class__((new_addr, new_prefixlen))
yield current
def supernet(self, prefixlen_diff=1, new_prefix=None):