Skip to content

Commit 69a6612

Browse files
authored
gh-156680: Raise the documented error from IPv6Network.next_network() (#156681)
* gh-156680: Raise the documented error from IPv6Network.next_network() next_network() guarded address-space exhaustion with except OverflowError, which only int.to_bytes() on the IPv4 path raises. _BaseV6._string_from_ip_int() raises ValueError instead, so the handler never ran for IPv6 and the internal 'IPv6 address is too large' message escaped. Build the result from an (address, prefix) tuple rather than formatting and reparsing a string.
1 parent 9398655 commit 69a6612

4 files changed

Lines changed: 23 additions & 14 deletions

File tree

Doc/whatsnew/3.16.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,9 +412,9 @@ io
412412
ipaddress
413413
---------
414414

415-
* Add :meth:`~ipaddress.IPv4Network.next_network` and
416-
:meth:`~ipaddress.IPv6Network.next_network` methods to find the next nearest
417-
network with a specific prefix size.
415+
* Add :meth:`IPv4Network.next_network() <ipaddress.IPv4Network.next_network>`
416+
and :meth:`IPv6Network.next_network() <ipaddress.IPv6Network.next_network>`
417+
methods to find the next nearest network with a specific prefix size.
418418
(Contributed by Faisal Mahmood in :gh:`87027`.)
419419

420420

Lib/ipaddress.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,11 +1124,15 @@ def next_network(self, next_prefix=None):
11241124
11251125
Args:
11261126
next_prefix: The desired next prefix length, if not specified the
1127-
same self.prefixlen will be used
1127+
same self.prefixlen will be used.
11281128
11291129
Returns:
11301130
An IPv(4|6) Network object of the next closest network.
11311131
1132+
Raises:
1133+
ValueError: If next_prefix is outside the range of valid prefix
1134+
lengths, or if no further network of that size exists.
1135+
11321136
"""
11331137
if next_prefix is None:
11341138
next_prefix = self.prefixlen
@@ -1150,15 +1154,13 @@ def next_network(self, next_prefix=None):
11501154
((new_netmask._ip & self.network_address._ip) >> bit_shift) + 1
11511155
) << bit_shift
11521156

1153-
try:
1154-
return self.__class__(
1155-
f"{self._string_from_ip_int(next_ip)}/{next_prefix}"
1156-
)
1157-
except OverflowError:
1157+
if next_ip > self._ALL_ONES:
11581158
raise ValueError(
11591159
f"out of address space, cannot make another /{next_prefix} "
11601160
"network"
1161-
) from None
1161+
)
1162+
1163+
return self.__class__((next_ip, next_prefix))
11621164

11631165

11641166
class _BaseConstants:

Lib/test/test_ipaddress.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,9 +1596,15 @@ def testNextNetworkWithBadPrefix(self):
15961596

15971597
def testNextNetworkOutOfAddressSpace(self):
15981598
ipv4 = ipaddress.IPv4Network('255.255.255.0/24')
1599-
self.assertRaises(ValueError, ipv4.next_network)
1599+
self.assertRaisesRegex(
1600+
ValueError,
1601+
'out of address space, cannot make another /24 network',
1602+
ipv4.next_network)
16001603
ipv6 = ipaddress.IPv6Network('ffff:ffff:ffff:ffff:ffff:ffff:ffff:0/112')
1601-
self.assertRaises(ValueError, ipv6.next_network)
1604+
self.assertRaisesRegex(
1605+
ValueError,
1606+
'out of address space, cannot make another /112 network',
1607+
ipv6.next_network)
16021608

16031609
def testFancySubnetting(self):
16041610
self.assertEqual(sorted(self.ipv4_network.subnets(prefixlen_diff=3)),
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
Add :meth:`~ipaddress.IPv4Network.next_network` and
2-
:meth:`~ipaddress.IPv6Network.next_network`. Patch by Faisal Mahmood.
1+
Add :meth:`IPv4Network.next_network() <ipaddress.IPv4Network.next_network>`
2+
and :meth:`IPv6Network.next_network() <ipaddress.IPv6Network.next_network>`.
3+
Patch by Faisal Mahmood.

0 commit comments

Comments
 (0)