Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b53f0fb

Browse files
Issue #23266: Restore the performance of ipaddress.collapse_addresses() whith
duplicated addresses and simplify the code.
1 parent 1202a47 commit b53f0fb

2 files changed

Lines changed: 25 additions & 25 deletions

File tree

Lib/ipaddress.py

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -164,25 +164,23 @@ def _split_optional_netmask(address):
164164

165165

166166
def _find_address_range(addresses):
167-
"""Find a sequence of IPv#Address.
167+
"""Find a sequence of sorted deduplicated IPv#Address.
168168
169169
Args:
170170
addresses: a list of IPv#Address objects.
171171
172-
Returns:
173-
A tuple containing the first and last IP addresses in the sequence,
174-
and the number of distinct IP addresses in the sequence.
172+
Yields:
173+
A tuple containing the first and last IP addresses in the sequence.
175174
176175
"""
177-
first = last = addresses[0]
178-
i = 1
179-
for ip in addresses[1:]:
180-
if ip._ip == last._ip + 1:
181-
last = ip
182-
i += 1
183-
else:
184-
break
185-
return (first, last, i)
176+
it = iter(addresses)
177+
first = last = next(it)
178+
for ip in it:
179+
if ip._ip != last._ip + 1:
180+
yield first, last
181+
first = ip
182+
last = ip
183+
yield first, last
186184

187185

188186
def _count_righthand_zero_bits(number, bits):
@@ -323,7 +321,6 @@ def collapse_addresses(addresses):
323321
TypeError: If passed a list of mixed version objects.
324322
325323
"""
326-
i = 0
327324
addrs = []
328325
ips = []
329326
nets = []
@@ -349,14 +346,13 @@ def collapse_addresses(addresses):
349346
ip, nets[-1]))
350347
nets.append(ip)
351348

352-
# sort
353-
ips = sorted(ips)
349+
# sort and dedup
350+
ips = sorted(set(ips))
354351

355352
# find consecutive address ranges in the sorted sequence and summarize them
356-
while i < len(ips):
357-
(first, last, items) = _find_address_range(ips[i:])
358-
i = items + i
359-
addrs.extend(summarize_address_range(first, last))
353+
if ips:
354+
for first, last in _find_address_range(ips):
355+
addrs.extend(summarize_address_range(first, last))
360356

361357
return _collapse_addresses_internal(addrs + nets)
362358

Lib/test/test_ipaddress.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -790,11 +790,15 @@ def testInvalidIntToBytes(self):
790790
2 ** ipaddress.IPV6LENGTH)
791791

792792
def testInternals(self):
793-
first, last, nitems = ipaddress._find_address_range([
794-
ipaddress.IPv4Address('10.10.10.10'),
795-
ipaddress.IPv4Address('10.10.10.12')])
796-
self.assertEqual(first, last)
797-
self.assertEqual(nitems, 1)
793+
ip1 = ipaddress.IPv4Address('10.10.10.10')
794+
ip2 = ipaddress.IPv4Address('10.10.10.11')
795+
ip3 = ipaddress.IPv4Address('10.10.10.12')
796+
self.assertEqual(list(ipaddress._find_address_range([ip1])),
797+
[(ip1, ip1)])
798+
self.assertEqual(list(ipaddress._find_address_range([ip1, ip3])),
799+
[(ip1, ip1), (ip3, ip3)])
800+
self.assertEqual(list(ipaddress._find_address_range([ip1, ip2, ip3])),
801+
[(ip1, ip3)])
798802
self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128))
799803
self.assertEqual("IPv4Network('1.2.3.0/24')", repr(self.ipv4_network))
800804

0 commit comments

Comments
 (0)